123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509 |
- // (C) Copyright Jeremy Siek 2002.
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_ITERATOR_ARCHETYPES_HPP
- #define BOOST_ITERATOR_ARCHETYPES_HPP
- #include <boost/iterator/iterator_categories.hpp>
- #include <boost/operators.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/iterator/detail/facade_iterator_category.hpp>
- #include <boost/type_traits/is_const.hpp>
- #include <boost/type_traits/add_const.hpp>
- #include <boost/type_traits/remove_const.hpp>
- #include <boost/type_traits/remove_cv.hpp>
- #include <boost/concept_archetype.hpp>
- #include <boost/mpl/bitand.hpp>
- #include <boost/mpl/int.hpp>
- #include <boost/mpl/equal_to.hpp>
- #include <boost/mpl/if.hpp>
- #include <boost/mpl/eval_if.hpp>
- #include <boost/mpl/and.hpp>
- #include <boost/mpl/identity.hpp>
- #include <cstddef>
- namespace boost {
- namespace iterators {
- template <class Value, class AccessCategory>
- struct access_archetype;
- template <class Derived, class Value, class AccessCategory, class TraversalCategory>
- struct traversal_archetype;
- namespace archetypes
- {
- enum {
- readable_iterator_bit = 1
- , writable_iterator_bit = 2
- , swappable_iterator_bit = 4
- , lvalue_iterator_bit = 8
- };
- // Not quite tags, since dispatching wouldn't work.
- typedef mpl::int_<readable_iterator_bit>::type readable_iterator_t;
- typedef mpl::int_<writable_iterator_bit>::type writable_iterator_t;
- typedef mpl::int_<
- (readable_iterator_bit|writable_iterator_bit)
- >::type readable_writable_iterator_t;
- typedef mpl::int_<
- (readable_iterator_bit|lvalue_iterator_bit)
- >::type readable_lvalue_iterator_t;
- typedef mpl::int_<
- (lvalue_iterator_bit|writable_iterator_bit)
- >::type writable_lvalue_iterator_t;
- typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t;
- typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t;
- template <class Derived, class Base>
- struct has_access
- : mpl::equal_to<
- mpl::bitand_<Derived,Base>
- , Base
- >
- {};
- }
- namespace detail
- {
- template <class T>
- struct assign_proxy
- {
- assign_proxy& operator=(T) { return *this; }
- };
- template <class T>
- struct read_proxy
- {
- operator T() { return static_object<T>::get(); }
- };
- template <class T>
- struct read_write_proxy
- : read_proxy<T> // Use to inherit from assign_proxy, but that doesn't work. -JGS
- {
- read_write_proxy& operator=(T) { return *this; }
- };
- template <class T>
- struct arrow_proxy
- {
- T const* operator->() const { return 0; }
- };
- struct no_operator_brackets {};
- template <class ValueType>
- struct readable_operator_brackets
- {
- read_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_proxy<ValueType>(); }
- };
- template <class ValueType>
- struct writable_operator_brackets
- {
- read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_write_proxy<ValueType>(); }
- };
- template <class Value, class AccessCategory, class TraversalCategory>
- struct operator_brackets
- : mpl::eval_if<
- is_convertible<TraversalCategory, random_access_traversal_tag>
- , mpl::eval_if<
- archetypes::has_access<
- AccessCategory
- , archetypes::writable_iterator_t
- >
- , mpl::identity<writable_operator_brackets<Value> >
- , mpl::if_<
- archetypes::has_access<
- AccessCategory
- , archetypes::readable_iterator_t
- >
- , readable_operator_brackets<Value>
- , no_operator_brackets
- >
- >
- , mpl::identity<no_operator_brackets>
- >::type
- {};
- template <class TraversalCategory>
- struct traversal_archetype_impl
- {
- template <class Derived,class Value> struct archetype;
- };
- // Constructor argument for those iterators that
- // are not default constructible
- struct ctor_arg {};
- template <class Derived, class Value, class TraversalCategory>
- struct traversal_archetype_
- : traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
- {
- typedef typename
- traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
- base;
- traversal_archetype_() {}
- traversal_archetype_(ctor_arg arg)
- : base(arg)
- {}
- };
- template <>
- struct traversal_archetype_impl<incrementable_traversal_tag>
- {
- template<class Derived, class Value>
- struct archetype
- {
- explicit archetype(ctor_arg) {}
- struct bogus { }; // This use to be void, but that causes trouble for iterator_facade. Need more research. -JGS
- typedef bogus difference_type;
- Derived& operator++() { return (Derived&)static_object<Derived>::get(); }
- Derived operator++(int) const { return (Derived&)static_object<Derived>::get(); }
- };
- };
- template <>
- struct traversal_archetype_impl<single_pass_traversal_tag>
- {
- template<class Derived, class Value>
- struct archetype
- : public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
- public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
- {
- explicit archetype(ctor_arg arg)
- : traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)
- {}
- typedef std::ptrdiff_t difference_type;
- };
- };
- template <class Derived, class Value>
- bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
- traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
- template <>
- struct traversal_archetype_impl<forward_traversal_tag>
- {
- template<class Derived, class Value>
- struct archetype
- : public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
- {
- archetype()
- : traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())
- {}
- };
- };
- template <>
- struct traversal_archetype_impl<bidirectional_traversal_tag>
- {
- template<class Derived, class Value>
- struct archetype
- : public traversal_archetype_<Derived, Value, forward_traversal_tag>
- {
- Derived& operator--() { return static_object<Derived>::get(); }
- Derived operator--(int) const { return static_object<Derived>::get(); }
- };
- };
- template <>
- struct traversal_archetype_impl<random_access_traversal_tag>
- {
- template<class Derived, class Value>
- struct archetype
- : public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
- {
- Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); }
- Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); }
- };
- };
- template <class Derived, class Value>
- Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
- std::ptrdiff_t) { return static_object<Derived>::get(); }
- template <class Derived, class Value>
- Derived& operator+(std::ptrdiff_t,
- traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
- { return static_object<Derived>::get(); }
- template <class Derived, class Value>
- Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
- std::ptrdiff_t)
- { return static_object<Derived>::get(); }
- template <class Derived, class Value>
- std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
- traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
- { return 0; }
- template <class Derived, class Value>
- bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
- traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
- { return true; }
- template <class Derived, class Value>
- bool operator>(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
- traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
- { return true; }
- template <class Derived, class Value>
- bool operator<=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
- traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
- { return true; }
- template <class Derived, class Value>
- bool operator>=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
- traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
- { return true; }
- struct bogus_type;
- template <class Value>
- struct convertible_type
- : mpl::if_< is_const<Value>,
- typename remove_const<Value>::type,
- bogus_type >
- {};
- } // namespace detail
- template <class> struct undefined;
- template <class AccessCategory>
- struct iterator_access_archetype_impl
- {
- template <class Value> struct archetype;
- };
- template <class Value, class AccessCategory>
- struct iterator_access_archetype
- : iterator_access_archetype_impl<
- AccessCategory
- >::template archetype<Value>
- {
- };
- template <>
- struct iterator_access_archetype_impl<
- archetypes::readable_iterator_t
- >
- {
- template <class Value>
- struct archetype
- {
- typedef typename remove_cv<Value>::type value_type;
- typedef Value reference;
- typedef Value* pointer;
- value_type operator*() const { return static_object<value_type>::get(); }
- detail::arrow_proxy<Value> operator->() const { return detail::arrow_proxy<Value>(); }
- };
- };
- template <>
- struct iterator_access_archetype_impl<
- archetypes::writable_iterator_t
- >
- {
- template <class Value>
- struct archetype
- {
- BOOST_STATIC_ASSERT(!is_const<Value>::value);
- typedef void value_type;
- typedef void reference;
- typedef void pointer;
- detail::assign_proxy<Value> operator*() const { return detail::assign_proxy<Value>(); }
- };
- };
- template <>
- struct iterator_access_archetype_impl<
- archetypes::readable_writable_iterator_t
- >
- {
- template <class Value>
- struct archetype
- : public virtual iterator_access_archetype<
- Value, archetypes::readable_iterator_t
- >
- {
- typedef detail::read_write_proxy<Value> reference;
- detail::read_write_proxy<Value> operator*() const { return detail::read_write_proxy<Value>(); }
- };
- };
- template <>
- struct iterator_access_archetype_impl<archetypes::readable_lvalue_iterator_t>
- {
- template <class Value>
- struct archetype
- : public virtual iterator_access_archetype<
- Value, archetypes::readable_iterator_t
- >
- {
- typedef Value& reference;
- Value& operator*() const { return static_object<Value>::get(); }
- Value* operator->() const { return 0; }
- };
- };
- template <>
- struct iterator_access_archetype_impl<archetypes::writable_lvalue_iterator_t>
- {
- template <class Value>
- struct archetype
- : public virtual iterator_access_archetype<
- Value, archetypes::readable_lvalue_iterator_t
- >
- {
- BOOST_STATIC_ASSERT((!is_const<Value>::value));
- };
- };
- template <class Value, class AccessCategory, class TraversalCategory>
- struct iterator_archetype;
- template <class Value, class AccessCategory, class TraversalCategory>
- struct traversal_archetype_base
- : detail::operator_brackets<
- typename remove_cv<Value>::type
- , AccessCategory
- , TraversalCategory
- >
- , detail::traversal_archetype_<
- iterator_archetype<Value, AccessCategory, TraversalCategory>
- , Value
- , TraversalCategory
- >
- {
- };
- namespace detail
- {
- template <class Value, class AccessCategory, class TraversalCategory>
- struct iterator_archetype_base
- : iterator_access_archetype<Value, AccessCategory>
- , traversal_archetype_base<Value, AccessCategory, TraversalCategory>
- {
- typedef iterator_access_archetype<Value, AccessCategory> access;
- typedef typename detail::facade_iterator_category<
- TraversalCategory
- , typename mpl::eval_if<
- archetypes::has_access<
- AccessCategory, archetypes::writable_iterator_t
- >
- , remove_const<Value>
- , add_const<Value>
- >::type
- , typename access::reference
- >::type iterator_category;
- // Needed for some broken libraries (see below)
- struct workaround_iterator_base
- {
- typedef typename iterator_archetype_base::iterator_category iterator_category;
- typedef Value value_type;
- typedef typename traversal_archetype_base<
- Value, AccessCategory, TraversalCategory
- >::difference_type difference_type;
- typedef typename access::pointer pointer;
- typedef typename access::reference reference;
- };
- };
- }
- template <class Value, class AccessCategory, class TraversalCategory>
- struct iterator_archetype
- : public detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>
- // These broken libraries require derivation from std::iterator
- // (or related magic) in order to handle iter_swap and other
- // iterator operations
- # if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
- || BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
- , public detail::iterator_archetype_base<
- Value, AccessCategory, TraversalCategory
- >::workaround_iterator_base
- # endif
- {
- // Derivation from std::iterator above caused references to nested
- // types to be ambiguous, so now we have to redeclare them all
- // here.
- # if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
- || BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
- typedef detail::iterator_archetype_base<
- Value,AccessCategory,TraversalCategory
- > base;
- typedef typename base::value_type value_type;
- typedef typename base::reference reference;
- typedef typename base::pointer pointer;
- typedef typename base::difference_type difference_type;
- typedef typename base::iterator_category iterator_category;
- # endif
- iterator_archetype() { }
- iterator_archetype(iterator_archetype const& x)
- : detail::iterator_archetype_base<
- Value
- , AccessCategory
- , TraversalCategory
- >(x)
- {}
- iterator_archetype& operator=(iterator_archetype const&)
- { return *this; }
- # if 0
- // Optional conversion from mutable
- iterator_archetype(
- iterator_archetype<
- typename detail::convertible_type<Value>::type
- , AccessCategory
- , TraversalCategory> const&
- );
- # endif
- };
- } // namespace iterators
- // Backward compatibility names
- namespace iterator_archetypes = iterators::archetypes;
- using iterators::access_archetype;
- using iterators::traversal_archetype;
- using iterators::iterator_archetype;
- using iterators::undefined;
- using iterators::iterator_access_archetype_impl;
- using iterators::traversal_archetype_base;
- } // namespace boost
- #endif // BOOST_ITERATOR_ARCHETYPES_HPP
|