• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
polymorphic_ref_downcast(SourceT & source)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>
dereference_cast(T & x)33         Reference dereference_cast(T& x)
34         {
35             return static_cast<Reference>(x);
36         }
37         template<class Reference, class T>
dereference_cast(const T & x)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 
any_incrementable_iterator_wrapper()63             any_incrementable_iterator_wrapper()
64                 : m_it()
65             {}
66 
any_incrementable_iterator_wrapper(wrapped_type it)67             explicit any_incrementable_iterator_wrapper(wrapped_type it)
68                 : m_it(it)
69             {}
70 
71         // any_incrementable_iterator implementation
clone(typename any_incrementable_iterator_wrapper::buffer_type & buffer) const72             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
clone_const_ref(typename any_incrementable_iterator_wrapper::buffer_type & buffer) const84                     >* 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
clone_reference_as_value(typename any_incrementable_iterator_wrapper::buffer_type & buffer) const102                     >* 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 
increment()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 
any_single_pass_iterator_wrapper()146             any_single_pass_iterator_wrapper()
147                 : m_it()
148             {}
149 
any_single_pass_iterator_wrapper(const WrappedIterator & it)150             explicit any_single_pass_iterator_wrapper(const WrappedIterator& it)
151                 : m_it(it)
152             {}
153         // any_single_pass_iterator_interface<Reference> implementation
clone(typename any_single_pass_iterator_wrapper::buffer_type & buffer) const154             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
clone_const_ref(typename any_single_pass_iterator_wrapper::buffer_type & buffer) const166             >* 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
clone_reference_as_value(typename any_single_pass_iterator_wrapper::buffer_type & buffer) const184             >* 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 
increment()198             virtual void increment()
199             {
200                 ++m_it;
201             }
202 
equal(const any_single_pass_iterator_interface<Reference,Buffer> & other) const203             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 
dereference() const208             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 
any_forward_iterator_wrapper()237             any_forward_iterator_wrapper()
238                 : m_it()
239             {}
240 
any_forward_iterator_wrapper(const WrappedIterator & it)241             explicit any_forward_iterator_wrapper(const WrappedIterator& it)
242                 : m_it(it)
243             {}
244 
245             // any_forward_iterator_interface<Reference> implementation
clone(typename any_forward_iterator_wrapper::buffer_type & buffer) const246             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
clone_const_ref(typename any_forward_iterator_wrapper::buffer_type & buffer) const258                     >* 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
clone_reference_as_value(typename any_forward_iterator_wrapper::buffer_type & buffer) const276                     >* 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 
increment()290             virtual void increment()
291             {
292                 ++m_it;
293             }
294 
equal(const any_single_pass_iterator_interface<Reference,Buffer> & other) const295             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 
dereference() const300             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 
any_bidirectional_iterator_wrapper()328             any_bidirectional_iterator_wrapper()
329                 : m_it()
330             {
331             }
332 
any_bidirectional_iterator_wrapper(const WrappedIterator & it)333             explicit any_bidirectional_iterator_wrapper(const WrappedIterator& it)
334                 : m_it(it)
335             {
336             }
337 
clone(typename any_bidirectional_iterator_wrapper::buffer_type & buffer) const338             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
clone_const_ref(typename any_bidirectional_iterator_wrapper::buffer_type & buffer) const350                     >* 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
clone_reference_as_value(typename any_bidirectional_iterator_wrapper::buffer_type & buffer) const368                     >* 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 
increment()382             virtual void increment()
383             {
384                 ++m_it;
385             }
386 
decrement()387             virtual void decrement()
388             {
389                 --m_it;
390             }
391 
equal(const any_single_pass_iterator_interface<Reference,Buffer> & other) const392             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 
dereference() const397             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 
any_random_access_iterator_wrapper()430             any_random_access_iterator_wrapper()
431                 : m_it()
432             {
433             }
434 
any_random_access_iterator_wrapper(const WrappedIterator & other)435             explicit any_random_access_iterator_wrapper(const WrappedIterator& other)
436                 : m_it(other)
437             {
438             }
439 
clone(typename any_random_access_iterator_wrapper::buffer_type & buffer) const440             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
clone_const_ref(typename any_random_access_iterator_wrapper::buffer_type & buffer) const453                     >* 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
clone_reference_as_value(typename any_random_access_iterator_wrapper::buffer_type & buffer) const473                     >* 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 
increment()488             virtual void increment()
489             {
490                 ++m_it;
491             }
492 
equal(const any_single_pass_iterator_interface<Reference,Buffer> & other) const493             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 
decrement()498             virtual void decrement()
499             {
500                 --m_it;
501             }
502 
advance(Difference offset)503             virtual void advance(Difference offset)
504             {
505                 m_it += offset;
506             }
507 
dereference() const508             virtual reference dereference() const
509             {
510                 return dereference_cast<reference>(*m_it);
511             }
512 
distance_to(const any_random_access_iterator_interface<Reference,Difference,Buffer> & other) const513             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