]> AND Private Git Repository - canny.git/blob - stc/exp/ml_stc_linux_make_v1.0/include/boost/iterator/iterator_facade.hpp
Logo AND Algorithmique Numérique Distribuée

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