]> git.lyx.org Git - features.git/blobdiff - boost/boost/iterator/zip_iterator.hpp
boost: add eol property
[features.git] / boost / boost / iterator / zip_iterator.hpp
index edc7e09578c484fdeda4b156bf34648770a49fff..f3896ad955176aa7328000db280d9d7b0d72b70a 100644 (file)
-// Copyright David Abrahams and Thomas Becker 2000-2006. Distributed\r
-// under the Boost Software License, Version 1.0. (See accompanying\r
-// file LICENSE_1_0.txt or copy at\r
-// http://www.boost.org/LICENSE_1_0.txt)\r
-\r
-#ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_\r
-# define BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_\r
-\r
-#include <stddef.h>\r
-#include <boost/iterator.hpp>\r
-#include <boost/iterator/iterator_traits.hpp>\r
-#include <boost/iterator/iterator_facade.hpp>\r
-#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible\r
-#include <boost/iterator/iterator_categories.hpp>\r
-#include <boost/detail/iterator.hpp>\r
-\r
-#include <boost/iterator/detail/minimum_category.hpp>\r
-\r
-#include <boost/tuple/tuple.hpp>\r
-\r
-#include <boost/type_traits/is_same.hpp>\r
-#include <boost/mpl/and.hpp>\r
-#include <boost/mpl/apply.hpp>\r
-#include <boost/mpl/eval_if.hpp>\r
-#include <boost/mpl/lambda.hpp>\r
-#include <boost/mpl/placeholders.hpp>\r
-#include <boost/mpl/aux_/lambda_support.hpp>\r
-\r
-namespace boost {\r
-\r
-  // Zip iterator forward declaration for zip_iterator_base\r
-  template<typename IteratorTuple>\r
-  class zip_iterator;\r
-\r
-  // One important design goal of the zip_iterator is to isolate all\r
-  // functionality whose implementation relies on the current tuple\r
-  // implementation. This goal has been achieved as follows: Inside\r
-  // the namespace detail there is a namespace tuple_impl_specific.\r
-  // This namespace encapsulates all functionality that is specific\r
-  // to the current Boost tuple implementation. More precisely, the\r
-  // namespace tuple_impl_specific provides the following tuple\r
-  // algorithms and meta-algorithms for the current Boost tuple\r
-  // implementation:\r
-  //\r
-  // tuple_meta_transform\r
-  // tuple_meta_accumulate\r
-  // tuple_transform\r
-  // tuple_for_each\r
-  //\r
-  // If the tuple implementation changes, all that needs to be\r
-  // replaced is the implementation of these four (meta-)algorithms.\r
-\r
-  namespace detail\r
-  {\r
-\r
-    // Functors to be used with tuple algorithms\r
-    //\r
-    template<typename DiffType>\r
-    class advance_iterator\r
-    {\r
-    public:\r
-      advance_iterator(DiffType step) : m_step(step) {}\r
-      \r
-      template<typename Iterator>\r
-      void operator()(Iterator& it) const\r
-      { it += m_step; }\r
-\r
-    private:\r
-      DiffType m_step;\r
-    };\r
-    //\r
-    struct increment_iterator\r
-    {\r
-      template<typename Iterator>\r
-      void operator()(Iterator& it)\r
-      { ++it; }\r
-    };\r
-    //\r
-    struct decrement_iterator\r
-    {\r
-      template<typename Iterator>\r
-      void operator()(Iterator& it)\r
-      { --it; }\r
-    };\r
-    //\r
-    struct dereference_iterator\r
-    {\r
-      template<typename Iterator>\r
-      struct apply\r
-      { \r
-        typedef typename\r
-          iterator_traits<Iterator>::reference\r
-        type;\r
-      };\r
-\r
-      template<typename Iterator>\r
-        typename apply<Iterator>::type operator()(Iterator const& it)\r
-      { return *it; }\r
-    };\r
-           \r
-\r
-    // The namespace tuple_impl_specific provides two meta-\r
-    // algorithms and two algorithms for tuples.\r
-    //\r
-    namespace tuple_impl_specific\r
-    {\r
-      // Meta-transform algorithm for tuples\r
-      //\r
-      template<typename Tuple, class UnaryMetaFun>\r
-      struct tuple_meta_transform;\r
-      \r
-      template<typename Tuple, class UnaryMetaFun>\r
-      struct tuple_meta_transform_impl\r
-      {\r
-          typedef tuples::cons<\r
-              typename mpl::apply1<\r
-                  typename mpl::lambda<UnaryMetaFun>::type\r
-                , typename Tuple::head_type\r
-              >::type\r
-            , typename tuple_meta_transform<\r
-                  typename Tuple::tail_type\r
-                , UnaryMetaFun \r
-              >::type\r
-          > type;\r
-      };\r
-\r
-      template<typename Tuple, class UnaryMetaFun>\r
-      struct tuple_meta_transform\r
-        : mpl::eval_if<\r
-              boost::is_same<Tuple, tuples::null_type>\r
-            , mpl::identity<tuples::null_type>\r
-            , tuple_meta_transform_impl<Tuple, UnaryMetaFun>\r
-        >\r
-      {\r
-      };\r
-      \r
-      // Meta-accumulate algorithm for tuples. Note: The template \r
-      // parameter StartType corresponds to the initial value in \r
-      // ordinary accumulation.\r
-      //\r
-      template<class Tuple, class BinaryMetaFun, class StartType>\r
-      struct tuple_meta_accumulate;\r
-      \r
-      template<\r
-          typename Tuple\r
-        , class BinaryMetaFun\r
-        , typename StartType\r
-      >\r
-      struct tuple_meta_accumulate_impl\r
-      {\r
-         typedef typename mpl::apply2<\r
-             typename mpl::lambda<BinaryMetaFun>::type\r
-           , typename Tuple::head_type\r
-           , typename tuple_meta_accumulate<\r
-                 typename Tuple::tail_type\r
-               , BinaryMetaFun\r
-               , StartType \r
-             >::type\r
-         >::type type;\r
-      };\r
-\r
-      template<\r
-          typename Tuple\r
-        , class BinaryMetaFun\r
-        , typename StartType\r
-      >\r
-      struct tuple_meta_accumulate\r
-        : mpl::eval_if<\r
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)\r
-              mpl::or_<\r
-#endif \r
-                  boost::is_same<Tuple, tuples::null_type>\r
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)\r
-                , boost::is_same<Tuple,int>\r
-              >\r
-#endif \r
-            , mpl::identity<StartType>\r
-            , tuple_meta_accumulate_impl<\r
-                  Tuple\r
-                , BinaryMetaFun\r
-                , StartType\r
-              >\r
-          >\r
-      {\r
-      };  \r
-\r
-#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)                            \\r
-    || (                                                                    \\r
-      BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, != 0) && defined(_MSC_VER)  \\r
-    )\r
-// Not sure why intel's partial ordering fails in this case, but I'm\r
-// assuming int's an MSVC bug-compatibility feature.\r
-      \r
-# define BOOST_TUPLE_ALGO_DISPATCH\r
-# define BOOST_TUPLE_ALGO(algo) algo##_impl\r
-# define BOOST_TUPLE_ALGO_TERMINATOR , int\r
-# define BOOST_TUPLE_ALGO_RECURSE , ...\r
-#else \r
-# define BOOST_TUPLE_ALGO(algo) algo\r
-# define BOOST_TUPLE_ALGO_TERMINATOR\r
-# define BOOST_TUPLE_ALGO_RECURSE\r
-#endif\r
-      \r
-      // transform algorithm for tuples. The template parameter Fun\r
-      // must be a unary functor which is also a unary metafunction\r
-      // class that computes its return type based on its argument\r
-      // type. For example:\r
-      //\r
-      // struct to_ptr\r
-      // {\r
-      //     template <class Arg>\r
-      //     struct apply\r
-      //     {\r
-      //          typedef Arg* type;\r
-      //     }\r
-      //\r
-      //     template <class Arg>\r
-      //     Arg* operator()(Arg x);\r
-      // };\r
-      template<typename Fun>\r
-      tuples::null_type BOOST_TUPLE_ALGO(tuple_transform)\r
-          (tuples::null_type const&, Fun BOOST_TUPLE_ALGO_TERMINATOR)\r
-      { return tuples::null_type(); }\r
-\r
-      template<typename Tuple, typename Fun>\r
-      typename tuple_meta_transform<\r
-          Tuple\r
-        , Fun\r
-      >::type\r
-      \r
-      BOOST_TUPLE_ALGO(tuple_transform)(\r
-        const Tuple& t, \r
-        Fun f\r
-        BOOST_TUPLE_ALGO_RECURSE\r
-      )\r
-      { \r
-          typedef typename tuple_meta_transform<\r
-              BOOST_DEDUCED_TYPENAME Tuple::tail_type\r
-            , Fun\r
-          >::type transformed_tail_type;\r
-\r
-        return tuples::cons<\r
-            BOOST_DEDUCED_TYPENAME mpl::apply1<\r
-                Fun, BOOST_DEDUCED_TYPENAME Tuple::head_type\r
-             >::type\r
-           , transformed_tail_type\r
-        >( \r
-            f(boost::tuples::get<0>(t)), tuple_transform(t.get_tail(), f)\r
-        );\r
-      }\r
-\r
-#ifdef BOOST_TUPLE_ALGO_DISPATCH\r
-      template<typename Tuple, typename Fun>\r
-      typename tuple_meta_transform<\r
-          Tuple\r
-        , Fun\r
-      >::type\r
-      \r
-      tuple_transform(\r
-        const Tuple& t, \r
-        Fun f\r
-      )\r
-      {\r
-          return tuple_transform_impl(t, f, 1);\r
-      }\r
-#endif\r
-      \r
-      // for_each algorithm for tuples.\r
-      //\r
-      template<typename Fun>\r
-      Fun BOOST_TUPLE_ALGO(tuple_for_each)(\r
-          tuples::null_type\r
-        , Fun f BOOST_TUPLE_ALGO_TERMINATOR\r
-      )\r
-      { return f; }\r
-\r
-      \r
-      template<typename Tuple, typename Fun>\r
-      Fun BOOST_TUPLE_ALGO(tuple_for_each)(\r
-          Tuple& t\r
-        , Fun f BOOST_TUPLE_ALGO_RECURSE)\r
-      { \r
-          f( t.get_head() );\r
-          return tuple_for_each(t.get_tail(), f);\r
-      }\r
-      \r
-#ifdef BOOST_TUPLE_ALGO_DISPATCH\r
-      template<typename Tuple, typename Fun>\r
-      Fun\r
-      tuple_for_each(\r
-        Tuple& t, \r
-        Fun f\r
-      )\r
-      {\r
-          return tuple_for_each_impl(t, f, 1);\r
-      }\r
-#endif\r
-      \r
-      // Equality of tuples. NOTE: "==" for tuples currently (7/2003)\r
-      // has problems under some compilers, so I just do my own.\r
-      // No point in bringing in a bunch of #ifdefs here. This is\r
-      // going to go away with the next tuple implementation anyway.\r
-      //\r
-      inline bool tuple_equal(tuples::null_type, tuples::null_type)\r
-      { return true; }\r
-\r
-      template<typename Tuple1, typename Tuple2>\r
-        bool tuple_equal(\r
-            Tuple1 const& t1, \r
-            Tuple2 const& t2\r
-        )\r
-      { \r
-          return t1.get_head() == t2.get_head() && \r
-          tuple_equal(t1.get_tail(), t2.get_tail());\r
-      }\r
-    }\r
-    //\r
-    // end namespace tuple_impl_specific\r
-\r
-    template<typename Iterator>\r
-    struct iterator_reference\r
-    {\r
-        typedef typename iterator_traits<Iterator>::reference type;\r
-    };\r
-\r
-#ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT\r
-    // Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work\r
-    // out well.  Instantiating the nested apply template also\r
-    // requires instantiating iterator_traits on the\r
-    // placeholder. Instead we just specialize it as a metafunction\r
-    // class.\r
-    template<>\r
-    struct iterator_reference<mpl::_1>\r
-    {\r
-        template <class T>\r
-        struct apply : iterator_reference<T> {};\r
-    };\r
-#endif\r
-    \r
-    // Metafunction to obtain the type of the tuple whose element types\r
-    // are the reference types of an iterator tuple.\r
-    //\r
-    template<typename IteratorTuple>\r
-    struct tuple_of_references\r
-      : tuple_impl_specific::tuple_meta_transform<\r
-            IteratorTuple, \r
-            iterator_reference<mpl::_1>\r
-          >\r
-    {\r
-    };\r
-\r
-    // Metafunction to obtain the minimal traversal tag in a tuple\r
-    // of iterators.\r
-    //\r
-    template<typename IteratorTuple>\r
-    struct minimum_traversal_category_in_iterator_tuple\r
-    {\r
-      typedef typename tuple_impl_specific::tuple_meta_transform<\r
-          IteratorTuple\r
-        , iterator_traversal<>\r
-      >::type tuple_of_traversal_tags;\r
-          \r
-      typedef typename tuple_impl_specific::tuple_meta_accumulate<\r
-          tuple_of_traversal_tags\r
-        , minimum_category<>\r
-        , random_access_traversal_tag\r
-      >::type type;\r
-    };\r
-\r
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround\r
-      template <>\r
-      struct minimum_traversal_category_in_iterator_tuple<int>\r
-      {\r
-          typedef int type;\r
-      };\r
-#endif\r
-      \r
-      // We need to call tuple_meta_accumulate with mpl::and_ as the\r
-      // accumulating functor. To this end, we need to wrap it into\r
-      // a struct that has exactly two arguments (that is, template\r
-      // parameters) and not five, like mpl::and_ does.\r
-      //\r
-      template<typename Arg1, typename Arg2>\r
-      struct and_with_two_args\r
-        : mpl::and_<Arg1, Arg2>\r
-      {\r
-      };\r
-    \r
-# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT\r
-  // Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work\r
-  // out well.  In this case I think it's an MPL bug\r
-      template<>\r
-      struct and_with_two_args<mpl::_1,mpl::_2>\r
-      {\r
-          template <class A1, class A2>\r
-          struct apply : mpl::and_<A1,A2>\r
-          {};\r
-      };\r
-# endif \r
-\r
-    ///////////////////////////////////////////////////////////////////\r
-    //\r
-    // Class zip_iterator_base\r
-    //\r
-    // Builds and exposes the iterator facade type from which the zip \r
-    // iterator will be derived.\r
-    //\r
-    template<typename IteratorTuple>\r
-    struct zip_iterator_base\r
-    {\r
-     private:\r
-        // Reference type is the type of the tuple obtained from the\r
-        // iterators' reference types.\r
-        typedef typename \r
-        detail::tuple_of_references<IteratorTuple>::type reference;\r
-      \r
-        // Value type is the same as reference type.\r
-        typedef reference value_type;\r
-      \r
-        // Difference type is the first iterator's difference type\r
-        typedef typename iterator_traits<\r
-            typename tuples::element<0, IteratorTuple>::type\r
-            >::difference_type difference_type;\r
-      \r
-        // Traversal catetgory is the minimum traversal category in the \r
-        // iterator tuple.\r
-        typedef typename \r
-        detail::minimum_traversal_category_in_iterator_tuple<\r
-            IteratorTuple\r
-        >::type traversal_category;\r
-     public:\r
-      \r
-        // The iterator facade type from which the zip iterator will\r
-        // be derived.\r
-        typedef iterator_facade<\r
-            zip_iterator<IteratorTuple>,\r
-            value_type,  \r
-            traversal_category,\r
-            reference,\r
-            difference_type\r
-        > type;\r
-    };\r
-\r
-    template <>\r
-    struct zip_iterator_base<int>\r
-    {\r
-        typedef int type;\r
-    };\r
-  }\r
-  \r
-  /////////////////////////////////////////////////////////////////////\r
-  //\r
-  // zip_iterator class definition\r
-  //\r
-  template<typename IteratorTuple>\r
-  class zip_iterator : \r
-    public detail::zip_iterator_base<IteratorTuple>::type\r
-  {  \r
-\r
-   // Typedef super_t as our base class. \r
-   typedef typename \r
-     detail::zip_iterator_base<IteratorTuple>::type super_t;\r
-\r
-   // iterator_core_access is the iterator's best friend.\r
-   friend class iterator_core_access;\r
-\r
-  public:\r
-    \r
-    // Construction\r
-    // ============\r
-    \r
-    // Default constructor\r
-    zip_iterator() { }\r
-\r
-    // Constructor from iterator tuple\r
-    zip_iterator(IteratorTuple iterator_tuple) \r
-      : m_iterator_tuple(iterator_tuple) \r
-    { }\r
-\r
-    // Copy constructor\r
-    template<typename OtherIteratorTuple>\r
-    zip_iterator(\r
-       const zip_iterator<OtherIteratorTuple>& other,\r
-       typename enable_if_convertible<\r
-         OtherIteratorTuple,\r
-         IteratorTuple\r
-         >::type* = 0\r
-    ) : m_iterator_tuple(other.get_iterator_tuple())\r
-    {}\r
-\r
-    // Get method for the iterator tuple.\r
-    const IteratorTuple& get_iterator_tuple() const\r
-    { return m_iterator_tuple; }\r
-\r
-  private:\r
-    \r
-    // Implementation of Iterator Operations\r
-    // =====================================\r
-    \r
-    // Dereferencing returns a tuple built from the dereferenced\r
-    // iterators in the iterator tuple.\r
-    typename super_t::reference dereference() const\r
-    { \r
-      return detail::tuple_impl_specific::tuple_transform( \r
-        get_iterator_tuple(),\r
-        detail::dereference_iterator()\r
-       );\r
-    }\r
-\r
-    // Two zip iterators are equal if all iterators in the iterator\r
-    // tuple are equal. NOTE: It should be possible to implement this\r
-    // as\r
-    //\r
-    // return get_iterator_tuple() == other.get_iterator_tuple();\r
-    //\r
-    // but equality of tuples currently (7/2003) does not compile\r
-    // under several compilers. No point in bringing in a bunch\r
-    // of #ifdefs here.\r
-    //\r
-    template<typename OtherIteratorTuple>   \r
-    bool equal(const zip_iterator<OtherIteratorTuple>& other) const\r
-    {\r
-      return detail::tuple_impl_specific::tuple_equal(\r
-        get_iterator_tuple(),\r
-        other.get_iterator_tuple()\r
-        );\r
-    }\r
-\r
-    // Advancing a zip iterator means to advance all iterators in the\r
-    // iterator tuple.\r
-    void advance(typename super_t::difference_type n)\r
-    { \r
-      detail::tuple_impl_specific::tuple_for_each(\r
-          m_iterator_tuple,\r
-          detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n)\r
-          );\r
-    }\r
-    // Incrementing a zip iterator means to increment all iterators in\r
-    // the iterator tuple.\r
-    void increment()\r
-    { \r
-      detail::tuple_impl_specific::tuple_for_each(\r
-        m_iterator_tuple,\r
-        detail::increment_iterator()\r
-        );\r
-    }\r
-    \r
-    // Decrementing a zip iterator means to decrement all iterators in\r
-    // the iterator tuple.\r
-    void decrement()\r
-    { \r
-      detail::tuple_impl_specific::tuple_for_each(\r
-        m_iterator_tuple,\r
-        detail::decrement_iterator()\r
-        );\r
-    }\r
-    \r
-    // Distance is calculated using the first iterator in the tuple.\r
-    template<typename OtherIteratorTuple>\r
-      typename super_t::difference_type distance_to(\r
-        const zip_iterator<OtherIteratorTuple>& other\r
-        ) const\r
-    { \r
-        return boost::tuples::get<0>(other.get_iterator_tuple()) - \r
-            boost::tuples::get<0>(this->get_iterator_tuple());\r
-    }\r
-  \r
-    // Data Members\r
-    // ============\r
-    \r
-    // The iterator tuple.\r
-    IteratorTuple m_iterator_tuple;\r
\r
-  };\r
-\r
-  // Make function for zip iterator\r
-  //\r
-  template<typename IteratorTuple> \r
-  zip_iterator<IteratorTuple> \r
-  make_zip_iterator(IteratorTuple t)\r
-  { return zip_iterator<IteratorTuple>(t); }\r
-\r
-}\r
-\r
-#endif\r
+// 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
+      )
+      {
+          return tuple_for_each_impl(t, f, 1);
+      }
+#endif
+      
+      // Equality of tuples. NOTE: "==" for tuples currently (7/2003)
+      // has problems under some compilers, so I just do my own.
+      // No point in bringing in a bunch of #ifdefs here. This is
+      // going to go away with the next tuple implementation anyway.
+      //
+      inline bool tuple_equal(tuples::null_type, tuples::null_type)
+      { return true; }
+
+      template<typename Tuple1, typename Tuple2>
+        bool tuple_equal(
+            Tuple1 const& t1, 
+            Tuple2 const& t2
+        )
+      { 
+          return t1.get_head() == t2.get_head() && 
+          tuple_equal(t1.get_tail(), t2.get_tail());
+      }
+    }
+    //
+    // end namespace tuple_impl_specific
+
+    template<typename Iterator>
+    struct iterator_reference
+    {
+        typedef typename iterator_traits<Iterator>::reference type;
+    };
+
+#ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
+    // Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
+    // out well.  Instantiating the nested apply template also
+    // requires instantiating iterator_traits on the
+    // placeholder. Instead we just specialize it as a metafunction
+    // class.
+    template<>
+    struct iterator_reference<mpl::_1>
+    {
+        template <class T>
+        struct apply : iterator_reference<T> {};
+    };
+#endif
+    
+    // Metafunction to obtain the type of the tuple whose element types
+    // are the reference types of an iterator tuple.
+    //
+    template<typename IteratorTuple>
+    struct tuple_of_references
+      : tuple_impl_specific::tuple_meta_transform<
+            IteratorTuple, 
+            iterator_reference<mpl::_1>
+          >
+    {
+    };
+
+    // Metafunction to obtain the minimal traversal tag in a tuple
+    // of iterators.
+    //
+    template<typename IteratorTuple>
+    struct minimum_traversal_category_in_iterator_tuple
+    {
+      typedef typename tuple_impl_specific::tuple_meta_transform<
+          IteratorTuple
+        , iterator_traversal<>
+      >::type tuple_of_traversal_tags;
+          
+      typedef typename tuple_impl_specific::tuple_meta_accumulate<
+          tuple_of_traversal_tags
+        , minimum_category<>
+        , random_access_traversal_tag
+      >::type type;
+    };
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
+      template <>
+      struct minimum_traversal_category_in_iterator_tuple<int>
+      {
+          typedef int type;
+      };
+#endif
+      
+      // We need to call tuple_meta_accumulate with mpl::and_ as the
+      // accumulating functor. To this end, we need to wrap it into
+      // a struct that has exactly two arguments (that is, template
+      // parameters) and not five, like mpl::and_ does.
+      //
+      template<typename Arg1, typename Arg2>
+      struct and_with_two_args
+        : mpl::and_<Arg1, Arg2>
+      {
+      };
+    
+# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
+  // Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
+  // out well.  In this case I think it's an MPL bug
+      template<>
+      struct and_with_two_args<mpl::_1,mpl::_2>
+      {
+          template <class A1, class A2>
+          struct apply : mpl::and_<A1,A2>
+          {};
+      };
+# endif 
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // Class zip_iterator_base
+    //
+    // Builds and exposes the iterator facade type from which the zip 
+    // iterator will be derived.
+    //
+    template<typename IteratorTuple>
+    struct zip_iterator_base
+    {
+     private:
+        // Reference type is the type of the tuple obtained from the
+        // iterators' reference types.
+        typedef typename 
+        detail::tuple_of_references<IteratorTuple>::type reference;
+      
+        // Value type is the same as reference type.
+        typedef reference value_type;
+      
+        // Difference type is the first iterator's difference type
+        typedef typename iterator_traits<
+            typename tuples::element<0, IteratorTuple>::type
+            >::difference_type difference_type;
+      
+        // Traversal catetgory is the minimum traversal category in the 
+        // iterator tuple.
+        typedef typename 
+        detail::minimum_traversal_category_in_iterator_tuple<
+            IteratorTuple
+        >::type traversal_category;
+     public:
+      
+        // The iterator facade type from which the zip iterator will
+        // be derived.
+        typedef iterator_facade<
+            zip_iterator<IteratorTuple>,
+            value_type,  
+            traversal_category,
+            reference,
+            difference_type
+        > type;
+    };
+
+    template <>
+    struct zip_iterator_base<int>
+    {
+        typedef int type;
+    };
+  }
+  
+  /////////////////////////////////////////////////////////////////////
+  //
+  // zip_iterator class definition
+  //
+  template<typename IteratorTuple>
+  class zip_iterator : 
+    public detail::zip_iterator_base<IteratorTuple>::type
+  {  
+
+   // Typedef super_t as our base class. 
+   typedef typename 
+     detail::zip_iterator_base<IteratorTuple>::type super_t;
+
+   // iterator_core_access is the iterator's best friend.
+   friend class iterator_core_access;
+
+  public:
+    
+    // Construction
+    // ============
+    
+    // Default constructor
+    zip_iterator() { }
+
+    // Constructor from iterator tuple
+    zip_iterator(IteratorTuple iterator_tuple) 
+      : m_iterator_tuple(iterator_tuple) 
+    { }
+
+    // Copy constructor
+    template<typename OtherIteratorTuple>
+    zip_iterator(
+       const zip_iterator<OtherIteratorTuple>& other,
+       typename enable_if_convertible<
+         OtherIteratorTuple,
+         IteratorTuple
+         >::type* = 0
+    ) : m_iterator_tuple(other.get_iterator_tuple())
+    {}
+
+    // Get method for the iterator tuple.
+    const IteratorTuple& get_iterator_tuple() const
+    { return m_iterator_tuple; }
+
+  private:
+    
+    // Implementation of Iterator Operations
+    // =====================================
+    
+    // Dereferencing returns a tuple built from the dereferenced
+    // iterators in the iterator tuple.
+    typename super_t::reference dereference() const
+    { 
+      return detail::tuple_impl_specific::tuple_transform( 
+        get_iterator_tuple(),
+        detail::dereference_iterator()
+       );
+    }
+
+    // Two zip iterators are equal if all iterators in the iterator
+    // tuple are equal. NOTE: It should be possible to implement this
+    // as
+    //
+    // return get_iterator_tuple() == other.get_iterator_tuple();
+    //
+    // but equality of tuples currently (7/2003) does not compile
+    // under several compilers. No point in bringing in a bunch
+    // of #ifdefs here.
+    //
+    template<typename OtherIteratorTuple>   
+    bool equal(const zip_iterator<OtherIteratorTuple>& other) const
+    {
+      return detail::tuple_impl_specific::tuple_equal(
+        get_iterator_tuple(),
+        other.get_iterator_tuple()
+        );
+    }
+
+    // Advancing a zip iterator means to advance all iterators in the
+    // iterator tuple.
+    void advance(typename super_t::difference_type n)
+    { 
+      detail::tuple_impl_specific::tuple_for_each(
+          m_iterator_tuple,
+          detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n)
+          );
+    }
+    // Incrementing a zip iterator means to increment all iterators in
+    // the iterator tuple.
+    void increment()
+    { 
+      detail::tuple_impl_specific::tuple_for_each(
+        m_iterator_tuple,
+        detail::increment_iterator()
+        );
+    }
+    
+    // Decrementing a zip iterator means to decrement all iterators in
+    // the iterator tuple.
+    void decrement()
+    { 
+      detail::tuple_impl_specific::tuple_for_each(
+        m_iterator_tuple,
+        detail::decrement_iterator()
+        );
+    }
+    
+    // Distance is calculated using the first iterator in the tuple.
+    template<typename OtherIteratorTuple>
+      typename super_t::difference_type distance_to(
+        const zip_iterator<OtherIteratorTuple>& other
+        ) const
+    { 
+        return boost::tuples::get<0>(other.get_iterator_tuple()) - 
+            boost::tuples::get<0>(this->get_iterator_tuple());
+    }
+  
+    // Data Members
+    // ============
+    
+    // The iterator tuple.
+    IteratorTuple m_iterator_tuple;
+  };
+
+  // Make function for zip iterator
+  //
+  template<typename IteratorTuple> 
+  zip_iterator<IteratorTuple> 
+  make_zip_iterator(IteratorTuple t)
+  { return zip_iterator<IteratorTuple>(t); }
+
+}
+
+#endif