iterator_adaptor.hpp

来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 365 行

HPP
365
字号
// (C) Copyright David Abrahams 2002.// (C) Copyright Jeremy Siek    2002.// (C) Copyright Thomas Witt    2002.// Distributed under 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)#ifndef BOOST_ITERATOR_ADAPTOR_23022003THW_HPP#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP#include <boost/static_assert.hpp>#include <boost/iterator.hpp>#include <boost/detail/iterator.hpp>#include <boost/iterator/iterator_categories.hpp>#include <boost/iterator/iterator_facade.hpp>#include <boost/iterator/detail/enable_if.hpp>#include <boost/mpl/and.hpp>#include <boost/mpl/not.hpp>#include <boost/mpl/or.hpp>#include <boost/type_traits/is_same.hpp>#include <boost/type_traits/is_convertible.hpp>#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY# include <boost/type_traits/remove_reference.hpp>#else # include <boost/type_traits/add_reference.hpp>#endif #include <boost/iterator/detail/config_def.hpp>#include <boost/iterator/iterator_traits.hpp>namespace boost{  // Used as a default template argument internally, merely to  // indicate "use the default", this can also be passed by users  // explicitly in order to specify that the default should be used.  struct use_default;  # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION  // the incompleteness of use_default causes massive problems for  // is_convertible (naturally).  This workaround is fortunately not  // needed for vc6/vc7.  template<class To>  struct is_convertible<use_default,To>    : mpl::false_ {};# endif     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 BaseIterator>  // class adapted_iterator :  //   public iterator_adaptor< adapted_iterator<Iterator>, Iterator >  // {  // public:  //     //   ...  //  //   template <class OtherIterator>  //   adapted_iterator(  //       OtherIterator const& it  //     , typename enable_if_convertible<OtherIterator, Iterator>::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 BOOST_WORKAROUND(BOOST_MSVC, <= 1300)    template<typename From, typename To>  struct enable_if_convertible  {     typedef typename mpl::if_<         mpl::or_<             is_same<From,To>           , is_convertible<From, To>         >      , detail::enable_type      , int&     >::type type;  };  #  elif defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)    template <class From, class To>  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<typename From, typename To>  struct enable_if_convertible    : iterators::enable_if<        mpl::or_<            is_same<From,To>          , is_convertible<From, To>        >      , detail::enable_type    >  {};  #  else     template<typename From, typename To>  struct enable_if_convertible    : iterators::enable_if<          is_convertible<From, To>        , 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 <class T, class DefaultNullaryFn>    struct ia_dflt_help      : mpl::eval_if<            is_same<T, use_default>          , DefaultNullaryFn          , mpl::identity<T>        >    {    };    // A metafunction which computes an iterator_adaptor's base class,    // a specialization of iterator_facade.    template <        class Derived      , class Base      , class Value      , class Traversal      , class Reference      , class Difference    >    struct iterator_adaptor_base    {        typedef iterator_facade<            Derived            # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY          , typename detail::ia_dflt_help<                Value              , mpl::eval_if<                    is_same<Reference,use_default>                  , iterator_value<Base>                  , remove_reference<Reference>                >            >::type# else          , typename detail::ia_dflt_help<                Value, iterator_value<Base>            >::type# endif                      , typename detail::ia_dflt_help<                Traversal              , iterator_traversal<Base>            >::type          , typename detail::ia_dflt_help<                Reference              , mpl::eval_if<                    is_same<Value,use_default>                  , iterator_reference<Base>                  , add_reference<Value>                >            >::type          , typename detail::ia_dflt_help<                Difference, iterator_difference<Base>            >::type        >        type;    };      // workaround for aC++ CR JAGaf33512    template <class Tr1, class Tr2>    inline void iterator_adaptor_assert_traversal ()    {      BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value));    }  }    //  // 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<Base>::value_type is used  //  //   Category - the traversal category of the resulting iterator. If not  //      supplied, iterator_traversal<Base>::type 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<Base>::reference is used.  //  //   Difference - the difference_type of the resulting iterator. If not  //      supplied, iterator_traits<Base>::difference_type is used.  //  template <      class Derived    , class Base    , class Value        = use_default    , class Traversal    = use_default    , class Reference    = use_default    , class Difference   = use_default  >  class iterator_adaptor    : public detail::iterator_adaptor_base<        Derived, Base, Value, Traversal, Reference, Difference      >::type  {      friend class iterator_core_access;   protected:      typedef typename detail::iterator_adaptor_base<          Derived, Base, Value, Traversal, Reference, Difference      >::type super_t;   public:      iterator_adaptor() {}      explicit iterator_adaptor(Base const &iter)          : m_iterator(iter)      {      }      Base const& base() const        { return m_iterator; }   protected:      // for convenience in derived classes      typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;            //      // 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<OtherDerived, OtherIterator, V, C, R, D> const& x) const      {        // Maybe readd with same_distance        //           BOOST_STATIC_ASSERT(        //               (detail::same_category_and_difference<Derived,OtherDerived>::value)        //               );          return m_iterator == x.base();      }      typedef typename iterator_category_to_traversal<          typename super_t::iterator_category      >::type my_traversal;# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \      detail::iterator_adaptor_assert_traversal<my_traversal, cat>();      void advance(typename super_t::difference_type n)      {          BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)          m_iterator += n;      }        void increment() { ++m_iterator; }      void decrement()       {          BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)           --m_iterator;      }      template <          class OtherDerived, class OtherIterator, class V, class C, class R, class D      >         typename super_t::difference_type distance_to(          iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const      {          BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)          // Maybe readd with same_distance          //           BOOST_STATIC_ASSERT(          //               (detail::same_category_and_difference<Derived,OtherDerived>::value)          //               );          return y.base() - m_iterator;      }# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL         private: // data members      Base m_iterator;  };} // namespace boost#include <boost/iterator/detail/config_undef.hpp>#endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?