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