diff --git a/doc/boost_range.html b/doc/boost_range.html index 41f4e81..ec65bdc 100644 --- a/doc/boost_range.html +++ b/doc/boost_range.html @@ -3,6 +3,7 @@ Boost.Range Range Implementation + @@ -42,17 +43,14 @@ Five types of objects are currently supported by the library: standard containers
  • - built-in arrays + std::pair<iterator,iterator>
  • null terminated strings (this includes char[],wchar_t[], char*, and wchar_t*)
  • - std::pair<iterator,iterator> -
  • -
  • - iterators which when default constructed denotes the end of the range + built-in arrays
  • It is worth noticing that some functionality requires partial template @@ -61,99 +59,102 @@ small problem since one would use boost::array<> anyway). Also note that arrays and pointers of char or whar_t are treated special because of their use in string algorithms.

    -

    ExternalCollectionConcept

    +

    -The concept is defined by the type-generators and the functions below. Even +The concept is defined by the metafunction and the functions below. Even though these functions are defined in namespace boost, there is no such general requirement, that is, if one wants to extend the list of supported types, it can be done in any namespace.

    +

    Synopsis

    +

    +

    -    namespace boost
    -    {
    -        //
    -        // type generators
    -        //
    -        
    -        template< typename EC >
    -        struct value_type_of
    -        {
    -            typedef ... type; // type of stored objects
    -        };
    -                     
    -        template< typename EC >
    -        struct iterator_of
    -        {
    -            typedef ... type; // iterator over stored objects
    -        };
    -        
    -        template< typename EC >
    -        struct const_iterator_of
    -        {
    -            typedef ... type; // iterator over immutable stored objects
    -        };
    -
    -        template< typename EC >
    -        struct difference_type_of
    -        {
    -            typedef ... type;
    -            BOOST_STATIC_ASSERT( boost::is_signed< type >::value );
    -            //
    -            // remark: if std::iterator_traits<> works for the type, this assertion must
    -            hold
    -            //
    -            BOOST_STATIC_ASSERT( boost::is_same< type, std::iterator_traits< typename
    -                                                       iterator_of< EC >::type >::difference_type>::value );
    -        };
    -
    -        template< typename EC >
    -        struct size_type_of
    -        {
    -            typedef ... type;
    -            BOOST_STATIC_ASSERT( boost::is_unsigned< type >::value );
    -            BOOST_STATIC_ASSERT( sizeof( type ) >= sizeof( 
    -            difference_type_of< EC >::type ) );
    -        };
    -
    -        template< typename EC >
    -        struct result_iterator_of
    -        {
    -            typedef ... type;
    -            // iterator_of< EC >::type if EC is non-const, 
    -            const_iterator_of< EC >::type otherwise
    -        };
    -                     
    -        //
    -        // funtions
    -        //
    -        
    -        template< typename EC >
    -        inline typename iterator_of::type
    -        begin( EC& c );
    +namespace boost
    +{
    +    //
    +    // Range metafunctions
    +    //
         
    -        template< typename EC >
    -        inline typename const_iterator_of< EC >::type
    -        begin( const EC& c );
    -            
    -        template< typename EC >
    -        inline typename iterator_of< EC >::type
    -        end( EC& c );
    -                          
    -        template< typename EC >
    -        inline typename const_iterator_of< EC >::type
    -        end( const EC& c );
    +    template< class T >
    +    struct value_type_of
    +    {
    +        typedef ... type; // type of stored objTts
    +    };
    +                 
    +    template< class T >
    +    struct iterator_of
    +    {
    +        typedef ... type; // iterator over stored objects
    +    };
    +    
    +    template< class T >
    +    struct const_iterator_of
    +    {
    +        typedef ... type; // iterator over immutable stored objects
    +    };
    +    
    +    template< class T >
    +    struct difference_type_of
    +    {
    +        typedef ... type;
    +        BOOST_STATIC_ASSERT( boost::is_signed< type >::value );
    +        //
    +        // remark: if std::iterator_traits<> works for the type, this assertion must
    +        hold
    +        //
    +        BOOST_STATIC_ASSERT( boost::is_same< type, std::iterator_traits< typename
    +                                                   iterator_of< T >::type >::difference_type>::value );
    +    };
    +    
    +    template< class T >
    +    struct size_type_of
    +    {
    +        typedef ... type;
    +        BOOST_STATIC_ASSERT( boost::is_unsigned< type >::value );
    +        BOOST_STATIC_ASSERT( sizeof( type ) >= sizeof( 
    +        difference_type_of< T >::type ) );
    +    };
    +    
    +    template< class T >
    +    struct result_iterator_of
    +    {
    +        typedef ... type;
    +        // iterator_of< T >::type if T is non-const, 
    +        const_iterator_of< T >::type otherwise
    +    };
    +                 
    +    //
    +    // funtions
    +    //
    +    
    +    template< class T >
    +    inline typename iterator_of::type
    +    begin( T& c );
    +    
    +    template< class T >
    +    inline typename const_iterator_of< T >::type
    +    begin( const T& c );
             
    -        template< typename EC >
    -        inline bool
    -        empty( const EC& c );
    -                   
    -        template< typename EC >
    -        inline typename size_type_of< EC >::type
    -        size( const EC& c );
    -                     
    -     } // namespace 'boost' 
    + template< class T > + inline 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 > + inline bool + empty( const T& c ); + + template< class T > + inline typename size_type_of< T >::type + size( const T& c ); + +} // namespace 'boost'

    diff --git a/doc/external_concepts.html b/doc/external_concepts.html index 98ccf90..f04671d 100644 --- a/doc/external_concepts.html +++ b/doc/external_concepts.html @@ -1,38 +1,123 @@ - Concepts and External Concepts

    Concepts and External Concepts

    Generic programming in C++ is characterized by the use of function and class templates where - the template parameter(s) must satisfy certain requirements.Often these - requirements are so important that we give them a name: we call - such a set of type requirements a concept. We say that a type - conforms to a concept or that it is a model of a concept if it - satisfies all of those requirements. The concept can be specified as a set - of member functions with well-defined semantics - and a set of nested typedefs with well-defined properties.

    Often it much more flexible to provide free-standing functions and typedefs - which provides the exact same semantics (but a different syntax) as - specified - by the concept. This allows generic code to treat different types as if - they fulfilled the concept. In this case we say that the concept has - been externalized or that the new requirements constitutes an external - concept . We say that a type conforms to an external concept - or that it is a model of an external concept . A concept may exist - without a corresponding external concept and conversely.

    Whenever a concept specifies a member function, the corresponding external - concept - must specify a free-standing function of the same name, same return type and - the same argument list except there is an extra first argument which must - be of the type (or a reference to that type) that is to fulfill the external - concept. If the corresonding member function has any cv-qulifiers, the - first argument must have the same cv-qualifiers. Whenever a concept - specifies a nested typedef, the corresponding external concept - specifies a type-generator, that is, a type with a nested typedef - named type. The type-generator has the name as the nested typedef with - _of appended. - The converse relationship of an external concept and its corresponding concept - also holds.

    Example:

    A type T fulfills the FooConcept if it - has the follwing public members:

    void T::foo( int ) const;
    - int T::bar();
    - typedef implementation defined foo_type;

    The corresponding external concept is the ExternalFooConcept.

    A type T fullfills the ExternalFooConcept if these - free-standing functions and type-generators exists:

    void foo( const T&, int );
    - int bar( T& );
    - foo_type_of< T >::type;



    Literature


    © Thorsten Ottosen 2003-2004 (nesotto_AT_cs.auc.dk). - Permission to copy, use, modify, sell and distribute this software is granted provided this copyright notice appears - in all copies. This software is provided "as is" without express or implied warranty, and with no - claim as to its suitability for any purpose.































    - \ No newline at end of file + + + + Concepts and External Concepts + + + + + + + + +

    Concepts and External Concepts

    +

    +Generic programming in C++ is characterized by the use of function and class +templates where the template parameter(s) must satisfy certain requirements.Often +these requirements are so important that we give them a name: we call such a set +of type requirements a concept. We say that a type conforms to a +concept or that it is a model of a concept if it satisfies all of +those requirements. The concept can be specified as a set of member functions +with well-defined semantics and a set of nested typedefs with well-defined +properties. +

    +

    +Often it much more flexible to provide free-standing functions and typedefs +which provides the exact same semantics (but a different syntax) as specified by +the concept. This allows generic code to treat different types as if they +fulfilled the concept. In this case we say that the concept has been externalized + or that the new requirements constitutes an external concept . We +say that a type conforms to an external concept or that it is a model +of an external concept . A concept may exist without a corresponding +external concept and conversely. +

    +

    +Whenever a concept specifies a member function, the corresponding external +concept must specify a free-standing function of the same name, same return type +and the same argument list except there is an extra first argument which must be +of the type (or a reference to that type) that is to fulfill the external +concept. If the corresonding member function has any cv-qulifiers, the first +argument must have the same cv-qualifiers. Whenever a concept specifies a nested +typedef, the corresponding external concept specifies a metafunction, +that is, a type with a nested typedef named type. The metafunction +has the name as the nested typedef with _of appended. The converse +relationship of an external concept and its corresponding concept also holds. +

    +

    +Example: +

    +

    +A type T fulfills the FooConcept if it has the follwing public +members: +

    +void T::foo( int ) const;
    +int T::bar();
    +typedef implementation defined foo_type;
    +

    +The corresponding external concept is the ExternalFooConcept. +

    +

    +A type T fullfills the ExternalFooConcept if these free-standing +functions and metafunctions exists: +

    +void foo( const T&, int );
    +int bar( T& );
    +foo_type_of< T >::type;

    +
    +
    +

    Literature

    + +
    +

    +© Thorsten Ottosen 2003-2004 (nesotto_AT_cs.auc.dk). Permission to copy, +use, modify, sell and distribute this software is granted provided this +copyright notice appears in all copies. This software is provided "as is" +without express or implied warranty, and with no claim as to its suitability for +any purpose. +

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/doc/faq.html b/doc/faq.html index 91b1587..86506ef 100755 --- a/doc/faq.html +++ b/doc/faq.html @@ -17,12 +17,12 @@

    -

    FAQ

    - +

    FAQ

    1. - Why is there no difference between iterator_of<C>::type and const_iterator_of<C>::type - for std::pair<iterator, iterator>. + Why is there no difference between iterator_of<C>::type + and const_iterator_of<C>::type for std::pair<iterator, + iterator>.
    2. In general it is not possible nor desirable to find a corresponding const_iterator. @@ -30,24 +30,71 @@ object.

    3. - Why is there not supplied more types or more functions? + Why is there not supplied more types or more functions?

      - The library have been kept small because its current interface will serve - most purposes. If and when a genuine need arises for more functionality, it can - be implemented. + The library have been kept small because its current interface will serve most + purposes. If and when a genuine need arises for more functionality, it can be + implemented.

    4. - How should I implement generic algorithms for ranges? + How should I implement generic algorithms for ranges?

      - One should always start with a generic algorithm that takes two - iterators (or more) as - input. Then use Boost.Range to build handier versions on top of the - iterator based algorithm. Please notice that once the range version - of the algorithm is done, it makes sense not to expose the - iterator version in the public interface. + One should always start with a generic algorithm that takes two iterators (or + more) as input. Then use Boost.Range to build handier versions on top of the + iterator based algorithm. Please notice that once the range version of the + algorithm is done, it makes sense not to expose the iterator version in + the public interface.

    5. +
    6. + Why is there no Incrementable Range concept? +

      + Even though we speak of incrementable iterators, it would not make + much sense for ranges; for example, we cannot determine the size and + emptiness of a range since we cannot even compare + its iterators. +

      +
    7. +
    8. + Should I use qualified syntax, for example +
      boost::begin( r ); 
      + instead of +
      +
      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?
      +

      + The answer to the first question is that "it's up to you". The + answer to the second question is Yes. Normally qualified syntax + disables ADL, but the functions are implemented in a special + manner that preserves ADL properties. The trick was explained by + 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 */ }
      +    }   
      +                
      +    template< class T >                
      +    typename iterator_of<T>::type begin( T& r )
      +    {
      +        //        
      +        // Create ADL hook
      +        //        
      +        using range_detail::begin;                    
      +        return begin( r );                
      +    }
      +}    
      +
      +

      +
    diff --git a/doc/headers.html b/doc/headers.html index 47b6b48..a7b1eb2 100755 --- a/doc/headers.html +++ b/doc/headers.html @@ -22,87 +22,108 @@ Header Includes + Related concept <boost/range.hpp> everything + - - <boost/range/types.hpp> - every meta-function + <boost/range/metafunctions.hpp> + every metafunction + - <boost/range/functions.hpp> every function + - <boost/range/value_type.hpp> value_type_of + Single Pass Range <boost/range/iterator.hpp> iterator_of + Single Pass Range <boost/range/const_iterator.hpp> const_iterator_of + Single Pass Range <boost/range/difference_type.hpp> difference_type_of + Forward Range <boost/range/size_type.hpp> size_type_of + Forward Range <boost/range/result_iterator.hpp> result_iterator_of + - <boost/range/reverse_iterator.hpp> reverse_iterator_of + Bidirectional Range <boost/range/const_reverse_iterator.hpp> const_reverse_iterator_of + Bidirectional Range <boost/range/reverse_result_iterator.hpp> reverse_result_iterator_of + - <boost/range/begin.hpp> begin + Single Pass Range <boost/range/end.hpp> end + Single Pass Range <boost/range/empty.hpp> empty + Single Pass Range <boost/range/size.hpp> size + Forward Range <boost/range/rbegin.hpp> rbegin + Bidirectional Range <boost/range/rend.hpp> rend + Bidirectional Range <boost/range/iterator_range.hpp> iterator_range + >iterator_range + - <boost/range/sub_range.hpp> sub_range + - diff --git a/doc/history_ack.html b/doc/history_ack.html index d201580..5514348 100755 --- a/doc/history_ack.html +++ b/doc/history_ack.html @@ -25,10 +25,25 @@

    - Meanwhile work on container algorithms in various context showed the + Meanwhile work on algorithms for containers in various contexts showed the need for handling pairs of iterators, and string libraries needed special - treatment of character arrays. -

    + treatment of character arrays. In the end it made sense to formalize the + minimal requirements of these similar concepts. And the results are the + Range concepts found in this library.

    + +

    + The term Range was adopted because of paragraph 24.1/7 from the +C++ standard:

    + Most of the library's algorithmic templates that operate on data + structures have interfaces that use ranges. A range is a pair of + iterators that designate the beginning and end of the computation. A + range [i, i) is an empty range; in general, a range [i, j) refers to + the elements in the data structure starting with the one pointed to + by i and up to but not including the one pointed to by j. Range [i, + j) is valid if and only if j is reachable from i. The result of the + application of functions in the library to invalid ranges is + undefined. +

    Special thanks goes to diff --git a/doc/intro.html b/doc/intro.html index eadca07..e65c7d1 100755 --- a/doc/intro.html +++ b/doc/intro.html @@ -18,22 +18,32 @@

    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 + 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, + null terminated strings, std::pairs of iterators, and raw +arrays, such that the same generic code can work with them all. +

    + +

    The main advantages are

    Below are given a small example (the complete example can be found here ): -

    +    
    +
    +    //
    +    // example: extracting bounds in a generic algorithm
    +    //
    +    template< typename ForwardRange, typename T >
    +    inline typename boost::iterator_of< ForwardRange >::type
    +    find( ForwardRange& c, const T& value )
    +    {
    +       return std::find( boost::begin( c ), boost::end( c ), value );
    +    }
    +    
    +    template< typename ForwardRange, typename T >
    +    inline typename boost::const_iterator_of< ForwardRange >::type
    +    find( const ForwardRange& c, const T& value )
    +    {
    +       return std::find( boost::begin( c ), boost::end( c ), value );
    +    }
    +                   
    +    //
    +    // replace first value and return its index
    +    //
    +    template< class ForwardRange, class T >
    +    inline typename boost::size_type_of< ForwardRange >::type
    +    my_generic_replace( ForwardRange& c, const T& value, const T& replacement )
    +    {
    +       typename boost::iterator_of< ForwardRange >::type found = find( c, value );
            
    -       //
    -       // Example: extracting bounds in generic algorithms
    -       //
    -                       
    -       template< typename XRange, typename T >
    -       inline typename boost::iterator_of<XRange>::type
    -       find( XRange& c, const T& value )
    -       {
    -           return std::find( boost::begin( c ), boost::end( c ), value );
    -       }
    -
    -       template< typename XRange, typename T >
    -       inline typename boost::const_iterator_of<XRange>::type
    -       find( const XRange& c, const T& value )
    -       {
    -           return std::find( boost::begin( c ), boost::end( c ), value );
    -       }
    -                       
    -       //
    -       // replace first value and return its index
    -       //
    -       template< typename EC, typename T >
    -       inline typename boost::size_type_of< EC >::type
    -       my_generic_replace( EC& c, const T& value, const T& replacement )
    -       {
    -           typename boost::const_iterator_of<EC>::type found = find( c, value );
    +       if( found != boost::end( c ) )
                *found = replacement;
    -           return std::distance( boost::begin( c ), found );
    -       }
    -                       
    -       //
    -       // usage
    -       //
    -       std::vector<int>              my_vector;
    -       typedef vector<int>::iterator iterator;
    -       std::pair<iterator,iterator>  my_view( my_vector.begin(), my_vector.begin(
    -       ) + N );
    -       char str[] = "a string";
    -       // ...
    -       std::cout << my_generic_replace( my_vector, 4, 2 )
    -                 << my_generic_replace( my_view, 4, 2 )
    -                 << my_generic_replace( str, 'a', 'b' );
    -       
    + return std::distance( boost::begin( c ), found ); + } - By using the free-standing functions and type-generators, the code automatically + // + // usage + // + const int N = 5; + std::vector my_vector; + int values[] = { 1,2,3,4,5,6,7,8,9 }; + my_vector.assign( values, values + 9 ); + typedef std::vector::iterator iterator; + std::pair my_view( boost::begin( my_vector ), + boost::begin( my_vector ) + N ); + 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' ); + +
    + + + By using the free-standing functions and metafunctions, the code automatically works for all the types supported by this library. Notice that we have to provide two version of find() since we cannot forward a non-const rvalue with reference arguments (see this article about The diff --git a/doc/portability.html b/doc/portability.html index 92ee98a..2d61ffd 100755 --- a/doc/portability.html +++ b/doc/portability.html @@ -20,7 +20,7 @@

    Full support for built-in arrays require that the compiler supports class template partial specialization. For non-conforming compilers there might - be a change that it works anyway thanks to workarounds in the type traits + be a chance that it works anyway thanks to workarounds in the type traits library.

    Notice that some compilers cannot do function template ordering properly. In diff --git a/doc/range.htm b/doc/range.htm index c4308ed..42c5864 100755 --- a/doc/range.htm +++ b/doc/range.htm @@ -16,318 +16,454 @@ - - - - - -

    Boost.Range

    + + + + + +

    Boost.Range

    -

    Range concepts

    +

    Range concepts

    -
    -
    + -

    Range

    +
    +
    +

    Overview

    -

    Description

    +

    + A Range is a concept similar to the STL Container concept. A + Range provides iterators for accessing a closed-open range +[first,one_past_last) of elements and provides + information about the number of elements in the Range. However, a Range has + fewer requirements than a Container. +

    +

    + The motivation for the Range concept is + that there are many useful Container-like types that do not meet the full + requirements of Container, and many algorithms that can be written with this + reduced set of requirements. In particular, a Range does not necessarily -A Range is a concept similar to the STL Container concept. A -Range provides iterators for accessing a range of elements and provides -information about the number of elements in the Range. However, a Range has -fewer requirements than a Container. The motivation for the Range concept is -that there are many useful Container-like types that do not meet the full -requirements of Container, and many algorithms that can be written with this -reduced set of requirements. In particular, a Range does not necessarily +

    - + + Because of the second requirement, a Range object must be passed by reference in + generic code. -Because of the second requirement, a Range object must be passed by reference in -generic code. +

    +

    + The operations that can be performed on a Range is dependent on the + traversal +category of the underlying iterator type. Therefore + the range concepts are named to reflect which traversal category its + iterators support. See also terminology and style guidelines. + for more information about naming of ranges.

    + +

    -

    +

    -

    Notation

    - - - - - - - - - - - - - -
    XA type that is a model of Range.
    a, bObject of type X.
    TThe value type of X.
    +
    + +

    Single Pass Range

    -

    Associated types

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Value typevalue_type_of<X>::typeThe type of the object stored in a Range. -
    Iterator typeiterator_of<X>::typeThe type of iterator used to iterate through a Range's elements. - The iterator's value type is expected to be the Range's value type. A - conversion from the iterator type to the const iterator type must exist. The - iterator type must at least be an InputIterator.
    Const iterator typeconst_iterator_of<X>::typeA type of iterator that may be used to examine, but not to - modify, a Range's elements.
    Reference typereference_of<X>::typeA type that behaves like a reference to the Range's value type. [1]
    Distance typedifference_type_of<>::typeA signed integral type used to represent the distance between - two of the Range's iterators. This type must be the same as the iterator's - distance type.
    Size typesize_type_of<X>::typeAn unsigned integral type that can represent any nonnegative - value of the Range's distance type.
    - - -

    Valid expressions

    - -The following expressions must be valid. -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameExpressionReturn type
    Beginning of rangebegin(a)iterator if a is mutable, const_iterator - otherwise
    End of rangeend(a)iterator if a is mutable, const_iterator - otherwise
    Size of rangesize(a)size_type
    Is range empty?empty(a)Convertible to bool
    -

    Expression semantics

    - - - - - - - - + + + +
    ExpressionSemanticsPostcondition
    +

    Notation

    + - - - + + - + + + +
    begin(a)Returns an iterator pointing to the first element in the Range.begin(a) is either dereferenceable or -past-the-end. It is past-the-end if and only if size(a) == 0.XA type that is a model of Single Pass Range.
    end(a)aObject of type X.
    + + +

    Description

    +

    + A range X where iterator_of<X>::type is a model of +Single Pass Iterator + +

    + + +

    Associated types

    + + + + + + + + + + + + + + + + +
    Value typevalue_type_of<X>::typeThe type of the object stored in a Range. +
    Iterator typeiterator_of<X>::typeThe type of iterator used to iterate through a Range's elements. + The iterator's value type is expected to be the Range's value type. A + conversion from the iterator type to the const iterator type must exist. +
    Const iterator typeconst_iterator_of<X>::typeA type of iterator that may be used to examine, but not to + modify, a Range's elements.
    + + +

    Valid expressions

    + + The following expressions must be valid. +

    + + + + + + + + + + + + + + + + + + + + + +
    NameExpressionReturn type
    Beginning of rangebegin(a)iterator_of<X>::type if +a is mutable, const_iterator_of<X>::type +otherwise
    End of rangeend(a)iterator_of<X>::type if +a is mutable, const_iterator_of<X>::type +otherwise
    Is range empty?empty(a)Convertible to bool
    +

    Expression semantics

    + + + + + + + + + + + + + + - + - - - + + + + +
    ExpressionSemanticsPostcondition
    begin(a)Returns an iterator pointing to the first element in the Range.begin(a) is either dereferenceable or past-the-end. + It is past-the-end if and only if size(a) == 0.
    end(a) Returns an iterator pointing one past the last element in the Range.end(a) is past-the-end.end(a) is past-the-end.
    size(a)Returns the size of the Collection, that is, its number of - elements.size(a) >= 0empty(a)Equivalent to begin(a) == end(a). (But possibly + faster.) - 
    + +

    Complexity guarantees

    + + All three functions are at most amortized linear time. For most practical + purposes, one can expect begin(a), end(a) and empty(a) + to be amortized constant time. + +

    Invariants

    + + + + - - + + + +
    Valid rangeFor any Range a, [begin(a),end(a)) is + a valid range, that is, end(a) is reachable from begin(a) + in a finite number of increments.
    empty(a)Equivalent to size(a) == 0. (But -possibly faster.)  - CompletenessAn algorithm that iterates through the range [begin(a),end(a)) + will pass through every element of a.
    + + +

    See also

    +

    + Container +

    + +
    +

    Forward Range

    + +

    Notation

    + + + + -
    XA type that is a model of Forward Range.
    +
    aObject of type X.
    -

    Complexity guarantees

    +

    Description

    +

    + A range X where iterator_of<X>::type is a model +of Forward Traversal Iterator +

    -All four functions are at most amortized linear time. For most practical -purposes, one can expect begin(a), end(a) and -empty(a) to be amortized constant time. +

    Refinement of

    Single Pass +Range + +

    Associated types

    -

    Invariants

    - - - - - - - - - - - - - -
    Valid rangeFor any Range a, [begin(a),end(a)) is a - valid range, that is, end(a) is reachable from begin(a) - in a finite number of increments.
    Range sizesize(a) is equal to the distance from -begin(a) to end(a).
    CompletenessAn algorithm that iterates through the range -[begin(a),end(a)) will pass through every element of a.
    + + + + + + + + + + + +
    Distance typedifference_type_of<X>::typeA signed integral type used to represent the distance between + two of the Range's iterators. This type must be the same as the iterator's + distance type.
    Size typesize_type_of<X>::typeAn unsigned integral type that can represent any nonnegative + value of the Range's distance type.
    + +

    Valid expressions

    + + + + + + + + + + + + +
    NameExpressionReturn type
    Size of rangesize(a)size_type
    + +

    Expression semantics

    + + + + + + + + + + + + +
    ExpressionSemanticsPostcondition
    size(a)Returns the size of the Range, that is, its number +of elements. Note size(a) == 0u is equivalent to +empty(a).size(a) >= 0
    + +

    Complexity guarantees

    + +

    size(a) is at most amortized linear time.

    + +

    Invariants

    +

    + + + +
    Range sizesize(a) is equal to the distance from begin(a) + to end(a).
    +

    +
    + +

    Bidirectional Range

    + +

    Notation

    + + + + + + + + + +
    XA type that is a model of Bidirectional Range.
    aObject of type X.
    + +

    Description

    This concept provides access to iterators that traverse in + both directions (forward and reverse). The +iterator_of<X>::type iterator must meet all of the requirements +of
    Bidirectional Traversal Iterator. + +

    Refinement of

    Forward Range + +

    Associated types

    + + + + + + + + + + + + +
    Reverse Iterator typereverse_iterator_of<X>::typeThe type of iterator used to iterate through a Range's elements + in reverse order. The iterator's value type is expected to be the Range's value + type. A conversion from the reverse iterator type to the const reverse iterator + type must exist.
    Const reverse iterator typeconst_reverse_iterator_of<X>::typeA type of reverse iterator that may be used to examine, but not + to modify, a Range's elements.
    -

    Models

    - +

    Valid expressions

    -

    See also

    Container + + + + + + + + + + + + + + + + + -
    -
    -
    -
    +
    NameExpressionReturn typeSemantics
    Beginning of rangerbegin(a)reverse_iterator_of<X>::type if +a is mutable, const_reverse_iterator_of<X>::type +otherwise.Equivalent to +reverse_iterator_of<X>::type(end(a)).
    End of rangerend(a)reverse_iterator_of<X>::type if +a is mutable, const_reverse_iterator_of<X>::type +otherwise.Equivalent to +reverse_iterator_of<X>::type(begin(a)).
    -

    ReversibleRange

    +

    Complexity guarantees

    + + rbegin(a) has the same complexity as end(a) and rend(a) + has the same complexity as begin(a) from
    Forward Range. + +

    Invariants

    +

    + + + + + + + + + +
    Valid reverse rangeFor any Bidirectional Range a, [rbegin(a),rend(a)) + is a valid range, that is, rend(a) is reachable from rbegin(a) + in a finite number of increments.
    CompletenessAn algorithm that iterates through the range [rbegin(a),rend(a)) + will pass through every element of a.
    +

    +
    + +

    Random Access Range

    Description

    +

    + A range X where iterator_of<X>::type is a model +of Random Access Traversal Iterator +

    + +

    Refinement of

    +

    + Bidirectional Range +

    + +
    -

    Description

    This concept provides access to iterators that traverse in -both directions (forward and reverse). The iterator type must meet all of the -requirements of BidirectionalIterator -except that the reference type does not have to be a real C++ reference. + + + + + + + +
    Copyright © 2000Jeremy Siek +
    Copyright © 2004Thorsten Ottosen. +
    -

    Valid expressions

    - - - - - - - - - - - - - - - - - - - -
    NameExpressionReturn typeSemantics
    Beginning of rangerbegin(a)reverse_iterator if a is mutable, const_reverse_iterator - otherwise.Equivalent to X::reverse_iterator(end(a)).
    End of rangerend(a)reverse_iterator if a is mutable, const_reverse_iterator - otherwise.Equivalent to -X::reverse_iterator(begin(a)).
    - -

    Complexity guarantees

    - -rbegin(a) has the same complexity as end(a) and -rend(a) has the same complexity as begin(a) from Range. - -

    Models

    - - - -
    -

    Notes

    - -

    -[1] - -The reference type does not have to be a real C++ reference. The requirements of -the reference type is that it behaves like a real reference. Hence the -reference type must be convertible to the value_type and assignment through - -
    -
    -


    -
    - - - - - - - -
    Copyright © 2000Jeremy Siek -
    Copyright © 2004Thorsten Ottosen. -
    - - +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/doc/style.html b/doc/style.html index 673a474..b719356 100755 --- a/doc/style.html +++ b/doc/style.html @@ -12,71 +12,65 @@ - + +

    Boost.Range

    Boost.Range

    Terminology and style guidelines

    - +

    - The use of a consistent terminologi is as important for iterator Ranges - and ExternalRange-based algorithms as it - is for iterators and iterator-based algorithms. If a conventional set of names - are adopted, we can avoid misunderstandings and write generic function - prototypes that are self-documenting. + The use of a consistent terminology is as important for Ranges + and range-based algorithms as it is for iterators and iterator-based algorithms. + If a conventional set of names are adopted, we can avoid misunderstandings and + write generic function prototypes that are self-documenting.

    - Since iterator ranges are characterized by a specific underlying iterator type, - we get a type of iterator range for each type of iterator. Hence we can speak of - the following types of iterator ranges: + Since ranges are characterized by a specific underlying iterator type, we get a + type of range for each type of iterator. Hence we can speak of the following + types of ranges:

    Notice how we have used the categories from the new - style iterators. - + style iterators. +

    - Notice that an interator (and therefore an iterator range) has one traversal + Notice that an iterator (and therefore an range) has one traversal property and one or more properties from the value access category. So in - reality we will mostly talk about mixtures such as + reality we will mostly talk about mixtures such as

    - By convention, we should always specify the travelsal property first as - done above. This seems resonable since there will only be one traversal - property, but perhaps many value acccess properties. + By convention, we should always specify the traversal property first as + done above. This seems reasonable since there will only be one traversal + property, but perhaps many value access properties.

    @@ -88,7 +82,7 @@ void sort( RandomAccessTraversalReadableWritableIterator first, RandomAccessTraversalReadableWritableIterator last ); - For iterator ranges the interface becomes + For ranges the interface becomes

        template< class RandomAccessReadableWritableRange >
    diff --git a/doc/utility_class.html b/doc/utility_class.html
    index d2db418..338db5a 100644
    --- a/doc/utility_class.html
    +++ b/doc/utility_class.html
    @@ -2,146 +2,179 @@
     
     
     
    -
    -Boost.Range Utility Classes 
    -
    +    
    +    Boost.Range Utilities 
    +    
     
     
    -
    -  
    -    
    -      
    -      
    -    
    -  
    -

    Boost.Range utility classes

    -
    + + + + + + +

    Boost.Range

    +

    Utilities

    +

    + Having an abstraction that encapsulates a pair of iterators is very useful. The + standard library uses std::pair in some circumstances, but that + class is cumbersome to use because we need to specify two template arguments, + and for all range algorithm purposes we must enforce the two template arguments + to be the same. Moreover, std::pair<iterator,iterator> is hardly + self-documenting whereas more domain specific class names are. Therefore these + two classes are provided: -

    Having an abstraction that encapsulates a pair of iterators is very - useful. The standard library uses std::pair in some -cercumstances, but that class is cumbersome to use because we need to -specify two template arguments, and for all range algorithm purposes, -we must enforce the two template arguments to be the same. Moreover, -std::pair<iterator,iterator> is hardly self-documenting -whereas more domain specific class names are. Therefore these two -classes are provided: +

    + - - + The iterator_range class is templated on an Forward + Traversal Iterator and should be used whenever fairly general code is needed. + The sub_range class is templated on an Forward + Range and it is less general, but a bit easier to use since its template + argument is easier to specify. +

    -The iterator_range class is templated on an iterator and should be -used whenever super general code is needed. The sub_range class -is templated on an ExternalRange -and it is less general, but a bit easier to use since its template argument -is easier to specify. -

    +
    +

    Class iterator_range

    +

    + The intention of the iterator_range class is to encapsulate two + iterators so they fulfill the Forward Range concept. A few other functions + are also provided for convenience. +

    +

    + If the template argument is not a model of Forward Traversal Iterator, one + can still use a subset of the interface. In particular, size() + requires Forward Traversal Iterators whereas empty() only +requires Single Pass Iterators. +

    -

    Class iterator_range

    - - The intention of the -iterator_range class is to encapsulate -two iterators so they fulfill the Range concept. -A few other functions are also provided for convinience. +

    Synopsis

    -

    Synopsis

    - -
    +    
     namespace boost
     {
    -    template< class Iterator > 
    +    template< class ForwardTraversalIterator >
         class iterator_range
         {
             iterator_range(); // not implemented
             
    -    public: // Range types
    -        typedef ...        value_type;
    -        typedef ...        difference_type;
    -        typedef ...        size_type;
    -        typedef Iterator   iterator;        
    -        typedef Iterator   const_iterator;
    +    public: // Forward Range types
    +        typedef ...                        value_type;
    +        typedef ...                        difference_type;
    +        typedef ...                        size_type;
    +        typedef ForwardTraversalIterator   iterator;
    +        typedef ForwardTraversalIterator   const_iterator;
     
         public: // construction, assignment
    -        template< class Iterator >
    -        iterator_range( Iterator Begin, Iterator End );
    +        template< class ForwardTraversalIterator2 >
    +        iterator_range( ForwardTraversalIterator2 Begin, ForwardTraversalIterator2 End );
                         
    -        template< class XRange >
    -        iterator_range( XRange& r ); 
    +        template< class ForwardRange >
    +        iterator_range( ForwardRange& r );
       
    -        template< class XRange >
    -        iterator_range( const XRange& r ); 
    +        template< class ForwardRange >
    +        iterator_range( const ForwardRange& r );
             
    -        template< class XRange >
    -        iterator_range& operator=( XRange& r );
    +        template< class ForwardRange >
    +        iterator_range& operator=( ForwardRange& r );
     
    -        template< class XRange >
    -        iterator_range& operator=( const XRange& r );
    +        template< class ForwardRange >
    +        iterator_range& operator=( const ForwardRange& r );
         
    -    public: // Range functions
    -        iterator  begin() const; 
    -        iterator  end() const; 
    +    public: // Forward Range functions
    +        iterator  begin() const;
    +        iterator  end() const;
             size_type size() const;
             bool      empty() const;
             
         public: // convenience
    -        operator  unspecified_bool_type() const;
    -        void      swap( iterator_range& r );
    +        operator  unspecified_bool_type() const; 
         };
         
         // stream output
    -    template< class Iterator, class T, class Traits >
    +    template< class ForwardTraversalIterator, class T, class Traits >
         std::basic_ostream<T,Traits>& operator<<( std::basic_ostream<T,Traits>& Os,
    -                                              const iterator_range<Iterator>& r );
    +                                              const iterator_range<ForwardTraversalIterator>& r );
     
         // comparison
    -    template< class Iterator > 
    -    bool operator==( const iterator_range<Iterator>& l, const iterator_range<Iterator>& r );
    +    template< class ForwardTraversalIterator >
    +    bool operator==( const iterator_range<ForwardTraversalIterator>& l, const iterator_range<ForwardTraversalIterator>& r );
         
    -    template< class Iterator > 
    -    bool operator!=( const iterator_range<Iterator>& l, const iterator_range<Iterator>& r );
    +    template< class ForwardTraversalIterator >
    +    bool operator!=( const iterator_range<ForwardTraversalIterator>& l, const iterator_range<ForwardTraversalIterator>& r );
     
         // external construction
    -    template< class Iterator >
    -    iterator_range< Iterator > 
    -    make_iterator_range( Iterator Begin, Iterator End ); 
    +    template< class ForwardTraversalIterator >
    +    iterator_range< ForwardTraversalIterator >
    +    make_iterator_range( ForwardTraversalIterator Begin, ForwardTraversalIterator End );
            
    -    template< class XRange >
    -    iterator_range< typename iterator_of<XRange>::type >
    -    make_iterator_range( XRange& r ); 
    +    template< class ForwardRange >
    +    iterator_range< typename iterator_of<ForwardRange>::type >
    +    make_iterator_range( ForwardRange& r );
     
    -    template< class XRange >
    -    iterator_range< typename const_iterator_of<XRange>::type >
    -    make_iterator_range( const XRange& r ); 
    +    template< class ForwardRange >
    +    iterator_range< typename const_iterator_of<ForwardRange>::type >
    +    make_iterator_range( const ForwardRange& r );
     
         // convenience
    -    template< class Sequence, class XRange >
    -    Sequence copy_range( const XRange& r )
    +    template< class Sequence, class ForwardRange >
    +    Sequence copy_range( const ForwardRange& r );
     
    -    template< class Sequence, class XRange, class Func >
    -    Sequence transform_range( const XRange& r, Func func );
    +    template< class Sequence, class ForwardRange, class Func >
    +    Sequence transform_range( const ForwardRange& r, Func func );
     
     } // namespace 'boost'
    -
    +

    -It is worth noticing that the templated constructors and assignment operators -allow conversion from iterator_range to -iterator_range. If an instance of -iterator_range is constructed by a client with two iterators, the -client must ensure that the two iterators delimit a valid closed-open range +It is worth noticing that the templated constructors and assignment operators +allow conversion from iterator_range<iterator> to +iterator_range<const_iterator>. If an instance of +iterator_range is constructed by a client with two iterators, the +client must ensure that the two iterators delimit a valid closed-open range [begin,end). -

    + +

    Details member functions

    + +operator unspecified_bool_type() const; +
    +Returns !empty(). -
    -

    Class sub_range

    + +
    + +

    Details functions

    -The sub_range class inherits all its functionality -from the iterator_range class. +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, +transformed by a function. + +
    + +
    +

    Class sub_range

    + +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 ExternalRange +one must specify the Forward Range template argument instead of an iterator.

    Synopsis

    @@ -150,32 +183,40 @@ template argument instead of an iterator. namespace boost { - template< class XRange > - class sub_range : public iterator_range< typename result_iterator_of<XRange>::type > + template< class ForwardRange > + class sub_range : public iterator_range< typename result_iterator_of<ForwardRange>::type > { public: // construction, assignment - template< class Iterator > - sub_range( Iterator Begin, Iterator End ); + template< class ForwardTraversalIterator > + sub_range( ForwardTraversalIterator Begin, ForwardTraversalIterator End ); - template< class XRange2 > - sub_range( XRange2& r ); + template< class ForwardRange2 > + sub_range( ForwardRange2& r ); - template< class XRange2 > + template< class ForwardRange2 > sub_range( const Range2& r ); - template< class XRange2 > - sub_range& operator=( XRange2& r ); + template< class ForwardRange2 > + sub_range& operator=( ForwardRange2& r ); - template< class XRange2 > - sub_range& operator=( const XRange2& r ); + template< class ForwardRange2 > + sub_range& operator=( const ForwardRange2& r ); public: // rest of interface inherited from iterator_range }; } // namespace 'boost' - -
    + + +

    + The class should be trivial to use, an example with strings is shown below. +

    +    typedef sub_range sub_string;
    +    std::string s = "something";
    +    sub_string  ss( s ); 
    +    sub_string  ss2( begin( s ), begin( s ) + 2 );
    +

    @@ -195,6 +236,6 @@ namespace boost

    - + diff --git a/index.html b/index.html index e2d1dd2..fc6fce6 100755 --- a/index.html +++ b/index.html @@ -36,17 +36,19 @@