1 // Boost.Range library 2 // 3 // Copyright Thorsten Ottosen, Neil Groves 2006 - 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 #ifndef BOOST_RANGE_ADAPTOR_REVERSED_HPP 12 #define BOOST_RANGE_ADAPTOR_REVERSED_HPP 13 14 #include <boost/range/iterator_range.hpp> 15 #include <boost/range/concepts.hpp> 16 #include <boost/iterator/reverse_iterator.hpp> 17 18 namespace boost 19 { 20 namespace range_detail 21 { 22 template< class R > 23 struct reversed_range : 24 public boost::iterator_range< 25 boost::reverse_iterator< 26 BOOST_DEDUCED_TYPENAME range_iterator<R>::type 27 > 28 > 29 { 30 private: 31 typedef boost::iterator_range< 32 boost::reverse_iterator< 33 BOOST_DEDUCED_TYPENAME range_iterator<R>::type 34 > 35 > 36 base; 37 38 public: 39 typedef boost::reverse_iterator<BOOST_DEDUCED_TYPENAME range_iterator<R>::type> iterator; 40 reversed_rangeboost::range_detail::reversed_range41 explicit reversed_range( R& r ) 42 : base( iterator(boost::end(r)), iterator(boost::begin(r)) ) 43 { } 44 }; 45 46 struct reverse_forwarder {}; 47 48 template< class BidirectionalRange > 49 inline reversed_range<BidirectionalRange> operator |(BidirectionalRange & r,reverse_forwarder)50 operator|( BidirectionalRange& r, reverse_forwarder ) 51 { 52 BOOST_RANGE_CONCEPT_ASSERT(( 53 BidirectionalRangeConcept<BidirectionalRange>)); 54 55 return reversed_range<BidirectionalRange>( r ); 56 } 57 58 template< class BidirectionalRange > 59 inline reversed_range<const BidirectionalRange> operator |(const BidirectionalRange & r,reverse_forwarder)60 operator|( const BidirectionalRange& r, reverse_forwarder ) 61 { 62 BOOST_RANGE_CONCEPT_ASSERT(( 63 BidirectionalRangeConcept<const BidirectionalRange>)); 64 65 return reversed_range<const BidirectionalRange>( r ); 66 } 67 68 } // 'range_detail' 69 70 using range_detail::reversed_range; 71 72 namespace adaptors 73 { 74 namespace 75 { 76 const range_detail::reverse_forwarder reversed = 77 range_detail::reverse_forwarder(); 78 } 79 80 template<class BidirectionalRange> 81 inline reversed_range<BidirectionalRange> reverse(BidirectionalRange & rng)82 reverse(BidirectionalRange& rng) 83 { 84 BOOST_RANGE_CONCEPT_ASSERT(( 85 BidirectionalRangeConcept<BidirectionalRange>)); 86 87 return reversed_range<BidirectionalRange>(rng); 88 } 89 90 template<class BidirectionalRange> 91 inline reversed_range<const BidirectionalRange> reverse(const BidirectionalRange & rng)92 reverse(const BidirectionalRange& rng) 93 { 94 BOOST_RANGE_CONCEPT_ASSERT(( 95 BidirectionalRangeConcept<const BidirectionalRange>)); 96 97 return reversed_range<const BidirectionalRange>(rng); 98 } 99 } // 'adaptors' 100 101 } // 'boost' 102 103 #endif 104