diff --git a/doc/boost_range.html b/doc/boost_range.html index 0d9c8f0..f9fec8c 100644 --- a/doc/boost_range.html +++ b/doc/boost_range.html @@ -27,6 +27,8 @@
  • Semantics
  • +
  • + Extending the library
    @@ -35,7 +37,7 @@ Four types of objects are currently supported by the library: - - Even though the behavior of the primary templates are exactly such - that standard containers will be supported by default, the requirements - are much lower than the standard container requirements. For example, - the utility class iterator_range implements the minimal interface required to make the class - a Forward Range. + + Even though the behavior of the primary templates are exactly such that standard + containers will be supported by default, the requirements are much lower than + the standard container requirements. For example, the utility class iterator_range implements + the minimal interface required to make the + class a Forward Range.

    - +

    - Please also see Range concepts for more details. + Please also see Range concepts for more details.

    - - -

    Synopsis

    + +

    Synopsis

    -namespace boost
    -{
    -    //
    +namespace boost
    +{
    +    //
         // Single Pass Range metafunctions
         //
         
    -    template< class T >
    -    struct value_type_of;
    +    template< class T >
    +    struct value_type_of;
                      
    -    template< class T >
    -    struct iterator_of;
    +    template< class T >
    +    struct iterator_of;
         
    -    template< class T >
    -    struct const_iterator_of;
    +    template< class T >
    +    struct const_iterator_of;
         
    -    //
    +    //
         // Forward Range metafunctions
         //
         
    -    template< class T >
    -    struct difference_type_of;
    +    template< class T >
    +    struct difference_type_of;
         
    -    template< class T >
    -    struct size_type_of;
    +    template< class T >
    +    struct size_type_of;
         
    -    //
    +    //
         // Bidirectional Range metafunctions
         //
         
    -    template< class T >
    -    struct reverse_iterator_of;
    +    template< class T >
    +    struct reverse_iterator_of;
     
    -    template< class T >
    -    struct const_reverse_iterator_of;
    +    template< class T >
    +    struct const_reverse_iterator_of;
         
    -    //
    +    //
         // Special metafunctions
         //
         
    -    template< class T >
    -    struct result_iterator_of;
    +    template< class T >
    +    struct result_iterator_of;
                      
    -    template< class T >
    -    struct reverse_result_iterator_of;
    +    template< class T >
    +    struct reverse_result_iterator_of;
     
    -    //
    +    //
         // Single Pass Range functions
         //
         
    -    template< class T >
    -    inline typename iterator_of<T>::type
    -    begin( T& c );
    +    template< class T >
    +    typename iterator_of<T>::type
    +    begin( T& c );
         
    -    template< class T >
    -    inline typename const_iterator_of<T>::type
    -    begin( const T& c );
    +    template< class T >
    +    typename const_iterator_of<T>::type
    +    begin( const T& c );
             
    -    template< class T >
    -    inline typename iterator_of<T>::type
    -    end( T& c );
    +    template< class T >
    +    typename iterator_of<T>::type
    +    end( T& c );
                           
    -    template< class T >
    -    inline typename const_iterator_of<T>::type
    -    end( const T& c );
    +    template< class T >
    +    typename const_iterator_of<T>::type
    +    end( const T& c );
         
    -    template< class T >
    -    inline bool
    -    empty( const T& c );
    +    template< class T >
    +    bool
    +    empty( const T& c );
                    
    -    //
    +    //
         // Forward Range functions
         //
         
    -    template< class T >
    -    inline typename size_type_of<T>::type
    -    size( const T& c );
    +    template< class T >
    +    typename size_type_of<T>::type
    +    size( const T& c );
                                 
    -    //
    +    //
         // Bidirectional Range functions
         //
                          
    -    template< class T >
    -    inline typename reverse_iterator_of<T>::type
    -    rbegin( T& c );
    +    template< class T >
    +    typename reverse_iterator_of<T>::type
    +    rbegin( T& c );
         
    -    template< class T >
    -    inline typename const_reverse_iterator_of<T>::type
    -    rbegin( const T& c );
    +    template< class T >
    +    typename const_reverse_iterator_of<T>::type
    +    rbegin( const T& c );
             
    -    template< class T >
    -    inline typename reverse_iterator_of<T>::type
    -    rend( T& c );
    +    template< class T >
    +    typename reverse_iterator_of<T>::type
    +    rend( T& c );
                           
    -    template< class T >
    -    inline typename const_reverse_iterator_of<T>::type
    -    rend( const T& c );
    -    
    -} // namespace 'boost' 
    + template< class T > + typename const_reverse_iterator_of<T>::type + rend( const T& c ); + +} // namespace 'boost' +

    - -

    Semantics

    +

    Semantics

    notation

    @@ -179,7 +194,7 @@ namespace boost X - x + x any type @@ -206,10 +221,9 @@ namespace boost

    - Please notice in tables below that when four lines appear in a - cell, the first line will describe the primary template, the second - line pairs of iterators, the third line arrays and the last line - null-terminated strings. + Please notice in tables below that when four lines appear in a cell, the first + line will describe the primary template, the second line pairs of iterators, the + third line arrays and the last line null-terminated strings.

    Metafunctions

    @@ -232,16 +246,16 @@ namespace boost iterator_of<X>::type T::iterator
    - P::first_type
    - A*
    - Char* + P::first_type
    + A*
    + Char* compile time const_iterator_of<X>::type T::const_iterator
    - P::first_type
    + P::first_type
    const A*
    const Char* compile time @@ -250,10 +264,10 @@ namespace boost difference_type_of<X>::type T::difference_type
    - boost_iterator_difference<P::first_type>::type
    - std::ptrdiff_t
    - std::ptrdiff_t
    + std::ptrdiff_t
    + std::ptrdiff_t
    compile time @@ -268,8 +282,8 @@ namespace boost result_iterator_of<X>::type - const_iterator_of<X>::type if X is const
    + const_iterator_of<X>::type if X is const
    iterator_of<X>::type otherwise compile time @@ -289,7 +303,8 @@ namespace boost reverse_result_iterator_of<X>::type - boost::reverse_iterator< typename result_iterator_of<T>::type > + boost::reverse_iterator< typename result_iterator_of<T>::type + > compile time @@ -297,12 +312,11 @@ namespace boost

    - The special metafunctions result_iterator_of and - reverse_result_iterator_of are not part -of any Range concept, but they are very useful when implementing certain - Range classes like sub_range because of -their ability to select iterators based on constness. + The special metafunctions result_iterator_of and reverse_result_iterator_of + are not part of any Range concept, but they are very useful when implementing + certain Range classes like sub_range because of their + ability to select iterators based on constness.

    Functions

    @@ -319,7 +333,7 @@ their ability to select iterators based on constness. begin(x) result_iterator_of<X>::type t.begin()
    - p.first
    + p.first
    a
    s constant time @@ -329,13 +343,13 @@ their ability to select iterators based on constness. end(x) result_iterator_of<X>::type t.end()
    - p.second
    - a + sz
    - s + std::char_traits<X>::length( s ) if -X is Char*
    + p.second
    + a + sz
    + s + std::char_traits<X>::length( s ) if X is Char* +
    s + sz - 1 if X is Char[sz]
    - + linear if X is Char*
    constant time otherwise @@ -353,9 +367,9 @@ their ability to select iterators based on constness. size(x) size_type_of<X>::type t.size()
    - std::distance(p.first,p.second)
    - sz
    - end(s) - s + std::distance(p.first,p.second)
    + sz
    + end(s) - s linear if X is Char*
    or if std::distance() is linear
    @@ -365,22 +379,91 @@ their ability to select iterators based on constness. rbegin(x) reverse_result_iterator_of<X>::type - reverse_result_iterator_of<X>::type( end(x) -)
    same as end(x) + reverse_result_iterator_of<X>::type( end(x) )
    + same as end(x) rend(x) reverse_result_iterator_of<X>::type - reverse_result_iterator_of<X>::type( begin(x) -) same as begin(x) + reverse_result_iterator_of<X>::type( begin(x) ) + same as begin(x)

    -
    +

    Extending the library

    +

    + The primary templates in this library are implemented such that standard + containers will work automatically and so will boost::array. Below is given an overview of + which member functions and member types a class must specify to +be useable as a certain Range concept. +

    +

    + + + + + + + + + + + + + + + + + +
    Member functionRelated concept
    begin()Single Pass Range
    end() Single Pass Range
    size()Forward Range
    +

    +

    + Notice that rbegin() and rend() member functions + are not needed even though the container can support bidirectional iteration. +

    +

    + The required member types are: +

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Member typeRelated concept
    value_typeSingle Pass Range
    iteratorSingle Pass Range
    const_iteratorSingle Pass Range
    difference_typeForward Range
    size_typeForward Range
    +

    +

    + Again one should notice that member types reverse_iterator and + const_reverse_iterator are not needed. +

    + +

    (C) Copyright Thorsten Ottosen 2003-2004

    diff --git a/doc/faq.html b/doc/faq.html index 86506ef..4a65e49 100755 --- a/doc/faq.html +++ b/doc/faq.html @@ -29,6 +29,9 @@ When it is possible to come up with one, the client might choose to construct a std::pair<const_iterator,const_iterator> object.

    +

    + Note that an iterator_range +is somewhat more convenient than a pair.

  • Why is there not supplied more types or more functions?

    @@ -58,11 +61,13 @@

  • Should I use qualified syntax, for example -
    boost::begin( r ); 
    +
    +boost::begin( r ); 
    +
    instead of
    -
    using namespace boost;
    -begin( r )
    +
    using namespace boost;
    +begin( r )
    when calling functions in this library? If so, can I still rely on argument dependent lookup (ADL) to kick in?

    @@ -73,27 +78,30 @@ begin( r ) Daniel Frey on comp.lang.std.c++ in the thread "Whence Swap" and it is best explained by some code:

    -namespace boost
    -{
    -    namespace range_detail                
    -    {
    -        template< class T >            
    -        typename iterator_of<T>:type begin( T& r )
    -        { /* normal implementation */ }
    -    }   
    +namespace boost
    +{
    +    namespace range_detail                
    +    {
    +        template< class T >            
    +        typename iterator_of<T>:type begin( T& r )
    +        { /* normal implementation */ }
    +    }   
                     
    -    template< class T >                
    -    typename iterator_of<T>::type begin( T& r )
    -    {
    -        //        
    +    template< class T >                
    +    typename iterator_of<T>::type begin( T& r )
    +    {
    +        //        
             // Create ADL hook
             //        
    -        using range_detail::begin;                    
    -        return begin( r );                
    -    }
    -}    
    + using range_detail::begin; + return begin( r ); + } +} +
    +Cool indeed!

    + diff --git a/doc/history_ack.html b/doc/history_ack.html index 5514348..3216e4b 100755 --- a/doc/history_ack.html +++ b/doc/history_ack.html @@ -19,7 +19,7 @@

    History and Acknowledgement

    The library have been under way for a long time. Dietmar Kühl originally - intended to submit an array_traits<> class template which + intended to submit an array_traits class template which had most of the functionality present now, but only for arrays and standard containers.

    @@ -48,9 +48,10 @@ C++ standard:

    Special thanks goes to


    diff --git a/doc/intro.html b/doc/intro.html index e65c7d1..ecc44e8 100755 --- a/doc/intro.html +++ b/doc/intro.html @@ -18,16 +18,24 @@

    Introduction

    - When writing generic code that works with Standard Library containers, one often - finds it desirable to extend that code to work with other types that offer + When writing generic code that works with standard library containers, one +often finds it desirable to extend that code to work with other types that offer enough functionality to satisfy the needs of the generic code, but in an altered form. For example, raw arrays are often suitable for use with generic code that works with containers, provided a suitable adapter is used. Likewise, null terminated strings can be treated as containers of characters, if suitably - adapted. This library provides the means to adapt Standard Library containers, + adapted. +

    + +

    + This library provides the means to adapt standard library + containers, null terminated strings, std::pairs of iterators, and raw -arrays, such that the same generic code can work with them all. -

    + arrays (and more), such that the same generic code can work with them all. +The basic idea is to add another layer of indirection using metafunctions and +free-standing functions so syntactic and/or semantic differences can be removed. +

    + +

    Details functions

    + Sequence copy_range( const ForwardRange& r );
    Constructs a new sequence of the specified type from the elements in the given range.
    - + Sequence transform_range( const ForwardRange& r, Func func );
    - Constructs a new sequence from the elements in the range, + Constructs a new sequence from the elements in the range, transformed by a function.
    @@ -175,48 +199,67 @@ The sub_range class inherits all its functionality from the iterator_range class. The sub_range class is often easier to use because one must specify the Forward Range -template argument instead of an iterator. - +template argument instead of an iterator. Moreover, the sub_range +class can propagate constness since it knows what a corresponding +const_iterator is. +

    Synopsis

    -namespace boost
    -{
    +namespace boost
    +{
    +    template< class ForwardRange >
    +    class sub_range : public iterator_range< typename result_iterator_of<ForwardRange>::type >
    +    {
    +    public: 
    +        typedef typename iterator_of<ForwardRange>::type       iterator;
    +        typedef typename const_iterator_of<ForwardRange>::type const_iterator;
         
    -    template< class ForwardRange >
    -    class sub_range : public iterator_range< typename result_iterator_of<ForwardRange>::type >
    -    {
    -    public: // construction, assignment
    -        template< class ForwardTraversalIterator >
    -        sub_range( ForwardTraversalIterator Begin, ForwardTraversalIterator End );
    +    public: // construction, assignment
    +        template< class ForwardTraversalIterator >
    +        sub_range( ForwardTraversalIterator Begin, ForwardTraversalIterator End );
     
    -        template< class ForwardRange2 >
    -        sub_range( ForwardRange2& r );
    +        template< class ForwardRange2 >
    +        sub_range( ForwardRange2& r );
              
    -        template< class ForwardRange2 >
    -        sub_range( const Range2& r );
    +        template< class ForwardRange2 >
    +        sub_range( const Range2& r );
              
    -        template< class ForwardRange2 >
    -        sub_range& operator=( ForwardRange2& r );
    +        template< class ForwardRange2 >
    +        sub_range& operator=( ForwardRange2& r );
     
    -        template< class ForwardRange2 >
    -        sub_range& operator=( const ForwardRange2& r );
    +        template< class ForwardRange2 >
    +        sub_range& operator=( const ForwardRange2& r );    
    +    
    +    public:
    +        iterator        begin();
    +        const_iterator  begin() const;
    +        iterator        end();
    +        const_iterator  end() const;    
             
    -    public:
    -        // rest of interface inherited from iterator_range
    -    };
    -    
    -} // namespace 'boost'
    -    
    + public: + // rest of interface inherited from iterator_range + }; + +} // namespace 'boost' +

    - The class should be trivial to use, an example with strings is shown below. + The class should be trivial to use as seen below. + Imagine that we have an algorithm that searches for a sub-string in a string. + The + result is an iterator_range, that delimits the match. We need to +store the result + from this algorithm. Here is an example of how we can do it with and without +sub_range

    -    typedef sub_range sub_string;
    -    std::string s = "something";
    -    sub_string  ss( s ); 
    -    sub_string  ss2( begin( s ), begin( s ) + 2 );
    - + std::string str("hello"); + iterator_range<std::string::iterator> ir = find_first( str, "ll" ); + sub_range<std::string> sub = find_first( str, "ll" ); + +


    @@ -236,6 +279,7 @@ namespace boost

    + diff --git a/include/boost/range/iterator_range.hpp b/include/boost/range/iterator_range.hpp index c6fa806..2d2e9d6 100755 --- a/include/boost/range/iterator_range.hpp +++ b/include/boost/range/iterator_range.hpp @@ -51,8 +51,6 @@ namespace boost { template class iterator_range { - iterator_range(); // not implemented - public: //! this type typedef iterator_range type; @@ -185,9 +183,9 @@ namespace boost { /*! Compare operands for equality */ - template< class IteratorT > + template< class IteratorT, class IteratorT2 > inline bool operator==( const iterator_range& l, - const iterator_range& r ) + const iterator_range& r ) { return ! (l != r); } @@ -196,9 +194,9 @@ namespace boost { /*! Compare operands for non-equality */ - template< class IteratorT > + template< class IteratorT, class IteratorT2 > inline bool operator!=( const iterator_range& l, - const iterator_range& r ) + const iterator_range& r ) { return l.begin() != r.begin() || l.end() != r.end(); } diff --git a/include/boost/range/sub_range.hpp b/include/boost/range/sub_range.hpp index b21aeb8..2c6ae35 100755 --- a/include/boost/range/sub_range.hpp +++ b/include/boost/range/sub_range.hpp @@ -23,17 +23,15 @@ namespace boost template< class ForwardRange > class sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME result_iterator_of::type > { - sub_range(); // not implemented - typedef BOOST_DEDUCED_TYPENAME result_iterator_of::type iterator_t; typedef iterator_range< iterator_t > base; public: - using base::iterator; - using base::const_iterator; - using base::value_type; - typedef BOOST_DEDUCED_TYPENAME difference_type_of::type difference_type; - typedef BOOST_DEDUCED_TYPENAME size_type_of::type size_type; + using BOOST_DEDUCED_TYPENAME base::value_type; + using BOOST_DEDUCED_TYPENAME base::iterator; + typedef BOOST_DEDUCED_TYPENAME const_iterator_of::type const_iterator; + typedef BOOST_DEDUCED_TYPENAME difference_type_of::type difference_type; + typedef BOOST_DEDUCED_TYPENAME size_type_of::type size_type; public: template< class ForwardRange2 > @@ -63,10 +61,13 @@ namespace boost return *this; } - size_type size() const - { - return base::size(); - } + public: + + iterator begin() { return base::begin(); } + const_iterator begin() const { return base::begin(); } + iterator end() { return base::end(); } + const_iterator end() const { return base::end(); } + size_type size() const { return std::distance( begin(), end() ); } }; diff --git a/include/boost/range/types.hpp b/include/boost/range/types.hpp deleted file mode 100755 index f0bd5cf..0000000 --- a/include/boost/range/types.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// Boost.Range library -// -// Copyright Thorsten Ottosen 2003-2004. Use, modification and -// distribution is subject to the Boost Software License, Version -// 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// For more information, see http://www.boost.org/libs/range/ -// - -#ifndef BOOST_RANGE_TYPES_HPP -#define BOOST_RANGE_TYPES_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif diff --git a/test/algorithm_example.cpp b/test/algorithm_example.cpp index 2b552f8..41014b7 100755 --- a/test/algorithm_example.cpp +++ b/test/algorithm_example.cpp @@ -17,6 +17,8 @@ #include #include +#include +#include #include #include #include @@ -24,7 +26,6 @@ namespace { - // // example: extrating bounds in a generic algorithm // @@ -58,12 +59,12 @@ namespace } -int main() +void check_algorithm() { // // usage // - const int N = 5; + const unsigned N = 5; std::vector my_vector; int values[] = { 1,2,3,4,5,6,7,8,9 }; my_vector.assign( values, values + 9 ); @@ -73,8 +74,24 @@ int main() char str_val[] = "a string"; char* str = str_val; - std::cout << my_generic_replace( my_vector, 4, 2 ) - << my_generic_replace( my_view, 4, 2 ) - << my_generic_replace( str, 'a', 'b' ); - return 0; + BOOST_CHECK_EQUAL( my_generic_replace( my_vector, 4, 2 ), 3u ); + BOOST_CHECK_EQUAL( my_generic_replace( my_view, 4, 2 ), N ); + BOOST_CHECK_EQUAL( my_generic_replace( str, 'a', 'b' ), 0u ); + } + +#include + +using boost::unit_test_framework::test_suite; + +test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); + + test->add( BOOST_TEST_CASE( &check_algorithm ) ); + + return test; +} + + + diff --git a/test/sub_range.cpp b/test/sub_range.cpp index fe3edb8..3fc1974 100755 --- a/test/sub_range.cpp +++ b/test/sub_range.cpp @@ -60,11 +60,13 @@ void check_iterator_range() typedef sub_range csrange; srange s = r; BOOST_CHECK( r == r ); + BOOST_CHECK( s == r ); s = make_iterator_range( str ); csrange s2 = r; s2 = r2; s2 = make_iterator_range( cstr ); BOOST_CHECK( r2 == r2 ); + BOOST_CHECK( s2 != r2 ); s2 = make_iterator_range( str ); BOOST_CHECK( !(s != s) ); @@ -88,7 +90,10 @@ void check_iterator_range() string res = copy_range( r ); BOOST_CHECK( equal( res.begin(), res.end(), r.begin() ) ); - + res = transform_range( r, add_one() ); + BOOST_CHECK( res[0] == 'i' ); + BOOST_CHECK( *res.rbegin() == 'e' ); + r.empty(); s.empty(); r.size();