diff options
author | Remko Tronçon <git@el-tramo.be> | 2009-06-01 08:48:42 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2009-06-01 09:24:28 (GMT) |
commit | 2812bddd81f8a1b804c7460f4e14cd0aa393d129 (patch) | |
tree | d46294f35150c4f0f43deaf2d31fceaf945ae715 /3rdParty/Boost/boost/iterator/iterator_adaptor.hpp | |
download | swift-2812bddd81f8a1b804c7460f4e14cd0aa393d129.zip swift-2812bddd81f8a1b804c7460f4e14cd0aa393d129.tar.bz2 |
Import.
Diffstat (limited to '3rdParty/Boost/boost/iterator/iterator_adaptor.hpp')
-rw-r--r-- | 3rdParty/Boost/boost/iterator/iterator_adaptor.hpp | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/3rdParty/Boost/boost/iterator/iterator_adaptor.hpp b/3rdParty/Boost/boost/iterator/iterator_adaptor.hpp new file mode 100644 index 0000000..27b08ff --- /dev/null +++ b/3rdParty/Boost/boost/iterator/iterator_adaptor.hpp @@ -0,0 +1,371 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 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_ADAPTOR_23022003THW_HPP +#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP + +#include <boost/static_assert.hpp> +#include <boost/iterator.hpp> +#include <boost/detail/iterator.hpp> + +#include <boost/iterator/iterator_categories.hpp> +#include <boost/iterator/iterator_facade.hpp> +#include <boost/iterator/detail/enable_if.hpp> + +#include <boost/mpl/and.hpp> +#include <boost/mpl/not.hpp> +#include <boost/mpl/or.hpp> + +#include <boost/type_traits/is_same.hpp> +#include <boost/type_traits/is_convertible.hpp> + +#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY +# include <boost/type_traits/remove_reference.hpp> + +# if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610)) +# include <boost/type_traits/add_reference.hpp> +# endif + +#else +# include <boost/type_traits/add_reference.hpp> +#endif + +#include <boost/iterator/detail/config_def.hpp> + +#include <boost/iterator/iterator_traits.hpp> + +namespace boost +{ + // Used as a default template argument internally, merely to + // indicate "use the default", this can also be passed by users + // explicitly in order to specify that the default should be used. + struct use_default; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // the incompleteness of use_default causes massive problems for + // is_convertible (naturally). This workaround is fortunately not + // needed for vc6/vc7. + template<class To> + struct is_convertible<use_default,To> + : mpl::false_ {}; +# endif + + namespace detail + { + + // + // Result type used in enable_if_convertible meta function. + // This can be an incomplete type, as only pointers to + // enable_if_convertible< ... >::type are used. + // We could have used void for this, but conversion to + // void* is just to easy. + // + struct enable_type; + } + + + // + // enable_if for use in adapted iterators constructors. + // + // In order to provide interoperability between adapted constant and + // mutable iterators, adapted iterators will usually provide templated + // conversion constructors of the following form + // + // template <class BaseIterator> + // class adapted_iterator : + // public iterator_adaptor< adapted_iterator<Iterator>, Iterator > + // { + // public: + // + // ... + // + // template <class OtherIterator> + // adapted_iterator( + // OtherIterator const& it + // , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0); + // + // ... + // }; + // + // enable_if_convertible is used to remove those overloads from the overload + // set that cannot be instantiated. For all practical purposes only overloads + // for constant/mutable interaction will remain. This has the advantage that + // meta functions like boost::is_convertible do not return false positives, + // as they can only look at the signature of the conversion constructor + // and not at the actual instantiation. + // + // enable_if_interoperable can be safely used in user code. It falls back to + // always enabled for compilers that don't support enable_if or is_convertible. + // There is no need for compiler specific workarounds in user code. + // + // The operators implementation relies on boost::is_convertible not returning + // false positives for user/library defined iterator types. See comments + // on operator implementation for consequences. + // +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + + template<typename From, typename To> + struct enable_if_convertible + { + typedef typename mpl::if_< + mpl::or_< + is_same<From,To> + , is_convertible<From, To> + > + , boost::detail::enable_type + , int& + >::type type; + }; + +# elif defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE) + + template <class From, class To> + struct enable_if_convertible + { + typedef boost::detail::enable_type type; + }; + +# elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300 + + // For some reason vc7.1 needs us to "cut off" instantiation + // of is_convertible in a few cases. + template<typename From, typename To> + struct enable_if_convertible + : iterators::enable_if< + mpl::or_< + is_same<From,To> + , is_convertible<From, To> + > + , boost::detail::enable_type + > + {}; + +# else + + template<typename From, typename To> + struct enable_if_convertible + : iterators::enable_if< + is_convertible<From, To> + , boost::detail::enable_type + > + {}; + +# endif + + // + // Default template argument handling for iterator_adaptor + // + namespace detail + { + // If T is use_default, return the result of invoking + // DefaultNullaryFn, otherwise return T. + template <class T, class DefaultNullaryFn> + struct ia_dflt_help + : mpl::eval_if< + is_same<T, use_default> + , DefaultNullaryFn + , mpl::identity<T> + > + { + }; + + // A metafunction which computes an iterator_adaptor's base class, + // a specialization of iterator_facade. + template < + class Derived + , class Base + , class Value + , class Traversal + , class Reference + , class Difference + > + struct iterator_adaptor_base + { + typedef iterator_facade< + Derived + +# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY + , typename boost::detail::ia_dflt_help< + Value + , mpl::eval_if< + is_same<Reference,use_default> + , iterator_value<Base> + , remove_reference<Reference> + > + >::type +# else + , typename boost::detail::ia_dflt_help< + Value, iterator_value<Base> + >::type +# endif + + , typename boost::detail::ia_dflt_help< + Traversal + , iterator_traversal<Base> + >::type + + , typename boost::detail::ia_dflt_help< + Reference + , mpl::eval_if< + is_same<Value,use_default> + , iterator_reference<Base> + , add_reference<Value> + > + >::type + + , typename boost::detail::ia_dflt_help< + Difference, iterator_difference<Base> + >::type + > + type; + }; + + // workaround for aC++ CR JAGaf33512 + template <class Tr1, class Tr2> + inline void iterator_adaptor_assert_traversal () + { + BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value)); + } + } + + // + // Iterator Adaptor + // + // The parameter ordering changed slightly with respect to former + // versions of iterator_adaptor The idea is that when the user needs + // to fiddle with the reference type it is highly likely that the + // iterator category has to be adjusted as well. Any of the + // following four template arguments may be ommitted or explicitly + // replaced by use_default. + // + // Value - if supplied, the value_type of the resulting iterator, unless + // const. If const, a conforming compiler strips constness for the + // value_type. If not supplied, iterator_traits<Base>::value_type is used + // + // Category - the traversal category of the resulting iterator. If not + // supplied, iterator_traversal<Base>::type is used. + // + // Reference - the reference type of the resulting iterator, and in + // particular, the result type of operator*(). If not supplied but + // Value is supplied, Value& is used. Otherwise + // iterator_traits<Base>::reference is used. + // + // Difference - the difference_type of the resulting iterator. If not + // supplied, iterator_traits<Base>::difference_type is used. + // + template < + class Derived + , class Base + , class Value = use_default + , class Traversal = use_default + , class Reference = use_default + , class Difference = use_default + > + class iterator_adaptor + : public boost::detail::iterator_adaptor_base< + Derived, Base, Value, Traversal, Reference, Difference + >::type + { + friend class iterator_core_access; + + protected: + typedef typename boost::detail::iterator_adaptor_base< + Derived, Base, Value, Traversal, Reference, Difference + >::type super_t; + public: + iterator_adaptor() {} + + explicit iterator_adaptor(Base const &iter) + : m_iterator(iter) + { + } + + typedef Base base_type; + + Base const& base() const + { return m_iterator; } + + protected: + // for convenience in derived classes + typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_; + + // + // lvalue access to the Base object for Derived + // + Base const& base_reference() const + { return m_iterator; } + + Base& base_reference() + { return m_iterator; } + + private: + // + // Core iterator interface for iterator_facade. This is private + // to prevent temptation for Derived classes to use it, which + // will often result in an error. Derived classes should use + // base_reference(), above, to get direct access to m_iterator. + // + typename super_t::reference dereference() const + { return *m_iterator; } + + template < + class OtherDerived, class OtherIterator, class V, class C, class R, class D + > + bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const + { + // Maybe readd with same_distance + // BOOST_STATIC_ASSERT( + // (detail::same_category_and_difference<Derived,OtherDerived>::value) + // ); + return m_iterator == x.base(); + } + + typedef typename iterator_category_to_traversal< + typename super_t::iterator_category + >::type my_traversal; + +# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \ + boost::detail::iterator_adaptor_assert_traversal<my_traversal, cat>(); + + void advance(typename super_t::difference_type n) + { + BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag) + m_iterator += n; + } + + void increment() { ++m_iterator; } + + void decrement() + { + BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag) + --m_iterator; + } + + template < + class OtherDerived, class OtherIterator, class V, class C, class R, class D + > + typename super_t::difference_type distance_to( + iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const + { + BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag) + // Maybe readd with same_distance + // BOOST_STATIC_ASSERT( + // (detail::same_category_and_difference<Derived,OtherDerived>::value) + // ); + return y.base() - m_iterator; + } + +# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL + + private: // data members + Base m_iterator; + }; + +} // namespace boost + +#include <boost/iterator/detail/config_undef.hpp> + +#endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP |