1// (C) Copyright David Abrahams 2002.
2// (C) Copyright Jeremy Siek 2002.
3// (C) Copyright Thomas Witt 2002.
4// Distributed under the Boost Software License, Version 1.0. (See
5// accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt)
7#ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
8#define BOOST_ITERATOR_FACADE_23022003THW_HPP
9
10#include <boost/config.hpp>
11#include <boost/iterator/interoperable.hpp>
12#include <boost/iterator/iterator_traits.hpp>
13#include <boost/iterator/iterator_categories.hpp>
14
15#include <boost/iterator/detail/facade_iterator_category.hpp>
16#include <boost/iterator/detail/enable_if.hpp>
17
18#include <boost/static_assert.hpp>
19#include <boost/core/addressof.hpp>
20
21#include <boost/type_traits/is_same.hpp>
22#include <boost/type_traits/add_const.hpp>
23#include <boost/type_traits/add_pointer.hpp>
24#include <boost/type_traits/add_lvalue_reference.hpp>
25#include <boost/type_traits/remove_const.hpp>
26#include <boost/type_traits/remove_reference.hpp>
27#include <boost/type_traits/is_convertible.hpp>
28#include <boost/type_traits/is_pod.hpp>
29
30#include <boost/mpl/eval_if.hpp>
31#include <boost/mpl/if.hpp>
32#include <boost/mpl/or.hpp>
33#include <boost/mpl/and.hpp>
34#include <boost/mpl/not.hpp>
35#include <boost/mpl/always.hpp>
36#include <boost/mpl/apply.hpp>
37#include <boost/mpl/identity.hpp>
38
39#include <cstddef>
40
41#include <boost/iterator/detail/config_def.hpp> // this goes last
42
43namespace boost {
44namespace iterators {
45
46 // This forward declaration is required for the friend declaration
47 // in iterator_core_access
48 template <class I, class V, class TC, class R, class D> class iterator_facade;
49
50 namespace detail
51 {
52 // A binary metafunction class that always returns bool. VC6
53 // ICEs on mpl::always<bool>, probably because of the default
54 // parameters.
55 struct always_bool2
56 {
57 template <class T, class U>
58 struct apply
59 {
60 typedef bool type;
61 };
62 };
63
64 // The type trait checks if the category or traversal is at least as advanced as the specified required traversal
65 template< typename CategoryOrTraversal, typename Required >
66 struct is_traversal_at_least :
67 public boost::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required >
68 {};
69
70 //
71 // enable if for use in operator implementation.
72 //
73 template <
74 class Facade1
75 , class Facade2
76 , class Return
77 >
78 struct enable_if_interoperable :
79 public boost::iterators::enable_if<
80 is_interoperable< Facade1, Facade2 >
81 , Return
82 >
83 {};
84
85 //
86 // enable if for use in implementation of operators specific for random access traversal.
87 //
88 template <
89 class Facade1
90 , class Facade2
91 , class Return
92 >
93 struct enable_if_interoperable_and_random_access_traversal :
94 public boost::iterators::enable_if<
95 mpl::and_<
96 is_interoperable< Facade1, Facade2 >
97 , is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag >
98 , is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag >
99 >
100 , Return
101 >
102 {};
103
104 //
105 // Generates associated types for an iterator_facade with the
106 // given parameters.
107 //
108 template <
109 class ValueParam
110 , class CategoryOrTraversal
111 , class Reference
112 , class Difference
113 >
114 struct iterator_facade_types
115 {
116 typedef typename facade_iterator_category<
117 CategoryOrTraversal, ValueParam, Reference
118 >::type iterator_category;
119
120 typedef typename remove_const<ValueParam>::type value_type;
121
122 // Not the real associated pointer type
123 typedef typename mpl::eval_if<
124 boost::iterators::detail::iterator_writability_disabled<ValueParam,Reference>
125 , add_pointer<const value_type>
126 , add_pointer<value_type>
127 >::type pointer;
128
129# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
130 && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \
131 || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \
132 || BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \
133 || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310)
134
135 // To interoperate with some broken library/compiler
136 // combinations, user-defined iterators must be derived from
137 // std::iterator. It is possible to implement a standard
138 // library for broken compilers without this limitation.
139# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
140
141 typedef
142 iterator<iterator_category, value_type, Difference, pointer, Reference>
143 base;
144# endif
145 };
146
147 // iterators whose dereference operators reference the same value
148 // for all iterators into the same sequence (like many input
149 // iterators) need help with their postfix ++: the referenced
150 // value must be read and stored away before the increment occurs
151 // so that *a++ yields the originally referenced element and not
152 // the next one.
153 template <class Iterator>
154 class postfix_increment_proxy
155 {
156 typedef typename iterator_value<Iterator>::type value_type;
157
158 public:
159 explicit postfix_increment_proxy(Iterator const& x)
160 : stored_iterator(x)
161 , stored_value(*x)
162 {}
163
164 // Returning a mutable reference allows nonsense like
165 // (*r++).mutate(), but it imposes fewer assumptions about the
166 // behavior of the value_type. In particular, recall that
167 // (*r).mutate() is legal if operator* returns by value.
168 // Provides readability of *r++
169 value_type& operator*() const
170 {
171 return stored_value;
172 }
173
174 // Provides X(r++)
175 operator Iterator const&() const
176 {
177 return stored_iterator;
178 }
179
180 // Provides (r++)->foo()
181 value_type* operator->() const
182 {
183 return boost::addressof(stored_value);
184 }
185
186 private:
187 Iterator stored_iterator;
188 mutable value_type stored_value;
189 };
190
191
192 template <class Iterator>
193 class writable_postfix_increment_dereference_proxy;
194
195 template <class T>
196 struct is_not_writable_postfix_increment_dereference_proxy :
197 public boost::true_type
198 {};
199
200 template <class Iterator>
201 struct is_not_writable_postfix_increment_dereference_proxy<
202 writable_postfix_increment_dereference_proxy<Iterator>
203 > :
204 public boost::false_type
205 {};
206
207 template <class Iterator>
208 class writable_postfix_increment_proxy;
209
210 //
211 // In general, we can't determine that such an iterator isn't
212 // writable -- we also need to store a copy of the old iterator so
213 // that it can be written into.
214 template <class Iterator>
215 class writable_postfix_increment_dereference_proxy
216 {
217 friend class writable_postfix_increment_proxy<Iterator>;
218
219 typedef typename iterator_value<Iterator>::type value_type;
220
221 public:
222 explicit writable_postfix_increment_dereference_proxy(Iterator const& x)
223 : stored_iterator(x)
224 , stored_value(*x)
225 {}
226
227 // Provides readability of *r++
228 operator value_type&() const
229 {
230 return this->stored_value;
231 }
232
233 template <class OtherIterator>
234 writable_postfix_increment_dereference_proxy const&
235 operator=(writable_postfix_increment_dereference_proxy<OtherIterator> const& x) const
236 {
237 typedef typename iterator_value<OtherIterator>::type other_value_type;
238 *this->stored_iterator = static_cast<other_value_type&>(x);
239 return *this;
240 }
241
242 // Provides writability of *r++
243#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
244 template <class T>
245 typename iterators::enable_if<
246 is_not_writable_postfix_increment_dereference_proxy< T >,
247 writable_postfix_increment_dereference_proxy const&
248 >::type operator=(T&& x) const
249 {
250 *this->stored_iterator = static_cast< T&& >(x);
251 return *this;
252 }
253#else
254 template <class T>
255 typename iterators::enable_if<
256 is_not_writable_postfix_increment_dereference_proxy< T >,
257 writable_postfix_increment_dereference_proxy const&
258 >::type operator=(T const& x) const
259 {
260 *this->stored_iterator = x;
261 return *this;
262 }
263
264 // This overload just in case only non-const objects are writable
265 template <class T>
266 typename iterators::enable_if<
267 is_not_writable_postfix_increment_dereference_proxy< T >,
268 writable_postfix_increment_dereference_proxy const&
269 >::type operator=(T& x) const
270 {
271 *this->stored_iterator = x;
272 return *this;
273 }
274#endif
275
276 private:
277 Iterator stored_iterator;
278 mutable value_type stored_value;
279 };
280
281 template <class Iterator>
282 class writable_postfix_increment_proxy
283 {
284 typedef typename iterator_value<Iterator>::type value_type;
285
286 public:
287 explicit writable_postfix_increment_proxy(Iterator const& x)
288 : dereference_proxy(x)
289 {}
290
291 writable_postfix_increment_dereference_proxy<Iterator> const&
292 operator*() const
293 {
294 return dereference_proxy;
295 }
296
297 // Provides X(r++)
298 operator Iterator const&() const
299 {
300 return dereference_proxy.stored_iterator;
301 }
302
303 // Provides (r++)->foo()
304 value_type* operator->() const
305 {
306 return boost::addressof(dereference_proxy.stored_value);
307 }
308
309 private:
310 writable_postfix_increment_dereference_proxy<Iterator> dereference_proxy;
311 };
312
313# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
314
315 template <class Reference, class Value>
316 struct is_non_proxy_reference_impl
317 {
318 static Reference r;
319
320 template <class R>
321 static typename mpl::if_<
322 is_convertible<
323 R const volatile*
324 , Value const volatile*
325 >
326 , char[1]
327 , char[2]
328 >::type& helper(R const&);
329
330 BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
331 };
332
333 template <class Reference, class Value>
334 struct is_non_proxy_reference
335 : mpl::bool_<
336 is_non_proxy_reference_impl<Reference, Value>::value
337 >
338 {};
339# else
340 template <class Reference, class Value>
341 struct is_non_proxy_reference
342 : is_convertible<
343 typename remove_reference<Reference>::type
344 const volatile*
345 , Value const volatile*
346 >
347 {};
348# endif
349
350 // A metafunction to choose the result type of postfix ++
351 //
352 // Because the C++98 input iterator requirements say that *r++ has
353 // type T (value_type), implementations of some standard
354 // algorithms like lexicographical_compare may use constructions
355 // like:
356 //
357 // *r++ < *s++
358 //
359 // If *r++ returns a proxy (as required if r is writable but not
360 // multipass), this sort of expression will fail unless the proxy
361 // supports the operator<. Since there are any number of such
362 // operations, we're not going to try to support them. Therefore,
363 // even if r++ returns a proxy, *r++ will only return a proxy if
364 // *r also returns a proxy.
365 template <class Iterator, class Value, class Reference, class CategoryOrTraversal>
366 struct postfix_increment_result
367 : mpl::eval_if<
368 mpl::and_<
369 // A proxy is only needed for readable iterators
370 is_convertible<
371 Reference
372 // Use add_lvalue_reference to form `reference to Value` due to
373 // some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
374 // 'reference-to-reference' in the template which described in CWG
375 // DR106.
376 // http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
377 , typename add_lvalue_reference<Value const>::type
378 >
379
380 // No multipass iterator can have values that disappear
381 // before positions can be re-visited
382 , mpl::not_<
383 is_convertible<
384 typename iterator_category_to_traversal<CategoryOrTraversal>::type
385 , forward_traversal_tag
386 >
387 >
388 >
389 , mpl::if_<
390 is_non_proxy_reference<Reference,Value>
391 , postfix_increment_proxy<Iterator>
392 , writable_postfix_increment_proxy<Iterator>
393 >
394 , mpl::identity<Iterator>
395 >
396 {};
397
398 // operator->() needs special support for input iterators to strictly meet the
399 // standard's requirements. If *i is not a reference type, we must still
400 // produce an lvalue to which a pointer can be formed. We do that by
401 // returning a proxy object containing an instance of the reference object.
402 template <class Reference, class Pointer>
403 struct operator_arrow_dispatch // proxy references
404 {
405 struct proxy
406 {
407 explicit proxy(Reference const & x) : m_ref(x) {}
408 Reference* operator->() { return boost::addressof(m_ref); }
409 // This function is needed for MWCW and BCC, which won't call
410 // operator-> again automatically per 13.3.1.2 para 8
411 operator Reference*() { return boost::addressof(m_ref); }
412 Reference m_ref;
413 };
414 typedef proxy result_type;
415 static result_type apply(Reference const & x)
416 {
417 return result_type(x);
418 }
419 };
420
421 template <class T, class Pointer>
422 struct operator_arrow_dispatch<T&, Pointer> // "real" references
423 {
424 typedef Pointer result_type;
425 static result_type apply(T& x)
426 {
427 return boost::addressof(x);
428 }
429 };
430
431 // A proxy return type for operator[], needed to deal with
432 // iterators that may invalidate referents upon destruction.
433 // Consider the temporary iterator in *(a + n)
434 template <class Iterator>
435 class operator_brackets_proxy
436 {
437 // Iterator is actually an iterator_facade, so we do not have to
438 // go through iterator_traits to access the traits.
439 typedef typename Iterator::reference reference;
440 typedef typename Iterator::value_type value_type;
441
442 public:
443 operator_brackets_proxy(Iterator const& iter)
444 : m_iter(iter)
445 {}
446
447 operator reference() const
448 {
449 return *m_iter;
450 }
451
452 operator_brackets_proxy& operator=(value_type const& val)
453 {
454 *m_iter = val;
455 return *this;
456 }
457
458 private:
459 Iterator m_iter;
460 };
461
462 // A metafunction that determines whether operator[] must return a
463 // proxy, or whether it can simply return a copy of the value_type.
464 template <class ValueType, class Reference>
465 struct use_operator_brackets_proxy
466 : mpl::not_<
467 mpl::and_<
468 // Really we want an is_copy_constructible trait here,
469 // but is_POD will have to suffice in the meantime.
470 boost::is_POD<ValueType>
471 , iterator_writability_disabled<ValueType,Reference>
472 >
473 >
474 {};
475
476 template <class Iterator, class Value, class Reference>
477 struct operator_brackets_result
478 {
479 typedef typename mpl::if_<
480 use_operator_brackets_proxy<Value,Reference>
481 , operator_brackets_proxy<Iterator>
482 , Value
483 >::type type;
484 };
485
486 template <class Iterator>
487 operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
488 {
489 return operator_brackets_proxy<Iterator>(iter);
490 }
491
492 template <class Iterator>
493 typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
494 {
495 return *iter;
496 }
497
498 struct choose_difference_type
499 {
500 template <class I1, class I2>
501 struct apply
502 :
503# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
504 iterator_difference<I1>
505# else
506 mpl::eval_if<
507 is_convertible<I2,I1>
508 , iterator_difference<I1>
509 , iterator_difference<I2>
510 >
511# endif
512 {};
513
514 };
515
516 template <
517 class Derived
518 , class Value
519 , class CategoryOrTraversal
520 , class Reference
521 , class Difference
522 , bool IsBidirectionalTraversal
523 , bool IsRandomAccessTraversal
524 >
525 class iterator_facade_base;
526
527 } // namespace detail
528
529
530 // Macros which describe the declarations of binary operators
531# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
532# define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \
533 template < \
534 class Derived1, class V1, class TC1, class Reference1, class Difference1 \
535 , class Derived2, class V2, class TC2, class Reference2, class Difference2 \
536 > \
537 prefix typename mpl::apply2<result_type,Derived1,Derived2>::type \
538 operator op( \
539 iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \
540 , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
541# else
542# define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \
543 template < \
544 class Derived1, class V1, class TC1, class Reference1, class Difference1 \
545 , class Derived2, class V2, class TC2, class Reference2, class Difference2 \
546 > \
547 prefix typename enabler< \
548 Derived1, Derived2 \
549 , typename mpl::apply2<result_type,Derived1,Derived2>::type \
550 >::type \
551 operator op( \
552 iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \
553 , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
554# endif
555
556# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
557 BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable)
558
559# define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(prefix, op, result_type) \
560 BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal)
561
562# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
563 template <class Derived, class V, class TC, class R, class D> \
564 prefix typename boost::iterators::enable_if< \
565 boost::iterators::detail::is_traversal_at_least< TC, boost::iterators::random_access_traversal_tag >, \
566 Derived \
567 >::type operator+ args
568
569 //
570 // Helper class for granting access to the iterator core interface.
571 //
572 // The simple core interface is used by iterator_facade. The core
573 // interface of a user/library defined iterator type should not be made public
574 // so that it does not clutter the public interface. Instead iterator_core_access
575 // should be made friend so that iterator_facade can access the core
576 // interface through iterator_core_access.
577 //
578 class iterator_core_access
579 {
580# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
581 // Tasteless as this may seem, making all members public allows member templates
582 // to work in the absence of member template friends.
583 public:
584# else
585
586 template <class I, class V, class TC, class R, class D> friend class iterator_facade;
587 template <class I, class V, class TC, class R, class D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal>
588 friend class detail::iterator_facade_base;
589
590# define BOOST_ITERATOR_FACADE_RELATION(op) \
591 BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, boost::iterators::detail::always_bool2);
592
593 BOOST_ITERATOR_FACADE_RELATION(==)
594 BOOST_ITERATOR_FACADE_RELATION(!=)
595
596# undef BOOST_ITERATOR_FACADE_RELATION
597
598# define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op) \
599 BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend,op, boost::iterators::detail::always_bool2);
600
601 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<)
602 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>)
603 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=)
604 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=)
605
606# undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
607
608 BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(
609 friend, -, boost::iterators::detail::choose_difference_type)
610 ;
611
612 BOOST_ITERATOR_FACADE_PLUS_HEAD(
613 friend inline
614 , (iterator_facade<Derived, V, TC, R, D> const&
615 , typename Derived::difference_type)
616 )
617 ;
618
619 BOOST_ITERATOR_FACADE_PLUS_HEAD(
620 friend inline
621 , (typename Derived::difference_type
622 , iterator_facade<Derived, V, TC, R, D> const&)
623 )
624 ;
625
626# endif
627
628 template <class Facade>
629 static typename Facade::reference dereference(Facade const& f)
630 {
631 return f.dereference();
632 }
633
634 template <class Facade>
635 static void increment(Facade& f)
636 {
637 f.increment();
638 }
639
640 template <class Facade>
641 static void decrement(Facade& f)
642 {
643 f.decrement();
644 }
645
646 template <class Facade1, class Facade2>
647 static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::true_)
648 {
649 return f1.equal(f2);
650 }
651
652 template <class Facade1, class Facade2>
653 static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::false_)
654 {
655 return f2.equal(f1);
656 }
657
658 template <class Facade>
659 static void advance(Facade& f, typename Facade::difference_type n)
660 {
661 f.advance(n);
662 }
663
664 template <class Facade1, class Facade2>
665 static typename Facade1::difference_type distance_from(
666 Facade1 const& f1, Facade2 const& f2, mpl::true_)
667 {
668 return -f1.distance_to(f2);
669 }
670
671 template <class Facade1, class Facade2>
672 static typename Facade2::difference_type distance_from(
673 Facade1 const& f1, Facade2 const& f2, mpl::false_)
674 {
675 return f2.distance_to(f1);
676 }
677
678 //
679 // Curiously Recurring Template interface.
680 //
681 template <class I, class V, class TC, class R, class D>
682 static I& derived(iterator_facade<I,V,TC,R,D>& facade)
683 {
684 return *static_cast<I*>(&facade);
685 }
686
687 template <class I, class V, class TC, class R, class D>
688 static I const& derived(iterator_facade<I,V,TC,R,D> const& facade)
689 {
690 return *static_cast<I const*>(&facade);
691 }
692
693 // objects of this class are useless
694 BOOST_DELETED_FUNCTION(iterator_core_access())
695 };
696
697 namespace detail {
698
699 // Implementation for forward traversal iterators
700 template <
701 class Derived
702 , class Value
703 , class CategoryOrTraversal
704 , class Reference
705 , class Difference
706 >
707 class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
708# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
709 : public boost::iterators::detail::iterator_facade_types<
710 Value, CategoryOrTraversal, Reference, Difference
711 >::base
712# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
713# endif
714 {
715 private:
716 typedef boost::iterators::detail::iterator_facade_types<
717 Value, CategoryOrTraversal, Reference, Difference
718 > associated_types;
719
720 typedef boost::iterators::detail::operator_arrow_dispatch<
721 Reference
722 , typename associated_types::pointer
723 > operator_arrow_dispatch_;
724
725 public:
726 typedef typename associated_types::value_type value_type;
727 typedef Reference reference;
728 typedef Difference difference_type;
729
730 typedef typename operator_arrow_dispatch_::result_type pointer;
731
732 typedef typename associated_types::iterator_category iterator_category;
733
734 public:
735 reference operator*() const
736 {
737 return iterator_core_access::dereference(this->derived());
738 }
739
740 pointer operator->() const
741 {
742 return operator_arrow_dispatch_::apply(*this->derived());
743 }
744
745 Derived& operator++()
746 {
747 iterator_core_access::increment(this->derived());
748 return this->derived();
749 }
750
751 protected:
752 //
753 // Curiously Recurring Template interface.
754 //
755 Derived& derived()
756 {
757 return *static_cast<Derived*>(this);
758 }
759
760 Derived const& derived() const
761 {
762 return *static_cast<Derived const*>(this);
763 }
764 };
765
766 // Implementation for bidirectional traversal iterators
767 template <
768 class Derived
769 , class Value
770 , class CategoryOrTraversal
771 , class Reference
772 , class Difference
773 >
774 class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > :
775 public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
776 {
777 public:
778 Derived& operator--()
779 {
780 iterator_core_access::decrement(this->derived());
781 return this->derived();
782 }
783
784 Derived operator--(int)
785 {
786 Derived tmp(this->derived());
787 --*this;
788 return tmp;
789 }
790 };
791
792 // Implementation for random access traversal iterators
793 template <
794 class Derived
795 , class Value
796 , class CategoryOrTraversal
797 , class Reference
798 , class Difference
799 >
800 class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > :
801 public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >
802 {
803 private:
804 typedef iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > base_type;
805
806 public:
807 typedef typename base_type::reference reference;
808 typedef typename base_type::difference_type difference_type;
809
810 public:
811 typename boost::iterators::detail::operator_brackets_result<Derived, Value, reference>::type
812 operator[](difference_type n) const
813 {
814 typedef boost::iterators::detail::use_operator_brackets_proxy<Value, Reference> use_proxy;
815
816 return boost::iterators::detail::make_operator_brackets_result<Derived>(
817 this->derived() + n
818 , use_proxy()
819 );
820 }
821
822 Derived& operator+=(difference_type n)
823 {
824 iterator_core_access::advance(this->derived(), n);
825 return this->derived();
826 }
827
828 Derived& operator-=(difference_type n)
829 {
830 iterator_core_access::advance(this->derived(), -n);
831 return this->derived();
832 }
833
834 Derived operator-(difference_type x) const
835 {
836 Derived result(this->derived());
837 return result -= x;
838 }
839 };
840
841 } // namespace detail
842
843 //
844 // iterator_facade - use as a public base class for defining new
845 // standard-conforming iterators.
846 //
847 template <
848 class Derived // The derived iterator type being constructed
849 , class Value
850 , class CategoryOrTraversal
851 , class Reference = Value&
852 , class Difference = std::ptrdiff_t
853 >
854 class iterator_facade :
855 public detail::iterator_facade_base<
856 Derived,
857 Value,
858 CategoryOrTraversal,
859 Reference,
860 Difference,
861 detail::is_traversal_at_least< CategoryOrTraversal, bidirectional_traversal_tag >::value,
862 detail::is_traversal_at_least< CategoryOrTraversal, random_access_traversal_tag >::value
863 >
864 {
865 protected:
866 // For use by derived classes
867 typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
868 };
869
870 template <class I, class V, class TC, class R, class D>
871 inline typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type
872 operator++(
873 iterator_facade<I,V,TC,R,D>& i
874 , int
875 )
876 {
877 typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type
878 tmp(*static_cast<I*>(&i));
879
880 ++i;
881
882 return tmp;
883 }
884
885
886 //
887 // Comparison operator implementation. The library supplied operators
888 // enables the user to provide fully interoperable constant/mutable
889 // iterator types. I.e. the library provides all operators
890 // for all mutable/constant iterator combinations.
891 //
892 // Note though that this kind of interoperability for constant/mutable
893 // iterators is not required by the standard for container iterators.
894 // All the standard asks for is a conversion mutable -> constant.
895 // Most standard library implementations nowadays provide fully interoperable
896 // iterator implementations, but there are still heavily used implementations
897 // that do not provide them. (Actually it's even worse, they do not provide
898 // them for only a few iterators.)
899 //
900 // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
901 // enable the user to turn off mixed type operators
902 //
903 // The library takes care to provide only the right operator overloads.
904 // I.e.
905 //
906 // bool operator==(Iterator, Iterator);
907 // bool operator==(ConstIterator, Iterator);
908 // bool operator==(Iterator, ConstIterator);
909 // bool operator==(ConstIterator, ConstIterator);
910 //
911 // ...
912 //
913 // In order to do so it uses c++ idioms that are not yet widely supported
914 // by current compiler releases. The library is designed to degrade gracefully
915 // in the face of compiler deficiencies. In general compiler
916 // deficiencies result in less strict error checking and more obscure
917 // error messages, functionality is not affected.
918 //
919 // For full operation compiler support for "Substitution Failure Is Not An Error"
920 // (aka. enable_if) and boost::is_convertible is required.
921 //
922 // The following problems occur if support is lacking.
923 //
924 // Pseudo code
925 //
926 // ---------------
927 // AdaptorA<Iterator1> a1;
928 // AdaptorA<Iterator2> a2;
929 //
930 // // This will result in a no such overload error in full operation
931 // // If enable_if or is_convertible is not supported
932 // // The instantiation will fail with an error hopefully indicating that
933 // // there is no operator== for Iterator1, Iterator2
934 // // The same will happen if no enable_if is used to remove
935 // // false overloads from the templated conversion constructor
936 // // of AdaptorA.
937 //
938 // a1 == a2;
939 // ----------------
940 //
941 // AdaptorA<Iterator> a;
942 // AdaptorB<Iterator> b;
943 //
944 // // This will result in a no such overload error in full operation
945 // // If enable_if is not supported the static assert used
946 // // in the operator implementation will fail.
947 // // This will accidently work if is_convertible is not supported.
948 //
949 // a == b;
950 // ----------------
951 //
952
953# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
954# define BOOST_ITERATOR_CONVERTIBLE(a,b) mpl::true_()
955# else
956# define BOOST_ITERATOR_CONVERTIBLE(a,b) is_convertible<a,b>()
957# endif
958
959# define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
960 BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \
961 { \
962 /* For those compilers that do not support enable_if */ \
963 BOOST_STATIC_ASSERT(( \
964 is_interoperable< Derived1, Derived2 >::value \
965 )); \
966 return_prefix iterator_core_access::base_op( \
967 *static_cast<Derived1 const*>(&lhs) \
968 , *static_cast<Derived2 const*>(&rhs) \
969 , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1) \
970 ); \
971 }
972
973# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
974 BOOST_ITERATOR_FACADE_INTEROP( \
975 op \
976 , boost::iterators::detail::always_bool2 \
977 , return_prefix \
978 , base_op \
979 )
980
981 BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
982 BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
983
984# undef BOOST_ITERATOR_FACADE_RELATION
985
986
987# define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op) \
988 BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type) \
989 { \
990 /* For those compilers that do not support enable_if */ \
991 BOOST_STATIC_ASSERT(( \
992 is_interoperable< Derived1, Derived2 >::value && \
993 boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived1 >::type, random_access_traversal_tag >::value && \
994 boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived2 >::type, random_access_traversal_tag >::value \
995 )); \
996 return_prefix iterator_core_access::base_op( \
997 *static_cast<Derived1 const*>(&lhs) \
998 , *static_cast<Derived2 const*>(&rhs) \
999 , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1) \
1000 ); \
1001 }
1002
1003# define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \
1004 BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS( \
1005 op \
1006 , boost::iterators::detail::always_bool2 \
1007 , return_prefix \
1008 , base_op \
1009 )
1010
1011 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from)
1012 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>, return 0 <, distance_from)
1013 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=, return 0 >=, distance_from)
1014 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=, return 0 <=, distance_from)
1015
1016# undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
1017
1018 // operator- requires an additional part in the static assertion
1019 BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(
1020 -
1021 , boost::iterators::detail::choose_difference_type
1022 , return
1023 , distance_from
1024 )
1025
1026# undef BOOST_ITERATOR_FACADE_INTEROP
1027# undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS
1028
1029# define BOOST_ITERATOR_FACADE_PLUS(args) \
1030 BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \
1031 { \
1032 Derived tmp(static_cast<Derived const&>(i)); \
1033 return tmp += n; \
1034 }
1035
1036 BOOST_ITERATOR_FACADE_PLUS((
1037 iterator_facade<Derived, V, TC, R, D> const& i
1038 , typename Derived::difference_type n
1039 ))
1040
1041 BOOST_ITERATOR_FACADE_PLUS((
1042 typename Derived::difference_type n
1043 , iterator_facade<Derived, V, TC, R, D> const& i
1044 ))
1045
1046# undef BOOST_ITERATOR_FACADE_PLUS
1047# undef BOOST_ITERATOR_FACADE_PLUS_HEAD
1048
1049# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
1050# undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD
1051# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL
1052
1053} // namespace iterators
1054
1055using iterators::iterator_core_access;
1056using iterators::iterator_facade;
1057
1058} // namespace boost
1059
1060#include <boost/iterator/detail/config_undef.hpp>
1061
1062#endif // BOOST_ITERATOR_FACADE_23022003THW_HPP
1063

source code of boost/libs/iterator/include/boost/iterator/iterator_facade.hpp