// (C) Copyright Thomas Becker 2005. 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. // Revision History // ================ // // 27 Dec 2006 (Thomas Becker) Created // 12 Jul 2010 (Thomas Becker acting on bug report by Edgar Binder) // Bug fix: Constructors and create function of any_iterator_wrapper // from wrapped iterator must take their argument by const reference (performance!). #ifndef ANY_ITERATOR_WRAPPER_01102007TMB_HPP #define ANY_ITERATOR_WRAPPER_01102007TMB_HPP // Includes // ======== #include "any_iterator_abstract_base.hpp" #include "any_iterator_metafunctions.hpp" #include #include #include namespace IteratorTypeErasure { namespace detail { /////////////////////////////////////////////////////////////////////// // // The partial specializations of any_iterator_wrapper (which is the // the equivalent of boost::any::holder) mirror the hierarchy of // boost's iterator traversal tags. // // The first four template arguments are as in boost::iterator_facade. // The last template argument is the traversal tag of the most // derived class of the current instantiation of the hierarchy. This // is a slight variant of the CRTP where the derived class passes // itself as a template argument to the base class(es). Here, it seemed // more convenient to pass up just the traversal tag of the most // derived class. // template< class WrappedIterator, class Value, class Traversal, class Reference, class Difference, class UsedAsBaseForTraversal = Traversal > class any_iterator_wrapper; /////////////////////////////////////////////////////////////////////// // template< class WrappedIterator, class Value, class Reference, class Difference, class UsedAsBaseForTraversal > class any_iterator_wrapper< WrappedIterator, Value, boost::incrementable_traversal_tag, Reference, Difference, UsedAsBaseForTraversal > : public any_iterator_abstract_base< Value, UsedAsBaseForTraversal, Reference, Difference > { protected: typedef any_iterator_abstract_base abstract_base_type; private: typedef typename abstract_base_type::clone_result_type clone_result_type; typedef typename abstract_base_type::const_clone_with_const_value_type_result_type const_clone_with_const_value_type_result_type; typedef typename abstract_base_type::const_clone_with_non_const_value_type_result_type const_clone_with_non_const_value_type_result_type; typedef any_iterator_wrapper< WrappedIterator, Value, UsedAsBaseForTraversal, Reference, Difference > clone_type; typedef any_iterator_wrapper< WrappedIterator, typename boost::add_const::type, UsedAsBaseForTraversal, typename make_iterator_reference_const::type, Difference > const_clone_type_with_const_value_type; typedef any_iterator_wrapper< WrappedIterator, typename boost::remove_const::type, UsedAsBaseForTraversal, typename make_iterator_reference_const::type, Difference > const_clone_type_with_non_const_value_type; public: any_iterator_wrapper() {} any_iterator_wrapper(WrappedIterator const& wrapped_iterator) : m_wrapped_iterator(wrapped_iterator) {} static abstract_base_type* create(WrappedIterator const& wrapped_iterator) { return new clone_type(wrapped_iterator); } // Plain clone function for copy construction and assignment. virtual clone_result_type * clone() const { return new clone_type(m_wrapped_iterator); } // Clone functions for conversion to a const iterator virtual const_clone_with_const_value_type_result_type* make_const_clone_with_const_value_type() const { return new const_clone_type_with_const_value_type(m_wrapped_iterator); } // virtual const_clone_with_non_const_value_type_result_type* make_const_clone_with_non_const_value_type() const { return new const_clone_type_with_non_const_value_type(m_wrapped_iterator); } virtual Reference dereference() const { // This const cast is needed for output iterators. Is this perhaps an oversight // in iterator_facade? return *const_cast(this)->m_wrapped_iterator; } virtual void increment() { ++m_wrapped_iterator; } protected: WrappedIterator& get_wrapped_iterator() { return m_wrapped_iterator; } WrappedIterator const & get_wrapped_iterator() const { return m_wrapped_iterator; } private: WrappedIterator m_wrapped_iterator; }; /////////////////////////////////////////////////////////////////////// // template< class WrappedIterator, class Value, class Reference, class Difference, class UsedAsBaseForTraversal > class any_iterator_wrapper< WrappedIterator, Value, boost::single_pass_traversal_tag, Reference, Difference, UsedAsBaseForTraversal > : public any_iterator_wrapper< WrappedIterator, Value, boost::incrementable_traversal_tag, Reference, Difference, UsedAsBaseForTraversal > { public: typedef any_iterator_wrapper< WrappedIterator, Value, boost::incrementable_traversal_tag, Reference, Difference, UsedAsBaseForTraversal > super_type; any_iterator_wrapper() {} any_iterator_wrapper(WrappedIterator const& wrapped_iterator) : super_type(wrapped_iterator) {} // gcc 3.4.2 insists on qualification of abstract_base_type. virtual bool equal(typename any_iterator_wrapper::abstract_base_type const & rhs) const { return this->get_wrapped_iterator() == boost::polymorphic_downcast(&rhs)->get_wrapped_iterator(); } any_iterator_abstract_base< Value, boost::incrementable_traversal_tag, Reference, Difference >* make_incrementable_version() const { return new any_iterator_wrapper< WrappedIterator, Value, boost::incrementable_traversal_tag, Reference, Difference >(this->get_wrapped_iterator()); } }; /////////////////////////////////////////////////////////////////////// // template< class WrappedIterator, class Value, class Reference, class Difference, class UsedAsBaseForTraversal > class any_iterator_wrapper< WrappedIterator, Value, boost::forward_traversal_tag, Reference, Difference, UsedAsBaseForTraversal > : public any_iterator_wrapper< WrappedIterator, Value, boost::single_pass_traversal_tag, Reference, Difference, UsedAsBaseForTraversal > { public: typedef any_iterator_wrapper< WrappedIterator, Value, boost::single_pass_traversal_tag, Reference, Difference, UsedAsBaseForTraversal > super_type; any_iterator_wrapper() {} any_iterator_wrapper(WrappedIterator const& wrapped_iterator) : super_type(wrapped_iterator) {} any_iterator_abstract_base< Value, boost::single_pass_traversal_tag, Reference, Difference >* make_single_pass_version() const { return new any_iterator_wrapper< WrappedIterator, Value, boost::single_pass_traversal_tag, Reference, Difference >(this->get_wrapped_iterator()); } }; /////////////////////////////////////////////////////////////////////// // template< class WrappedIterator, class Value, class Reference, class Difference, class UsedAsBaseForTraversal > class any_iterator_wrapper< WrappedIterator, Value, boost::bidirectional_traversal_tag, Reference, Difference, UsedAsBaseForTraversal > : public any_iterator_wrapper< WrappedIterator, Value, boost::forward_traversal_tag, Reference, Difference, UsedAsBaseForTraversal > { public: typedef any_iterator_wrapper< WrappedIterator, Value, boost::forward_traversal_tag, Reference, Difference, UsedAsBaseForTraversal > super_type; any_iterator_wrapper() {} any_iterator_wrapper(WrappedIterator const& wrapped_iterator) : super_type(wrapped_iterator) {} virtual void decrement() { --(this->get_wrapped_iterator()); } any_iterator_abstract_base< Value, boost::forward_traversal_tag, Reference, Difference >* make_forward_version() const { return new any_iterator_wrapper< WrappedIterator, Value, boost::forward_traversal_tag, Reference, Difference >(this->get_wrapped_iterator()); } }; /////////////////////////////////////////////////////////////////////// // template< class WrappedIterator, class Value, class Reference, class Difference, class UsedAsBaseForTraversal > class any_iterator_wrapper< WrappedIterator, Value, boost::random_access_traversal_tag, Reference, Difference, UsedAsBaseForTraversal > : public any_iterator_wrapper< WrappedIterator, Value, boost::bidirectional_traversal_tag, Reference, Difference, UsedAsBaseForTraversal > { public: typedef any_iterator_wrapper< WrappedIterator, Value, boost::bidirectional_traversal_tag, Reference, Difference, UsedAsBaseForTraversal > super_type; any_iterator_wrapper() {} any_iterator_wrapper(WrappedIterator const& wrapped_iterator) : super_type(wrapped_iterator) {} virtual void advance(Difference n) { this->get_wrapped_iterator() += n; } // gcc 3.4.2 insists on qualification of abstract_base_type. virtual Difference distance_to(typename any_iterator_wrapper::abstract_base_type const & other) const { return boost::polymorphic_downcast(&other)->get_wrapped_iterator() - this->get_wrapped_iterator(); } any_iterator_abstract_base< Value, boost::bidirectional_traversal_tag, Reference, Difference >* make_bidirectional_version() const { return new any_iterator_wrapper< WrappedIterator, Value, boost::bidirectional_traversal_tag, Reference, Difference >(this->get_wrapped_iterator()); } }; } // end namespace detail } // end namespace IteratorTypeErasure #endif // ANY_ITERATOR_WRAPPER_01102007TMB_HPP