]> git.lyx.org Git - lyx.git/blob - boost/boost/iterator/iterator_archetypes.hpp
update to boost 1.39: add new files
[lyx.git] / boost / boost / iterator / iterator_archetypes.hpp
1 // (C) Copyright Jeremy Siek 2002.\r
2 // Distributed under the Boost Software License, Version 1.0. (See\r
3 // accompanying file LICENSE_1_0.txt or copy at\r
4 // http://www.boost.org/LICENSE_1_0.txt)\r
5 \r
6 #ifndef BOOST_ITERATOR_ARCHETYPES_HPP\r
7 #define BOOST_ITERATOR_ARCHETYPES_HPP\r
8 \r
9 #include <boost/iterator/iterator_categories.hpp>\r
10 #include <boost/operators.hpp>\r
11 #include <boost/static_assert.hpp>\r
12 #include <boost/iterator.hpp>\r
13 \r
14 #include <boost/iterator/detail/facade_iterator_category.hpp>\r
15 \r
16 #include <boost/type_traits/is_const.hpp>\r
17 #include <boost/type_traits/add_const.hpp>\r
18 #include <boost/type_traits/remove_const.hpp>\r
19 #include <boost/type_traits/remove_cv.hpp>\r
20 \r
21 #include <boost/concept_archetype.hpp>\r
22 \r
23 #include <boost/mpl/aux_/msvc_eti_base.hpp>\r
24 #include <boost/mpl/bitand.hpp>\r
25 #include <boost/mpl/int.hpp>\r
26 #include <boost/mpl/equal_to.hpp>\r
27 #include <boost/mpl/if.hpp>\r
28 #include <boost/mpl/eval_if.hpp>\r
29 #include <boost/mpl/and.hpp>\r
30 #include <boost/mpl/identity.hpp>\r
31 \r
32 #include <cstddef>\r
33 \r
34 namespace boost {\r
35 \r
36 template <class Value, class AccessCategory>\r
37 struct access_archetype;\r
38 \r
39 template <class Derived, class Value, class AccessCategory, class TraversalCategory>\r
40 struct traversal_archetype;\r
41 \r
42 namespace iterator_archetypes\r
43 {\r
44   enum {\r
45       readable_iterator_bit = 1\r
46     , writable_iterator_bit = 2\r
47     , swappable_iterator_bit = 4\r
48     , lvalue_iterator_bit = 8\r
49   };\r
50 \r
51   // Not quite tags, since dispatching wouldn't work.\r
52   typedef mpl::int_<readable_iterator_bit>::type readable_iterator_t;\r
53   typedef mpl::int_<writable_iterator_bit>::type writable_iterator_t;\r
54   \r
55   typedef mpl::int_<\r
56       (readable_iterator_bit|writable_iterator_bit)\r
57           >::type readable_writable_iterator_t;\r
58   \r
59   typedef mpl::int_<\r
60       (readable_iterator_bit|lvalue_iterator_bit)\r
61           >::type readable_lvalue_iterator_t;\r
62   \r
63   typedef mpl::int_<\r
64       (lvalue_iterator_bit|writable_iterator_bit)\r
65           >::type writable_lvalue_iterator_t;\r
66   \r
67   typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t;\r
68   typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t;\r
69 \r
70   template <class Derived, class Base>\r
71   struct has_access\r
72     : mpl::equal_to<\r
73           mpl::bitand_<Derived,Base>\r
74         , Base\r
75       >\r
76   {};\r
77 }\r
78 \r
79 namespace detail\r
80 {\r
81   template <class T>\r
82   struct assign_proxy\r
83   {\r
84       assign_proxy& operator=(T) { return *this; }\r
85   };\r
86 \r
87   template <class T>\r
88   struct read_proxy\r
89   {\r
90       operator T() { return static_object<T>::get(); }\r
91   };\r
92 \r
93   template <class T>\r
94   struct read_write_proxy\r
95     : read_proxy<T> // Use to inherit from assign_proxy, but that doesn't work. -JGS\r
96   {\r
97       read_write_proxy& operator=(T) { return *this; }\r
98   };\r
99 \r
100   template <class T>\r
101   struct arrow_proxy\r
102   {\r
103       T const* operator->() const { return 0; }\r
104   };\r
105 \r
106   struct no_operator_brackets {};\r
107 \r
108   template <class ValueType>\r
109   struct readable_operator_brackets\r
110   {\r
111       read_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_proxy<ValueType>(); }\r
112   };\r
113 \r
114   template <class ValueType>\r
115   struct writable_operator_brackets\r
116   {\r
117       read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_write_proxy<ValueType>(); }\r
118   };\r
119 \r
120   template <class Value, class AccessCategory, class TraversalCategory>\r
121   struct operator_brackets\r
122     : mpl::aux::msvc_eti_base<\r
123           typename mpl::eval_if<\r
124               is_convertible<TraversalCategory, random_access_traversal_tag>\r
125             , mpl::eval_if<\r
126                   iterator_archetypes::has_access<\r
127                       AccessCategory\r
128                     , iterator_archetypes::writable_iterator_t\r
129                   >\r
130                 , mpl::identity<writable_operator_brackets<Value> >\r
131                 , mpl::if_<\r
132                       iterator_archetypes::has_access<\r
133                           AccessCategory\r
134                         , iterator_archetypes::readable_iterator_t\r
135                       >\r
136                     , readable_operator_brackets<Value>\r
137                     , no_operator_brackets\r
138                   >\r
139               >\r
140             , mpl::identity<no_operator_brackets>\r
141           >::type\r
142       >::type\r
143   {};\r
144   \r
145   template <class TraversalCategory>\r
146   struct traversal_archetype_impl\r
147   {\r
148       template <class Derived,class Value> struct archetype;\r
149   };\r
150 \r
151   // Constructor argument for those iterators that\r
152   // are not default constructible\r
153   struct ctor_arg {};\r
154 \r
155   template <class Derived, class Value, class TraversalCategory>\r
156   struct traversal_archetype_\r
157     : mpl::aux::msvc_eti_base<\r
158           typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>\r
159       >::type\r
160   {\r
161       typedef typename\r
162         traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>\r
163       base;\r
164       \r
165       traversal_archetype_() {}\r
166 \r
167       traversal_archetype_(ctor_arg arg)\r
168         : base(arg) \r
169       {}\r
170   };\r
171 \r
172   template <>\r
173   struct traversal_archetype_impl<incrementable_traversal_tag>\r
174   {\r
175       template<class Derived, class Value>\r
176       struct archetype\r
177       {\r
178           explicit archetype(ctor_arg) {}\r
179 \r
180           struct bogus { }; // This use to be void, but that causes trouble for iterator_facade. Need more research. -JGS\r
181           typedef bogus difference_type;\r
182 \r
183           Derived& operator++() { return (Derived&)static_object<Derived>::get(); }\r
184           Derived  operator++(int) const { return (Derived&)static_object<Derived>::get(); }\r
185       };\r
186   };\r
187 \r
188   template <>\r
189   struct traversal_archetype_impl<single_pass_traversal_tag>\r
190   {\r
191       template<class Derived, class Value>\r
192       struct archetype\r
193         : public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,\r
194           public traversal_archetype_<Derived, Value, incrementable_traversal_tag>\r
195       {\r
196           explicit archetype(ctor_arg arg)\r
197             : traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)\r
198           {}\r
199           \r
200           typedef std::ptrdiff_t difference_type;\r
201       };\r
202   };\r
203 \r
204   template <class Derived, class Value>\r
205   bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,\r
206                   traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }\r
207   \r
208 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)\r
209   // doesn't seem to pick up != from equality_comparable\r
210   template <class Derived, class Value>\r
211   bool operator!=(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,\r
212                   traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }\r
213 #endif \r
214   template <>\r
215   struct traversal_archetype_impl<forward_traversal_tag>\r
216   {\r
217       template<class Derived, class Value>\r
218       struct archetype\r
219         : public traversal_archetype_<Derived, Value, single_pass_traversal_tag>\r
220       {\r
221           archetype() \r
222             : traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())\r
223           {}\r
224       };\r
225   };\r
226 \r
227   template <>\r
228   struct traversal_archetype_impl<bidirectional_traversal_tag>\r
229   {\r
230       template<class Derived, class Value>\r
231       struct archetype\r
232         : public traversal_archetype_<Derived, Value, forward_traversal_tag>\r
233       {\r
234           Derived& operator--() { return static_object<Derived>::get(); }\r
235           Derived  operator--(int) const { return static_object<Derived>::get(); }\r
236       };\r
237   };\r
238 \r
239   template <>\r
240   struct traversal_archetype_impl<random_access_traversal_tag>\r
241   {\r
242       template<class Derived, class Value>\r
243       struct archetype\r
244         : public traversal_archetype_<Derived, Value, bidirectional_traversal_tag> \r
245       {\r
246           Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); }\r
247           Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); }\r
248       };\r
249   };\r
250 \r
251   template <class Derived, class Value>\r
252   Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,\r
253                      std::ptrdiff_t) { return static_object<Derived>::get(); }\r
254 \r
255   template <class Derived, class Value>\r
256   Derived& operator+(std::ptrdiff_t,\r
257                      traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)\r
258       { return static_object<Derived>::get(); }\r
259 \r
260   template <class Derived, class Value>\r
261   Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,\r
262                      std::ptrdiff_t)\r
263       { return static_object<Derived>::get(); }\r
264 \r
265   template <class Derived, class Value>\r
266   std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,\r
267                            traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)\r
268       { return 0; }\r
269 \r
270   template <class Derived, class Value>\r
271   bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,\r
272                  traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)\r
273       { return true; }\r
274 \r
275   template <class Derived, class Value>\r
276   bool operator>(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,\r
277                  traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)\r
278       { return true; }\r
279 \r
280   template <class Derived, class Value>\r
281   bool operator<=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,\r
282                  traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)\r
283       { return true; }\r
284 \r
285   template <class Derived, class Value>\r
286   bool operator>=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,\r
287                  traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)\r
288       { return true; }\r
289 \r
290   struct bogus_type;\r
291 \r
292   template <class Value>\r
293   struct convertible_type\r
294     : mpl::if_< is_const<Value>,\r
295                 typename remove_const<Value>::type,\r
296                 bogus_type >\r
297   {};\r
298 \r
299 } // namespace detail\r
300 \r
301 \r
302 template <class> struct undefined;\r
303   \r
304 template <class AccessCategory>\r
305 struct iterator_access_archetype_impl\r
306 {\r
307     template <class Value> struct archetype;\r
308 };\r
309 \r
310 template <class Value, class AccessCategory>\r
311 struct iterator_access_archetype\r
312   : mpl::aux::msvc_eti_base<\r
313         typename iterator_access_archetype_impl<\r
314             AccessCategory\r
315         >::template archetype<Value>\r
316     >::type\r
317 {\r
318 };\r
319 \r
320 template <>\r
321 struct iterator_access_archetype_impl<\r
322     iterator_archetypes::readable_iterator_t\r
323 >\r
324 {\r
325     template <class Value>\r
326     struct archetype\r
327     {\r
328         typedef typename remove_cv<Value>::type value_type;\r
329         typedef Value                           reference;\r
330         typedef Value*                          pointer;\r
331 \r
332         value_type operator*() const { return static_object<value_type>::get(); }\r
333 \r
334         detail::arrow_proxy<Value> operator->() const { return detail::arrow_proxy<Value>(); }\r
335     };\r
336 };\r
337 \r
338 template <>\r
339 struct iterator_access_archetype_impl<\r
340     iterator_archetypes::writable_iterator_t\r
341 >\r
342 {\r
343     template <class Value>\r
344     struct archetype\r
345     {\r
346 # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)\r
347         BOOST_STATIC_ASSERT(!is_const<Value>::value);\r
348 # endif \r
349         typedef void value_type;\r
350         typedef void reference;\r
351         typedef void pointer;\r
352 \r
353         detail::assign_proxy<Value> operator*() const { return detail::assign_proxy<Value>(); }\r
354     };\r
355 };\r
356 \r
357 template <>\r
358 struct iterator_access_archetype_impl<\r
359     iterator_archetypes::readable_writable_iterator_t\r
360 >\r
361 {\r
362     template <class Value>\r
363     struct archetype\r
364       : public virtual iterator_access_archetype<\r
365             Value, iterator_archetypes::readable_iterator_t\r
366         >\r
367     {\r
368         typedef detail::read_write_proxy<Value>    reference;\r
369 \r
370         detail::read_write_proxy<Value> operator*() const { return detail::read_write_proxy<Value>(); }\r
371     };\r
372 };\r
373 \r
374 template <>\r
375 struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_iterator_t>\r
376 {\r
377     template <class Value>\r
378     struct archetype\r
379       : public virtual iterator_access_archetype<\r
380             Value, iterator_archetypes::readable_iterator_t\r
381         >\r
382     {\r
383         typedef Value&    reference;\r
384 \r
385         Value& operator*() const { return static_object<Value>::get(); }\r
386         Value* operator->() const { return 0; }\r
387     };\r
388 };\r
389   \r
390 template <>\r
391 struct iterator_access_archetype_impl<iterator_archetypes::writable_lvalue_iterator_t>\r
392 {\r
393     template <class Value>\r
394     struct archetype\r
395       : public virtual iterator_access_archetype<\r
396             Value, iterator_archetypes::readable_lvalue_iterator_t\r
397         >\r
398     {\r
399 # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)\r
400         BOOST_STATIC_ASSERT((!is_const<Value>::value));\r
401 # endif \r
402     };\r
403 };\r
404   \r
405 \r
406 template <class Value, class AccessCategory, class TraversalCategory>\r
407 struct iterator_archetype;\r
408   \r
409 template <class Value, class AccessCategory, class TraversalCategory>\r
410 struct traversal_archetype_base \r
411   : detail::operator_brackets<\r
412         typename remove_cv<Value>::type\r
413       , AccessCategory\r
414       , TraversalCategory\r
415     >\r
416   , detail::traversal_archetype_<\r
417         iterator_archetype<Value, AccessCategory, TraversalCategory>\r
418       , Value\r
419       , TraversalCategory\r
420     >\r
421 {\r
422 };\r
423 \r
424 namespace detail\r
425 {\r
426   template <class Value, class AccessCategory, class TraversalCategory>\r
427   struct iterator_archetype_base\r
428     : iterator_access_archetype<Value, AccessCategory>\r
429     , traversal_archetype_base<Value, AccessCategory, TraversalCategory>\r
430   {\r
431       typedef iterator_access_archetype<Value, AccessCategory> access;\r
432       \r
433       typedef typename detail::facade_iterator_category<\r
434           TraversalCategory\r
435         , typename mpl::eval_if<\r
436               iterator_archetypes::has_access<\r
437                   AccessCategory, iterator_archetypes::writable_iterator_t\r
438               >\r
439             , remove_const<Value>\r
440             , add_const<Value>\r
441           >::type\r
442         , typename access::reference\r
443       >::type iterator_category;\r
444 \r
445       // Needed for some broken libraries (see below)\r
446       typedef boost::iterator<\r
447           iterator_category\r
448         , Value\r
449         , typename traversal_archetype_base<\r
450               Value, AccessCategory, TraversalCategory\r
451           >::difference_type\r
452         , typename access::pointer\r
453         , typename access::reference\r
454       > workaround_iterator_base;\r
455   };\r
456 }\r
457 \r
458 template <class Value, class AccessCategory, class TraversalCategory>\r
459 struct iterator_archetype\r
460   : public detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>\r
461 \r
462     // These broken libraries require derivation from std::iterator\r
463     // (or related magic) in order to handle iter_swap and other\r
464     // iterator operations\r
465 # if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310)           \\r
466     || BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))\r
467   , public detail::iterator_archetype_base<\r
468         Value, AccessCategory, TraversalCategory\r
469     >::workaround_iterator_base\r
470 # endif \r
471 {\r
472     // Derivation from std::iterator above caused references to nested\r
473     // types to be ambiguous, so now we have to redeclare them all\r
474     // here.\r
475 # if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310)           \\r
476     || BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))\r
477     \r
478     typedef detail::iterator_archetype_base<\r
479         Value,AccessCategory,TraversalCategory\r
480     > base;\r
481     \r
482     typedef typename base::value_type value_type;\r
483     typedef typename base::reference reference;\r
484     typedef typename base::pointer pointer;\r
485     typedef typename base::difference_type difference_type;\r
486     typedef typename base::iterator_category iterator_category;\r
487 # endif\r
488 \r
489     iterator_archetype() { }\r
490     iterator_archetype(iterator_archetype const& x)\r
491       : detail::iterator_archetype_base<\r
492             Value\r
493           , AccessCategory\r
494           , TraversalCategory\r
495         >(x)\r
496     {}\r
497 \r
498     iterator_archetype& operator=(iterator_archetype const&)\r
499         { return *this; }\r
500 \r
501 # if 0\r
502     // Optional conversion from mutable\r
503     iterator_archetype(\r
504         iterator_archetype<\r
505         typename detail::convertible_type<Value>::type\r
506       , AccessCategory\r
507       , TraversalCategory> const&\r
508     );\r
509 # endif\r
510 };\r
511 \r
512 } // namespace boost\r
513 \r
514 \r
515 #endif // BOOST_ITERATOR_ARCHETYPES_HPP\r