~ubuntu-branches/ubuntu/wily/davix/wily

« back to all changes in this revision

Viewing changes to deps/boost_intern/boost/iterator/iterator_facade.hpp

  • Committer: Package Import Robot
  • Author(s): Mattias Ellert
  • Date: 2015-07-31 13:17:55 UTC
  • mfrom: (5.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20150731131755-mizprbmn7ogv33te
Tags: 0.4.1-1
* Update to version 0.4.1
* Implement Multi-Arch support

Show diffs side-by-side

added added

removed removed

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