zip_iterator.hpp

来自「support vector clustering for vc++」· HPP 代码 · 共 586 行 · 第 1/2 页

HPP
586
字号
// Copyright David Abrahams and Thomas Becker 2000-2006. 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_ZIP_ITERATOR_TMB_07_13_2003_HPP_
# define 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, < 1300)
              mpl::or_<
#endif 
                  boost::is_same<Tuple, tuples::null_type>
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
                , 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);
      }
      
#ifdef BOOST_TUPLE_ALGO_DISPATCH
      template<typename Tuple, typename Fun>
      Fun
      tuple_for_each(
        Tuple& t, 
        Fun f
      )

⌨️ 快捷键说明

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