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 + -
显示快捷键?