1 // Copyright Neil Groves 2009. Use, modification and 2 // distribution is subject to the Boost Software License, Version 3 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 // 6 // 7 // For more information, see http://www.boost.org/libs/range/ 8 // 9 #ifndef BOOST_RANGE_DETAIL_RANGE_RETURN_HPP_INCLUDED 10 #define BOOST_RANGE_DETAIL_RANGE_RETURN_HPP_INCLUDED 11 12 #include <boost/range/begin.hpp> 13 #include <boost/range/end.hpp> 14 #include <boost/range/iterator_range.hpp> 15 #include <boost/next_prior.hpp> 16 17 namespace boost 18 { 19 enum range_return_value 20 { 21 // (*) indicates the most common values 22 return_found, // only the found resulting iterator (*) 23 return_next, // next(found) iterator 24 return_prior, // prior(found) iterator 25 return_begin_found, // [begin, found) range (*) 26 return_begin_next, // [begin, next(found)) range 27 return_begin_prior, // [begin, prior(found)) range 28 return_found_end, // [found, end) range (*) 29 return_next_end, // [next(found), end) range 30 return_prior_end, // [prior(found), end) range 31 return_begin_end // [begin, end) range 32 }; 33 34 template< class SinglePassRange, range_return_value > 35 struct range_return 36 { 37 typedef boost::iterator_range< 38 BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type; 39 packboost::range_return40 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found, 41 SinglePassRange& rng) 42 { 43 return type(found, boost::end(rng)); 44 } 45 }; 46 47 template< class SinglePassRange > 48 struct range_return< SinglePassRange, return_found > 49 { 50 typedef BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type type; 51 packboost::range_return52 static type pack(type found, SinglePassRange&) 53 { 54 return found; 55 } 56 }; 57 58 template< class SinglePassRange > 59 struct range_return< SinglePassRange, return_next > 60 { 61 typedef BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type type; 62 packboost::range_return63 static type pack(type found, SinglePassRange& rng) 64 { 65 return found == boost::end(rng) 66 ? found 67 : boost::next(found); 68 } 69 }; 70 71 template< class BidirectionalRange > 72 struct range_return< BidirectionalRange, return_prior > 73 { 74 typedef BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type type; 75 packboost::range_return76 static type pack(type found, BidirectionalRange& rng) 77 { 78 return found == boost::begin(rng) 79 ? found 80 : boost::prior(found); 81 } 82 }; 83 84 template< class SinglePassRange > 85 struct range_return< SinglePassRange, return_begin_found > 86 { 87 typedef boost::iterator_range< 88 BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type; 89 packboost::range_return90 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found, 91 SinglePassRange& rng) 92 { 93 return type(boost::begin(rng), found); 94 } 95 }; 96 97 template< class SinglePassRange > 98 struct range_return< SinglePassRange, return_begin_next > 99 { 100 typedef boost::iterator_range< 101 BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type; 102 packboost::range_return103 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found, 104 SinglePassRange& rng) 105 { 106 return type( boost::begin(rng), 107 found == boost::end(rng) ? found : boost::next(found) ); 108 } 109 }; 110 111 template< class BidirectionalRange > 112 struct range_return< BidirectionalRange, return_begin_prior > 113 { 114 typedef boost::iterator_range< 115 BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type > type; 116 packboost::range_return117 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type found, 118 BidirectionalRange& rng) 119 { 120 return type( boost::begin(rng), 121 found == boost::begin(rng) ? found : boost::prior(found) ); 122 } 123 }; 124 125 template< class SinglePassRange > 126 struct range_return< SinglePassRange, return_found_end > 127 { 128 typedef boost::iterator_range< 129 BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type; 130 packboost::range_return131 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found, 132 SinglePassRange& rng) 133 { 134 return type(found, boost::end(rng)); 135 } 136 }; 137 138 template< class SinglePassRange > 139 struct range_return< SinglePassRange, return_next_end > 140 { 141 typedef boost::iterator_range< 142 BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type; 143 packboost::range_return144 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found, 145 SinglePassRange& rng) 146 { 147 return type( found == boost::end(rng) ? found : boost::next(found), 148 boost::end(rng) ); 149 } 150 }; 151 152 template< class BidirectionalRange > 153 struct range_return< BidirectionalRange, return_prior_end > 154 { 155 typedef boost::iterator_range< 156 BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type > type; 157 packboost::range_return158 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type found, 159 BidirectionalRange& rng) 160 { 161 return type( found == boost::begin(rng) ? found : boost::prior(found), 162 boost::end(rng) ); 163 } 164 }; 165 166 template< class SinglePassRange > 167 struct range_return< SinglePassRange, return_begin_end > 168 { 169 typedef boost::iterator_range< 170 BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type; 171 packboost::range_return172 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type, 173 SinglePassRange& rng) 174 { 175 return type(boost::begin(rng), boost::end(rng)); 176 } 177 }; 178 179 } 180 181 #endif // include guard 182