1 // Boost.Range library 2 // 3 // Copyright Thorsten Ottosen 2003-2008. Use, modification and 4 // distribution is subject to the Boost Software License, Version 5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 // 8 // For more information, see http://www.boost.org/libs/range/ 9 // 10 11 #include <boost/range.hpp> 12 #include <iterator> // for std::iterator_traits, std::distance() 13 14 namespace Foo 15 { 16 // 17 // Our sample UDT. A 'Pair' 18 // will work as a range when the stored 19 // elements are iterators. 20 // 21 template< class T > 22 struct Pair 23 { 24 T first, last; 25 }; 26 27 } // namespace 'Foo' 28 29 namespace boost 30 { 31 // 32 // Specialize metafunctions. We must include the range.hpp header. 33 // We must open the 'boost' namespace. 34 // 35 /* 36 template< class T > 37 struct range_value< Foo::Pair<T> > 38 { 39 typedef typename std::iterator_traits<T>::value_type type; 40 }; 41 */ 42 43 template< class T > 44 struct range_iterator< Foo::Pair<T> > 45 { 46 typedef T type; 47 }; 48 49 template< class T > 50 struct range_const_iterator< Foo::Pair<T> > 51 { 52 // 53 // Remark: this is defined similar to 'range_iterator' 54 // because the 'Pair' type does not distinguish 55 // between an iterator and a const_iterator. 56 // 57 typedef T type; 58 }; 59 60 /* 61 template< class T > 62 struct range_difference< Foo::Pair<T> > 63 { 64 typedef typename std::iterator_traits<T>::difference_type type; 65 }; 66 */ 67 68 template< class T > 69 struct range_size< Foo::Pair<T> > 70 { 71 int static_assertion[ sizeof( std::size_t ) >= 72 sizeof( typename range_difference< Foo::Pair<T> >::type ) ]; 73 typedef std::size_t type; 74 }; 75 76 } // namespace 'boost' 77 78 namespace Foo 79 { 80 // 81 // The required functions. These should be defined in 82 // the same namespace as 'Pair', in this case 83 // in namespace 'Foo'. 84 // 85 86 template< class T > boost_range_begin(Pair<T> & x)87 inline T boost_range_begin( Pair<T>& x ) 88 { 89 return x.first; 90 } 91 92 template< class T > boost_range_begin(const Pair<T> & x)93 inline T boost_range_begin( const Pair<T>& x ) 94 { 95 return x.first; 96 } 97 98 template< class T > boost_range_end(Pair<T> & x)99 inline T boost_range_end( Pair<T>& x ) 100 { 101 return x.last; 102 } 103 104 template< class T > boost_range_end(const Pair<T> & x)105 inline T boost_range_end( const Pair<T>& x ) 106 { 107 return x.last; 108 } 109 110 template< class T > 111 inline typename boost::range_size< Pair<T> >::type boost_range_size(const Pair<T> & x)112 boost_range_size( const Pair<T>& x ) 113 { 114 return std::distance(x.first,x.last); 115 } 116 117 } // namespace 'Foo' 118 119 #include <vector> 120 main()121int main() 122 { 123 typedef std::vector<int>::iterator iter; 124 std::vector<int> vec; 125 vec.push_back( 42 ); 126 Foo::Pair<iter> pair = { vec.begin(), vec.end() }; 127 const Foo::Pair<iter>& cpair = pair; 128 // 129 // Notice that we call 'begin' etc with qualification. 130 // 131 iter i = boost::begin( pair ); 132 iter e = boost::end( pair ); 133 i = boost::begin( cpair ); 134 e = boost::end( cpair ); 135 boost::range_size< Foo::Pair<iter> >::type s = boost::size( pair ); 136 s = boost::size( cpair ); 137 boost::range_const_reverse_iterator< Foo::Pair<iter> >::type 138 ri = boost::rbegin( cpair ), 139 re = boost::rend( cpair ); 140 141 // 142 // Test metafunctions 143 // 144 145 boost::range_value< Foo::Pair<iter> >::type 146 v = *boost::begin(pair); 147 148 boost::range_difference< Foo::Pair<iter> >::type 149 d = boost::end(pair) - boost::begin(pair); 150 } 151 152