diff --git a/include/boost/iterator/iterator_adaptors.hpp b/include/boost/iterator/iterator_adaptors.hpp index 7e14645..b82b652 100644 --- a/include/boost/iterator/iterator_adaptors.hpp +++ b/include/boost/iterator/iterator_adaptors.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -52,10 +53,11 @@ #endif -namespace boost { - - namespace detail { +namespace boost +{ + namespace detail + { // // Base machinery for all kinds of enable if // @@ -152,6 +154,30 @@ namespace boost { // struct enable_type; + // traits_iterator has two important properties: + // + // 1. It is derived from boost::iterator<...>, which is + // important for standard library interoperability of + // iterator types on some (broken) implementations. + // + // 2. The associated types are taken from iterator_traits. + // + // It might arguably be better to arrange for + // boost::detail::iterator_traits to be derived from + // boost::iterator<...>, then we could use + // boost::detail::iterator_traits directly. + template + struct traits_iterator + : iterator< + typename iterator_traits::iterator_category + , typename iterator_traits::value_type + , typename iterator_traits::difference_type + , typename iterator_traits::pointer + , typename iterator_traits::reference + > + { + }; + } // namespace detail // @@ -256,41 +282,37 @@ namespace boost { { return f1.distance_to(f2); } - }; - template - class repository : - public iterator + namespace detail { - public: - typedef Derived derived_t; + struct empty_base {}; + } + + // Encapsulates the "Curiously Recursive Template" pattern. + // Derived should be a class derived from this instantiation, and + // Base will be inserted as a base class. + template + class downcastable + : public Base + { + public: + typedef Derived derived_t; + + Derived& derived() + { + return static_cast(*this); + } + + Derived const& derived() const + { + return static_cast(*this); + } }; 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); - } - }; - - template - class iterator_comparisons : - public Base + class iterator_comparisons + : public Base { }; @@ -496,9 +518,11 @@ namespace boost { template inline - typename detail::enable_if_interoperable::type + typename detail::enable_if_interoperable< + typename Base1::derived_t + , typename Base2::derived_t + , typename Base1::difference_type + >::type operator-(iterator_arith const& lhs, iterator_arith const& rhs) { @@ -514,33 +538,27 @@ namespace boost { lhs.derived()); } - template > > > + template < + class Derived + , class Traits + , class Super = iterator_arith< + iterator_comparisons< + downcastable > > > - class iterator_facade : - public Super + class iterator_facade + : public Super { - typedef Super super_t; - - public: + typedef Super super_t; + public: typedef typename super_t::reference reference; typedef typename super_t::difference_type difference_type; + typedef typename super_t::pointer pointer; reference operator*() const { return iterator_core_access::dereference(this->derived()); } // Needs eventual help for input iterators - P operator->() const { return &iterator_core_access::dereference(this->derived()); } + pointer operator->() const { return &iterator_core_access::dereference(this->derived()); } reference operator[](difference_type n) const { return *(*this + n); } @@ -567,24 +585,34 @@ namespace boost { { Derived result(this->derived()); return result -= x; } }; + namespace detail + { + template + struct same_category_and_difference + : mpl::logical_and< + is_same< + typename Traits::iterator_category + , typename Other::iterator_category + > + , is_same< + typename Traits::iterator_category + , typename Other::iterator_category + > + > + {}; + } + // // TODO Handle default arguments the same way as // in former ia lib // - template ::value_type, - class Reference = typename detail::iterator_traits::reference, - class Pointer = typename detail::iterator_traits::pointer, - class Category = typename detail::iterator_traits::iterator_category, - class Distance = typename detail::iterator_traits::difference_type> - class iterator_adaptor : - public iterator_facade + template < + class Derived + , class Iterator + , class Traits = detail::traits_iterator + > + class iterator_adaptor + : public iterator_facade { friend class iterator_core_access; @@ -601,50 +629,39 @@ namespace boost { protected: // Core iterator interface for iterator_facade // - Reference dereference() const { return *m_iterator; } + typename Traits::reference dereference() const { return *m_iterator; } - template - bool equal(iterator_adaptor const& x) const + template < + class OtherDerived, class OtherIterator, class OtherTraits + > + bool equal(iterator_adaptor const& x) const { - return m_iterator == x.base(); + BOOST_STATIC_ASSERT( + (detail::same_category_and_difference::value) + ); + return m_iterator == x.base(); } - void advance(Distance n) + void advance(typename Traits::difference_type n) { - m_iterator += n; + m_iterator += n; } void increment() { ++m_iterator; } void decrement() { --m_iterator; } - template - Distance distance_to(iterator_adaptor const& y) const + template + typename Traits::difference_type distance_to( + iterator_adaptor const& y) const { - return y.base() - m_iterator; + BOOST_STATIC_ASSERT( + (detail::same_category_and_difference::value) + ); + return y.base() - m_iterator; } - private: - Iterator m_iterator; + private: // data members + Iterator m_iterator; }; @@ -699,23 +716,35 @@ namespace boost { return reverse_iterator(x); } + // Given the transform iterator's transformation and iterator, this + // is the type used as its traits. + template + struct transform_iterator_traits + : iterator< + typename detail::iterator_traits::iterator_category + , typename AdaptableUnaryFunction::result_type + , typename detail::iterator_traits::difference_type + , typename AdaptableUnaryFunction::result_type* + , typename AdaptableUnaryFunction::result_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* - > + class transform_iterator + : public iterator_adaptor< + transform_iterator + , Iterator + , transform_iterator_traits + > { - typedef iterator_adaptor< transform_iterator, - Iterator, - typename AdaptableUnaryFunction::result_type, - typename AdaptableUnaryFunction::result_type, - typename AdaptableUnaryFunction::result_type* > super_t; + typedef iterator_adaptor< + transform_iterator + , Iterator + , transform_iterator_traits + > super_t; friend class iterator_core_access; @@ -816,30 +845,34 @@ namespace boost { typedef typename iterator_traits::difference_type difference_type; }; + // The traits to use for indirect iterator, by default. Whatever + // is supplied gets passed through traits_iterator<...> so that it + // is ultimately derived from boost::iterator<...> template struct indirect_traits - : mpl::if_, indirect_defaults, Traits>::type + : traits_iterator< + typename mpl::if_< + is_same + , 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 > + public iterator_adaptor< + indirect_iterator + , Iterator + , detail::indirect_traits > { - 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; + typedef iterator_adaptor< + indirect_iterator + , Iterator + , detail::indirect_traits + > super_t; friend class iterator_core_access; @@ -892,21 +925,14 @@ namespace boost { template class filter_iterator : public iterator_adaptor< - filter_iterator, Iterator, - typename filter_iterator_traits::value_type, - typename filter_iterator_traits::reference, - typename filter_iterator_traits::pointer, - typename filter_iterator_traits::iterator_category, - typename filter_iterator_traits::difference_type + filter_iterator, Iterator + , detail::traits_iterator > > { typedef iterator_adaptor< - filter_iterator, Iterator, - typename filter_iterator_traits::value_type, - typename filter_iterator_traits::reference, - typename filter_iterator_traits::pointer, - typename filter_iterator_traits::iterator_category, - typename filter_iterator_traits::difference_type > super_t; + filter_iterator, Iterator + , detail::traits_iterator > + > super_t; friend class iterator_core_access;