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
6 #ifndef BOOST_ITERATOR_ARCHETYPES_HPP
\r
7 #define BOOST_ITERATOR_ARCHETYPES_HPP
\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
14 #include <boost/iterator/detail/facade_iterator_category.hpp>
\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
21 #include <boost/concept_archetype.hpp>
\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
36 template <class Value, class AccessCategory>
\r
37 struct access_archetype;
\r
39 template <class Derived, class Value, class AccessCategory, class TraversalCategory>
\r
40 struct traversal_archetype;
\r
42 namespace iterator_archetypes
\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
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
56 (readable_iterator_bit|writable_iterator_bit)
\r
57 >::type readable_writable_iterator_t;
\r
60 (readable_iterator_bit|lvalue_iterator_bit)
\r
61 >::type readable_lvalue_iterator_t;
\r
64 (lvalue_iterator_bit|writable_iterator_bit)
\r
65 >::type writable_lvalue_iterator_t;
\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
70 template <class Derived, class Base>
\r
73 mpl::bitand_<Derived,Base>
\r
84 assign_proxy& operator=(T) { return *this; }
\r
90 operator T() { return static_object<T>::get(); }
\r
94 struct read_write_proxy
\r
95 : read_proxy<T> // Use to inherit from assign_proxy, but that doesn't work. -JGS
\r
97 read_write_proxy& operator=(T) { return *this; }
\r
103 T const* operator->() const { return 0; }
\r
106 struct no_operator_brackets {};
\r
108 template <class ValueType>
\r
109 struct readable_operator_brackets
\r
111 read_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_proxy<ValueType>(); }
\r
114 template <class ValueType>
\r
115 struct writable_operator_brackets
\r
117 read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_write_proxy<ValueType>(); }
\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
126 iterator_archetypes::has_access<
\r
128 , iterator_archetypes::writable_iterator_t
\r
130 , mpl::identity<writable_operator_brackets<Value> >
\r
132 iterator_archetypes::has_access<
\r
134 , iterator_archetypes::readable_iterator_t
\r
136 , readable_operator_brackets<Value>
\r
137 , no_operator_brackets
\r
140 , mpl::identity<no_operator_brackets>
\r
145 template <class TraversalCategory>
\r
146 struct traversal_archetype_impl
\r
148 template <class Derived,class Value> struct archetype;
\r
151 // Constructor argument for those iterators that
\r
152 // are not default constructible
\r
153 struct ctor_arg {};
\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
162 traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
\r
165 traversal_archetype_() {}
\r
167 traversal_archetype_(ctor_arg arg)
\r
173 struct traversal_archetype_impl<incrementable_traversal_tag>
\r
175 template<class Derived, class Value>
\r
178 explicit archetype(ctor_arg) {}
\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
183 Derived& operator++() { return (Derived&)static_object<Derived>::get(); }
\r
184 Derived operator++(int) const { return (Derived&)static_object<Derived>::get(); }
\r
189 struct traversal_archetype_impl<single_pass_traversal_tag>
\r
191 template<class Derived, class Value>
\r
193 : public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
\r
194 public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
\r
196 explicit archetype(ctor_arg arg)
\r
197 : traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)
\r
200 typedef std::ptrdiff_t difference_type;
\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
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
215 struct traversal_archetype_impl<forward_traversal_tag>
\r
217 template<class Derived, class Value>
\r
219 : public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
\r
222 : traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())
\r
228 struct traversal_archetype_impl<bidirectional_traversal_tag>
\r
230 template<class Derived, class Value>
\r
232 : public traversal_archetype_<Derived, Value, forward_traversal_tag>
\r
234 Derived& operator--() { return static_object<Derived>::get(); }
\r
235 Derived operator--(int) const { return static_object<Derived>::get(); }
\r
240 struct traversal_archetype_impl<random_access_traversal_tag>
\r
242 template<class Derived, class Value>
\r
244 : public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
\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
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
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
260 template <class Derived, class Value>
\r
261 Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
\r
263 { return static_object<Derived>::get(); }
\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
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
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
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
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
292 template <class Value>
\r
293 struct convertible_type
\r
294 : mpl::if_< is_const<Value>,
\r
295 typename remove_const<Value>::type,
\r
299 } // namespace detail
\r
302 template <class> struct undefined;
\r
304 template <class AccessCategory>
\r
305 struct iterator_access_archetype_impl
\r
307 template <class Value> struct archetype;
\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
315 >::template archetype<Value>
\r
321 struct iterator_access_archetype_impl<
\r
322 iterator_archetypes::readable_iterator_t
\r
325 template <class Value>
\r
328 typedef typename remove_cv<Value>::type value_type;
\r
329 typedef Value reference;
\r
330 typedef Value* pointer;
\r
332 value_type operator*() const { return static_object<value_type>::get(); }
\r
334 detail::arrow_proxy<Value> operator->() const { return detail::arrow_proxy<Value>(); }
\r
339 struct iterator_access_archetype_impl<
\r
340 iterator_archetypes::writable_iterator_t
\r
343 template <class Value>
\r
346 # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
\r
347 BOOST_STATIC_ASSERT(!is_const<Value>::value);
\r
349 typedef void value_type;
\r
350 typedef void reference;
\r
351 typedef void pointer;
\r
353 detail::assign_proxy<Value> operator*() const { return detail::assign_proxy<Value>(); }
\r
358 struct iterator_access_archetype_impl<
\r
359 iterator_archetypes::readable_writable_iterator_t
\r
362 template <class Value>
\r
364 : public virtual iterator_access_archetype<
\r
365 Value, iterator_archetypes::readable_iterator_t
\r
368 typedef detail::read_write_proxy<Value> reference;
\r
370 detail::read_write_proxy<Value> operator*() const { return detail::read_write_proxy<Value>(); }
\r
375 struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_iterator_t>
\r
377 template <class Value>
\r
379 : public virtual iterator_access_archetype<
\r
380 Value, iterator_archetypes::readable_iterator_t
\r
383 typedef Value& reference;
\r
385 Value& operator*() const { return static_object<Value>::get(); }
\r
386 Value* operator->() const { return 0; }
\r
391 struct iterator_access_archetype_impl<iterator_archetypes::writable_lvalue_iterator_t>
\r
393 template <class Value>
\r
395 : public virtual iterator_access_archetype<
\r
396 Value, iterator_archetypes::readable_lvalue_iterator_t
\r
399 # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
\r
400 BOOST_STATIC_ASSERT((!is_const<Value>::value));
\r
406 template <class Value, class AccessCategory, class TraversalCategory>
\r
407 struct iterator_archetype;
\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
414 , TraversalCategory
\r
416 , detail::traversal_archetype_<
\r
417 iterator_archetype<Value, AccessCategory, TraversalCategory>
\r
419 , TraversalCategory
\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
431 typedef iterator_access_archetype<Value, AccessCategory> access;
\r
433 typedef typename detail::facade_iterator_category<
\r
435 , typename mpl::eval_if<
\r
436 iterator_archetypes::has_access<
\r
437 AccessCategory, iterator_archetypes::writable_iterator_t
\r
439 , remove_const<Value>
\r
442 , typename access::reference
\r
443 >::type iterator_category;
\r
445 // Needed for some broken libraries (see below)
\r
446 typedef boost::iterator<
\r
449 , typename traversal_archetype_base<
\r
450 Value, AccessCategory, TraversalCategory
\r
452 , typename access::pointer
\r
453 , typename access::reference
\r
454 > workaround_iterator_base;
\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
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
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
475 # if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
\r
476 || BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
\r
478 typedef detail::iterator_archetype_base<
\r
479 Value,AccessCategory,TraversalCategory
\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
489 iterator_archetype() { }
\r
490 iterator_archetype(iterator_archetype const& x)
\r
491 : detail::iterator_archetype_base<
\r
494 , TraversalCategory
\r
498 iterator_archetype& operator=(iterator_archetype const&)
\r
502 // Optional conversion from mutable
\r
503 iterator_archetype(
\r
504 iterator_archetype<
\r
505 typename detail::convertible_type<Value>::type
\r
507 , TraversalCategory> const&
\r
512 } // namespace boost
\r
515 #endif // BOOST_ITERATOR_ARCHETYPES_HPP
\r