diff --git a/include/boost/iterator/iterator_adaptors.hpp b/include/boost/iterator/iterator_adaptors.hpp index d2158d1..00e53c1 100644 --- a/include/boost/iterator/iterator_adaptors.hpp +++ b/include/boost/iterator/iterator_adaptors.hpp @@ -1,400 +1,660 @@ #ifndef BOOST_ITERATOR_ADAPTORS_HPP #define BOOST_ITERATOR_ADAPTORS_HPP +#include #include // for prior #include #include #include +#include #include +#include #include "boost/type_traits/detail/bool_trait_def.hpp" namespace boost { -template -struct repository : iterator + namespace detail { -{ - typedef Final final; -}; + template + struct enabled + { + template + struct base + { + typedef T type; + }; + }; + + template<> + struct enabled + { + template + struct base + { + }; + }; -template -struct downcastable : Base -{ - typedef typename Base::final final_t; -public: - final_t& self() { return static_cast(*this); } - const final_t& self() const { return static_cast(*this); } -}; + struct enable_type {}; -template -struct iterator_comparisons : Base -{ -}; + template + struct is_interoperable : + mpl::logical_or< is_convertible< A, B >, + is_convertible< B, A > > + { + }; -template -inline bool operator==(const iterator_comparisons& xb, - const iterator_comparisons& yb) -{ - return xb.self().equal(yb.self()); -} + template + struct enable_if_interoperable : + enabled<(is_interoperable::value)>::template base + { + }; -template -inline bool operator!=(const iterator_comparisons& xb, - const iterator_comparisons& yb) -{ - return !xb.self().equal(yb.self()); -} - -template -inline bool operator<(const iterator_comparisons& xb, - const iterator_comparisons& yb) -{ - return xb.self().distance_to(yb.self()) > 0; -} - -template -inline bool operator>(const iterator_comparisons& xb, - const iterator_comparisons& yb) -{ - return xb.self().distance_to(yb.self()) < 0; -} - -template -inline bool operator>=(const iterator_comparisons& xb, - const iterator_comparisons& yb) -{ - return xb.self().distance_to(yb.self()) <= 0; -} - -template -inline bool operator<=(const iterator_comparisons& xb, - const iterator_comparisons& yb) -{ - return xb.self().distance_to(yb.self()) >= 0; -} + } // namespace detail -template -struct iterator_arith : B { }; + template + struct enable_if_convertible : + detail::enabled<(is_convertible::value)>::template base + { + }; -template -typename Base::final operator+( - const iterator_arith& i, // pass by ref, not value to avoid slicing -JGS - typename Base::difference_type n) -{ - typename Base::final tmp(i.self()); - return tmp += n; -} + // + // Helper class for granting access to the iterator core interface. + // + // The simple core interface is used by iterator_facade. The core + // interface should not be made public so that it does not clutter + // the public interface of user defined iterators. Instead iterator_core_access + // should be made friend so that iterator_facade can access the core + // interface through iterator_core_access. + // + struct iterator_core_access + { + template + static typename Facade::reference dereference(Facade const& f) + { + return f.dereference(); + } -template -typename Base::final operator+( - typename Base::difference_type n, - const iterator_arith& i) // pass by ref, not value to avoid slicing -JGS -{ - typename Base::final tmp(i.self()); - return tmp += n; -} + template + static void increment(Facade& f) + { + f.increment(); + } -template -typename Base1::difference_type operator-( - const iterator_arith& i, - const iterator_arith& j) -{ - return j.self().distance_to(i.self()); -} + template + static void decrement(Facade& f) + { + f.decrement(); + } -// Used for a default template argument, when we can't afford to -// instantiate the default calculation if unused. -struct unspecified {}; + template + static bool equal(Facade1 const& f1, Facade2 const& f2, Facade1* = 0, Facade2* = 0) + { + 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, + Facade1* = 0, + Facade2* = 0) + { + return f1.distance_to(f2); + } + + }; + + template + class repository : + public iterator + { + typedef Derived derived_t; + }; + + template + class downcastable : + public Base + { + public: + typename Base::derived_t& derived() + { + return static_cast(*this); + } + + typename Base::derived_t const& derived() const + { + return static_cast(*this); + } + }; #if 0 -// Beginnings of a failed attempt to conditionally provide base() -// functions in iterator_adaptor. It may be that a public m_base -// member is the only way to avoid boilerplate! + namespace detail { -template -struct base_wrapper_impl -{ - template - struct apply : Super - { - apply() {} - apply(Base b) : m_base(b) {} - - Base base() const { return m_base; } - Base& base() { return m_base; } - private: - Base m_base; - }; -}; - -template <> -struct base_wrapper_impl -{ - template - struct apply : Super + template + struct compare_traits : + mpl::if_< is_convertible, + Final1, + Final2 > { }; -}; + + } // namespace detail #endif -template > > > - > -struct iterator_adaptor : B -{ - typedef V value_type; - typedef R reference; - typedef P pointer; - typedef C iterator_category; - typedef D difference_type; + template + class iterator_comparisons : + public Base + { + }; + + template + inline + typename detail::enable_if_interoperable::type + operator==(iterator_comparisons const& lhs, + iterator_comparisons const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((detail::is_interoperable< + typename Base1::derived_t, + typename Base2::derived_t >::value)); + + return iterator_core_access::equal(lhs.derived(), + rhs.derived()); + } + + template + inline + typename detail::enable_if_interoperable::type + operator!=(iterator_comparisons const& lhs, + iterator_comparisons const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((detail::is_interoperable< + typename Base1::derived_t, + typename Base2::derived_t >::value)); + + return !iterator_core_access::equal(lhs.derived(), + rhs.derived()); + } + + template + inline + typename detail::enable_if_interoperable::type + operator<(iterator_comparisons const& lhs, + iterator_comparisons const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((detail::is_interoperable< + typename Base1::derived_t, + typename Base2::derived_t >::value)); + + return iterator_core_access::distance_to(lhs.derived(), + rhs.derived()) > 0; + } + + template + inline + typename detail::enable_if_interoperable::type + operator>(iterator_comparisons const& lhs, + iterator_comparisons const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((detail::is_interoperable< + typename Base1::derived_t, + typename Base2::derived_t >::value)); + + return iterator_core_access::distance_to(lhs.derived(), + rhs.derived()) < 0; + } + + template + inline + typename detail::enable_if_interoperable::type + operator<=(iterator_comparisons const& lhs, + iterator_comparisons const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((detail::is_interoperable< + typename Base1::derived_t, + typename Base2::derived_t >::value)); + + return iterator_core_access::distance_to(lhs.derived(), + rhs.derived()) >= 0; + } + + template + inline + typename detail::enable_if_interoperable::type + operator>=(iterator_comparisons const& lhs, + iterator_comparisons const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((detail::is_interoperable< + typename Base1::derived_t, + typename Base2::derived_t >::value)); + + return iterator_core_access::distance_to(lhs.derived(), + rhs.derived()) <= 0; + } + + + template + class iterator_arith : + public Base + { + }; + + template + inline + typename Base::derived_t operator+(iterator_arith const& i, + typename Base::difference_type n) + { + typename Base::derived_t tmp(i.derived()); + return tmp += n; + } + + template + inline + typename Base::derived_t operator+(typename Base::difference_type n, + iterator_arith const& i) + { + typename Base::derived_t tmp(i.derived()); + return tmp += n; + } + + template + inline + typename detail::enable_if_interoperable::type + operator-(iterator_arith const& lhs, + iterator_arith const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((detail::is_interoperable< + typename Base1::derived_t, + typename Base2::derived_t >::value)); + + BOOST_STATIC_ASSERT((is_same::value)); + + return iterator_core_access::distance_to(lhs.derived(), + rhs.derived()); + } + + template > > > + > + class iterator_facade : + public Super + { + typedef Super super_t; + + public: + typedef typename super_t::reference reference; + typedef typename super_t::difference_type difference_type; reference operator*() const - { return self().dereference(); } + { return iterator_core_access::dereference(this->derived()); } // Needs eventual help for input iterators - P operator->() const { return &self().dereference(); } - - //operator->() const { return detail::operator_arrow(*this, iterator_category()); } - + P operator->() const { return &iterator_core_access::dereference(this->derived()); } + reference operator[](difference_type n) const { return *(*this + n); } - Final& operator++() - { self().increment(); return self(); } - Final operator++(int) - { Final tmp(self()); ++*this; return tmp; } - Final& operator--() - { self().decrement(); return self(); } - Final operator--(int) - { Final tmp(self()); --*this; return tmp; } - Final& operator+=(difference_type n) - { self().advance(n); return self(); } - Final& operator-=(difference_type n) - { self().advance(-n); return self(); } - Final operator-(difference_type x) const - { Final result(self()); return result -= x; } - template - bool equal(iterator_adaptor const& x) const + 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; } + }; + + // + // We should provide NTP here + // + // TODO Handle default arguments the same way as + // in former ia lib + // + template ::value_type, + class Reference = typename std::iterator_traits::reference, + class Pointer = typename std::iterator_traits::pointer, + class Category = typename std::iterator_traits::iterator_category, + class Distance = typename std::iterator_traits::difference_type> + class iterator_adaptor : + public iterator_facade + { + friend class iterator_core_access; + + public: + iterator_adaptor() {} + + explicit iterator_adaptor(Iterator iter) + : m_iterator(iter) { - return self().base() == x.self().base(); - } - void advance(difference_type n) - { - self().base() += n; } - reference dereference() const { return *self().base(); } - - void increment() { ++self().base(); } - void decrement() { --self().base(); } + Iterator base() const { return m_iterator; } - template - difference_type - distance_to(const iterator_adaptor& y) const + protected: + // Core iterator interface for iterator_facade + // + Reference dereference() const { return *m_iterator; } + + template + bool equal(iterator_adaptor const& x) const { - return y.self().base() - self().base();//? + return m_iterator == x.base(); + } + + void advance(Distance n) + { + m_iterator += n; + } + + void increment() { ++m_iterator; } + void decrement() { --m_iterator; } + + template + Distance distance_to(iterator_adaptor const& y) const + { + return y.base() - m_iterator; } - // Can't be private, or const/non-const interactions don't work - using B::self; -}; + private: + Iterator m_iterator; + }; -template -struct reverse_iterator - : iterator_adaptor< - reverse_iterator, V, R, P, C, D - > -{ - typedef iterator_adaptor, V, R, P, C, D> super; + // + // + // + 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()); } -// friend class super; - // hmm, I don't like the next two lines -// template friend struct iterator_comparisons; -// template friend struct iterator_arith; - - public: - reverse_iterator(const Base& x) : m_base(x) { } + void increment() { super_t::decrement(); } + void decrement() { super_t::increment(); } - reverse_iterator() { } - - Base const& base() const { return m_base; } - - template - reverse_iterator(const reverse_iterator& y) - : m_base(y.m_base) { } - - - typename super::reference dereference() const { return *boost::prior(m_base); } - - void increment() { --m_base; } - void decrement() { ++m_base; } - void advance(typename super::difference_type n) + void advance(typename super_t::difference_type n) { - m_base -= n; + super_t::advance(-n); } - template - typename super::difference_type - distance_to(const reverse_iterator& y) const + template + typename super_t::difference_type + distance_to(reverse_iterator const& y) const { - return y.m_base - m_base; + return -super_t::distance_to(y); } - private: - Base m_base; -}; + }; -template -struct transform_iterator - : iterator_adaptor< - transform_iterator, - typename AdaptableUnaryFunction::result_type, - typename AdaptableUnaryFunction::result_type, - typename AdaptableUnaryFunction::result_type*, - iterator_tag::type>, - typename detail::iterator_traits::difference_type - > -{ - public: // types - typedef typename AdaptableUnaryFunction::result_type value_type; + // + // TODO fix category + // + template + class transform_iterator : + public iterator_adaptor< transform_iterator, + Iterator, + typename AdaptableUnaryFunction::result_type, + typename AdaptableUnaryFunction::result_type, + typename AdaptableUnaryFunction::result_type* + > + { + typedef iterator_adaptor< transform_iterator, + Iterator, + typename AdaptableUnaryFunction::result_type, + typename AdaptableUnaryFunction::result_type, + typename AdaptableUnaryFunction::result_type* > super_t; - public: // member functions - transform_iterator() { } + friend class iterator_core_access; - transform_iterator(const Base& x, AdaptableUnaryFunction f) - : m_base(x), m_f(f) { } + public: + transform_iterator() { } - value_type dereference() const { return m_f(*m_base); } + transform_iterator(Iterator const& x, + AdaptableUnaryFunction f) + : super_t(x), m_f(f) { } - template - transform_iterator(const transform_iterator& y) - : m_base(y.m_base), m_f(y.m_f) { } + template + transform_iterator(transform_iterator const& t, + typename enable_if_convertible::type* = 0) + : super_t(t.base()), m_f(t.functor()) {} - Base& base() { return m_base; } - Base const& base() const { return m_base; } - -private: - Base m_base; - AdaptableUnaryFunction m_f; -}; + AdaptableUnaryFunction functor() const { return m_f; } -// This macro definition is only temporary in this file + private: + typename super_t::value_type dereference() const { return m_f(super_t::dereference()); } + + AdaptableUnaryFunction m_f; + }; + + // This macro definition is only temporary in this file # if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 # define BOOST_ARG_DEPENDENT_TYPENAME typename # else # define BOOST_ARG_DEPENDENT_TYPENAME # endif -namespace detail -{ - // - // Detection for whether a type has a nested `element_type' - // typedef. Used to detect smart pointers. We're having trouble - // auto-detecting smart pointers with gcc-2.95 via the nested - // element_type member. 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. - // - namespace aux - { - BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type) - } + struct unspecified {}; - template - struct has_element_type + namespace detail + { + // + // Detection for whether a type has a nested `element_type' + // typedef. Used to detect smart pointers. We're having trouble + // auto-detecting smart pointers with gcc-2.95 via the nested + // element_type member. 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. + // + namespace aux + { + BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type) + } + + template + struct has_element_type : mpl::if_< - is_class + is_class # if __GNUC__ == 2 // gcc 2.95 doesn't seem to be able to detect element_type without barfing - , mpl::bool_c + , mpl::bool_c # else - , aux::has_element_type + , aux::has_element_type # endif - , mpl::bool_c - >::type - { - }; + , mpl::bool_c + >::type + { + }; - // Metafunction returning the nested element_type typedef - template - struct smart_pointer_traits - { + // Metafunction returning the nested element_type typedef + template + struct smart_pointer_traits + { typedef typename remove_const< - typename T::element_type + typename T::element_type >::type value_type; typedef typename T::element_type& reference; typedef typename T::element_type* pointer; - }; + }; - // If the Value parameter is unspecified, we use this metafunction - // to deduce the default types - template - struct indirect_defaults + // If the Value parameter is unspecified, we use this metafunction + // to deduce the default types + template + struct indirect_defaults : mpl::if_c< - has_element_type::value_type>::value - , smart_pointer_traits::value_type> - , iterator_traits::value_type> - >::type - { + has_element_type::value_type>::value + , smart_pointer_traits::value_type> + , iterator_traits::value_type> + >::type + { typedef typename iterator_traits::iterator_category iterator_category; typedef typename iterator_traits::difference_type difference_type; - }; + }; - template - struct indirect_traits + template + struct indirect_traits : mpl::if_, indirect_defaults, Traits>::type + { + }; + } // namespace detail + + template + class indirect_iterator : + public iterator_adaptor< indirect_iterator, + Iterator, + typename detail::indirect_traits::value_type, + typename detail::indirect_traits::reference, + typename detail::indirect_traits::pointer, + typename detail::indirect_traits::iterator_category, + typename detail::indirect_traits::difference_type > { - }; -} // namespace detail + typedef iterator_adaptor< indirect_iterator, + Iterator, + typename detail::indirect_traits::value_type, + typename detail::indirect_traits::reference, + typename detail::indirect_traits::pointer, + typename detail::indirect_traits::iterator_category, + typename detail::indirect_traits::difference_type > super_t; -template -struct indirect_iterator - : iterator_adaptor< - indirect_iterator - , typename detail::indirect_traits::value_type - , typename detail::indirect_traits::reference - , typename detail::indirect_traits::pointer - , typename detail::indirect_traits::iterator_category - , typename detail::indirect_traits::difference_type - > -{ + friend class iterator_core_access; + + public: indirect_iterator() {} - - typename detail::indirect_traits::reference - dereference() const { return **this->m_base; } - indirect_iterator(Base iter) - : m_base(iter) {} + indirect_iterator(Iterator iter) + : super_t(iter) {} - template - indirect_iterator(const indirect_iterator& y) - : m_base(y.base()) - {} - - Base& base() { return m_base; } - Base const& base() const { return m_base; } - private: - Base m_base; -}; + template + indirect_iterator(indirect_iterator const& y, + typename enable_if_convertible::type* = 0) + : super_t(y.base()) {} -template -indirect_iterator make_indirect_iterator(Iter x) -{ + private: + typename super_t::reference dereference() const { return **this->base(); } + + }; + + template + inline + indirect_iterator make_indirect_iterator(Iter x) + { return indirect_iterator(x); -} + } -template -indirect_iterator make_indirect_iterator(Iter x, Traits* = 0) -{ - return indirect_iterator(x); -} + template + inline + indirect_iterator make_indirect_iterator(Iter x, Traits* = 0) + { + return indirect_iterator(x); + } } // namespace boost