zip_iterator.hpp

来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 600 行 · 第 1/2 页

HPP
600
字号
// (C) Copyright David Abrahams and Thomas Becker 2000. 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.//// Compilers Tested:// =================// Metrowerks Codewarrior Pro 7.2, 8.3// gcc 2.95.3// gcc 3.2// Microsoft VC 6sp5 (test fails due to some compiler bug)// Microsoft VC 7 (works)// Microsoft VC 7.1// Intel 5// Intel 6// Intel 7.1// Intel 8// Borland 5.5.1 (broken due to lack of support from Boost.Tuples)#ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_#include <stddef.h>#include <boost/iterator.hpp>#include <boost/iterator/iterator_traits.hpp>#include <boost/iterator/iterator_facade.hpp>#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible#include <boost/iterator/iterator_categories.hpp>#include <boost/detail/iterator.hpp>#include <boost/iterator/detail/minimum_category.hpp>#include <boost/tuple/tuple.hpp>#include <boost/type_traits/is_same.hpp>#include <boost/mpl/and.hpp>#include <boost/mpl/apply.hpp>#include <boost/mpl/eval_if.hpp>#include <boost/mpl/lambda.hpp>#include <boost/mpl/placeholders.hpp>#include <boost/mpl/aux_/lambda_support.hpp>namespace boost {  // Zip iterator forward declaration for zip_iterator_base  template<typename IteratorTuple>  class zip_iterator;  // One important design goal of the zip_iterator is to isolate all  // functionality whose implementation relies on the current tuple  // implementation. This goal has been achieved as follows: Inside  // the namespace detail there is a namespace tuple_impl_specific.  // This namespace encapsulates all functionality that is specific  // to the current Boost tuple implementation. More precisely, the  // namespace tuple_impl_specific provides the following tuple  // algorithms and meta-algorithms for the current Boost tuple  // implementation:  //  // tuple_meta_transform  // tuple_meta_accumulate  // tuple_transform  // tuple_for_each  //  // If the tuple implementation changes, all that needs to be  // replaced is the implementation of these four (meta-)algorithms.  namespace detail  {    // Functors to be used with tuple algorithms    //    template<typename DiffType>    class advance_iterator    {    public:      advance_iterator(DiffType step) : m_step(step) {}            template<typename Iterator>      void operator()(Iterator& it) const      { it += m_step; }    private:      DiffType m_step;    };    //    struct increment_iterator    {      template<typename Iterator>      void operator()(Iterator& it)      { ++it; }    };    //    struct decrement_iterator    {      template<typename Iterator>      void operator()(Iterator& it)      { --it; }    };    //    struct dereference_iterator    {      template<typename Iterator>      struct apply      {         typedef typename          iterator_traits<Iterator>::reference        type;      };      template<typename Iterator>        typename apply<Iterator>::type operator()(Iterator const& it)      { return *it; }    };               // The namespace tuple_impl_specific provides two meta-    // algorithms and two algorithms for tuples.    //    namespace tuple_impl_specific    {      // Meta-transform algorithm for tuples      //      template<typename Tuple, class UnaryMetaFun>      struct tuple_meta_transform;            template<typename Tuple, class UnaryMetaFun>      struct tuple_meta_transform_impl      {          typedef tuples::cons<              typename mpl::apply1<                  typename mpl::lambda<UnaryMetaFun>::type                , typename Tuple::head_type              >::type            , typename tuple_meta_transform<                  typename Tuple::tail_type                , UnaryMetaFun               >::type          > type;      };      template<typename Tuple, class UnaryMetaFun>      struct tuple_meta_transform        : mpl::eval_if<              boost::is_same<Tuple, tuples::null_type>            , mpl::identity<tuples::null_type>            , tuple_meta_transform_impl<Tuple, UnaryMetaFun>        >      {      };            // Meta-accumulate algorithm for tuples. Note: The template       // parameter StartType corresponds to the initial value in       // ordinary accumulation.      //      template<class Tuple, class BinaryMetaFun, class StartType>      struct tuple_meta_accumulate;            template<          typename Tuple        , class BinaryMetaFun        , typename StartType      >      struct tuple_meta_accumulate_impl      {         typedef typename mpl::apply2<             typename mpl::lambda<BinaryMetaFun>::type           , typename Tuple::head_type           , typename tuple_meta_accumulate<                 typename Tuple::tail_type               , BinaryMetaFun               , StartType              >::type         >::type type;      };      template<          typename Tuple        , class BinaryMetaFun        , typename StartType      >      struct tuple_meta_accumulate        : mpl::eval_if<#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)              mpl::or_<#endif                   boost::is_same<Tuple, tuples::null_type>#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)                , boost::is_same<Tuple,int>              >#endif             , mpl::identity<StartType>            , tuple_meta_accumulate_impl<                  Tuple                , BinaryMetaFun                , StartType              >          >      {      };  #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)                            \    || (                                                                    \      BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, != 0) && defined(_MSC_VER)  \    )// Not sure why intel's partial ordering fails in this case, but I'm// assuming int's an MSVC bug-compatibility feature.      # define BOOST_TUPLE_ALGO_DISPATCH# define BOOST_TUPLE_ALGO(algo) algo##_impl# define BOOST_TUPLE_ALGO_TERMINATOR , int# define BOOST_TUPLE_ALGO_RECURSE , ...#else # define BOOST_TUPLE_ALGO(algo) algo# define BOOST_TUPLE_ALGO_TERMINATOR# define BOOST_TUPLE_ALGO_RECURSE#endif            // transform algorithm for tuples. The template parameter Fun      // must be a unary functor which is also a unary metafunction      // class that computes its return type based on its argument      // type. For example:      //      // struct to_ptr      // {      //     template <class Arg>      //     struct apply      //     {      //          typedef Arg* type;      //     }      //      //     template <class Arg>      //     Arg* operator()(Arg x);      // };      template<typename Fun>      tuples::null_type BOOST_TUPLE_ALGO(tuple_transform)          (tuples::null_type const&, Fun BOOST_TUPLE_ALGO_TERMINATOR)      { return tuples::null_type(); }      template<typename Tuple, typename Fun>      typename tuple_meta_transform<          Tuple        , Fun      >::type            BOOST_TUPLE_ALGO(tuple_transform)(        const Tuple& t,         Fun f        BOOST_TUPLE_ALGO_RECURSE      )      {           typedef typename tuple_meta_transform<              BOOST_DEDUCED_TYPENAME Tuple::tail_type            , Fun          >::type transformed_tail_type;        return tuples::cons<            BOOST_DEDUCED_TYPENAME mpl::apply1<                Fun, BOOST_DEDUCED_TYPENAME Tuple::head_type             >::type           , transformed_tail_type        >(             f(boost::tuples::get<0>(t)), tuple_transform(t.get_tail(), f)        );      }#ifdef BOOST_TUPLE_ALGO_DISPATCH      template<typename Tuple, typename Fun>      typename tuple_meta_transform<          Tuple        , Fun      >::type            tuple_transform(        const Tuple& t,         Fun f      )      {          return tuple_transform_impl(t, f, 1);      }#endif            // for_each algorithm for tuples.      //      template<typename Fun>      Fun BOOST_TUPLE_ALGO(tuple_for_each)(          tuples::null_type        , Fun f BOOST_TUPLE_ALGO_TERMINATOR      )      { return f; }            template<typename Tuple, typename Fun>      Fun BOOST_TUPLE_ALGO(tuple_for_each)(          Tuple& t        , Fun f BOOST_TUPLE_ALGO_RECURSE)      {           f( t.get_head() );          return tuple_for_each(t.get_tail(), f);      }      

⌨️ 快捷键说明

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