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

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