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 16 namespace boost 17 { 18 enum range_return_value 19 { 20 // (*) indicates the most common values 21 return_found, // only the found resulting iterator (*) 22 return_next, // next(found) iterator 23 return_prior, // prior(found) iterator 24 return_begin_found, // [begin, found) range (*) 25 return_begin_next, // [begin, next(found)) range 26 return_begin_prior, // [begin, prior(found)) range 27 return_found_end, // [found, end) range (*) 28 return_next_end, // [next(found), end) range 29 return_prior_end, // [prior(found), end) range 30 return_begin_end // [begin, end) range 31 }; 32 33 template< class SinglePassRange, range_return_value > 34 struct range_return 35 { 36 typedef boost::iterator_range< 37 BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type; 38 packboost::range_return39 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found, 40 SinglePassRange& rng) 41 { 42 return type(found, boost::end(rng)); 43 } 44 }; 45 46 template< class SinglePassRange > 47 struct range_return< SinglePassRange, return_found > 48 { 49 typedef BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type type; 50 packboost::range_return51 static type pack(type found, SinglePassRange&) 52 { 53 return found; 54 } 55 }; 56 57 template< class SinglePassRange > 58 struct range_return< SinglePassRange, return_next > 59 { 60 typedef BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type type; 61 packboost::range_return62 static type pack(type found, SinglePassRange& rng) 63 { 64 return found == boost::end(rng) 65 ? found 66 : boost::next(found); 67 } 68 }; 69 70 template< class BidirectionalRange > 71 struct range_return< BidirectionalRange, return_prior > 72 { 73 typedef BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type type; 74 packboost::range_return75 static type pack(type found, BidirectionalRange& rng) 76 { 77 return found == boost::begin(rng) 78 ? found 79 : boost::prior(found); 80 } 81 }; 82 83 template< class SinglePassRange > 84 struct range_return< SinglePassRange, return_begin_found > 85 { 86 typedef boost::iterator_range< 87 BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type; 88 packboost::range_return89 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found, 90 SinglePassRange& rng) 91 { 92 return type(boost::begin(rng), found); 93 } 94 }; 95 96 template< class SinglePassRange > 97 struct range_return< SinglePassRange, return_begin_next > 98 { 99 typedef boost::iterator_range< 100 BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type; 101 packboost::range_return102 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found, 103 SinglePassRange& rng) 104 { 105 return type( boost::begin(rng), 106 found == boost::end(rng) ? found : boost::next(found) ); 107 } 108 }; 109 110 template< class BidirectionalRange > 111 struct range_return< BidirectionalRange, return_begin_prior > 112 { 113 typedef boost::iterator_range< 114 BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type > type; 115 packboost::range_return116 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type found, 117 BidirectionalRange& rng) 118 { 119 return type( boost::begin(rng), 120 found == boost::begin(rng) ? found : boost::prior(found) ); 121 } 122 }; 123 124 template< class SinglePassRange > 125 struct range_return< SinglePassRange, return_found_end > 126 { 127 typedef boost::iterator_range< 128 BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type; 129 packboost::range_return130 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found, 131 SinglePassRange& rng) 132 { 133 return type(found, boost::end(rng)); 134 } 135 }; 136 137 template< class SinglePassRange > 138 struct range_return< SinglePassRange, return_next_end > 139 { 140 typedef boost::iterator_range< 141 BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type; 142 packboost::range_return143 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found, 144 SinglePassRange& rng) 145 { 146 return type( found == boost::end(rng) ? found : boost::next(found), 147 boost::end(rng) ); 148 } 149 }; 150 151 template< class BidirectionalRange > 152 struct range_return< BidirectionalRange, return_prior_end > 153 { 154 typedef boost::iterator_range< 155 BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type > type; 156 packboost::range_return157 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type found, 158 BidirectionalRange& rng) 159 { 160 return type( found == boost::begin(rng) ? found : boost::prior(found), 161 boost::end(rng) ); 162 } 163 }; 164 165 template< class SinglePassRange > 166 struct range_return< SinglePassRange, return_begin_end > 167 { 168 typedef boost::iterator_range< 169 BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type; 170 packboost::range_return171 static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type, 172 SinglePassRange& rng) 173 { 174 return type(boost::begin(rng), boost::end(rng)); 175 } 176 }; 177 178 } 179 180 #endif // include guard 181