From acf9b4d4cfceb6d81fc8c6d30aa26afcc6ed9738 Mon Sep 17 00:00:00 2001 From: Kohei Takahashi Date: Wed, 17 Oct 2012 18:09:08 +0900 Subject: [PATCH 1/5] Reimplement zip_iterator based on Boost.Fusion By default, backward compatibility for Boost.Tuple is presented. Signed-off-by: Kohei Takahashi --- include/boost/iterator/zip_iterator.hpp | 441 +++++------------------- 1 file changed, 94 insertions(+), 347 deletions(-) diff --git a/include/boost/iterator/zip_iterator.hpp b/include/boost/iterator/zip_iterator.hpp index a468070..497ba7d 100644 --- a/include/boost/iterator/zip_iterator.hpp +++ b/include/boost/iterator/zip_iterator.hpp @@ -1,6 +1,8 @@ -// 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 +// Copyright David Abrahams and Thomas Becker 2000-2006. +// Copyright Kohei Takahashi 2012-2014. +// +// 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_ @@ -16,40 +18,30 @@ #include -#include +#include // for backward compatibility -#include -#include -#include -#include -#include +#include +#include + +#include +#include +#include #include #include +#include +#include +#include +#include +#include +#include + namespace boost { // Zip iterator forward declaration for zip_iterator_base template 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 { @@ -60,7 +52,7 @@ namespace boost { { public: advance_iterator(DiffType step) : m_step(step) {} - + template void operator()(Iterator& it) const { it += m_step; } @@ -72,250 +64,39 @@ namespace boost { struct increment_iterator { template - void operator()(Iterator& it) + void operator()(Iterator& it) const { ++it; } }; // struct decrement_iterator { template - void operator()(Iterator& it) + void operator()(Iterator& it) const { --it; } }; // struct dereference_iterator { - template - struct apply - { + template + struct result; + + template + struct result + { typedef typename - iterator_traits::reference + remove_reference::type>::type + iterator; + + typedef typename + iterator_traits::reference type; }; template - typename apply::type operator()(Iterator const& it) + typename result::type + operator()(Iterator const& it) const { 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 - struct tuple_meta_transform; - - template - struct tuple_meta_transform_impl - { - typedef tuples::cons< - typename mpl::apply1< - typename mpl::lambda::type - , typename Tuple::head_type - >::type - , typename tuple_meta_transform< - typename Tuple::tail_type - , UnaryMetaFun - >::type - > type; - }; - - template - struct tuple_meta_transform - : mpl::eval_if< - boost::is_same - , mpl::identity - , tuple_meta_transform_impl - > - { - }; - - // Meta-accumulate algorithm for tuples. Note: The template - // parameter StartType corresponds to the initial value in - // ordinary accumulation. - // - template - struct tuple_meta_accumulate; - - template< - typename Tuple - , class BinaryMetaFun - , typename StartType - > - struct tuple_meta_accumulate_impl - { - typedef typename mpl::apply2< - typename mpl::lambda::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 -#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) - , boost::is_same - > -#endif - , mpl::identity - , 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 - // struct apply - // { - // typedef Arg* type; - // } - // - // template - // Arg* operator()(Arg x); - // }; - template - tuples::null_type BOOST_TUPLE_ALGO(tuple_transform) - (tuples::null_type const&, Fun BOOST_TUPLE_ALGO_TERMINATOR) - { return tuples::null_type(); } - - template - 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_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 - Fun BOOST_TUPLE_ALGO(tuple_for_each)( - tuples::null_type - , Fun f BOOST_TUPLE_ALGO_TERMINATOR - ) - { return f; } - - - template - 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 - 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 - 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 struct iterator_reference @@ -336,14 +117,14 @@ namespace boost { struct apply : iterator_reference {}; }; #endif - + // Metafunction to obtain the type of the tuple whose element types // are the reference types of an iterator tuple. // template struct tuple_of_references - : tuple_impl_specific::tuple_meta_transform< - IteratorTuple, + : mpl::transform< + IteratorTuple, iterator_reference > { @@ -355,54 +136,23 @@ namespace boost { template struct minimum_traversal_category_in_iterator_tuple { - typedef typename tuple_impl_specific::tuple_meta_transform< + typedef typename mpl::transform< IteratorTuple , pure_traversal_tag > >::type tuple_of_traversal_tags; - - typedef typename tuple_impl_specific::tuple_meta_accumulate< + + typedef typename mpl::fold< tuple_of_traversal_tags - , minimum_category<> , random_access_traversal_tag + , minimum_category<> >::type type; }; -#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround - template <> - struct minimum_traversal_category_in_iterator_tuple - { - 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 - struct and_with_two_args - : mpl::and_ - { - }; - -# 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 - { - template - struct apply : mpl::and_ - {}; - }; -# endif - /////////////////////////////////////////////////////////////////// // // Class zip_iterator_base // - // Builds and exposes the iterator facade type from which the zip + // Builds and exposes the iterator facade type from which the zip // iterator will be derived. // template @@ -411,30 +161,30 @@ namespace boost { private: // Reference type is the type of the tuple obtained from the // iterators' reference types. - typedef typename + typedef typename detail::tuple_of_references::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 + typename mpl::at_c::type >::difference_type difference_type; - - // Traversal catetgory is the minimum traversal category in the + + // Traversal catetgory is the minimum traversal category in the // iterator tuple. - typedef typename + 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, - value_type, + value_type, traversal_category, reference, difference_type @@ -447,34 +197,34 @@ namespace boost { typedef int type; }; } - + ///////////////////////////////////////////////////////////////////// // // zip_iterator class definition // template - class zip_iterator : + class zip_iterator : public detail::zip_iterator_base::type - { + { - // Typedef super_t as our base class. - typedef typename + // Typedef super_t as our base class. + typedef typename detail::zip_iterator_base::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) + zip_iterator(IteratorTuple iterator_tuple) + : m_iterator_tuple(iterator_tuple) { } // Copy constructor @@ -493,18 +243,19 @@ namespace boost { { 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() - ); + { + typedef typename super_t::reference reference; + typedef typename fusion::traits::tag_of::type tag; + return fusion::convert(fusion::transform( + get_iterator_tuple(), + detail::dereference_iterator())); } // Two zip iterators are equal if all iterators in the iterator @@ -517,66 +268,62 @@ namespace boost { // under several compilers. No point in bringing in a bunch // of #ifdefs here. // - template + template bool equal(const zip_iterator& other) const { - return detail::tuple_impl_specific::tuple_equal( - get_iterator_tuple(), - other.get_iterator_tuple() - ); + return fusion::equal_to( + 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( + { + fusion::for_each( m_iterator_tuple, - detail::advance_iterator(n) - ); + detail::advance_iterator(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() - ); + { + fusion::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() - ); + { + fusion::for_each( + m_iterator_tuple, + detail::decrement_iterator()); } - + // Distance is calculated using the first iterator in the tuple. template typename super_t::difference_type distance_to( const zip_iterator& other ) const - { - return boost::tuples::get<0>(other.get_iterator_tuple()) - - boost::tuples::get<0>(this->get_iterator_tuple()); + { + return fusion::at_c<0>(other.get_iterator_tuple()) - + fusion::at_c<0>(this->get_iterator_tuple()); } - + // Data Members // ============ - + // The iterator tuple. IteratorTuple m_iterator_tuple; - + }; // Make function for zip iterator // - template - zip_iterator + template + zip_iterator make_zip_iterator(IteratorTuple t) { return zip_iterator(t); } From 1ddaca82975abcf151aefc62a64fd7189de97527 Mon Sep 17 00:00:00 2001 From: Kohei Takahashi Date: Thu, 18 Oct 2012 20:40:12 +0900 Subject: [PATCH 2/5] zip_iterator specialization for std::pair Signed-off-by: Kohei Takahashi --- include/boost/iterator/zip_iterator.hpp | 58 ++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/include/boost/iterator/zip_iterator.hpp b/include/boost/iterator/zip_iterator.hpp index 497ba7d..65dd82f 100644 --- a/include/boost/iterator/zip_iterator.hpp +++ b/include/boost/iterator/zip_iterator.hpp @@ -18,6 +18,7 @@ #include +#include // for std::pair #include // for backward compatibility #include @@ -130,6 +131,16 @@ namespace boost { { }; + // Specialization for std::pair + template + struct tuple_of_references > + { + typedef std::pair< + typename iterator_reference::type + , typename iterator_reference::type + > type; + }; + // Metafunction to obtain the minimal traversal tag in a tuple // of iterators. // @@ -148,6 +159,25 @@ namespace boost { >::type type; }; + template + struct minimum_traversal_category_in_iterator_tuple > + { + typedef typename pure_traversal_tag< + typename iterator_traversal::type + >::type iterator1_traversal; + typedef typename pure_traversal_tag< + typename iterator_traversal::type + >::type iterator2_traversal; + + typedef typename minimum_category< + iterator1_traversal + , typename minimum_category< + iterator2_traversal + , random_access_traversal_tag + >::type + >::type type; + }; + /////////////////////////////////////////////////////////////////// // // Class zip_iterator_base @@ -196,6 +226,30 @@ namespace boost { { typedef int type; }; + + template + struct converter + { + template + static reference call(Seq seq) + { + typedef typename fusion::traits::tag_of::type tag; + return fusion::convert(seq); + } + }; + + template + struct converter > + { + typedef std::pair reference; + template + static reference call(Seq seq) + { + return reference( + fusion::at_c<0>(seq) + , fusion::at_c<1>(seq)); + } + }; } ///////////////////////////////////////////////////////////////////// @@ -252,8 +306,8 @@ namespace boost { typename super_t::reference dereference() const { typedef typename super_t::reference reference; - typedef typename fusion::traits::tag_of::type tag; - return fusion::convert(fusion::transform( + typedef detail::converter gen; + return gen::call(fusion::transform( get_iterator_tuple(), detail::dereference_iterator())); } From c040d4c38b53a025788e197a89256507a06d13fd Mon Sep 17 00:00:00 2001 From: Kohei Takahashi Date: Sat, 14 Jun 2014 15:54:37 +0900 Subject: [PATCH 3/5] make_zip_iterator should be inlined Signed-off-by: Kohei Takahashi --- include/boost/iterator/zip_iterator.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/iterator/zip_iterator.hpp b/include/boost/iterator/zip_iterator.hpp index 65dd82f..e9a1c43 100644 --- a/include/boost/iterator/zip_iterator.hpp +++ b/include/boost/iterator/zip_iterator.hpp @@ -377,7 +377,7 @@ namespace boost { // Make function for zip iterator // template - zip_iterator + inline zip_iterator make_zip_iterator(IteratorTuple t) { return zip_iterator(t); } From 782313db8c6aec859a288f0a5f4dc87b24cdf437 Mon Sep 17 00:00:00 2001 From: Kohei Takahashi Date: Sat, 14 Jun 2014 15:58:52 +0900 Subject: [PATCH 4/5] Remove unnecessary specialization Signed-off-by: Kohei Takahashi --- include/boost/iterator/zip_iterator.hpp | 30 +++---------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/include/boost/iterator/zip_iterator.hpp b/include/boost/iterator/zip_iterator.hpp index e9a1c43..4863f68 100644 --- a/include/boost/iterator/zip_iterator.hpp +++ b/include/boost/iterator/zip_iterator.hpp @@ -14,7 +14,6 @@ #include #include // for enable_if_convertible #include -#include #include @@ -28,7 +27,6 @@ #include #include #include -#include #include #include @@ -88,9 +86,7 @@ namespace boost { remove_reference::type>::type iterator; - typedef typename - iterator_traits::reference - type; + typedef typename iterator_reference::type type; }; template @@ -99,26 +95,6 @@ namespace boost { { return *it; } }; - template - struct iterator_reference - { - typedef typename iterator_traits::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 - { - template - struct apply : iterator_reference {}; - }; -#endif - // Metafunction to obtain the type of the tuple whose element types // are the reference types of an iterator tuple. // @@ -198,9 +174,9 @@ namespace boost { typedef reference value_type; // Difference type is the first iterator's difference type - typedef typename iterator_traits< + typedef typename iterator_difference< typename mpl::at_c::type - >::difference_type difference_type; + >::type difference_type; // Traversal catetgory is the minimum traversal category in the // iterator tuple. From 9841d87212f39da1f99de1302c57d4ee25b8c56f Mon Sep 17 00:00:00 2001 From: Kohei Takahashi Date: Thu, 12 Jun 2014 01:04:29 +0900 Subject: [PATCH 5/5] Add tests for fusion based zip_iterator Signed-off-by: Kohei Takahashi --- test/Jamfile.v2 | 22 +++++---- test/detail/zip_iterator_test.ipp | 73 ++++++++++++++++++++++++++++ test/zip_iterator_test_fusion.cpp | 15 ++++++ test/zip_iterator_test_std_pair.cpp | 16 ++++++ test/zip_iterator_test_std_tuple.cpp | 29 +++++++++++ 5 files changed, 145 insertions(+), 10 deletions(-) create mode 100644 test/detail/zip_iterator_test.ipp create mode 100644 test/zip_iterator_test_fusion.cpp create mode 100644 test/zip_iterator_test_std_pair.cpp create mode 100644 test/zip_iterator_test_std_tuple.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 023a826..560c212 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -3,28 +3,30 @@ # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) test-suite iterator - : + : # These first two tests will run last, and are expected to fail # for many less-capable compilers. - + [ compile-fail interoperable_fail.cpp ] # test uses expected success, so that we catch unrelated # compilation problems. - [ run is_convertible_fail.cpp ] + [ run is_convertible_fail.cpp ] [ run zip_iterator_test.cpp - : : : - + : : : # stlport's debug mode generates long symbols which overwhelm # vc6 - #<*>release + #<*>release ] - + [ run zip_iterator_test_fusion.cpp ] + [ run zip_iterator_test_std_tuple.cpp ] + [ run zip_iterator_test_std_pair.cpp ] + # These tests should work for just about everything. [ compile is_lvalue_iterator.cpp ] [ compile is_readable_iterator.cpp ] [ compile pointee.cpp ] - + [ run unit_tests.cpp ] [ run concept_tests.cpp ] [ run iterator_adaptor_cc.cpp ] @@ -41,8 +43,8 @@ test-suite iterator [ run counting_iterator_test.cpp ] [ run interoperable.cpp ] [ run iterator_traits_test.cpp ] - [ run permutation_iterator_test.cpp : : : # on + [ run permutation_iterator_test.cpp : : : # on ] [ run function_input_iterator_test.cpp ] - + ; diff --git a/test/detail/zip_iterator_test.ipp b/test/detail/zip_iterator_test.ipp new file mode 100644 index 0000000..f659099 --- /dev/null +++ b/test/detail/zip_iterator_test.ipp @@ -0,0 +1,73 @@ +// Copyright (c) 2014 Kohei Takahashi. +// +// 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) +// +// See http://www.boost.org for most recent version including documentation. + +#include + +#include +#include +#include +#include +#include + + +int main() +{ + typedef TUPLE< + std::vector::iterator, + std::vector::iterator + > iterator_tuple; + + std::vector vi = boost::assign::list_of(42)(72); + std::vector vs = boost::assign::list_of("kokoro")("pyonpyon"); + + { + boost::zip_iterator i1(MAKE_TUPLE(vi.begin(), vs.begin())); + boost::zip_iterator i2 = i1; + + BOOST_TEST( i1 == i2); + BOOST_TEST( i1++ == i2); + BOOST_TEST( i1 == (i2 + 1)); + BOOST_TEST((i1 - 1) == i2); + BOOST_TEST( i1-- == ++i2); + BOOST_TEST( i1 == --i2); + } + + { + boost::zip_iterator i1(MAKE_TUPLE(vi.begin(), vs.begin())); + boost::zip_iterator i2 = i1 + 1; + + BOOST_TEST( i1 != i2); + BOOST_TEST( i1++ != i2); + BOOST_TEST( i1 != (i2 + 1)); + BOOST_TEST((i1 - 1) != i2); + BOOST_TEST( i1-- != ++i2); + BOOST_TEST( i1 != --i2); + } + + { + boost::zip_iterator i(MAKE_TUPLE(vi.begin(), vs.begin())); + + BOOST_TEST(boost::fusion::at_c<0>(* i ) == 42); + BOOST_TEST(boost::fusion::at_c<1>(* i ) == "kokoro"); + BOOST_TEST(boost::fusion::at_c<0>(*(i + 1)) == 72); + BOOST_TEST(boost::fusion::at_c<1>(*(i + 1)) == "pyonpyon"); + } + + { + boost::zip_iterator i1(MAKE_TUPLE(vi.begin(), vs.begin())); + boost::zip_iterator i2(MAKE_TUPLE(vi.end(), vs.end())); + + BOOST_TEST((i2 - i1) == 2); + ++i1; + BOOST_TEST((i2 - i1) == 1); + --i2; + BOOST_TEST((i2 - i1) == 0); + } + + return boost::report_errors(); +} diff --git a/test/zip_iterator_test_fusion.cpp b/test/zip_iterator_test_fusion.cpp new file mode 100644 index 0000000..542fd88 --- /dev/null +++ b/test/zip_iterator_test_fusion.cpp @@ -0,0 +1,15 @@ +// Copyright (c) 2014 Kohei Takahashi. +// +// 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) +// +// See http://www.boost.org for most recent version including documentation. + +#include +#include + +#define TUPLE boost::fusion::vector +#define MAKE_TUPLE boost::fusion::make_vector + +#include "detail/zip_iterator_test.ipp" diff --git a/test/zip_iterator_test_std_pair.cpp b/test/zip_iterator_test_std_pair.cpp new file mode 100644 index 0000000..215777a --- /dev/null +++ b/test/zip_iterator_test_std_pair.cpp @@ -0,0 +1,16 @@ +// Copyright (c) 2014 Kohei Takahashi. +// +// 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) +// +// See http://www.boost.org for most recent version including documentation. + +#include +#include + +#define TUPLE std::pair +#define MAKE_TUPLE std::make_pair + +#include "detail/zip_iterator_test.ipp" + diff --git a/test/zip_iterator_test_std_tuple.cpp b/test/zip_iterator_test_std_tuple.cpp new file mode 100644 index 0000000..02d648d --- /dev/null +++ b/test/zip_iterator_test_std_tuple.cpp @@ -0,0 +1,29 @@ +// Copyright (c) 2014 Kohei Takahashi. +// +// 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) +// +// See http://www.boost.org for most recent version including documentation. + +#include + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include +#include + +#define TUPLE std::tuple +#define MAKE_TUPLE std::make_tuple + +#include "detail/zip_iterator_test.ipp" + +#else + +int main() +{ + return 0; +} + +#endif +