]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/iterator/iterator_adaptor.hpp
Update to boost 1.72
[lyx.git] / 3rdparty / boost / boost / iterator / iterator_adaptor.hpp
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_ADAPTOR_23022003THW_HPP
8 #define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
9
10 #include <boost/static_assert.hpp>
11
12 #include <boost/core/use_default.hpp>
13
14 #include <boost/iterator/iterator_categories.hpp>
15 #include <boost/iterator/iterator_facade.hpp>
16 #include <boost/iterator/detail/enable_if.hpp>
17
18 #include <boost/mpl/and.hpp>
19 #include <boost/mpl/not.hpp>
20 #include <boost/mpl/or.hpp>
21
22 #include <boost/type_traits/is_same.hpp>
23 #include <boost/type_traits/is_convertible.hpp>
24
25 #ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
26 # include <boost/type_traits/remove_reference.hpp>
27 #endif
28
29 #include <boost/type_traits/add_reference.hpp>
30 #include <boost/iterator/detail/config_def.hpp>
31
32 #include <boost/iterator/iterator_traits.hpp>
33
34 namespace boost {
35 namespace iterators {
36
37   // Used as a default template argument internally, merely to
38   // indicate "use the default", this can also be passed by users
39   // explicitly in order to specify that the default should be used.
40   using boost::use_default;
41
42 } // namespace iterators
43
44 // the incompleteness of use_default causes massive problems for
45 // is_convertible (naturally).  This workaround is fortunately not
46 // needed for vc6/vc7.
47 template<class To>
48 struct is_convertible<use_default,To>
49   : mpl::false_ {};
50
51 namespace iterators {
52
53   namespace detail
54   {
55
56     //
57     // Result type used in enable_if_convertible meta function.
58     // This can be an incomplete type, as only pointers to
59     // enable_if_convertible< ... >::type are used.
60     // We could have used void for this, but conversion to
61     // void* is just to easy.
62     //
63     struct enable_type;
64   }
65
66
67   //
68   // enable_if for use in adapted iterators constructors.
69   //
70   // In order to provide interoperability between adapted constant and
71   // mutable iterators, adapted iterators will usually provide templated
72   // conversion constructors of the following form
73   //
74   // template <class BaseIterator>
75   // class adapted_iterator :
76   //   public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
77   // {
78   // public:
79   //
80   //   ...
81   //
82   //   template <class OtherIterator>
83   //   adapted_iterator(
84   //       OtherIterator const& it
85   //     , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0);
86   //
87   //   ...
88   // };
89   //
90   // enable_if_convertible is used to remove those overloads from the overload
91   // set that cannot be instantiated. For all practical purposes only overloads
92   // for constant/mutable interaction will remain. This has the advantage that
93   // meta functions like boost::is_convertible do not return false positives,
94   // as they can only look at the signature of the conversion constructor
95   // and not at the actual instantiation.
96   //
97   // enable_if_interoperable can be safely used in user code. It falls back to
98   // always enabled for compilers that don't support enable_if or is_convertible.
99   // There is no need for compiler specific workarounds in user code.
100   //
101   // The operators implementation relies on boost::is_convertible not returning
102   // false positives for user/library defined iterator types. See comments
103   // on operator implementation for consequences.
104   //
105 #  if defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
106
107   template <class From, class To>
108   struct enable_if_convertible
109   {
110       typedef boost::iterators::detail::enable_type type;
111   };
112
113 #  elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292))
114
115   // For some reason vc7.1 needs us to "cut off" instantiation
116   // of is_convertible in a few cases.
117   template<typename From, typename To>
118   struct enable_if_convertible
119     : iterators::enable_if<
120         mpl::or_<
121             is_same<From,To>
122           , is_convertible<From, To>
123         >
124       , boost::iterators::detail::enable_type
125     >
126   {};
127
128 #  else
129
130   template<typename From, typename To>
131   struct enable_if_convertible
132     : iterators::enable_if<
133           is_convertible<From, To>
134         , boost::iterators::detail::enable_type
135       >
136   {};
137
138 # endif
139
140   //
141   // Default template argument handling for iterator_adaptor
142   //
143   namespace detail
144   {
145     // If T is use_default, return the result of invoking
146     // DefaultNullaryFn, otherwise return T.
147     template <class T, class DefaultNullaryFn>
148     struct ia_dflt_help
149       : mpl::eval_if<
150             is_same<T, use_default>
151           , DefaultNullaryFn
152           , mpl::identity<T>
153         >
154     {
155     };
156
157     // A metafunction which computes an iterator_adaptor's base class,
158     // a specialization of iterator_facade.
159     template <
160         class Derived
161       , class Base
162       , class Value
163       , class Traversal
164       , class Reference
165       , class Difference
166     >
167     struct iterator_adaptor_base
168     {
169         typedef iterator_facade<
170             Derived
171
172 # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
173           , typename boost::iterators::detail::ia_dflt_help<
174                 Value
175               , mpl::eval_if<
176                     is_same<Reference,use_default>
177                   , iterator_value<Base>
178                   , remove_reference<Reference>
179                 >
180             >::type
181 # else
182           , typename boost::iterators::detail::ia_dflt_help<
183                 Value, iterator_value<Base>
184             >::type
185 # endif
186
187           , typename boost::iterators::detail::ia_dflt_help<
188                 Traversal
189               , iterator_traversal<Base>
190             >::type
191
192           , typename boost::iterators::detail::ia_dflt_help<
193                 Reference
194               , mpl::eval_if<
195                     is_same<Value,use_default>
196                   , iterator_reference<Base>
197                   , add_reference<Value>
198                 >
199             >::type
200
201           , typename boost::iterators::detail::ia_dflt_help<
202                 Difference, iterator_difference<Base>
203             >::type
204         >
205         type;
206     };
207
208     // workaround for aC++ CR JAGaf33512
209     template <class Tr1, class Tr2>
210     inline void iterator_adaptor_assert_traversal ()
211     {
212       BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value));
213     }
214   }
215
216   //
217   // Iterator Adaptor
218   //
219   // The parameter ordering changed slightly with respect to former
220   // versions of iterator_adaptor The idea is that when the user needs
221   // to fiddle with the reference type it is highly likely that the
222   // iterator category has to be adjusted as well.  Any of the
223   // following four template arguments may be ommitted or explicitly
224   // replaced by use_default.
225   //
226   //   Value - if supplied, the value_type of the resulting iterator, unless
227   //      const. If const, a conforming compiler strips constness for the
228   //      value_type. If not supplied, iterator_traits<Base>::value_type is used
229   //
230   //   Category - the traversal category of the resulting iterator. If not
231   //      supplied, iterator_traversal<Base>::type is used.
232   //
233   //   Reference - the reference type of the resulting iterator, and in
234   //      particular, the result type of operator*(). If not supplied but
235   //      Value is supplied, Value& is used. Otherwise
236   //      iterator_traits<Base>::reference is used.
237   //
238   //   Difference - the difference_type of the resulting iterator. If not
239   //      supplied, iterator_traits<Base>::difference_type is used.
240   //
241   template <
242       class Derived
243     , class Base
244     , class Value        = use_default
245     , class Traversal    = use_default
246     , class Reference    = use_default
247     , class Difference   = use_default
248   >
249   class iterator_adaptor
250     : public boost::iterators::detail::iterator_adaptor_base<
251         Derived, Base, Value, Traversal, Reference, Difference
252       >::type
253   {
254       friend class iterator_core_access;
255
256    protected:
257       typedef typename boost::iterators::detail::iterator_adaptor_base<
258           Derived, Base, Value, Traversal, Reference, Difference
259       >::type super_t;
260    public:
261       iterator_adaptor() {}
262
263       explicit iterator_adaptor(Base const &iter)
264           : m_iterator(iter)
265       {
266       }
267
268       typedef Base base_type;
269
270       Base const& base() const
271         { return m_iterator; }
272
273    protected:
274       // for convenience in derived classes
275       typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;
276
277       //
278       // lvalue access to the Base object for Derived
279       //
280       Base const& base_reference() const
281         { return m_iterator; }
282
283       Base& base_reference()
284         { return m_iterator; }
285
286    private:
287       //
288       // Core iterator interface for iterator_facade.  This is private
289       // to prevent temptation for Derived classes to use it, which
290       // will often result in an error.  Derived classes should use
291       // base_reference(), above, to get direct access to m_iterator.
292       //
293       typename super_t::reference dereference() const
294         { return *m_iterator; }
295
296       template <
297       class OtherDerived, class OtherIterator, class V, class C, class R, class D
298       >
299       bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const
300       {
301         // Maybe readd with same_distance
302         //           BOOST_STATIC_ASSERT(
303         //               (detail::same_category_and_difference<Derived,OtherDerived>::value)
304         //               );
305           return m_iterator == x.base();
306       }
307
308       typedef typename iterator_category_to_traversal<
309           typename super_t::iterator_category
310       >::type my_traversal;
311
312 # define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
313       boost::iterators::detail::iterator_adaptor_assert_traversal<my_traversal, cat>();
314
315       void advance(typename super_t::difference_type n)
316       {
317           BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
318           m_iterator += n;
319       }
320
321       void increment() { ++m_iterator; }
322
323       void decrement()
324       {
325           BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
326            --m_iterator;
327       }
328
329       template <
330           class OtherDerived, class OtherIterator, class V, class C, class R, class D
331       >
332       typename super_t::difference_type distance_to(
333           iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
334       {
335           BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
336           // Maybe readd with same_distance
337           //           BOOST_STATIC_ASSERT(
338           //               (detail::same_category_and_difference<Derived,OtherDerived>::value)
339           //               );
340           return y.base() - m_iterator;
341       }
342
343 # undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
344
345    private: // data members
346       Base m_iterator;
347   };
348
349 } // namespace iterators
350
351 using iterators::iterator_adaptor;
352 using iterators::enable_if_convertible;
353
354 } // namespace boost
355
356 #include <boost/iterator/detail/config_undef.hpp>
357
358 #endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP