Chris@16
|
1 // Boost.Range library
|
Chris@16
|
2 //
|
Chris@16
|
3 // Copyright Neil Groves 2009.
|
Chris@16
|
4 // Copyright Thorsten Ottosen 2003-2004. Use, modification and
|
Chris@16
|
5 // distribution is subject to the Boost Software License, Version
|
Chris@16
|
6 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 //
|
Chris@16
|
9 // For more information, see http://www.boost.org/libs/range/
|
Chris@16
|
10 //
|
Chris@16
|
11
|
Chris@16
|
12 #ifndef BOOST_RANGE_SUB_RANGE_HPP
|
Chris@16
|
13 #define BOOST_RANGE_SUB_RANGE_HPP
|
Chris@16
|
14
|
Chris@16
|
15 #include <boost/detail/workaround.hpp>
|
Chris@16
|
16
|
Chris@16
|
17 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
|
Chris@16
|
18 #pragma warning( push )
|
Chris@16
|
19 #pragma warning( disable : 4996 )
|
Chris@16
|
20 #endif
|
Chris@16
|
21
|
Chris@16
|
22 #include <boost/range/config.hpp>
|
Chris@16
|
23 #include <boost/range/iterator_range.hpp>
|
Chris@16
|
24 #include <boost/range/value_type.hpp>
|
Chris@16
|
25 #include <boost/range/size_type.hpp>
|
Chris@16
|
26 #include <boost/range/difference_type.hpp>
|
Chris@101
|
27 #include <boost/range/reference.hpp>
|
Chris@16
|
28 #include <boost/range/algorithm/equal.hpp>
|
Chris@16
|
29 #include <boost/assert.hpp>
|
Chris@16
|
30 #include <boost/type_traits/is_reference.hpp>
|
Chris@16
|
31 #include <boost/type_traits/remove_reference.hpp>
|
Chris@16
|
32
|
Chris@16
|
33 namespace boost
|
Chris@16
|
34 {
|
Chris@101
|
35 namespace range_detail
|
Chris@16
|
36 {
|
Chris@101
|
37
|
Chris@101
|
38 template<class ForwardRange, class TraversalTag>
|
Chris@101
|
39 class sub_range_base
|
Chris@101
|
40 : public iterator_range<
|
Chris@101
|
41 BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
Chris@101
|
42 >
|
Chris@101
|
43 {
|
Chris@101
|
44 typedef iterator_range<
|
Chris@101
|
45 BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
Chris@101
|
46 > base;
|
Chris@101
|
47
|
Chris@101
|
48 protected:
|
Chris@101
|
49 typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_;
|
Chris@101
|
50
|
Chris@101
|
51 public:
|
Chris@101
|
52 typedef BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type value_type;
|
Chris@101
|
53 typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator;
|
Chris@101
|
54 typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type const_iterator;
|
Chris@101
|
55 typedef BOOST_DEDUCED_TYPENAME range_difference<ForwardRange>::type difference_type;
|
Chris@101
|
56 typedef BOOST_DEDUCED_TYPENAME range_size<ForwardRange>::type size_type;
|
Chris@101
|
57 typedef BOOST_DEDUCED_TYPENAME range_reference<ForwardRange>::type reference;
|
Chris@101
|
58 typedef BOOST_DEDUCED_TYPENAME range_reference<const ForwardRange>::type const_reference;
|
Chris@101
|
59
|
Chris@101
|
60 sub_range_base()
|
Chris@101
|
61 {
|
Chris@101
|
62 }
|
Chris@101
|
63
|
Chris@101
|
64 template<class Iterator>
|
Chris@101
|
65 sub_range_base(Iterator first, Iterator last)
|
Chris@101
|
66 : base(first, last)
|
Chris@101
|
67 {
|
Chris@101
|
68 }
|
Chris@101
|
69
|
Chris@101
|
70 reference front()
|
Chris@101
|
71 {
|
Chris@101
|
72 return base::front();
|
Chris@101
|
73 }
|
Chris@101
|
74
|
Chris@101
|
75 const_reference front() const
|
Chris@101
|
76 {
|
Chris@101
|
77 return base::front();
|
Chris@101
|
78 }
|
Chris@101
|
79 };
|
Chris@101
|
80
|
Chris@101
|
81 template<class ForwardRange>
|
Chris@101
|
82 class sub_range_base<ForwardRange, bidirectional_traversal_tag>
|
Chris@101
|
83 : public sub_range_base<ForwardRange, forward_traversal_tag>
|
Chris@101
|
84 {
|
Chris@101
|
85 typedef sub_range_base<ForwardRange, forward_traversal_tag> base;
|
Chris@101
|
86 public:
|
Chris@101
|
87 sub_range_base()
|
Chris@101
|
88 {
|
Chris@101
|
89 }
|
Chris@101
|
90
|
Chris@101
|
91 template<class Iterator>
|
Chris@101
|
92 sub_range_base(Iterator first, Iterator last)
|
Chris@101
|
93 : base(first, last)
|
Chris@101
|
94 {
|
Chris@101
|
95 }
|
Chris@101
|
96
|
Chris@101
|
97 BOOST_DEDUCED_TYPENAME base::reference back()
|
Chris@101
|
98 {
|
Chris@101
|
99 return base::back();
|
Chris@101
|
100 }
|
Chris@101
|
101
|
Chris@101
|
102 BOOST_DEDUCED_TYPENAME base::const_reference back() const
|
Chris@101
|
103 {
|
Chris@101
|
104 return base::back();
|
Chris@101
|
105 }
|
Chris@101
|
106 };
|
Chris@101
|
107
|
Chris@101
|
108 template<class ForwardRange>
|
Chris@101
|
109 class sub_range_base<ForwardRange, random_access_traversal_tag>
|
Chris@101
|
110 : public sub_range_base<ForwardRange, bidirectional_traversal_tag>
|
Chris@101
|
111 {
|
Chris@101
|
112 typedef sub_range_base<ForwardRange, bidirectional_traversal_tag> base;
|
Chris@101
|
113
|
Chris@101
|
114 public:
|
Chris@101
|
115 sub_range_base()
|
Chris@101
|
116 {
|
Chris@101
|
117 }
|
Chris@101
|
118
|
Chris@101
|
119 template<class Iterator>
|
Chris@101
|
120 sub_range_base(Iterator first, Iterator last)
|
Chris@101
|
121 : base(first, last)
|
Chris@101
|
122 {
|
Chris@101
|
123 }
|
Chris@101
|
124
|
Chris@101
|
125 BOOST_DEDUCED_TYPENAME base::reference
|
Chris@101
|
126 operator[](BOOST_DEDUCED_TYPENAME base::difference_type n)
|
Chris@101
|
127 {
|
Chris@101
|
128 return this->begin()[n];
|
Chris@101
|
129 }
|
Chris@101
|
130
|
Chris@101
|
131 BOOST_DEDUCED_TYPENAME base::const_reference
|
Chris@101
|
132 operator[](BOOST_DEDUCED_TYPENAME base::difference_type n) const
|
Chris@101
|
133 {
|
Chris@101
|
134 return this->begin()[n];
|
Chris@101
|
135 }
|
Chris@101
|
136 };
|
Chris@101
|
137
|
Chris@101
|
138 } // namespace range_detail
|
Chris@101
|
139
|
Chris@101
|
140 template<class ForwardRange>
|
Chris@101
|
141 class sub_range
|
Chris@101
|
142 : public range_detail::sub_range_base<
|
Chris@101
|
143 ForwardRange,
|
Chris@101
|
144 BOOST_DEDUCED_TYPENAME iterator_traversal<
|
Chris@101
|
145 BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
Chris@101
|
146 >::type
|
Chris@101
|
147 >
|
Chris@101
|
148 {
|
Chris@101
|
149 typedef BOOST_DEDUCED_TYPENAME range_iterator<
|
Chris@101
|
150 ForwardRange
|
Chris@101
|
151 >::type iterator_t;
|
Chris@101
|
152
|
Chris@101
|
153 typedef range_detail::sub_range_base<
|
Chris@101
|
154 ForwardRange,
|
Chris@101
|
155 BOOST_DEDUCED_TYPENAME iterator_traversal<
|
Chris@101
|
156 BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
Chris@101
|
157 >::type
|
Chris@101
|
158 > base;
|
Chris@16
|
159
|
Chris@16
|
160 typedef BOOST_DEDUCED_TYPENAME base::impl impl;
|
Chris@101
|
161
|
Chris@101
|
162 protected:
|
Chris@101
|
163 typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_;
|
Chris@101
|
164
|
Chris@101
|
165 private:
|
Chris@101
|
166 template<class Source>
|
Chris@101
|
167 struct is_compatible_range
|
Chris@101
|
168 : is_convertible<
|
Chris@101
|
169 BOOST_DEDUCED_TYPENAME mpl::eval_if<
|
Chris@101
|
170 has_range_iterator<Source>,
|
Chris@101
|
171 range_iterator<Source>,
|
Chris@101
|
172 mpl::identity<void>
|
Chris@101
|
173 >::type,
|
Chris@101
|
174 BOOST_DEDUCED_TYPENAME base::iterator
|
Chris@101
|
175 >
|
Chris@101
|
176 {
|
Chris@101
|
177 };
|
Chris@16
|
178
|
Chris@16
|
179 public:
|
Chris@101
|
180 sub_range()
|
Chris@16
|
181 { }
|
Chris@101
|
182
|
Chris@16
|
183 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
|
Chris@101
|
184 sub_range(const sub_range& r)
|
Chris@101
|
185 : base(impl::adl_begin(static_cast<const base&>(r)),
|
Chris@101
|
186 impl::adl_end(static_cast<const base&>(r)))
|
Chris@16
|
187 { }
|
Chris@16
|
188 #endif
|
Chris@16
|
189
|
Chris@16
|
190 template< class ForwardRange2 >
|
Chris@101
|
191 sub_range(
|
Chris@101
|
192 ForwardRange2& r,
|
Chris@101
|
193 BOOST_DEDUCED_TYPENAME ::boost::enable_if<
|
Chris@101
|
194 is_compatible_range<ForwardRange2>
|
Chris@101
|
195 >::type* = 0
|
Chris@101
|
196 )
|
Chris@101
|
197 : base(impl::adl_begin(r), impl::adl_end(r))
|
Chris@101
|
198 {
|
Chris@101
|
199 }
|
Chris@101
|
200
|
Chris@16
|
201 template< class ForwardRange2 >
|
Chris@101
|
202 sub_range(
|
Chris@101
|
203 const ForwardRange2& r,
|
Chris@101
|
204 BOOST_DEDUCED_TYPENAME ::boost::enable_if<
|
Chris@101
|
205 is_compatible_range<const ForwardRange2>
|
Chris@101
|
206 >::type* = 0
|
Chris@101
|
207 )
|
Chris@101
|
208 : base(impl::adl_begin(r), impl::adl_end(r))
|
Chris@101
|
209 {
|
Chris@101
|
210 }
|
Chris@16
|
211
|
Chris@101
|
212 BOOST_DEDUCED_TYPENAME base::const_iterator begin() const
|
Chris@101
|
213 {
|
Chris@101
|
214 return base::begin();
|
Chris@101
|
215 }
|
Chris@101
|
216
|
Chris@101
|
217 BOOST_DEDUCED_TYPENAME base::iterator begin()
|
Chris@101
|
218 {
|
Chris@101
|
219 return base::begin();
|
Chris@101
|
220 }
|
Chris@101
|
221
|
Chris@101
|
222 BOOST_DEDUCED_TYPENAME base::const_iterator end() const
|
Chris@101
|
223 {
|
Chris@101
|
224 return base::end();
|
Chris@101
|
225 }
|
Chris@101
|
226
|
Chris@101
|
227 BOOST_DEDUCED_TYPENAME base::iterator end()
|
Chris@101
|
228 {
|
Chris@101
|
229 return base::end();
|
Chris@101
|
230 }
|
Chris@16
|
231
|
Chris@16
|
232 template< class Iter >
|
Chris@16
|
233 sub_range( Iter first, Iter last ) :
|
Chris@16
|
234 base( first, last )
|
Chris@16
|
235 { }
|
Chris@101
|
236
|
Chris@101
|
237 template<class ForwardRange2>
|
Chris@101
|
238 BOOST_DEDUCED_TYPENAME ::boost::enable_if<
|
Chris@101
|
239 is_compatible_range<ForwardRange2>,
|
Chris@101
|
240 sub_range&
|
Chris@101
|
241 >::type
|
Chris@101
|
242 operator=(ForwardRange2& r)
|
Chris@16
|
243 {
|
Chris@101
|
244 iterator_range_::operator=( r );
|
Chris@16
|
245 return *this;
|
Chris@16
|
246 }
|
Chris@16
|
247
|
Chris@101
|
248 template<class ForwardRange2>
|
Chris@101
|
249 BOOST_DEDUCED_TYPENAME ::boost::enable_if<
|
Chris@101
|
250 is_compatible_range<const ForwardRange2>,
|
Chris@101
|
251 sub_range&
|
Chris@101
|
252 >::type
|
Chris@101
|
253 operator=( const ForwardRange2& r )
|
Chris@16
|
254 {
|
Chris@101
|
255 iterator_range_::operator=( r );
|
Chris@16
|
256 return *this;
|
Chris@16
|
257 }
|
Chris@16
|
258
|
Chris@16
|
259 sub_range& operator=( const sub_range& r )
|
Chris@16
|
260 {
|
Chris@101
|
261 iterator_range_::operator=( static_cast<const iterator_range_&>(r) );
|
Chris@16
|
262 return *this;
|
Chris@16
|
263 }
|
Chris@16
|
264
|
Chris@101
|
265 sub_range& advance_begin(
|
Chris@101
|
266 BOOST_DEDUCED_TYPENAME base::difference_type n)
|
Chris@101
|
267 {
|
Chris@101
|
268 std::advance(this->m_Begin, n);
|
Chris@101
|
269 return *this;
|
Chris@101
|
270 }
|
Chris@16
|
271
|
Chris@101
|
272 sub_range& advance_end(
|
Chris@101
|
273 BOOST_DEDUCED_TYPENAME base::difference_type n)
|
Chris@16
|
274 {
|
Chris@101
|
275 std::advance(this->m_End, n);
|
Chris@101
|
276 return *this;
|
Chris@16
|
277 }
|
Chris@16
|
278 };
|
Chris@16
|
279
|
Chris@16
|
280 } // namespace 'boost'
|
Chris@16
|
281
|
Chris@16
|
282 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
|
Chris@16
|
283 #pragma warning( pop )
|
Chris@16
|
284 #endif
|
Chris@16
|
285
|
Chris@16
|
286 #endif
|
Chris@16
|
287
|