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
16namespace 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
39 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
51 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
62 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
75 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
89 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
102 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
116 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
130 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
143 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
157 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
171 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