590 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			590 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
// Boost.Range library
 | 
						|
//
 | 
						|
//  Copyright Neil Groves 2010. Use, modification and
 | 
						|
//  distribution is subject to the Boost Software License, Version
 | 
						|
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
						|
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
						|
//
 | 
						|
// For more information, see http://www.boost.org/libs/range/
 | 
						|
//
 | 
						|
#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
 | 
						|
#define BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
 | 
						|
 | 
						|
#include <boost/mpl/and.hpp>
 | 
						|
#include <boost/mpl/or.hpp>
 | 
						|
#include <boost/mpl/not.hpp>
 | 
						|
#include <boost/iterator/iterator_facade.hpp>
 | 
						|
#include <boost/type_traits/is_const.hpp>
 | 
						|
#include <boost/type_traits/is_reference.hpp>
 | 
						|
#include <boost/type_traits/remove_reference.hpp>
 | 
						|
#include <boost/range/detail/any_iterator_buffer.hpp>
 | 
						|
#include <boost/range/detail/any_iterator_interface.hpp>
 | 
						|
#include <boost/range/detail/any_iterator_wrapper.hpp>
 | 
						|
#include <boost/utility/enable_if.hpp>
 | 
						|
 | 
						|
namespace boost
 | 
						|
{
 | 
						|
    namespace range_detail
 | 
						|
    {
 | 
						|
        // metafunction to determine if T is a const reference
 | 
						|
        template<class T>
 | 
						|
        struct is_const_reference
 | 
						|
        {
 | 
						|
            typedef typename mpl::and_<
 | 
						|
                typename is_reference<T>::type,
 | 
						|
                typename is_const<
 | 
						|
                    typename remove_reference<T>::type
 | 
						|
                >::type
 | 
						|
            >::type type;
 | 
						|
        };
 | 
						|
 | 
						|
        // metafunction to determine if T is a mutable reference
 | 
						|
        template<class T>
 | 
						|
        struct is_mutable_reference
 | 
						|
        {
 | 
						|
            typedef typename mpl::and_<
 | 
						|
                typename is_reference<T>::type,
 | 
						|
                typename mpl::not_<
 | 
						|
                    typename is_const<
 | 
						|
                        typename remove_reference<T>::type
 | 
						|
                    >::type
 | 
						|
                >::type
 | 
						|
            >::type type;
 | 
						|
        };
 | 
						|
 | 
						|
        // metafunction to evaluate if a source 'reference' can be
 | 
						|
        // converted to a target 'reference' as a value.
 | 
						|
        //
 | 
						|
        // This is true, when the target reference type is actually
 | 
						|
        // not a reference, and the source reference is convertible
 | 
						|
        // to the target type.
 | 
						|
        template<class SourceReference, class TargetReference>
 | 
						|
        struct is_convertible_to_value_as_reference
 | 
						|
        {
 | 
						|
            typedef typename mpl::and_<
 | 
						|
                typename mpl::not_<
 | 
						|
                    typename is_reference<TargetReference>::type
 | 
						|
                >::type
 | 
						|
              , typename is_convertible<
 | 
						|
                    SourceReference
 | 
						|
                  , TargetReference
 | 
						|
                >::type
 | 
						|
            >::type type;
 | 
						|
        };
 | 
						|
 | 
						|
        template<
 | 
						|
            class Value
 | 
						|
          , class Traversal
 | 
						|
          , class Reference
 | 
						|
          , class Difference
 | 
						|
          , class Buffer = any_iterator_default_buffer
 | 
						|
        >
 | 
						|
        class any_iterator;
 | 
						|
 | 
						|
        // metafunction to determine if SomeIterator is an
 | 
						|
        // any_iterator.
 | 
						|
        //
 | 
						|
        // This is the general implementation which evaluates to false.
 | 
						|
        template<class SomeIterator>
 | 
						|
        struct is_any_iterator
 | 
						|
            : mpl::bool_<false>
 | 
						|
        {
 | 
						|
        };
 | 
						|
 | 
						|
        // specialization of is_any_iterator to return true for
 | 
						|
        // any_iterator classes regardless of template parameters.
 | 
						|
        template<
 | 
						|
            class Value
 | 
						|
          , class Traversal
 | 
						|
          , class Reference
 | 
						|
          , class Difference
 | 
						|
          , class Buffer
 | 
						|
        >
 | 
						|
        struct is_any_iterator<
 | 
						|
            any_iterator<
 | 
						|
                Value
 | 
						|
              , Traversal
 | 
						|
              , Reference
 | 
						|
              , Difference
 | 
						|
              , Buffer
 | 
						|
            >
 | 
						|
        >
 | 
						|
            : mpl::bool_<true>
 | 
						|
        {
 | 
						|
        };
 | 
						|
    } // namespace range_detail
 | 
						|
 | 
						|
    namespace iterators
 | 
						|
    {
 | 
						|
    namespace detail
 | 
						|
    {
 | 
						|
        // Rationale:
 | 
						|
        // These are specialized since the iterator_facade versions lack
 | 
						|
        // the requisite typedefs to allow wrapping to determine the types
 | 
						|
        // if a user copy constructs from a postfix increment.
 | 
						|
 | 
						|
        template<
 | 
						|
            class Value
 | 
						|
          , class Traversal
 | 
						|
          , class Reference
 | 
						|
          , class Difference
 | 
						|
          , class Buffer
 | 
						|
        >
 | 
						|
        class postfix_increment_proxy<
 | 
						|
                    range_detail::any_iterator<
 | 
						|
                        Value
 | 
						|
                      , Traversal
 | 
						|
                      , Reference
 | 
						|
                      , Difference
 | 
						|
                      , Buffer
 | 
						|
                    >
 | 
						|
                >
 | 
						|
        {
 | 
						|
            typedef range_detail::any_iterator<
 | 
						|
                Value
 | 
						|
              , Traversal
 | 
						|
              , Reference
 | 
						|
              , Difference
 | 
						|
              , Buffer
 | 
						|
            > any_iterator_type;
 | 
						|
 | 
						|
        public:
 | 
						|
            typedef Value value_type;
 | 
						|
            typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
 | 
						|
            typedef Difference difference_type;
 | 
						|
            typedef typename iterator_pointer<any_iterator_type>::type pointer;
 | 
						|
            typedef Reference reference;
 | 
						|
 | 
						|
            explicit postfix_increment_proxy(any_iterator_type const& x)
 | 
						|
                : stored_value(*x)
 | 
						|
            {}
 | 
						|
 | 
						|
            value_type&
 | 
						|
            operator*() const
 | 
						|
            {
 | 
						|
                return this->stored_value;
 | 
						|
            }
 | 
						|
        private:
 | 
						|
            mutable value_type stored_value;
 | 
						|
        };
 | 
						|
 | 
						|
        template<
 | 
						|
            class Value
 | 
						|
          , class Traversal
 | 
						|
          , class Reference
 | 
						|
          , class Difference
 | 
						|
          , class Buffer
 | 
						|
        >
 | 
						|
        class writable_postfix_increment_proxy<
 | 
						|
                    range_detail::any_iterator<
 | 
						|
                        Value
 | 
						|
                      , Traversal
 | 
						|
                      , Reference
 | 
						|
                      , Difference
 | 
						|
                      , Buffer
 | 
						|
                    >
 | 
						|
                >
 | 
						|
        {
 | 
						|
            typedef range_detail::any_iterator<
 | 
						|
                        Value
 | 
						|
                      , Traversal
 | 
						|
                      , Reference
 | 
						|
                      , Difference
 | 
						|
                      , Buffer
 | 
						|
                    > any_iterator_type;
 | 
						|
         public:
 | 
						|
            typedef Value value_type;
 | 
						|
            typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
 | 
						|
            typedef Difference difference_type;
 | 
						|
            typedef typename iterator_pointer<any_iterator_type>::type pointer;
 | 
						|
            typedef Reference reference;
 | 
						|
 | 
						|
            explicit writable_postfix_increment_proxy(any_iterator_type const& x)
 | 
						|
              : stored_value(*x)
 | 
						|
              , stored_iterator(x)
 | 
						|
            {}
 | 
						|
 | 
						|
            // Dereferencing must return a proxy so that both *r++ = o and
 | 
						|
            // value_type(*r++) can work.  In this case, *r is the same as
 | 
						|
            // *r++, and the conversion operator below is used to ensure
 | 
						|
            // readability.
 | 
						|
            writable_postfix_increment_proxy const&
 | 
						|
            operator*() const
 | 
						|
            {
 | 
						|
                return *this;
 | 
						|
            }
 | 
						|
 | 
						|
            // Provides readability of *r++
 | 
						|
            operator value_type&() const
 | 
						|
            {
 | 
						|
                return stored_value;
 | 
						|
            }
 | 
						|
 | 
						|
            // Provides writability of *r++
 | 
						|
            template <class T>
 | 
						|
            T const& operator=(T const& x) const
 | 
						|
            {
 | 
						|
                *this->stored_iterator = x;
 | 
						|
                return x;
 | 
						|
            }
 | 
						|
 | 
						|
            // This overload just in case only non-const objects are writable
 | 
						|
            template <class T>
 | 
						|
            T& operator=(T& x) const
 | 
						|
            {
 | 
						|
                *this->stored_iterator = x;
 | 
						|
                return x;
 | 
						|
            }
 | 
						|
 | 
						|
            // Provides X(r++)
 | 
						|
            operator any_iterator_type const&() const
 | 
						|
            {
 | 
						|
                return stored_iterator;
 | 
						|
            }
 | 
						|
 | 
						|
         private:
 | 
						|
            mutable value_type stored_value;
 | 
						|
            any_iterator_type stored_iterator;
 | 
						|
        };
 | 
						|
 | 
						|
    } //namespace detail
 | 
						|
    } //namespace iterators
 | 
						|
 | 
						|
    namespace range_detail
 | 
						|
    {
 | 
						|
        template<
 | 
						|
            class Value
 | 
						|
          , class Traversal
 | 
						|
          , class Reference
 | 
						|
          , class Difference
 | 
						|
          , class Buffer
 | 
						|
        >
 | 
						|
        class any_iterator
 | 
						|
            : public iterator_facade<
 | 
						|
                        any_iterator<
 | 
						|
                            Value
 | 
						|
                          , Traversal
 | 
						|
                          , Reference
 | 
						|
                          , Difference
 | 
						|
                          , Buffer
 | 
						|
                        >
 | 
						|
                    , Value
 | 
						|
                    , Traversal
 | 
						|
                    , Reference
 | 
						|
                    , Difference
 | 
						|
                >
 | 
						|
        {
 | 
						|
            template<
 | 
						|
                class OtherValue
 | 
						|
              , class OtherTraversal
 | 
						|
              , class OtherReference
 | 
						|
              , class OtherDifference
 | 
						|
              , class OtherBuffer
 | 
						|
            >
 | 
						|
            friend class any_iterator;
 | 
						|
 | 
						|
            struct enabler {};
 | 
						|
            struct disabler {};
 | 
						|
 | 
						|
            typedef typename any_iterator_interface_type_generator<
 | 
						|
                Traversal
 | 
						|
              , Reference
 | 
						|
              , Difference
 | 
						|
              , Buffer
 | 
						|
            >::type abstract_base_type;
 | 
						|
 | 
						|
            typedef iterator_facade<
 | 
						|
                        any_iterator<
 | 
						|
                            Value
 | 
						|
                          , Traversal
 | 
						|
                          , Reference
 | 
						|
                          , Difference
 | 
						|
                          , Buffer
 | 
						|
                        >
 | 
						|
                      , Value
 | 
						|
                      , Traversal
 | 
						|
                      , Reference
 | 
						|
                      , Difference
 | 
						|
                  > base_type;
 | 
						|
 | 
						|
            typedef Buffer buffer_type;
 | 
						|
 | 
						|
        public:
 | 
						|
            typedef typename base_type::value_type value_type;
 | 
						|
            typedef typename base_type::reference reference;
 | 
						|
            typedef typename base_type::difference_type difference_type;
 | 
						|
 | 
						|
            // Default constructor
 | 
						|
            any_iterator()
 | 
						|
                : m_impl(0) {}
 | 
						|
 | 
						|
            // Simple copy construction without conversion
 | 
						|
            any_iterator(const any_iterator& other)
 | 
						|
                : base_type(other)
 | 
						|
                , m_impl(other.m_impl
 | 
						|
                            ? other.m_impl->clone(m_buffer)
 | 
						|
                            : 0)
 | 
						|
            {
 | 
						|
            }
 | 
						|
 | 
						|
            // Simple assignment operator without conversion
 | 
						|
            any_iterator& operator=(const any_iterator& other)
 | 
						|
            {
 | 
						|
                if (this != &other)
 | 
						|
                {
 | 
						|
                    if (m_impl)
 | 
						|
                        m_impl->~abstract_base_type();
 | 
						|
                    m_buffer.deallocate();
 | 
						|
                    m_impl = 0;
 | 
						|
                    if (other.m_impl)
 | 
						|
                        m_impl = other.m_impl->clone(m_buffer);
 | 
						|
                }
 | 
						|
                return *this;
 | 
						|
            }
 | 
						|
 | 
						|
            // Implicit conversion from another any_iterator where the
 | 
						|
            // conversion is from a non-const reference to a const reference
 | 
						|
            template<
 | 
						|
                class OtherValue
 | 
						|
              , class OtherTraversal
 | 
						|
              , class OtherReference
 | 
						|
              , class OtherDifference
 | 
						|
            >
 | 
						|
            any_iterator(const any_iterator<
 | 
						|
                                OtherValue,
 | 
						|
                                OtherTraversal,
 | 
						|
                                OtherReference,
 | 
						|
                                OtherDifference,
 | 
						|
                                Buffer
 | 
						|
                            >& other,
 | 
						|
                         typename ::boost::enable_if<
 | 
						|
                            typename mpl::and_<
 | 
						|
                                typename is_mutable_reference<OtherReference>::type,
 | 
						|
                                typename is_const_reference<Reference>::type
 | 
						|
                            >::type,
 | 
						|
                            enabler
 | 
						|
                        >::type* = 0
 | 
						|
                    )
 | 
						|
                : m_impl(other.m_impl
 | 
						|
                            ? other.m_impl->clone_const_ref(m_buffer)
 | 
						|
                         : 0
 | 
						|
                        )
 | 
						|
            {
 | 
						|
            }
 | 
						|
 | 
						|
            // Implicit conversion from another any_iterator where the
 | 
						|
            // reference types of the source and the target are references
 | 
						|
            // that are either both const, or both non-const.
 | 
						|
            template<
 | 
						|
                class OtherValue
 | 
						|
              , class OtherTraversal
 | 
						|
              , class OtherReference
 | 
						|
              , class OtherDifference
 | 
						|
            >
 | 
						|
            any_iterator(const any_iterator<
 | 
						|
                                OtherValue
 | 
						|
                              , OtherTraversal
 | 
						|
                              , OtherReference
 | 
						|
                              , OtherDifference
 | 
						|
                              , Buffer
 | 
						|
                            >& other,
 | 
						|
                         typename ::boost::enable_if<
 | 
						|
                            typename mpl::or_<
 | 
						|
                                typename mpl::and_<
 | 
						|
                                    typename is_mutable_reference<OtherReference>::type,
 | 
						|
                                    typename is_mutable_reference<Reference>::type
 | 
						|
                                >::type,
 | 
						|
                                typename mpl::and_<
 | 
						|
                                    typename is_const_reference<OtherReference>::type,
 | 
						|
                                    typename is_const_reference<Reference>::type
 | 
						|
                                >::type
 | 
						|
                            >::type,
 | 
						|
                            enabler
 | 
						|
                        >::type* = 0
 | 
						|
                        )
 | 
						|
                : m_impl(other.m_impl
 | 
						|
                            ? other.m_impl->clone(m_buffer)
 | 
						|
                         : 0
 | 
						|
                        )
 | 
						|
            {
 | 
						|
            }
 | 
						|
 | 
						|
            // Implicit conversion to an any_iterator that uses a value for
 | 
						|
            // the reference type.
 | 
						|
            template<
 | 
						|
                class OtherValue
 | 
						|
              , class OtherTraversal
 | 
						|
              , class OtherReference
 | 
						|
              , class OtherDifference
 | 
						|
            >
 | 
						|
            any_iterator(const any_iterator<
 | 
						|
                                OtherValue
 | 
						|
                              , OtherTraversal
 | 
						|
                              , OtherReference
 | 
						|
                              , OtherDifference
 | 
						|
                              , Buffer
 | 
						|
                            >& other,
 | 
						|
                        typename ::boost::enable_if<
 | 
						|
                            typename is_convertible_to_value_as_reference<
 | 
						|
                                        OtherReference
 | 
						|
                                      , Reference
 | 
						|
                                    >::type,
 | 
						|
                            enabler
 | 
						|
                        >::type* = 0
 | 
						|
                        )
 | 
						|
                : m_impl(other.m_impl
 | 
						|
                            ? other.m_impl->clone_reference_as_value(m_buffer)
 | 
						|
                            : 0
 | 
						|
                            )
 | 
						|
            {
 | 
						|
            }
 | 
						|
 | 
						|
            any_iterator clone() const
 | 
						|
            {
 | 
						|
                any_iterator result;
 | 
						|
                if (m_impl)
 | 
						|
                    result.m_impl = m_impl->clone(result.m_buffer);
 | 
						|
                return result;
 | 
						|
            }
 | 
						|
 | 
						|
            any_iterator<
 | 
						|
                Value
 | 
						|
              , Traversal
 | 
						|
              , typename abstract_base_type::const_reference
 | 
						|
              , Difference
 | 
						|
              , Buffer
 | 
						|
            >
 | 
						|
            clone_const_ref() const
 | 
						|
            {
 | 
						|
                typedef any_iterator<
 | 
						|
                    Value
 | 
						|
                  , Traversal
 | 
						|
                  , typename abstract_base_type::const_reference
 | 
						|
                  , Difference
 | 
						|
                  , Buffer
 | 
						|
                > result_type;
 | 
						|
 | 
						|
                result_type result;
 | 
						|
 | 
						|
                if (m_impl)
 | 
						|
                    result.m_impl = m_impl->clone_const_ref(result.m_buffer);
 | 
						|
 | 
						|
                return result;
 | 
						|
            }
 | 
						|
 | 
						|
            // implicit conversion and construction from type-erasure-compatible
 | 
						|
            // iterators
 | 
						|
            template<class WrappedIterator>
 | 
						|
            explicit any_iterator(
 | 
						|
                const WrappedIterator& wrapped_iterator,
 | 
						|
                typename disable_if<
 | 
						|
                    typename is_any_iterator<WrappedIterator>::type
 | 
						|
                  , disabler
 | 
						|
                >::type* = 0
 | 
						|
                )
 | 
						|
            {
 | 
						|
                typedef typename any_iterator_wrapper_type_generator<
 | 
						|
                            WrappedIterator
 | 
						|
                          , Traversal
 | 
						|
                          , Reference
 | 
						|
                          , Difference
 | 
						|
                          , Buffer
 | 
						|
                        >::type wrapper_type;
 | 
						|
 | 
						|
                void* ptr = m_buffer.allocate(sizeof(wrapper_type));
 | 
						|
                m_impl = new(ptr) wrapper_type(wrapped_iterator);
 | 
						|
            }
 | 
						|
 | 
						|
            ~any_iterator()
 | 
						|
            {
 | 
						|
                // manually run the destructor, the deallocation is automatically
 | 
						|
                // handled by the any_iterator_small_buffer base class.
 | 
						|
                if (m_impl)
 | 
						|
                    m_impl->~abstract_base_type();
 | 
						|
            }
 | 
						|
 | 
						|
        private:
 | 
						|
            friend class ::boost::iterator_core_access;
 | 
						|
 | 
						|
            Reference dereference() const
 | 
						|
            {
 | 
						|
                BOOST_ASSERT( m_impl );
 | 
						|
                return m_impl->dereference();
 | 
						|
            }
 | 
						|
 | 
						|
            bool equal(const any_iterator& other) const
 | 
						|
            {
 | 
						|
                return (m_impl == other.m_impl)
 | 
						|
                    || (m_impl && other.m_impl && m_impl->equal(*other.m_impl));
 | 
						|
            }
 | 
						|
 | 
						|
            void increment()
 | 
						|
            {
 | 
						|
                BOOST_ASSERT( m_impl );
 | 
						|
                m_impl->increment();
 | 
						|
            }
 | 
						|
 | 
						|
            void decrement()
 | 
						|
            {
 | 
						|
                BOOST_ASSERT( m_impl );
 | 
						|
                m_impl->decrement();
 | 
						|
            }
 | 
						|
 | 
						|
            Difference distance_to(const any_iterator& other) const
 | 
						|
            {
 | 
						|
                return m_impl && other.m_impl
 | 
						|
                    ? m_impl->distance_to(*other.m_impl)
 | 
						|
                    : 0;
 | 
						|
            }
 | 
						|
 | 
						|
            void advance(Difference offset)
 | 
						|
            {
 | 
						|
                BOOST_ASSERT( m_impl );
 | 
						|
                m_impl->advance(offset);
 | 
						|
            }
 | 
						|
 | 
						|
            any_iterator& swap(any_iterator& other)
 | 
						|
            {
 | 
						|
                BOOST_ASSERT( this != &other );
 | 
						|
                // grab a temporary copy of the other iterator
 | 
						|
                any_iterator tmp(other);
 | 
						|
 | 
						|
                // deallocate the other iterator, taking care to obey the
 | 
						|
                // class-invariants in-case of exceptions later
 | 
						|
                if (other.m_impl)
 | 
						|
                {
 | 
						|
                    other.m_impl->~abstract_base_type();
 | 
						|
                    other.m_buffer.deallocate();
 | 
						|
                    other.m_impl = 0;
 | 
						|
                }
 | 
						|
 | 
						|
                // If this is a non-null iterator then we need to put
 | 
						|
                // a clone of this iterators implementation into the other
 | 
						|
                // iterator.
 | 
						|
                // We can't just swap because of the small buffer optimization.
 | 
						|
                if (m_impl)
 | 
						|
                {
 | 
						|
                    other.m_impl = m_impl->clone(other.m_buffer);
 | 
						|
                    m_impl->~abstract_base_type();
 | 
						|
                    m_buffer.deallocate();
 | 
						|
                    m_impl = 0;
 | 
						|
                }
 | 
						|
 | 
						|
                // assign to this instance a clone of the temporarily held
 | 
						|
                // tmp which represents the input other parameter at the
 | 
						|
                // start of execution of this function.
 | 
						|
                if (tmp.m_impl)
 | 
						|
                    m_impl = tmp.m_impl->clone(m_buffer);
 | 
						|
 | 
						|
                return *this;
 | 
						|
            }
 | 
						|
 | 
						|
            buffer_type m_buffer;
 | 
						|
            abstract_base_type* m_impl;
 | 
						|
        };
 | 
						|
 | 
						|
    } // namespace range_detail
 | 
						|
} // namespace boost
 | 
						|
 | 
						|
#endif // include guard
 |