1 | // Boost.Range library |
2 | // |
3 | // Copyright Neil Groves 2010. Use, modification and |
4 | // distribution is subject to the Boost Software License, Version |
5 | // 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
6 | // http://www.boost.org/LICENSE_1_0.txt) |
7 | // |
8 | // For more information, see http://www.boost.org/libs/range/ |
9 | // |
10 | #ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED |
11 | #define BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED |
12 | |
13 | #include <boost/cast.hpp> |
14 | #include <boost/range/config.hpp> |
15 | #include <boost/range/detail/any_iterator_interface.hpp> |
16 | #include <boost/range/concepts.hpp> |
17 | |
18 | namespace boost |
19 | { |
20 | namespace range_detail |
21 | { |
22 | template<typename TargetT, typename SourceT> |
23 | TargetT& polymorphic_ref_downcast(SourceT& source) |
24 | { |
25 | #ifdef BOOST_NO_RTTI |
26 | return static_cast<TargetT&>(source); |
27 | #else |
28 | return *boost::polymorphic_downcast<TargetT*>(&source); |
29 | #endif |
30 | } |
31 | |
32 | template<class Reference, class T> |
33 | Reference dereference_cast(T& x) |
34 | { |
35 | return static_cast<Reference>(x); |
36 | } |
37 | template<class Reference, class T> |
38 | Reference dereference_cast(const T& x) |
39 | { |
40 | return static_cast<Reference>(const_cast<T&>(x)); |
41 | } |
42 | |
43 | template< |
44 | class WrappedIterator |
45 | , class Reference |
46 | , class Buffer |
47 | > |
48 | class any_incrementable_iterator_wrapper |
49 | : public any_incrementable_iterator_interface< |
50 | Reference |
51 | , Buffer |
52 | > |
53 | { |
54 | BOOST_RANGE_CONCEPT_ASSERT(( IncrementableIteratorConcept<WrappedIterator> )); |
55 | public: |
56 | typedef WrappedIterator wrapped_type; |
57 | |
58 | BOOST_STATIC_ASSERT(( is_convertible< |
59 | typename iterator_reference<WrappedIterator>::type |
60 | , Reference |
61 | >::value )); |
62 | |
63 | any_incrementable_iterator_wrapper() |
64 | : m_it() |
65 | {} |
66 | |
67 | explicit any_incrementable_iterator_wrapper(wrapped_type it) |
68 | : m_it(it) |
69 | {} |
70 | |
71 | // any_incrementable_iterator implementation |
72 | virtual any_incrementable_iterator_wrapper* clone( |
73 | typename any_incrementable_iterator_wrapper::buffer_type& buffer |
74 | ) const |
75 | { |
76 | return new (buffer.allocate(sizeof(*this))) |
77 | any_incrementable_iterator_wrapper(m_it); |
78 | } |
79 | |
80 | virtual any_incrementable_iterator_wrapper< |
81 | WrappedIterator |
82 | , typename any_incrementable_iterator_wrapper::const_reference |
83 | , Buffer |
84 | >* clone_const_ref( |
85 | typename any_incrementable_iterator_wrapper::buffer_type& buffer |
86 | ) const |
87 | { |
88 | typedef any_incrementable_iterator_wrapper< |
89 | WrappedIterator |
90 | , typename any_incrementable_iterator_wrapper::const_reference |
91 | , Buffer |
92 | > result_type; |
93 | |
94 | return new (buffer.allocate(sizeof(result_type))) |
95 | result_type(m_it); |
96 | } |
97 | |
98 | virtual any_incrementable_iterator_wrapper< |
99 | WrappedIterator |
100 | , typename any_incrementable_iterator_wrapper::reference_as_value_type |
101 | , Buffer |
102 | >* clone_reference_as_value( |
103 | typename any_incrementable_iterator_wrapper::buffer_type& buffer |
104 | ) const |
105 | { |
106 | typedef any_incrementable_iterator_wrapper< |
107 | WrappedIterator |
108 | , typename any_incrementable_iterator_wrapper::reference_as_value_type |
109 | , Buffer |
110 | > result_type; |
111 | |
112 | return new (buffer.allocate(sizeof(result_type))) |
113 | result_type(m_it); |
114 | } |
115 | |
116 | virtual void increment() |
117 | { |
118 | ++m_it; |
119 | } |
120 | |
121 | private: |
122 | wrapped_type m_it; |
123 | }; |
124 | |
125 | template< |
126 | class WrappedIterator |
127 | , class Reference |
128 | , class Buffer |
129 | > |
130 | class any_single_pass_iterator_wrapper |
131 | : public any_single_pass_iterator_interface< |
132 | Reference |
133 | , Buffer |
134 | > |
135 | { |
136 | struct disabler {}; |
137 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassIteratorConcept<WrappedIterator> )); |
138 | typedef any_single_pass_iterator_interface< |
139 | Reference, |
140 | Buffer |
141 | > base_type; |
142 | |
143 | public: |
144 | typedef typename base_type::reference reference; |
145 | |
146 | any_single_pass_iterator_wrapper() |
147 | : m_it() |
148 | {} |
149 | |
150 | explicit any_single_pass_iterator_wrapper(const WrappedIterator& it) |
151 | : m_it(it) |
152 | {} |
153 | // any_single_pass_iterator_interface<Reference> implementation |
154 | virtual any_single_pass_iterator_wrapper* clone( |
155 | typename any_single_pass_iterator_wrapper::buffer_type& buffer |
156 | ) const |
157 | { |
158 | return new (buffer.allocate(sizeof(*this))) |
159 | any_single_pass_iterator_wrapper(m_it); |
160 | } |
161 | |
162 | virtual any_single_pass_iterator_wrapper< |
163 | WrappedIterator |
164 | , typename any_single_pass_iterator_wrapper::const_reference |
165 | , Buffer |
166 | >* clone_const_ref( |
167 | typename any_single_pass_iterator_wrapper::buffer_type& buffer |
168 | ) const |
169 | { |
170 | typedef any_single_pass_iterator_wrapper< |
171 | WrappedIterator |
172 | , typename any_single_pass_iterator_wrapper::const_reference |
173 | , Buffer |
174 | > result_type; |
175 | |
176 | return new (buffer.allocate(sizeof(result_type))) |
177 | result_type(m_it); |
178 | } |
179 | |
180 | virtual any_single_pass_iterator_wrapper< |
181 | WrappedIterator |
182 | , typename any_single_pass_iterator_wrapper::reference_as_value_type |
183 | , Buffer |
184 | >* clone_reference_as_value( |
185 | typename any_single_pass_iterator_wrapper::buffer_type& buffer |
186 | ) const |
187 | { |
188 | typedef any_single_pass_iterator_wrapper< |
189 | WrappedIterator |
190 | , typename any_single_pass_iterator_wrapper::reference_as_value_type |
191 | , Buffer |
192 | > result_type; |
193 | |
194 | return new (buffer.allocate(sizeof(result_type))) |
195 | result_type(m_it); |
196 | } |
197 | |
198 | virtual void increment() |
199 | { |
200 | ++m_it; |
201 | } |
202 | |
203 | virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const |
204 | { |
205 | return m_it == range_detail::polymorphic_ref_downcast<const any_single_pass_iterator_wrapper>(other).m_it; |
206 | } |
207 | |
208 | virtual reference dereference() const |
209 | { |
210 | return dereference_cast<reference>(*m_it); |
211 | } |
212 | |
213 | private: |
214 | WrappedIterator m_it; |
215 | }; |
216 | |
217 | template< |
218 | class WrappedIterator |
219 | , class Reference |
220 | , class Buffer |
221 | > |
222 | class any_forward_iterator_wrapper |
223 | : public any_forward_iterator_interface< |
224 | Reference |
225 | , Buffer |
226 | > |
227 | { |
228 | BOOST_RANGE_CONCEPT_ASSERT(( ForwardIteratorConcept<WrappedIterator> )); |
229 | typedef any_forward_iterator_interface< |
230 | Reference, |
231 | Buffer |
232 | > base_type; |
233 | |
234 | public: |
235 | typedef typename base_type::reference reference; |
236 | |
237 | any_forward_iterator_wrapper() |
238 | : m_it() |
239 | {} |
240 | |
241 | explicit any_forward_iterator_wrapper(const WrappedIterator& it) |
242 | : m_it(it) |
243 | {} |
244 | |
245 | // any_forward_iterator_interface<Reference> implementation |
246 | virtual any_forward_iterator_wrapper* clone( |
247 | typename any_forward_iterator_wrapper::buffer_type& buffer |
248 | ) const |
249 | { |
250 | return new (buffer.allocate(sizeof(*this))) |
251 | any_forward_iterator_wrapper(m_it); |
252 | } |
253 | |
254 | virtual any_forward_iterator_wrapper< |
255 | WrappedIterator |
256 | , typename any_forward_iterator_wrapper::const_reference |
257 | , Buffer |
258 | >* clone_const_ref( |
259 | typename any_forward_iterator_wrapper::buffer_type& buffer |
260 | ) const |
261 | { |
262 | typedef any_forward_iterator_wrapper< |
263 | WrappedIterator |
264 | , typename any_forward_iterator_wrapper::const_reference |
265 | , Buffer |
266 | > result_type; |
267 | |
268 | return new (buffer.allocate(sizeof(result_type))) |
269 | result_type(m_it); |
270 | } |
271 | |
272 | virtual any_forward_iterator_wrapper< |
273 | WrappedIterator |
274 | , typename any_forward_iterator_wrapper::reference_as_value_type |
275 | , Buffer |
276 | >* clone_reference_as_value( |
277 | typename any_forward_iterator_wrapper::buffer_type& buffer |
278 | ) const |
279 | { |
280 | typedef any_forward_iterator_wrapper< |
281 | WrappedIterator |
282 | , typename any_forward_iterator_wrapper::reference_as_value_type |
283 | , Buffer |
284 | > result_type; |
285 | |
286 | return new (buffer.allocate(sizeof(result_type))) |
287 | result_type(m_it); |
288 | } |
289 | |
290 | virtual void increment() |
291 | { |
292 | ++m_it; |
293 | } |
294 | |
295 | virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const |
296 | { |
297 | return m_it == range_detail::polymorphic_ref_downcast<const any_forward_iterator_wrapper>(other).m_it; |
298 | } |
299 | |
300 | virtual reference dereference() const |
301 | { |
302 | return dereference_cast<reference>(*m_it); |
303 | } |
304 | private: |
305 | WrappedIterator m_it; |
306 | }; |
307 | |
308 | template< |
309 | class WrappedIterator |
310 | , class Reference |
311 | , class Buffer |
312 | > |
313 | class any_bidirectional_iterator_wrapper |
314 | : public any_bidirectional_iterator_interface< |
315 | Reference |
316 | , Buffer |
317 | > |
318 | { |
319 | BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalIteratorConcept<WrappedIterator> )); |
320 | typedef any_bidirectional_iterator_interface< |
321 | Reference, |
322 | Buffer |
323 | > base_type; |
324 | |
325 | public: |
326 | typedef typename base_type::reference reference; |
327 | |
328 | any_bidirectional_iterator_wrapper() |
329 | : m_it() |
330 | { |
331 | } |
332 | |
333 | explicit any_bidirectional_iterator_wrapper(const WrappedIterator& it) |
334 | : m_it(it) |
335 | { |
336 | } |
337 | |
338 | virtual any_bidirectional_iterator_wrapper* clone( |
339 | typename any_bidirectional_iterator_wrapper::buffer_type& buffer |
340 | ) const |
341 | { |
342 | return new (buffer.allocate(sizeof(*this))) |
343 | any_bidirectional_iterator_wrapper(*this); |
344 | } |
345 | |
346 | virtual any_bidirectional_iterator_wrapper< |
347 | WrappedIterator |
348 | , typename any_bidirectional_iterator_wrapper::const_reference |
349 | , Buffer |
350 | >* clone_const_ref( |
351 | typename any_bidirectional_iterator_wrapper::buffer_type& buffer |
352 | ) const |
353 | { |
354 | typedef any_bidirectional_iterator_wrapper< |
355 | WrappedIterator |
356 | , typename any_bidirectional_iterator_wrapper::const_reference |
357 | , Buffer |
358 | > result_type; |
359 | |
360 | return new (buffer.allocate(sizeof(result_type))) |
361 | result_type(m_it); |
362 | } |
363 | |
364 | virtual any_bidirectional_iterator_wrapper< |
365 | WrappedIterator |
366 | , typename any_bidirectional_iterator_wrapper::reference_as_value_type |
367 | , Buffer |
368 | >* clone_reference_as_value( |
369 | typename any_bidirectional_iterator_wrapper::buffer_type& buffer |
370 | ) const |
371 | { |
372 | typedef any_bidirectional_iterator_wrapper< |
373 | WrappedIterator |
374 | , typename any_bidirectional_iterator_wrapper::reference_as_value_type |
375 | , Buffer |
376 | > result_type; |
377 | |
378 | return new (buffer.allocate(sizeof(result_type))) |
379 | result_type(m_it); |
380 | } |
381 | |
382 | virtual void increment() |
383 | { |
384 | ++m_it; |
385 | } |
386 | |
387 | virtual void decrement() |
388 | { |
389 | --m_it; |
390 | } |
391 | |
392 | virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const |
393 | { |
394 | return m_it == range_detail::polymorphic_ref_downcast<const any_bidirectional_iterator_wrapper>(other).m_it; |
395 | } |
396 | |
397 | virtual reference dereference() const |
398 | { |
399 | return dereference_cast<reference>(*m_it); |
400 | } |
401 | |
402 | private: |
403 | WrappedIterator m_it; |
404 | }; |
405 | |
406 | template< |
407 | class WrappedIterator |
408 | , class Reference |
409 | , class Difference |
410 | , class Buffer |
411 | > |
412 | class any_random_access_iterator_wrapper |
413 | : public any_random_access_iterator_interface< |
414 | Reference |
415 | , Difference |
416 | , Buffer |
417 | > |
418 | { |
419 | BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessIteratorConcept<WrappedIterator> )); |
420 | typedef any_random_access_iterator_interface< |
421 | Reference, |
422 | Difference, |
423 | Buffer |
424 | > base_type; |
425 | |
426 | public: |
427 | typedef typename base_type::reference reference; |
428 | typedef Difference difference_type; |
429 | |
430 | any_random_access_iterator_wrapper() |
431 | : m_it() |
432 | { |
433 | } |
434 | |
435 | explicit any_random_access_iterator_wrapper(const WrappedIterator& other) |
436 | : m_it(other) |
437 | { |
438 | } |
439 | |
440 | virtual any_random_access_iterator_wrapper* clone( |
441 | typename any_random_access_iterator_wrapper::buffer_type& buffer |
442 | ) const |
443 | { |
444 | return new (buffer.allocate(sizeof(*this))) |
445 | any_random_access_iterator_wrapper(*this); |
446 | } |
447 | |
448 | virtual any_random_access_iterator_wrapper< |
449 | WrappedIterator |
450 | , typename any_random_access_iterator_wrapper::const_reference |
451 | , Difference |
452 | , Buffer |
453 | >* clone_const_ref( |
454 | typename any_random_access_iterator_wrapper::buffer_type& buffer |
455 | ) const |
456 | { |
457 | typedef any_random_access_iterator_wrapper< |
458 | WrappedIterator |
459 | , typename any_random_access_iterator_wrapper::const_reference |
460 | , Difference |
461 | , Buffer |
462 | > result_type; |
463 | |
464 | return new (buffer.allocate(sizeof(result_type))) |
465 | result_type(m_it); |
466 | } |
467 | |
468 | virtual any_random_access_iterator_wrapper< |
469 | WrappedIterator |
470 | , typename any_random_access_iterator_wrapper::reference_as_value_type |
471 | , Difference |
472 | , Buffer |
473 | >* clone_reference_as_value( |
474 | typename any_random_access_iterator_wrapper::buffer_type& buffer |
475 | ) const |
476 | { |
477 | typedef any_random_access_iterator_wrapper< |
478 | WrappedIterator |
479 | , typename any_random_access_iterator_wrapper::reference_as_value_type |
480 | , Difference |
481 | , Buffer |
482 | > result_type; |
483 | |
484 | return new (buffer.allocate(sizeof(result_type))) |
485 | result_type(m_it); |
486 | } |
487 | |
488 | virtual void increment() |
489 | { |
490 | ++m_it; |
491 | } |
492 | |
493 | virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const |
494 | { |
495 | return m_it == range_detail::polymorphic_ref_downcast<const any_random_access_iterator_wrapper>(other).m_it; |
496 | } |
497 | |
498 | virtual void decrement() |
499 | { |
500 | --m_it; |
501 | } |
502 | |
503 | virtual void advance(Difference offset) |
504 | { |
505 | m_it += offset; |
506 | } |
507 | |
508 | virtual reference dereference() const |
509 | { |
510 | return dereference_cast<reference>(*m_it); |
511 | } |
512 | |
513 | virtual Difference distance_to(const any_random_access_iterator_interface<Reference, Difference, Buffer>& other) const |
514 | { |
515 | return range_detail::polymorphic_ref_downcast<const any_random_access_iterator_wrapper>(other).m_it - m_it; |
516 | } |
517 | |
518 | private: |
519 | WrappedIterator m_it; |
520 | }; |
521 | |
522 | template< |
523 | class WrappedIterator |
524 | , class Traversal |
525 | , class Reference |
526 | , class Difference |
527 | , class Buffer |
528 | > |
529 | struct any_iterator_wrapper_type_generator; |
530 | |
531 | template< |
532 | class WrappedIterator |
533 | , class Reference |
534 | , class Difference |
535 | , class Buffer |
536 | > |
537 | struct any_iterator_wrapper_type_generator< |
538 | WrappedIterator |
539 | , incrementable_traversal_tag |
540 | , Reference |
541 | , Difference |
542 | , Buffer |
543 | > |
544 | { |
545 | typedef any_incrementable_iterator_wrapper< |
546 | WrappedIterator |
547 | , Reference |
548 | , Buffer |
549 | > type; |
550 | }; |
551 | |
552 | template< |
553 | class WrappedIterator |
554 | , class Reference |
555 | , class Difference |
556 | , class Buffer |
557 | > |
558 | struct any_iterator_wrapper_type_generator< |
559 | WrappedIterator |
560 | , single_pass_traversal_tag |
561 | , Reference |
562 | , Difference |
563 | , Buffer |
564 | > |
565 | { |
566 | typedef any_single_pass_iterator_wrapper< |
567 | WrappedIterator |
568 | , Reference |
569 | , Buffer |
570 | > type; |
571 | }; |
572 | |
573 | template< |
574 | class WrappedIterator |
575 | , class Reference |
576 | , class Difference |
577 | , class Buffer |
578 | > |
579 | struct any_iterator_wrapper_type_generator< |
580 | WrappedIterator |
581 | , forward_traversal_tag |
582 | , Reference |
583 | , Difference |
584 | , Buffer |
585 | > |
586 | { |
587 | typedef any_forward_iterator_wrapper< |
588 | WrappedIterator |
589 | , Reference |
590 | , Buffer |
591 | > type; |
592 | }; |
593 | |
594 | template< |
595 | class WrappedIterator |
596 | , class Reference |
597 | , class Difference |
598 | , class Buffer |
599 | > |
600 | struct any_iterator_wrapper_type_generator< |
601 | WrappedIterator |
602 | , bidirectional_traversal_tag |
603 | , Reference |
604 | , Difference |
605 | , Buffer |
606 | > |
607 | { |
608 | typedef any_bidirectional_iterator_wrapper< |
609 | WrappedIterator |
610 | , Reference |
611 | , Buffer |
612 | > type; |
613 | }; |
614 | |
615 | template< |
616 | class WrappedIterator |
617 | , class Reference |
618 | , class Difference |
619 | , class Buffer |
620 | > |
621 | struct any_iterator_wrapper_type_generator< |
622 | WrappedIterator |
623 | , random_access_traversal_tag |
624 | , Reference |
625 | , Difference |
626 | , Buffer |
627 | > |
628 | { |
629 | typedef any_random_access_iterator_wrapper< |
630 | WrappedIterator |
631 | , Reference |
632 | , Difference |
633 | , Buffer |
634 | > type; |
635 | }; |
636 | |
637 | } // namespace range_detail |
638 | } // namespace boost |
639 | |
640 | #endif // include guard |
641 | |