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 | |
40 | 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 | |
52 | 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 | |
63 | 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 | |
76 | 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 | |
90 | 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 | |
103 | 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 | |
117 | 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 | |
131 | 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 | |
144 | 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 | |
158 | 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 | |
172 | 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 | |