Boost
C++ Libraries
...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
This is an older version of Boost and was released in 2023. The current version is 1.89.0.
This procedure assumes that you cannot (or do not wish to) change the types that should be made conformant to a Range concept. If this is not true, see method 1.
The primary templates in this library are implemented such that certain
functions are found via argument-dependent-lookup (ADL). Below is given
an overview of which free-standing functions a class must specify to be
useable as a certain Range concept. Let x
be a variable (const or mutable) of the class in question.
|
Function |
Related concept |
|---|---|
|
|
|
|
|
|
|
|
Optional. This can be used to specify a mechanism for constant-time
computation of the size of a range. The default behaviour is
to return |
range_begin()
and range_end()
must be overloaded for both const
and mutable reference arguments.
You must also specialize two metafunctions for your type X:
|
Metafunction |
Related concept |
|---|---|
|
|
|
|
|
A complete example is given here:
#include <boost/range.hpp> #include <iterator> // for std::iterator_traits, std::distance() namespace Foo { // // Our sample UDT. A 'Pair' // will work as a range when the stored // elements are iterators. // template< class T > struct Pair { T first, last; }; } // namespace 'Foo' namespace boost { // // Specialize metafunctions. We must include the range.hpp header. // We must open the 'boost' namespace. // template< class T > struct range_mutable_iterator< Foo::Pair<T> > { typedef T type; }; template< class T > struct range_const_iterator< Foo::Pair<T> > { // // Remark: this is defined similar to 'range_iterator' // because the 'Pair' type does not distinguish // between an iterator and a const_iterator. // typedef T type; }; } // namespace 'boost' namespace Foo { // // The required functions. These should be defined in // the same namespace as 'Pair', in this case // in namespace 'Foo'. // template< class T > inline T range_begin( Pair<T>& x ) { return x.first; } template< class T > inline T range_begin( const Pair<T>& x ) { return x.first; } template< class T > inline T range_end( Pair<T>& x ) { return x.last; } template< class T > inline T range_end( const Pair<T>& x ) { return x.last; } } // namespace 'Foo' #include <vector> int main(int argc, const char* argv[]) { typedef std::vector<int>::iterator iter; std::vector<int> vec; Foo::Pair<iter> pair = { vec.begin(), vec.end() }; const Foo::Pair<iter>& cpair = pair; // // Notice that we call 'begin' etc with qualification. // iter i = boost::begin( pair ); iter e = boost::end( pair ); i = boost::begin( cpair ); e = boost::end( cpair ); boost::range_difference< Foo::Pair<iter> >::type s = boost::size( pair ); s = boost::size( cpair ); boost::range_reverse_iterator< const Foo::Pair<iter> >::type ri = boost::rbegin( cpair ), re = boost::rend( cpair ); return 0; }