From 53eb5346de4fb644786374082526a6d083fdab8e Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Mon, 7 Jul 2003 14:14:36 +0000 Subject: [PATCH] Move from boost-sanbox [ JDG ] [SVN r18958] --- include/boost/iterator/counting_iterator.hpp | 193 ++++++ include/boost/iterator/filter_iterator.hpp | 109 +++ include/boost/iterator/indirect_iterator.hpp | 220 ++++++ include/boost/iterator/interoperable.hpp | 52 ++ include/boost/iterator/iterator_adaptor.hpp | 325 +++++++++ .../boost/iterator/iterator_archetypes.hpp | 350 ++++++++++ .../boost/iterator/iterator_categories.hpp | 405 ++++++++++++ include/boost/iterator/iterator_concepts.hpp | 358 ++++++++++ include/boost/iterator/iterator_facade.hpp | 625 ++++++++++++++++++ include/boost/iterator/iterator_traits.hpp | 93 +++ include/boost/iterator/new_iterator_tests.hpp | 204 ++++++ .../boost/iterator/permutation_iterator.hpp | 92 +++ include/boost/iterator/reverse_iterator.hpp | 71 ++ include/boost/iterator/transform_iterator.hpp | 154 +++++ 14 files changed, 3251 insertions(+) create mode 100644 include/boost/iterator/counting_iterator.hpp create mode 100644 include/boost/iterator/filter_iterator.hpp create mode 100644 include/boost/iterator/indirect_iterator.hpp create mode 100644 include/boost/iterator/interoperable.hpp create mode 100644 include/boost/iterator/iterator_adaptor.hpp create mode 100644 include/boost/iterator/iterator_archetypes.hpp create mode 100644 include/boost/iterator/iterator_categories.hpp create mode 100644 include/boost/iterator/iterator_concepts.hpp create mode 100644 include/boost/iterator/iterator_facade.hpp create mode 100644 include/boost/iterator/iterator_traits.hpp create mode 100644 include/boost/iterator/new_iterator_tests.hpp create mode 100644 include/boost/iterator/permutation_iterator.hpp create mode 100644 include/boost/iterator/reverse_iterator.hpp create mode 100644 include/boost/iterator/transform_iterator.hpp diff --git a/include/boost/iterator/counting_iterator.hpp b/include/boost/iterator/counting_iterator.hpp new file mode 100644 index 0000000..d168e2d --- /dev/null +++ b/include/boost/iterator/counting_iterator.hpp @@ -0,0 +1,193 @@ +// Copyright David Abrahams 2003. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef COUNTING_ITERATOR_DWA200348_HPP +# define COUNTING_ITERATOR_DWA200348_HPP + +# include +# include +# include +# include +# include +# include + +namespace boost { + +template class counting_iterator; + +namespace detail +{ + // Try to detect numeric types at compile time in ways compatible + // with the limitations of the compiler and library. + template + struct is_numeric_impl + { + // For a while, this wasn't true, but we rely on it below. This is a regression assert. + BOOST_STATIC_ASSERT(::boost::is_integral::value); + +# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + +# if defined(BOOST_HAS_LONG_LONG) + BOOST_STATIC_CONSTANT( + bool, value = ( + std::numeric_limits::is_specialized + | boost::is_same::value + | boost::is_same::value + )); +# else + BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits::is_specialized); +# endif + +# else + +# if !defined(__BORLANDC__) + BOOST_STATIC_CONSTANT( + bool, value = ( + boost::is_convertible::value + && boost::is_convertible::value + )); +# else + BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic::value); +# endif + +# endif + }; + + template + struct is_numeric + : mpl::bool_<(::boost::detail::is_numeric_impl::value)> + {}; + + template + struct numeric_difference + { + typedef typename boost::detail::numeric_traits::difference_type type; + }; + + BOOST_STATIC_ASSERT(is_numeric::value); + template + struct counting_iterator_base + { + typedef typename mpl::apply_if< + is_same + , mpl::apply_if< + is_numeric + , mpl::identity + , BOOST_ITERATOR_CATEGORY + > + , mpl::identity + >::type category; + + typedef typename mpl::apply_if< + is_same + , mpl::apply_if< + is_numeric + , numeric_difference + , iterator_difference + > + , mpl::identity + >::type difference; + + typedef iterator_adaptor< + counting_iterator // self + , Incrementable // Base + , Incrementable // value_type + , category + , Incrementable const& // reference + , difference + > type; + }; + + // Template class distance_policy_select -- choose a policy for computing the + // distance between counting_iterators at compile-time based on whether or not + // the iterator wraps an integer or an iterator, using "poor man's partial + // specialization". + + template struct distance_policy_select; + + // A policy for wrapped iterators + template + struct iterator_distance + { + static Difference distance(Incrementable1 x, Incrementable2 y) + { + return boost::detail::distance(x, y); + } + }; + + // A policy for wrapped numbers + template + struct number_distance + { + static Difference distance(Incrementable1 x, Incrementable2 y) + { + return numeric_distance(x, y); + } + }; +} + +template +class counting_iterator + : public detail::counting_iterator_base::type +{ + typedef typename detail::counting_iterator_base::type super_t; + friend class iterator_core_access; + + public: + typedef typename super_t::difference_type difference_type; + + counting_iterator() { } + + counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {} + + counting_iterator(Incrementable x) + : super_t(x) + { + } + +# if 0 + template + counting_iterator( + counting_iterator const& t + , typename enable_if_convertible::type* = 0 + ) + : super_t(t.base()) + {} +# endif + + private: + + typename super_t::reference dereference() const + { + return this->base_reference(); + } + + template + difference_type + distance_to(counting_iterator const& y) const + { + typedef typename mpl::if_< + detail::is_numeric + , detail::number_distance + , detail::iterator_distance + >::type d; + + return d::distance(this->base(), y.base()); + } +}; + +// Manufacture a counting iterator for an arbitrary incrementable type +template +inline counting_iterator +make_counting_iterator(Incrementable x) +{ + typedef counting_iterator result_t; + return result_t(x); +} + + +} // namespace boost::iterator + +#endif // COUNTING_ITERATOR_DWA200348_HPP diff --git a/include/boost/iterator/filter_iterator.hpp b/include/boost/iterator/filter_iterator.hpp new file mode 100644 index 0000000..ae46fba --- /dev/null +++ b/include/boost/iterator/filter_iterator.hpp @@ -0,0 +1,109 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BOOST_FILTER_ITERATOR_23022003THW_HPP +#define BOOST_FILTER_ITERATOR_23022003THW_HPP + +#include +#include +#include + +namespace boost +{ + namespace detail + { + template + struct filter_iterator_category + { + typedef iterator_tag< + typename access_category::type + , typename minimum_category< + bidirectional_traversal_tag + , typename traversal_category::type + >::type + > type; + }; + + } // namespace detail + + template + class filter_iterator + : public iterator_adaptor< + filter_iterator, Iterator + , use_default + , typename detail::filter_iterator_category::type + > + { + typedef iterator_adaptor< + filter_iterator, Iterator + , use_default + , typename detail::filter_iterator_category::type + > super_t; + + friend class iterator_core_access; + + public: + filter_iterator() { } + + filter_iterator(Predicate f, Iterator x, Iterator end = Iterator()) + : super_t(x), m_predicate(f), m_end(end) + { + satisfy_predicate(); + } + + filter_iterator(Iterator x, Iterator end = Iterator()) + : super_t(x), m_predicate(), m_end(end) + { + satisfy_predicate(); + } + + template + filter_iterator( + filter_iterator const& t + , typename enable_if_convertible::type* = 0 + ) + : super_t(t.base()), m_predicate(t.predicate()), m_end(t.end()) {} + + Predicate predicate() const { return m_predicate; } + + Iterator end() const { return m_end; } + + private: + void increment() + { + ++(this->base_reference()); + satisfy_predicate(); + } + + void decrement() + { + while(!this->m_predicate(*--(this->base_reference()))){}; + } + + void satisfy_predicate() + { + while (this->base() != this->m_end && !this->m_predicate(*this->base())) + ++(this->base_reference()); + } + + // Probably should be the initial base class so it can be + // optimized away via EBO if it is an empty class. + Predicate m_predicate; + Iterator m_end; + }; + + template + filter_iterator + make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator()) + { + return filter_iterator(f,x,end); + } + +} // namespace boost + +#endif // BOOST_FILTER_ITERATOR_23022003THW_HPP diff --git a/include/boost/iterator/indirect_iterator.hpp b/include/boost/iterator/indirect_iterator.hpp new file mode 100644 index 0000000..f6caa71 --- /dev/null +++ b/include/boost/iterator/indirect_iterator.hpp @@ -0,0 +1,220 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BOOST_INDIRECT_ITERATOR_23022003THW_HPP +#define BOOST_INDIRECT_ITERATOR_23022003THW_HPP + +#include +#include + +#include + +#include +#include +#include + +#ifdef BOOST_NO_MPL_AUX_HAS_XXX +# include +# include +# include +# include +#endif + +#include // must be last #include + +namespace boost +{ + template + struct indirect_iterator; + + namespace detail + { + struct unspecified {}; + + // + // Detection for whether a type has a nested `element_type' + // typedef. Used to detect smart pointers. For compilers not + // supporting mpl's has_xxx, we supply specializations. However, we + // really ought to have a specializable is_pointer template which + // can be used instead with something like + // boost/python/pointee.hpp to find the value_type. + // +# ifndef BOOST_NO_MPL_AUX_HAS_XXX + namespace aux + { + BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type) + } + + template + struct has_element_type + : mpl::bool_< + mpl::if_< + is_class + , ::boost::detail::aux::has_element_type + , mpl::false_ + >::type::value + > + { + }; +# else + template + struct has_element_type + : mpl::false_ {}; + + template + struct has_element_type > + : mpl::true_ {}; + + template + struct has_element_type > + : mpl::true_ {}; + + template + struct has_element_type > + : mpl::true_ {}; +# endif + + // Metafunction returning the nested element_type typedef + template + struct smart_pointer_value : remove_const + {}; + + template + struct iterator_is_mutable + : mpl::not_< + boost::python::detail::is_reference_to_const< + typename iterator_reference::type + > + > + { + }; + + template + struct not_int_impl + { + template + struct apply { + typedef T type; + }; + }; + + template <> + struct not_int_impl {}; + + template + struct not_int + : not_int_impl::template apply {}; + + // If the Value parameter is unspecified, we use this metafunction + // to deduce the default types + template + struct indirect_base + { + typedef typename iterator_value::type dereferenceable; + + typedef mpl::and_< + is_class + , has_element_type + > is_smart_ptr; + + typedef typename mpl::apply_if< + is_smart_ptr + , smart_pointer_value + , iterator_value + >::type value_type; + + typedef typename mpl::if_< + mpl::or_< + is_smart_ptr + , iterator_is_mutable + > + , value_type + , value_type const + >::type cv_value_type; + + typedef iterator_adaptor< + indirect_iterator + , Iter + , cv_value_type + , Category + , Reference + , Difference + > type; + }; + + template <> + struct indirect_base {}; + } // namespace detail + + template < + class Iterator + , class Value = use_default + , class Category = use_default + , class Reference = use_default + , class Difference = use_default + > + class indirect_iterator + : public detail::indirect_base< + Iterator, Value, Category, Reference, Difference + >::type + { + typedef typename detail::indirect_base< + Iterator, Value, Category, Reference, Difference + >::type super_t; + + friend class iterator_core_access; + + public: + indirect_iterator() {} + + indirect_iterator(Iterator iter) + : super_t(iter) {} + + template < + class Iterator2, class Value2, class Category2 + , class Reference2, class Difference2 + > + indirect_iterator( + indirect_iterator< + Iterator2, Value2, Category2, Reference2, Difference2 + > const& y + , typename enable_if_convertible::type* = 0 + ) + : super_t(y.base()) + {} + + private: + typename super_t::reference dereference() const + { +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + return const_cast(**this->base()); +# else + return **this->base(); +# endif + } + }; + + template + inline + indirect_iterator make_indirect_iterator(Iter x) + { + return indirect_iterator(x); + } + + template + inline + indirect_iterator make_indirect_iterator(Iter x, Traits* = 0) + { + return indirect_iterator(x); + } + +} // namespace boost + +#include + +#endif // BOOST_INDIRECT_ITERATOR_23022003THW_HPP diff --git a/include/boost/iterator/interoperable.hpp b/include/boost/iterator/interoperable.hpp new file mode 100644 index 0000000..b326250 --- /dev/null +++ b/include/boost/iterator/interoperable.hpp @@ -0,0 +1,52 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BOOST_INTEROPERABLE_23022003THW_HPP +# define BOOST_INTEROPERABLE_23022003THW_HPP + +# include +# include + +# include + +# include // must appear last + +namespace boost +{ + + // + // Meta function that determines whether two + // iterator types are considered interoperable. + // + // Two iterator types A,B are considered interoperable if either + // A is convertible to B or vice versa. + // This interoperability definition is in sync with the + // standards requirements on constant/mutable container + // iterators (23.1 [lib.container.requirements]). + // + // For compilers that don't support is_convertible + // is_interoperable gives false positives. See comments + // on operator implementation for consequences. + // + template + struct is_interoperable +# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY + : mpl::true_ +# else + : mpl::or_< + is_convertible< A, B > + , is_convertible< B, A > > +# endif + { + }; + +} // namespace boost + +# include + +#endif // BOOST_INTEROPERABLE_23022003THW_HPP diff --git a/include/boost/iterator/iterator_adaptor.hpp b/include/boost/iterator/iterator_adaptor.hpp new file mode 100644 index 0000000..c29dbd9 --- /dev/null +++ b/include/boost/iterator/iterator_adaptor.hpp @@ -0,0 +1,325 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BOOST_ITERATOR_ADAPTOR_23022003THW_HPP +#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include + +#include + +namespace boost +{ + 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 adapted_iterator : + // public iterator_adaptor< adapted_iterator, Iterator > + // { + // public: + // + // ... + // + // template + // adapted_iterator( + // OtherIterator const& it + // , typename enable_if_convertible::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 defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE) + + template + struct enable_if_convertible + { + typedef 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 + struct enable_if_convertible + : detail::enable_if< + mpl::or_< + is_same + , is_convertible + > + , detail::enable_type + > + {}; + +# else + + template + struct enable_if_convertible + : detail::enable_if< + is_convertible + , 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 + struct ia_dflt_help + : mpl::apply_if< + is_same + , DefaultNullaryFn + , mpl::identity + > + { + }; + + // A metafunction which computes an iterator_adaptor's base class, + // a specialization of iterator_facade. + template < + class Derived + , class Base + , class Value + , class Category + , class Reference + , class Difference + > + struct iterator_adaptor_base + { + private: // intermediate results + typedef typename detail::ia_dflt_help< + Category, BOOST_ITERATOR_CATEGORY + >::type category; + + typedef typename detail::ia_dflt_help< + Reference + , mpl::apply_if< + is_same + , iterator_reference + , mpl::identity + > + >::type reference; + + public: // return type + typedef iterator_facade< + Derived + + , typename detail::ia_dflt_help< + Value, iterator_value + >::type + + , typename access_category_tag::type + + , typename traversal_category_tag::type + + , reference + + , typename detail::ia_dflt_help< + Difference, iterator_difference + >::type + > + type; + }; + } + + // + // 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::value_type is used + // + // Category - the iterator_category of the resulting iterator. If not + // supplied, iterator_traits::iterator_category 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::reference is used. + // + // Difference - the difference_type of the resulting iterator. If not + // supplied, iterator_traits::difference_type is used. + // + template < + class Derived + , class Base + , class Value = use_default + , class Category = use_default + , class Reference = use_default + , class Difference = use_default + > + class iterator_adaptor + : public detail::iterator_adaptor_base< + Derived, Base, Value, Category, Reference, Difference + >::type + { + friend class iterator_core_access; + + typedef typename detail::iterator_adaptor_base< + Derived, Base, Value, Category, Reference, Difference + >::type super_t; + + public: + iterator_adaptor() {} + + explicit iterator_adaptor(Base iter) + : m_iterator(iter) + { + } + + Base base() const + { return m_iterator; } + + protected: + // + // 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 const& x) const + { + // Maybe readd with same_distance + // BOOST_STATIC_ASSERT( + // (detail::same_category_and_difference::value) + // ); + return m_iterator == x.base(); + } + + void advance(typename super_t::difference_type n) + { + BOOST_STATIC_ASSERT( + (detail::is_tag< + random_access_traversal_tag + , BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal + >::value) + ); + m_iterator += n; + } + + void increment() { ++m_iterator; } + + void decrement() + { + BOOST_STATIC_ASSERT( + (detail::is_tag< + bidirectional_traversal_tag + , BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal + >::value) + ); + --m_iterator; + } + + template < + class OtherDerived, class OtherIterator, class V, class C, class R, class D + > + typename super_t::difference_type distance_to( + iterator_adaptor const& y) const + { + BOOST_STATIC_ASSERT( + (detail::is_tag< + random_access_traversal_tag + , BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal + >::value) + ); + // Maybe readd with same_distance + // BOOST_STATIC_ASSERT( + // (detail::same_category_and_difference::value) + // ); + return y.base() - m_iterator; + } + + private: // data members + Base m_iterator; + }; + +} // namespace boost + +#include + +#endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP diff --git a/include/boost/iterator/iterator_archetypes.hpp b/include/boost/iterator/iterator_archetypes.hpp new file mode 100644 index 0000000..e9439e7 --- /dev/null +++ b/include/boost/iterator/iterator_archetypes.hpp @@ -0,0 +1,350 @@ +// (C) Copyright Jeremy Siek 2002. Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#ifndef BOOST_ITERATOR_ARCHETYPES_HPP +#define BOOST_ITERATOR_ARCHETYPES_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +namespace boost +{ + + template + struct access_archetype; + + template + struct traversal_archetype; + + namespace detail { + + template + struct assign_proxy + { + assign_proxy& operator=(T); + }; + + template + struct read_write_proxy : + assign_proxy + { + operator T(); + }; + + template + struct arrow_proxy + { + T const* operator->() const; + }; + + struct no_operator_brackets {}; + + template + struct readable_operator_brackets + { + ValueType operator[](std::ptrdiff_t n) const; + }; + + template + struct writable_operator_brackets + { + read_write_proxy operator[](std::ptrdiff_t n) const; + }; + + template + struct operator_brackets : + mpl::if_< is_tag, + mpl::if_< is_tag, + writable_operator_brackets< Value >, + mpl::if_< is_tag, + readable_operator_brackets, + no_operator_brackets > >, + no_operator_brackets >::type + { + }; + + template + struct traversal_archetype_impl + { + template struct archetype; + }; + + template + struct traversal_archetype_ + : mpl::aux::msvc_eti_base< + typename traversal_archetype_impl::template archetype + >::type + {}; + + template <> + struct traversal_archetype_impl + { + template + struct archetype + { + typedef void difference_type; + + Derived& operator++(); + Derived operator++(int) const; + }; + }; + + template <> + struct traversal_archetype_impl + { + template + struct archetype + : public equality_comparable< traversal_archetype_ >, + public traversal_archetype_ + { + }; + }; + + template + bool operator==(traversal_archetype_ const&, + traversal_archetype_ const&); + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + // doesn't seem to pick up != from equality_comparable + template + bool operator!=(traversal_archetype_ const&, + traversal_archetype_ const&); +#endif + template <> + struct traversal_archetype_impl + { + template + struct archetype + : public traversal_archetype_ + { + typedef std::ptrdiff_t difference_type; + }; + }; + + template <> + struct traversal_archetype_impl + { + template + struct archetype + : public traversal_archetype_ + { + Derived& operator--(); + Derived operator--(int) const; + }; + }; + + template <> + struct traversal_archetype_impl + { + template + struct archetype + : public partially_ordered >, + public traversal_archetype_ + { + Derived& operator+=(std::ptrdiff_t); + Derived& operator-=(std::ptrdiff_t); + }; + }; + + template + Derived& operator+(traversal_archetype_ const&, + std::ptrdiff_t); + + template + Derived& operator+(std::ptrdiff_t, + traversal_archetype_ const&); + + template + Derived& operator-(traversal_archetype_ const&, + std::ptrdiff_t); + + template + std::ptrdiff_t operator-(traversal_archetype_ const&, + traversal_archetype_ const&); + + template + bool operator<(traversal_archetype_ const&, + traversal_archetype_ const&); + + struct bogus_type; + + template + struct convertible_type + : mpl::if_< is_const, + typename remove_const::type, + bogus_type > + {}; + + } // namespace detail + + + template struct undefined; + + template + struct access_archetype_impl + { + template struct archetype; + }; + + template + struct access_archetype + : mpl::aux::msvc_eti_base< + typename access_archetype_impl::template archetype + >::type + { + }; + + template <> + struct access_archetype_impl + { + template + struct archetype + { + typedef typename remove_cv::type value_type; + typedef Value reference; + typedef Value* pointer; + + value_type operator*() const; + + detail::arrow_proxy operator->() const; + }; + }; + + template <> + struct access_archetype_impl + { + template + struct archetype + { +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + BOOST_STATIC_ASSERT(!is_const::value); +# endif + typedef void value_type; + typedef void reference; + typedef void pointer; + + detail::assign_proxy operator*() const; + }; + }; + + template <> + struct access_archetype_impl + { + template + struct archetype + : public virtual access_archetype + { + typedef detail::read_write_proxy reference; + + detail::read_write_proxy operator*() const; + }; + }; + + template <> + struct access_archetype_impl + { + template + struct archetype + : public virtual access_archetype + { + typedef Value& reference; + + Value& operator*() const; + Value* operator->() const; + }; + }; + + template <> + struct access_archetype_impl + { + template + struct archetype + : public virtual access_archetype + { +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + BOOST_STATIC_ASSERT((!is_const::value)); +# endif + }; + }; + + + template + struct iterator_archetype; + + template + struct traversal_archetype_base + : detail::operator_brackets< + typename remove_cv::type + , AccessCategory + , TraversalCategory + > + , detail::traversal_archetype_< + iterator_archetype + , Value + , TraversalCategory + > + { + }; + + template + struct iterator_archetype + : public traversal_archetype_base + , public access_archetype + + // 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 std::iterator< + iterator_tag + , typename access_archetype::value_type + , typename traversal_archetype_base< + Value, AccessCategory, TraversalCategory + >::difference_type + > +# endif + { + // Derivation from std::iterator above caused ambiguity, so now + // we have to declare all the types here. +# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \ + || BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101)) + typedef typename access_archetype::value_type value_type; + + typedef typename access_archetype::pointer pointer; + + typedef typename access_archetype::reference reference; + + typedef typename traversal_archetype_base< + Value, AccessCategory, TraversalCategory + >::difference_type difference_type; +# endif + + typedef iterator_tag iterator_category; + + iterator_archetype(); + iterator_archetype(iterator_archetype const&); + + iterator_archetype& operator=(iterator_archetype const&); + + // Optional conversion from mutable + // iterator_archetype(iterator_archetype::type, AccessCategory, TraversalCategory> const&); + }; + +} // namespace boost + + +#endif // BOOST_ITERATOR_ARCHETYPES_HPP diff --git a/include/boost/iterator/iterator_categories.hpp b/include/boost/iterator/iterator_categories.hpp new file mode 100644 index 0000000..23724b1 --- /dev/null +++ b/include/boost/iterator/iterator_categories.hpp @@ -0,0 +1,405 @@ +// (C) Copyright Jeremy Siek 2002. Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +// TODO: +// Add separate category tag for operator[]. + +#ifndef BOOST_ITERATOR_CATEGORIES_HPP +#define BOOST_ITERATOR_CATEGORIES_HPP + +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include // must be last #include + +#if BOOST_WORKAROUND(__MWERKS__, <=0x2407) +# define BOOST_NO_IS_CONVERTIBLE // "Convertible does not provide enough/is not working" +#endif + +namespace boost { + + namespace detail + { + // Helper metafunction for std_category below + template + struct match_tag + : mpl::apply_if, mpl::identity, Next> + { + }; + + // Converts a possibly user-defined category tag to the + // most-derived standard tag which is a base of that tag. + template + struct std_category + : match_tag< + Category, std::random_access_iterator_tag + , match_tag +# else + , void +# endif + > + > + > + > + > + { + }; + + // std_to_new_tags -- + // + // A metafunction which converts any standard tag into its + // corresponding new-style traversal tag. + // + // Also, instantiations are metafunction classes which convert a + // reference type into a corresponding new-style access tag. + template struct std_to_new_tags +# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) // handle ETI + { + typedef void type; + template struct apply { typedef void type; }; + } +# endif + ; + +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // handle ETI + template <> struct std_to_new_tags {}; +# endif + + // + // Specializations for specific standard tags + // + template <> + struct std_to_new_tags + { + typedef single_pass_traversal_tag type; + + template + struct apply + : mpl::identity {}; + + }; + + template <> + struct std_to_new_tags + { + typedef incrementable_traversal_tag type; + + template + struct apply + : mpl::identity {}; + }; + + template <> + struct std_to_new_tags + { + typedef forward_traversal_tag type; + + template + struct apply + : mpl::if_< + python::detail::is_reference_to_const + , boost::readable_lvalue_iterator_tag + , boost::writable_lvalue_iterator_tag + > + {}; + }; + + template <> + struct std_to_new_tags + : std_to_new_tags + { + typedef bidirectional_traversal_tag type; + }; + + template <> + struct std_to_new_tags + : std_to_new_tags + { + typedef random_access_traversal_tag type; + }; + + template + struct old_tag_converter + : std_to_new_tags< + typename std_category::type + > + { + }; + + template + struct iter_category_to_traversal + : std_to_new_tags< + typename std_category::type + > + {}; + + template + struct iter_category_to_access + : mpl::apply1< + iter_category_to_traversal + , Reference + > + {}; + +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) + // Deal with ETI + template <> struct iter_category_to_access {}; + template <> struct iter_category_to_traversal {}; +# endif + + // A metafunction returning true iff T is boost::iterator_tag + template + struct is_boost_iterator_tag; + +#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) + // + // has_xxx fails, so we have to use + // something less sophisticated. + // + // The solution depends on the fact that only + // std iterator categories work with is_xxx_iterator + // meta functions, as BOOST_NO_IS_CONVERTIBLE is + // defined for cwpro7. + // + template + struct is_new_iterator_tag + : mpl::not_< + mpl::or_< + is_tag + , is_tag + > + > + {}; + +#elif BOOST_WORKAROUND(__GNUC__, == 2 && __GNUC_MINOR__ == 95) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + + template + struct is_new_iterator_tag + : is_boost_iterator_tag + { + }; + +#else + + BOOST_MPL_HAS_XXX_TRAIT_DEF(traversal) + + template + struct is_new_iterator_tag + : mpl::if_< + is_class + , has_traversal + , mpl::false_ + >::type + { + }; + +#endif + + } // namespace detail + + namespace detail { + + template + struct get_traversal_category { + typedef typename NewCategoryTag::traversal type; + }; + + // Remove all writability from the given access tag. This + // functionality is part of new_category_to_access in order to + // support deduction of the proper default access category for + // iterator_adaptor; when the reference type is a reference to + // constant we must strip writability. + template + struct remove_access_writability + : mpl::apply_if< + is_tag + , mpl::identity + + , mpl::apply_if< + is_tag + , mpl::identity + + , mpl::if_< + is_tag + // Is this OK? I think it may correct be for all + // legitimate cases, because at this point the + // iterator is not readable, so it could not have + // been any more than writable + swappable. + , swappable_iterator_tag + , AccessTag + > + > + > + {}; + + template + struct new_category_to_access + : mpl::apply_if< + python::detail::is_reference_to_const + , remove_access_writability + , mpl::identity + > + {}; + + template + struct access_category_tag + : mpl::apply_if< + is_new_iterator_tag + , new_category_to_access + , iter_category_to_access + > + { + }; + + template + struct traversal_category_tag + : mpl::apply_if< + is_new_iterator_tag + , get_traversal_category + , iter_category_to_traversal + > + { + }; + +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) + // Deal with ETI + template <> struct access_category_tag { typedef void type; }; + template <> struct traversal_category_tag { typedef void type; }; +# endif + + // iterator_tag_base - a metafunction to compute the appropriate + // old-style tag (if any) to use as a base for a new-style tag. + template + struct iterator_tag_base + : minimum_category< + typename KnownAccessTag::max_category + , typename KnownTraversalTag::max_category + > + {}; + +# if BOOST_WORKAROUND(BOOST_MSVC,<=1200) + template <> + struct iterator_tag_base + : mpl::false_ {}; // just using false_ so that the result will be + // a legal base class +# endif + + // specialization for this special case. Otherwise we get + // input_output_iterator_tag, because the standard hierarchy has a + // sudden anomalous distinction between readability and + // writability at the level of input iterator/output iterator. + template <> + struct iterator_tag_base< + readable_lvalue_iterator_tag,single_pass_traversal_tag> + { + typedef std::input_iterator_tag type; + }; + + } // namespace detail + + template + struct access_category + : detail::access_category_tag< + typename detail::iterator_traits::iterator_category + , typename detail::iterator_traits::reference> + {}; + + template + struct traversal_category + : detail::traversal_category_tag< + typename detail::iterator_traits::iterator_category + > + { + }; + +# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + template + struct access_category + : mpl::if_< + is_const + , readable_lvalue_iterator_tag + , writable_lvalue_iterator_tag> + { + }; + + template + struct traversal_category + { + typedef random_access_traversal_tag type; + }; + +# endif + + template + struct iterator_tag + : detail::iterator_tag_base< + typename detail::max_known_access_tag::type + , typename detail::max_known_traversal_tag::type + >::type + { + typedef AccessTag access; + typedef TraversalTag traversal; + }; + + namespace detail + { +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + struct is_boost_iterator_tag + : mpl::false_ {}; + + template + struct is_boost_iterator_tag > + : mpl::true_ {}; +# else + template + struct is_boost_iterator_tag + { + typedef char (&yes)[1]; + typedef char (&no)[2]; + + template + static yes test(mpl::identity >*); + static no test(...); + + static mpl::identity* inst; + BOOST_STATIC_CONSTANT(bool, value = sizeof(test(inst)) == sizeof(yes)); + typedef mpl::bool_ type; + }; +# endif + } + +} // namespace boost + +#include + +#endif // BOOST_ITERATOR_CATEGORIES_HPP diff --git a/include/boost/iterator/iterator_concepts.hpp b/include/boost/iterator/iterator_concepts.hpp new file mode 100644 index 0000000..fe5b433 --- /dev/null +++ b/include/boost/iterator/iterator_concepts.hpp @@ -0,0 +1,358 @@ +// (C) Copyright Jeremy Siek 2002. Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#ifndef BOOST_ITERATOR_CONCEPTS_HPP +#define BOOST_ITERATOR_CONCEPTS_HPP + +// Revision History +// 26 Apr 2003 thw +// Adapted to new iterator concepts +// 22 Nov 2002 Thomas Witt +// Added interoperable concept. + +#include +#include +#include +#include +#include +#include +#include +#include + +// Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems. +#include + +// Use boost/limits to work around missing limits headers on some compilers +#include + +#include + +namespace boost_concepts { + // Used a different namespace here (instead of "boost") so that the + // concept descriptions do not take for granted the names in + // namespace boost. + + // We use this in place of STATIC_ASSERT((is_convertible<...>)) + // because some compilers (CWPro7.x) can't detect convertibility. + // + // Of course, that just gets us a different error at the moment with + // some tests, since new iterator category deduction still depends + // on convertibility detection. We might need some specializations + // to support this compiler. + template + struct static_assert_base_and_derived + { + static_assert_base_and_derived(Target* = (Source*)0) {} + }; + + //=========================================================================== + // Iterator Access Concepts + + template + class ReadableIteratorConcept { + public: + typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits::value_type value_type; + typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits::reference reference; + typedef BOOST_DEDUCED_TYPENAME ::boost::access_category::type access_category; + + void constraints() { + boost::function_requires< boost::SGIAssignableConcept >(); + boost::function_requires< boost::EqualityComparableConcept >(); + boost::function_requires< + boost::DefaultConstructibleConcept >(); + + BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); + + reference r = *i; // or perhaps read(x) + value_type v(r); + boost::ignore_unused_variable_warning(v); + } + Iterator i; + }; + + template + class WritableIteratorConcept { + public: + typedef typename boost::access_category::type access_category; + + void constraints() { + boost::function_requires< boost::SGIAssignableConcept >(); + boost::function_requires< boost::EqualityComparableConcept >(); + boost::function_requires< + boost::DefaultConstructibleConcept >(); + + BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); + + *i = v; // a good alternative could be something like write(x, v) + } + ValueType v; + Iterator i; + }; + + template + class SwappableIteratorConcept { + public: + typedef typename boost::access_category::type access_category; + + void constraints() { + BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); + + std::iter_swap(i1, i2); + } + Iterator i1; + Iterator i2; + }; + + template + class ReadableLvalueIteratorConcept { + public: + typedef typename boost::detail::iterator_traits::value_type value_type; + typedef typename boost::detail::iterator_traits::reference reference; + typedef typename boost::access_category::type access_category; + + void constraints() { + boost::function_requires< ReadableIteratorConcept >(); + + BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); + + typedef boost::mpl::or_< + boost::is_same, + boost::is_same > correct_reference; + + BOOST_STATIC_ASSERT(correct_reference::value); + + reference v = *i; + boost::ignore_unused_variable_warning(v); + } + Iterator i; + }; + + template + class WritableLvalueIteratorConcept { + public: + typedef typename boost::detail::iterator_traits::value_type value_type; + typedef typename boost::detail::iterator_traits::reference reference; + typedef typename boost::access_category::type access_category; + + void constraints() { + boost::function_requires< + ReadableLvalueIteratorConcept >(); + boost::function_requires< + WritableIteratorConcept >(); + boost::function_requires< + SwappableIteratorConcept >(); + + BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); + + BOOST_STATIC_ASSERT((boost::is_same::value)); + } + }; + + //=========================================================================== + // Iterator Traversal Concepts + + template + class IncrementableIteratorConcept { + public: + typedef typename boost::traversal_category::type traversal_category; + + void constraints() { + boost::function_requires< boost::SGIAssignableConcept >(); + boost::function_requires< + boost::DefaultConstructibleConcept >(); + + BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); + + ++i; + (void)i++; + } + Iterator i; + }; + + template + class SinglePassIteratorConcept { + public: + typedef typename boost::traversal_category::type traversal_category; + typedef typename boost::detail::iterator_traits::difference_type difference_type; + + void constraints() { + boost::function_requires< IncrementableIteratorConcept >(); + boost::function_requires< boost::EqualityComparableConcept >(); + + BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); + } + }; + + template + class ForwardTraversalConcept { + public: + typedef typename boost::traversal_category::type traversal_category; + typedef typename boost::detail::iterator_traits::difference_type difference_type; + + void constraints() { + boost::function_requires< SinglePassIteratorConcept >(); + + typedef boost::mpl::and_< + boost::is_integral, + boost::mpl::bool_< std::numeric_limits::is_signed > + > difference_type_is_signed_integral; + + BOOST_STATIC_ASSERT(difference_type_is_signed_integral::value); + BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); + } + }; + + template + class BidirectionalTraversalConcept { + public: + typedef typename boost::traversal_category::type traversal_category; + + void constraints() { + boost::function_requires< ForwardTraversalConcept >(); + + BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); + + --i; + (void)i--; + } + Iterator i; + }; + + template + class RandomAccessTraversalConcept { + public: + typedef typename boost::traversal_category::type traversal_category; + typedef typename boost::detail::iterator_traits::difference_type + difference_type; + + void constraints() { + boost::function_requires< BidirectionalTraversalConcept >(); + + BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); + + i += n; + i = i + n; + i = n + i; + i -= n; + i = i - n; + n = i - j; + } + difference_type n; + Iterator i, j; + }; + + //=========================================================================== + // Iterator Interoperability Concept + +namespace detail +{ + + template + struct Operations; + + template <> + struct Operations + { + template + static void constraints(Iterator1 const& i1, Iterator2 const& i2) + { + // no interoperability constraints + } + }; + + template <> + struct Operations + { + template + static void constraints(Iterator1 const& i1, Iterator2 const& i2) + { + Operations(i1, i2); + i1 == i2; + i1 != i2; + + i2 == i1; + i2 != i1; + } + }; + + template <> + struct Operations + { + template + static void constraints(Iterator1 const& i1, Iterator2 const& i2) + { + Operations::constraints(i1, i2); + } + }; + + template <> + struct Operations + { + template + static void constraints(Iterator1 const& i1, Iterator2 const& i2) + { + Operations::constraints(i1, i2); + } + }; + + template <> + struct Operations + { + template + static void constraints(Iterator1 const& i1, Iterator2 const& i2) + { + Operations::constraints(i1, i2); + + i1 < i2; + i1 <= i2; + i1 > i2; + i1 >= i2; + i1 - i2; + + i2 < i1; + i2 <= i1; + i2 > i1; + i2 >= i1; + i2 - i1; + } + }; + + } // namespace detail + + template + class InteroperableConcept + { + public: + typedef typename boost::traversal_category::type traversal_category; + typedef typename boost::detail::iterator_traits::difference_type + difference_type; + + typedef typename boost::traversal_category::type + const_traversal_category; + typedef typename boost::detail::iterator_traits::difference_type + const_difference_type; + + void constraints() { + BOOST_STATIC_ASSERT((boost::is_same< difference_type, + const_difference_type>::value)); + BOOST_STATIC_ASSERT((boost::is_same< traversal_category, + const_traversal_category>::value)); + + // ToDo check what the std really requires + + // detail::Operations::constraints(i, ci); + + ci = i; + + } + Iterator i; + ConstIterator ci; + }; + +} // namespace boost_concepts + + +#endif // BOOST_ITERATOR_CONCEPTS_HPP diff --git a/include/boost/iterator/iterator_facade.hpp b/include/boost/iterator/iterator_facade.hpp new file mode 100644 index 0000000..1abe0e0 --- /dev/null +++ b/include/boost/iterator/iterator_facade.hpp @@ -0,0 +1,625 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP +#define BOOST_ITERATOR_FACADE_23022003THW_HPP + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include // this goes last + +namespace boost +{ + + struct use_default; + + namespace detail + { + + // + // enable if for use in operator implementation. + // + // enable_if_interoperable falls back to always enabled for compilers + // that don't support enable_if or is_convertible. + // + template < + class Facade1 + , class Facade2 + , class Return + > + struct enable_if_interoperable +#ifndef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY + : ::boost::detail::enable_if< + mpl::or_< + is_convertible + , is_convertible + > + , Return + > +#endif + { +#ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY + typedef Return type; +#endif + }; + + + // + // Add const qualification for iterators which are not writable + // + template + struct const_qualified_ref : + mpl::if_< is_tag< writable_iterator_tag, AccessCategory >, + Value&, + Value const& > + {}; + + // The apparent duplication here works around a Borland problem + template + struct const_qualified_ptr : + mpl::if_< is_tag< writable_iterator_tag, AccessCategory >, + Value*, + Value const* > + {}; + + // + // Generates the associated types for an iterator_facade with the + // given parameters. Additionally generates a 'base' type for + // compiler/library combinations which require user-defined + // iterators to inherit from std::iterator. + // + template < + class Value + , class AccessCategory + , class TraversalCategory + , class Reference + , class Difference + > + struct iterator_facade_types + { + typedef iterator_tag iterator_category; + + typedef typename remove_cv::type value_type; + + typedef Difference difference_type; + + typedef typename const_qualified_ptr::type pointer; + + // The use_default support is needed for iterator_adaptor. + // For practical reasons iterator_adaptor needs to specify + // a fixed number of template arguments of iterator_facade. + // So use_default is its way to say: "What I really mean + // is your default parameter". + typedef typename mpl::if_< + is_same + , typename const_qualified_ref::type + , Reference + >::type reference; + +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \ + || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \ + || BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \ + || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310) + + // To interoperate with some broken library/compiler + // combinations, user-defined iterators must be derived from + // std::iterator. It is possible to implement a standard + // library for broken compilers without this limitation. +# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1 + + typedef + iterator + base; +# endif + }; + + + // operator->() needs special support for input iterators to strictly meet the + // standard's requirements. If *i is not a reference type, we must still + // produce a (constant) lvalue to which a pointer can be formed. We do that by + // returning an instantiation of this special proxy class template. + + template + struct operator_arrow_proxy + { + operator_arrow_proxy(T const* px) : m_value(*px) {} + const T* operator->() const { return &m_value; } + // This function is needed for MWCW and BCC, which won't call operator-> + // again automatically per 13.3.1.2 para 8 + operator const T*() const { return &m_value; } + T m_value; + }; + + // A metafunction that gets the result type for operator->. Also + // has a static function make() which builds the result from a + // Reference + template + struct operator_arrow_result + { + // CWPro8.3 won't accept "operator_arrow_result::type", and we + // need that type below, so metafunction forwarding would be a + // losing proposition here. + typedef typename mpl::if_< + is_tag< + readable_lvalue_iterator_tag + , typename access_category_tag::type + > + , Pointer + , operator_arrow_proxy + >::type type; + + static type make(Reference x) + { + return type(&x); + } + }; + +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) + // Deal with ETI + template<> + struct operator_arrow_result + { + typedef int type; + }; +# endif + + // + // Facade is actually an iterator. We require Facade here + // so that we do not have to go through iterator_traits + // to access the traits + // + template + class operator_brackets_proxy + { + typedef typename Iterator::reference reference; + typedef typename Iterator::value_type value_type; + + public: + operator_brackets_proxy(Iterator const& iter) + : m_iter(iter) + {} + + operator reference() + { + return *m_iter; + } + + operator_brackets_proxy& operator=(value_type const& val) + { + *m_iter = val; + return *this; + } + + private: + Iterator m_iter; + }; + + template + struct operator_brackets_result + { + typedef typename access_category_tag::type access_category; + + typedef is_tag use_proxy; + + typedef typename mpl::if_< + use_proxy + , operator_brackets_proxy + , ValueType + >::type type; + }; + + template + operator_brackets_proxy make_operator_brackets_result(Iterator const& iter, mpl::true_) + { + return operator_brackets_proxy(iter); + } + + template + typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_) + { + return *iter; + } + + } // namespace detail + + + // Macros which describe the declarations of binary operators +# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \ + template < \ + class Derived1, class V1, class AC1, class TC1, class R1, class D1 \ + , class Derived2, class V2, class AC2, class TC2, class R2, class D2 \ + > \ + prefix typename detail::enable_if_interoperable< \ + Derived1, Derived2, result_type \ + >::type \ + operator op( \ + iterator_facade const& lhs \ + , iterator_facade const& rhs) + +# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \ + template \ + prefix Derived operator+ args + + // + // Helper class for granting access to the iterator core interface. + // + // The simple core interface is used by iterator_facade. The core + // interface of a user/library defined iterator type should not be made public + // so that it does not clutter the public interface. Instead iterator_core_access + // should be made friend so that iterator_facade can access the core + // interface through iterator_core_access. + // + class iterator_core_access + { +# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + // Tasteless as this may seem, making all members public allows member templates + // to work in the absence of member template friends. + public: +# else + + template friend class iterator_facade; + +# define BOOST_ITERATOR_FACADE_RELATION(op) \ + BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, bool); + + BOOST_ITERATOR_FACADE_RELATION(==) + BOOST_ITERATOR_FACADE_RELATION(!=) + + BOOST_ITERATOR_FACADE_RELATION(<) + BOOST_ITERATOR_FACADE_RELATION(>) + BOOST_ITERATOR_FACADE_RELATION(<=) + BOOST_ITERATOR_FACADE_RELATION(>=) +# undef BOOST_ITERATOR_FACADE_RELATION + + BOOST_ITERATOR_FACADE_INTEROP_HEAD( + friend, -, typename Derived1::difference_type) + ; + + BOOST_ITERATOR_FACADE_PLUS_HEAD( + friend + , (iterator_facade const& + , typename Derived::difference_type) + ) + ; + + BOOST_ITERATOR_FACADE_PLUS_HEAD( + friend + , (typename Derived::difference_type + , iterator_facade const&) + ) + ; + +# endif + + template + static typename Facade::reference dereference(Facade const& f) + { + return f.dereference(); + } + + template + static void increment(Facade& f) + { + f.increment(); + } + + template + static void decrement(Facade& f) + { + f.decrement(); + } + + template + static bool equal(Facade1 const& f1, Facade2 const& f2) + { + return f1.equal(f2); + } + + template + static void advance(Facade& f, typename Facade::difference_type n) + { + f.advance(n); + } + + template + static typename Facade1::difference_type distance_to( + Facade1 const& f1, Facade2 const& f2) + { + return f1.distance_to(f2); + } + + private: + // objects of this class are useless + iterator_core_access(); //undefined + }; + + // + // iterator_facade - use as a public base class for defining new + // standard-conforming iterators. + // + template < + class Derived // The derived iterator type being constructed + , class Value + , class AccessCategory + , class TraversalCategory + , class Reference = typename detail::const_qualified_ref::type + , class Difference = std::ptrdiff_t + > + class iterator_facade +# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE + : public detail::iterator_facade_types< + Value, AccessCategory, TraversalCategory, Reference, Difference + >::base +# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE +# endif + { + private: + typedef typename + detail::iterator_facade_types + types; + + // + // Curiously Recursive Template interface. + // + typedef Derived derived_t; + + Derived& derived() + { + return static_cast(*this); + } + + Derived const& derived() const + { + return static_cast(*this); + } + + public: + + typedef typename types::value_type value_type; + typedef typename types::reference reference; + typedef typename types::difference_type difference_type; + typedef typename types::pointer pointer; + typedef typename types::iterator_category iterator_category; + + reference operator*() const + { + return iterator_core_access::dereference(this->derived()); + } + + typename detail::operator_arrow_result< + value_type + , iterator_category + , reference + , pointer + >::type + operator->() const + { + return detail::operator_arrow_result< + value_type + , iterator_category + , reference + , pointer + >::make(*this->derived()); + } + + typename detail::operator_brackets_result::type + operator[](difference_type n) const + { + typedef typename + detail::operator_brackets_result::use_proxy + use_proxy; + + return detail::make_operator_brackets_result(this->derived() + n, use_proxy()); + } + + Derived& operator++() + { + iterator_core_access::increment(this->derived()); + return this->derived(); + } + + Derived operator++(int) + { + Derived tmp(this->derived()); + ++*this; + return tmp; + } + + Derived& operator--() + { + iterator_core_access::decrement(this->derived()); + return this->derived(); + } + + Derived operator--(int) + { + Derived tmp(this->derived()); + --*this; + return tmp; + } + + Derived& operator+=(difference_type n) + { + iterator_core_access::advance(this->derived(), n); + return this->derived(); + } + + Derived& operator-=(difference_type n) + { + iterator_core_access::advance(this->derived(), -n); + return this->derived(); + } + + Derived operator-(difference_type x) const + { + Derived result(this->derived()); + return result -= x; + } + +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) + // There appears to be a bug which trashes the data of classes + // derived from iterator_facade when they are assigned unless we + // define this assignment operator. This bug is only revealed + // (so far) in STLPort debug mode, but it's clearly a codegen + // problem so we apply the workaround for all MSVC6. + iterator_facade& operator=(iterator_facade const&) + { + return *this; + } +# endif + }; + + // + // Operator implementation. The library supplied operators + // enables the user to provide fully interoperable constant/mutable + // iterator types. I.e. the library provides all operators + // for all mutable/constant iterator combinations. + // + // Note though that this kind of interoperability for constant/mutable + // iterators is not required by the standard for container iterators. + // All the standard asks for is a conversion mutable -> constant. + // Most standard library implementations nowadays provide fully interoperable + // iterator implementations, but there are still heavily used implementations + // that do not provide them. (Actually it's even worse, they do not provide + // them for only a few iterators.) + // + // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should + // enable the user to turn off mixed type operators + // + // The library takes care to provide only the right operator overloads. + // I.e. + // + // bool operator==(Iterator, Iterator); + // bool operator==(ConstIterator, Iterator); + // bool operator==(Iterator, ConstIterator); + // bool operator==(ConstIterator, ConstIterator); + // + // ... + // + // In order to do so it uses c++ idioms that are not yet widely supported + // by current compiler releases. The library is designed to degrade gracefully + // in the face of compiler deficiencies. In general compiler + // deficiencies result in less strict error checking and more obscure + // error messages, functionality is not affected. + // + // For full operation compiler support for "Substitution Failure Is Not An Error" + // (aka. enable_if) and boost::is_convertible is required. + // + // The following problems occur if support is lacking. + // + // Pseudo code + // + // --------------- + // AdaptorA a1; + // AdaptorA a2; + // + // // This will result in a no such overload error in full operation + // // If enable_if or is_convertible is not supported + // // The instantiation will fail with an error hopefully indicating that + // // there is no operator== for Iterator1, Iterator2 + // // The same will happen if no enable_if is used to remove + // // false overloads from the templated conversion constructor + // // of AdaptorA. + // + // a1 == a2; + // ---------------- + // + // AdaptorA a; + // AdaptorB b; + // + // // This will result in a no such overload error in full operation + // // If enable_if is not supported the static assert used + // // in the operator implementation will fail. + // // This will accidently work if is_convertible is not supported. + // + // a == b; + // ---------------- + // + +# define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, condition, return_prefix, base_op) \ + BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \ + { \ + /* For those compilers that do not support enable_if */ \ + BOOST_STATIC_ASSERT(( \ + is_interoperable< Derived1, Derived2 >::value \ + && condition \ + )); \ + return_prefix iterator_core_access::base_op( \ + static_cast(rhs), static_cast(lhs)); \ + } + +# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \ + BOOST_ITERATOR_FACADE_INTEROP( \ + op \ + , bool \ + , true \ + , return_prefix \ + , base_op \ + ) + + BOOST_ITERATOR_FACADE_RELATION(==, return, equal) + BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal) + + BOOST_ITERATOR_FACADE_RELATION(<, return 0 >, distance_to) + BOOST_ITERATOR_FACADE_RELATION(>, return 0 <, distance_to) + BOOST_ITERATOR_FACADE_RELATION(<=, return 0 >=, distance_to) + BOOST_ITERATOR_FACADE_RELATION(>=, return 0 <=, distance_to) +# undef BOOST_ITERATOR_FACADE_RELATION + + // operator- requires an additional part in the static assertion + BOOST_ITERATOR_FACADE_INTEROP( + - + , typename Derived1::difference_type + , (is_same< + BOOST_DEDUCED_TYPENAME Derived1::difference_type + , BOOST_DEDUCED_TYPENAME Derived2::difference_type + >::value) + , return + , distance_to ) +# undef BOOST_ITERATOR_FACADE_INTEROP +# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD + +# define BOOST_ITERATOR_FACADE_PLUS(args) \ + BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \ + { \ + Derived tmp(static_cast(i)); \ + return tmp += n; \ + } + +BOOST_ITERATOR_FACADE_PLUS(( + iterator_facade const& i + , typename Derived::difference_type n +)) + +BOOST_ITERATOR_FACADE_PLUS(( + typename Derived::difference_type n + , iterator_facade const& i +)) +# undef BOOST_ITERATOR_FACADE_PLUS +# undef BOOST_ITERATOR_FACADE_PLUS_HEAD + +} // namespace boost + +#include + +#endif // BOOST_ITERATOR_FACADE_23022003THW_HPP diff --git a/include/boost/iterator/iterator_traits.hpp b/include/boost/iterator/iterator_traits.hpp new file mode 100644 index 0000000..4f0d46f --- /dev/null +++ b/include/boost/iterator/iterator_traits.hpp @@ -0,0 +1,93 @@ +// Copyright David Abrahams 2003. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ITERATOR_TRAITS_DWA200347_HPP +# define ITERATOR_TRAITS_DWA200347_HPP + +# include +# include + +namespace boost { + +// Unfortunately, g++ 2.95.x chokes when we define a class template +// iterator_category which has the same name as its +// std::iterator_category() function, probably due in part to the +// "std:: is visible globally" hack it uses. Use +// BOOST_ITERATOR_CATEGORY to write code that's portable to older +// GCCs. + +# if BOOST_WORKAROUND(__GNUC__, <= 2) +# define BOOST_ITERATOR_CATEGORY iterator_category_ +# else +# define BOOST_ITERATOR_CATEGORY iterator_category +# endif + + +template +struct iterator_value +{ + typedef typename detail::iterator_traits::value_type type; +}; + +template +struct iterator_reference +{ + typedef typename detail::iterator_traits::reference type; +}; + + +template +struct iterator_pointer +{ + typedef typename detail::iterator_traits::pointer type; +}; + +template +struct iterator_difference +{ + typedef typename detail::iterator_traits::difference_type type; +}; + +template +struct BOOST_ITERATOR_CATEGORY +{ + typedef typename detail::iterator_traits::iterator_category type; +}; + +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) +template <> +struct iterator_value +{ + typedef void type; +}; + +template <> +struct iterator_reference +{ + typedef void type; +}; + +template <> +struct iterator_pointer +{ + typedef void type; +}; + +template <> +struct iterator_difference +{ + typedef void type; +}; + +template <> +struct BOOST_ITERATOR_CATEGORY +{ + typedef void type; +}; +# endif + +} // namespace boost::iterator + +#endif // ITERATOR_TRAITS_DWA200347_HPP diff --git a/include/boost/iterator/new_iterator_tests.hpp b/include/boost/iterator/new_iterator_tests.hpp new file mode 100644 index 0000000..759f8de --- /dev/null +++ b/include/boost/iterator/new_iterator_tests.hpp @@ -0,0 +1,204 @@ +#ifndef BOOST_NEW_ITERATOR_TESTS_HPP +# define BOOST_NEW_ITERATOR_TESTS_HPP + +// This is meant to be the beginnings of a comprehensive, generic +// test suite for STL concepts such as iterators and containers. +// +// Revision History: +// 28 Oct 2002 Started update for new iterator categories +// (Jeremy Siek) +// 28 Apr 2002 Fixed input iterator requirements. +// For a == b a++ == b++ is no longer required. +// See 24.1.1/3 for details. +// (Thomas Witt) +// 08 Feb 2001 Fixed bidirectional iterator test so that +// --i is no longer a precondition. +// (Jeremy Siek) +// 04 Feb 2001 Added lvalue test, corrected preconditions +// (David Abrahams) + +# include +# include +# include +# include +# include // for detail::dummy_constructor +# include +# include + +namespace boost { + +void is_readable(readable_iterator_tag) { } +void is_writable(writable_iterator_tag) { } +void is_swappable(swappable_iterator_tag) { } +void is_constant_lvalue(readable_lvalue_iterator_tag) { } +void is_mutable_lvalue(writable_lvalue_iterator_tag) { } + +// Preconditions: *i == v +template +void readable_iterator_test(const Iterator i1, T v) +{ + Iterator i2(i1); // Copy Constructible + typedef typename detail::iterator_traits::reference ref_t; + ref_t r1 = *i1; + ref_t r2 = *i2; + T v1 = r1; + T v2 = r2; + assert(v1 == v); + assert(v2 == v); + typedef typename access_category::type result_category; + is_readable(result_category()); +} + +template +void writable_iterator_test(Iterator i, T v) +{ + Iterator i2(i); // Copy Constructible + *i2 = v; + is_writable(typename access_category::type()); +} + +template +void swappable_iterator_test(Iterator i, Iterator j) +{ + Iterator i2(i), j2(j); + typename detail::iterator_traits::value_type bi = *i, bj = *j; + iter_swap(i2, j2); + typename detail::iterator_traits::value_type ai = *i, aj = *j; + assert(bi == aj && bj == ai); + typedef typename access_category::type result_category; + is_swappable(result_category()); +} + +template +void constant_lvalue_iterator_test(Iterator i, T v1) +{ + Iterator i2(i); + typedef typename detail::iterator_traits::value_type value_type; + typedef typename detail::iterator_traits::reference reference; + BOOST_STATIC_ASSERT((is_same::value)); + const T& v2 = *i2; + assert(v1 == v2); + typedef typename access_category::type result_category; + is_constant_lvalue(result_category()); +} + +template +void mutable_lvalue_iterator_test(Iterator i, T v1, T v2) +{ + Iterator i2(i); + typedef typename detail::iterator_traits::value_type value_type; + typedef typename detail::iterator_traits::reference reference; + BOOST_STATIC_ASSERT((is_same::value)); + T& v3 = *i2; + assert(v1 == v3); + *i = v2; + T& v4 = *i2; + assert(v2 == v4); + typedef typename access_category::type result_category; + is_mutable_lvalue(result_category()); +} + +template +void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2) +{ + Iterator i2; + Iterator i3(i); + i2 = i; + assert(i2 == i3); + assert(i != j); + assert(i2 != j); + readable_iterator_test(i, val1); + readable_iterator_test(i2, val1); + readable_iterator_test(i3, val1); + + assert(i == i2++); + assert(i != ++i3); + + readable_iterator_test(i2, val2); + readable_iterator_test(i3, val2); + + readable_iterator_test(i, val1); +} + +template +void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2) +{ + forward_readable_iterator_test(i, j, val1, val2); + Iterator i2 = i; + ++i2; + swappable_iterator_test(i, i2); +} + +// bidirectional +// Preconditions: *i == v1, *++i == v2 +template +void bidirectional_readable_iterator_test(Iterator i, T v1, T v2) +{ + Iterator j(i); + ++j; + forward_readable_iterator_test(i, j, v1, v2); + ++i; + + Iterator i1 = i, i2 = i; + + assert(i == i1--); + assert(i != --i2); + + readable_iterator_test(i, v2); + readable_iterator_test(i1, v1); + readable_iterator_test(i2, v1); + + --i; + assert(i == i1); + assert(i == i2); + ++i1; + ++i2; + + readable_iterator_test(i, v1); + readable_iterator_test(i1, v2); + readable_iterator_test(i2, v2); +} + + +// random access +// Preconditions: [i,i+N) is a valid range +template +void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals) +{ + bidirectional_readable_iterator_test(i, vals[0], vals[1]); + const Iterator j = i; + int c; + + for (c = 0; c < N-1; ++c) { + assert(i == j + c); + assert(*i == vals[c]); + assert(*i == j[c]); + assert(*i == *(j + c)); + assert(*i == *(c + j)); + ++i; + assert(i > j); + assert(i >= j); + assert(j <= i); + assert(j < i); + } + + Iterator k = j + N - 1; + for (c = 0; c < N-1; ++c) { + assert(i == k - c); + assert(*i == vals[N - 1 - c]); + assert(*i == j[N - 1 - c]); + Iterator q = k - c; + assert(*i == *q); + assert(i > j); + assert(i >= j); + assert(j <= i); + assert(j < i); + --i; + } +} + +// #if 0'd code snipped; see CVS v 1.4 if you need it back + +} // namespace boost + +#endif // BOOST_NEW_ITERATOR_TESTS_HPP diff --git a/include/boost/iterator/permutation_iterator.hpp b/include/boost/iterator/permutation_iterator.hpp new file mode 100644 index 0000000..f41da1a --- /dev/null +++ b/include/boost/iterator/permutation_iterator.hpp @@ -0,0 +1,92 @@ +// (C) Copyright Toon Knapen 2001. +// (C) Copyright David Abrahams 2003. +// (C) Copyright Roland Richter 2003. +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. + +#ifndef BOOST_PERMUTATION_ITERATOR_HPP +#define BOOST_PERMUTATION_ITERATOR_HPP + +#include + +#include + + +namespace boost +{ + +template< class ElementIterator + , class IndexIterator + , class ValueT = use_default + , class CategoryT = use_default + , class ReferenceT = use_default + , class DifferenceT = use_default > +class permutation_iterator + : public iterator_adaptor< + permutation_iterator + , ElementIterator, ValueT, CategoryT, ReferenceT, DifferenceT > +{ + typedef iterator_adaptor< + permutation_iterator + , ElementIterator, ValueT, CategoryT, ReferenceT, DifferenceT > super_t; + + friend class iterator_core_access; + +public: + permutation_iterator() : order_it_() {} + + explicit permutation_iterator(ElementIterator x, IndexIterator y) + : super_t(x), order_it_(y) {} + + template + permutation_iterator( + permutation_iterator const& r + , typename enable_if_convertible::type* = 0 + , typename enable_if_convertible::type* = 0 + ) + : super_t(r.base()) + {} + +private: + typename super_t::reference dereference() const + { return *(this->base() + *this->order_it_); } + + void increment() { ++this->order_it_; } + void decrement() { --this->order_it_; } + + void advance(typename super_t::difference_type n) + { + std::advance( order_it_, n ); + } + + template + typename super_t::difference_type + distance_to( permutation_iterator const& y ) const + { + return std::distance( this->order_it_, y.order_it_ ); + } + + template + bool + equal( permutation_iterator const& y ) const + { + return( y.order_it_ == this->order_it_ ); + } + + IndexIterator order_it_; +}; + + +template +permutation_iterator +make_permutation_iterator( ElementIterator e, IndexIterator i ) +{ + return permutation_iterator( e, i ); +} + + +} // namespace boost + +#endif diff --git a/include/boost/iterator/reverse_iterator.hpp b/include/boost/iterator/reverse_iterator.hpp new file mode 100644 index 0000000..43942eb --- /dev/null +++ b/include/boost/iterator/reverse_iterator.hpp @@ -0,0 +1,71 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BOOST_REVERSE_ITERATOR_23022003THW_HPP +#define BOOST_REVERSE_ITERATOR_23022003THW_HPP + +#include +#include +#include + +namespace boost +{ + + // + // + // + template + class reverse_iterator + : public iterator_adaptor< reverse_iterator, Iterator > + { + typedef iterator_adaptor< reverse_iterator, Iterator > super_t; + + friend class iterator_core_access; + + public: + reverse_iterator() {} + + explicit reverse_iterator(Iterator x) + : super_t(x) {} + + template + reverse_iterator( + reverse_iterator const& r + , typename enable_if_convertible::type* = 0 + ) + : super_t(r.base()) + {} + + private: + typename super_t::reference dereference() const { return *boost::prior(this->base()); } + + void increment() { --this->base_reference(); } + void decrement() { ++this->base_reference(); } + + void advance(typename super_t::difference_type n) + { + this->base_reference() += -n; + } + + template + typename super_t::difference_type + distance_to(reverse_iterator const& y) const + { + return this->base_reference() - y.base(); + } + }; + + template + reverse_iterator make_reverse_iterator(BidirectionalIterator x) + { + return reverse_iterator(x); + } + +} // namespace boost + +#endif // BOOST_REVERSE_ITERATOR_23022003THW_HPP diff --git a/include/boost/iterator/transform_iterator.hpp b/include/boost/iterator/transform_iterator.hpp new file mode 100644 index 0000000..26ed994 --- /dev/null +++ b/include/boost/iterator/transform_iterator.hpp @@ -0,0 +1,154 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP +#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + template + class transform_iterator; + + namespace detail + { + + template + struct function_object_result + { + typedef typename UnaryFunction::result_type type; + }; + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + struct function_object_result + { + typedef Return type; + }; +#endif + + // Given the transform iterator's transformation and iterator, this + // is the type used as its traits. + template + struct transform_iterator_base + { + private: + + // transform_iterator does not support writable/swappable iterators +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + BOOST_STATIC_ASSERT((is_tag< readable_iterator_tag, typename access_category::type >::value)); +#endif + + typedef typename mpl::apply_if< + is_same< Reference, use_default > + , function_object_result + , mpl::identity + >::type result_type; + + typedef typename mpl::if_< + is_same< Value, use_default > + , typename remove_reference< result_type >::type + , Value + >::type cv_value_type; + + typedef typename mpl::if_< + is_reference< result_type > + , typename mpl::if_< + is_const< cv_value_type > + , readable_lvalue_iterator_tag + , writable_lvalue_iterator_tag + >::type + , readable_iterator_tag + >::type maximum_access_tag; + + typedef typename minimum_category< + maximum_access_tag + , typename access_category::type + >::type access_category; + + public: + typedef iterator_adaptor< + transform_iterator + , Iterator + , cv_value_type + , iterator_tag< + access_category + , typename traversal_category::type + > + , result_type + > type; + }; + + } + + template + class transform_iterator + : public detail::transform_iterator_base::type + { + typedef typename + detail::transform_iterator_base::type + super_t; + + friend class iterator_core_access; + + public: + transform_iterator() { } + + transform_iterator(Iterator const& x, UnaryFunction f) + : super_t(x), m_f(f) { } + + template + transform_iterator( + transform_iterator const& t + , typename enable_if_convertible::type* = 0 + ) + : super_t(t.base()), m_f(t.functor()) {} + + UnaryFunction functor() const + { return m_f; } + + private: + typename super_t::reference dereference() const + { return m_f(*this->base()); } + + // Probably should be the initial base class so it can be + // optimized away via EBO if it is an empty class. + UnaryFunction m_f; + }; + + template + transform_iterator make_transform_iterator(Iterator it, UnaryFunction fun) + { + return transform_iterator(it, fun); + } + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + template + transform_iterator< Return (*)(Argument), Iterator, Return> + make_transform_iterator(Iterator it, Return (*fun)(Argument)) + { + return transform_iterator(it, fun); + } +#endif + +} // namespace boost + +#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP