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