diff --git a/include/boost/fusion/algorithm/iteration/detail/for_each.hpp b/include/boost/fusion/algorithm/iteration/detail/for_each.hpp index 0bef5cec4..c674511eb 100644 --- a/include/boost/fusion/algorithm/iteration/detail/for_each.hpp +++ b/include/boost/fusion/algorithm/iteration/detail/for_each.hpp @@ -30,7 +30,7 @@ namespace detail template BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED inline void - for_each_linear(First const& first, Last const& last, F const& f, mpl::false_) + for_each_linear(First const& first, Last const& last, F& f, mpl::false_) { f(*first); detail::for_each_linear(fusion::next(first), last, f, @@ -41,7 +41,7 @@ namespace detail template BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED inline void - for_each_dispatch(Sequence& seq, F const& f, Tag) + for_each_dispatch(Sequence& seq, F& f, Tag) { detail::for_each_linear( fusion::begin(seq) @@ -57,7 +57,7 @@ namespace detail { template BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static void call(I0 const& i0, F const& f) + static void call(I0 const& i0, F& f) { f(*i0); typedef typename result_of::next::type I1; @@ -78,7 +78,7 @@ namespace detail { template BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static void call(I0 const& i0, F const& f) + static void call(I0 const& i0, F& f) { f(*i0); typedef typename result_of::next::type I1; @@ -95,7 +95,7 @@ namespace detail { template BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static void call(I0 const& i0, F const& f) + static void call(I0 const& i0, F& f) { f(*i0); typedef typename result_of::next::type I1; @@ -109,7 +109,7 @@ namespace detail { template BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static void call(I0 const& i0, F const& f) + static void call(I0 const& i0, F& f) { f(*i0); } @@ -128,7 +128,7 @@ namespace detail template BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED inline void - for_each_dispatch(Sequence& seq, F const& f, random_access_traversal_tag) + for_each_dispatch(Sequence& seq, F& f, random_access_traversal_tag) { typedef typename result_of::begin::type begin; typedef typename result_of::end::type end; @@ -138,7 +138,7 @@ namespace detail template BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED inline void - for_each(Sequence& seq, F const& f, mpl::false_) // unsegmented implementation + for_each(Sequence& seq, F& f, mpl::false_) // unsegmented implementation { detail::for_each_dispatch(seq, f, typename traits::category_of::type()); } diff --git a/include/boost/fusion/algorithm/iteration/detail/segmented_for_each.hpp b/include/boost/fusion/algorithm/iteration/detail/segmented_for_each.hpp index a32d9dad0..7b299f869 100644 --- a/include/boost/fusion/algorithm/iteration/detail/segmented_for_each.hpp +++ b/include/boost/fusion/algorithm/iteration/detail/segmented_for_each.hpp @@ -19,11 +19,11 @@ namespace boost { namespace fusion { namespace detail struct segmented_for_each_fun { BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - explicit segmented_for_each_fun(Fun const& f) + explicit segmented_for_each_fun(Fun& f) : fun(f) {} - Fun const& fun; + Fun& fun; template struct apply @@ -43,7 +43,7 @@ namespace boost { namespace fusion { namespace detail template BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED inline void - for_each(Sequence& seq, F const& f, mpl::true_) // segmented implementation + for_each(Sequence& seq, F& f, mpl::true_) // segmented implementation { fusion::segmented_fold_until(seq, void_(), segmented_for_each_fun(f)); } diff --git a/include/boost/fusion/algorithm/iteration/for_each.hpp b/include/boost/fusion/algorithm/iteration/for_each.hpp index a523c85eb..349966751 100644 --- a/include/boost/fusion/algorithm/iteration/for_each.hpp +++ b/include/boost/fusion/algorithm/iteration/for_each.hpp @@ -1,6 +1,7 @@ /*============================================================================= Copyright (c) 2001-2007 Joel de Guzman Copyright (c) 2007 Dan Marsden + Copyright (c) 2018 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) @@ -13,7 +14,7 @@ #include #include #include -#include +#include namespace boost { namespace fusion { @@ -28,24 +29,16 @@ namespace boost { namespace fusion template BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED - inline typename - enable_if< - traits::is_sequence - , void - >::type - for_each(Sequence& seq, F const& f) + inline typename enable_if >::type + for_each(Sequence& seq, F f) { detail::for_each(seq, f, typename traits::is_segmented::type()); } template BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED - inline typename - enable_if< - traits::is_sequence - , void - >::type - for_each(Sequence const& seq, F const& f) + inline typename enable_if >::type + for_each(Sequence const& seq, F f) { detail::for_each(seq, f, typename traits::is_segmented::type()); } diff --git a/include/boost/fusion/algorithm/iteration/for_each_fwd.hpp b/include/boost/fusion/algorithm/iteration/for_each_fwd.hpp index 13720eada..c3ffaa42d 100644 --- a/include/boost/fusion/algorithm/iteration/for_each_fwd.hpp +++ b/include/boost/fusion/algorithm/iteration/for_each_fwd.hpp @@ -1,5 +1,6 @@ /*============================================================================= Copyright (c) 2011 Eric Niebler + Copyright (c) 2018 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) @@ -9,7 +10,7 @@ #include #include -#include +#include namespace boost { namespace fusion { @@ -21,21 +22,13 @@ namespace boost { namespace fusion template BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED - inline typename - enable_if< - traits::is_sequence - , void - >::type - for_each(Sequence& seq, F const& f); + inline typename enable_if >::type + for_each(Sequence& seq, F f); template BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED - inline typename - enable_if< - traits::is_sequence - , void - >::type - for_each(Sequence const& seq, F const& f); + inline typename enable_if >::type + for_each(Sequence const& seq, F f); }} #endif diff --git a/test/algorithm/for_each.cpp b/test/algorithm/for_each.cpp index c0bc441c5..982cb3a12 100644 --- a/test/algorithm/for_each.cpp +++ b/test/algorithm/for_each.cpp @@ -1,13 +1,15 @@ /*============================================================================= Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2018 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) ==============================================================================*/ -#include +#include #include #include #include +#include #include #include @@ -29,6 +31,15 @@ struct increment } }; +struct mutable_increment : increment +{ + template + void operator()(T& v) + { + return increment::operator()(v); + } +}; + int main() { @@ -44,9 +55,20 @@ main() } { + char const ruby[] = "Ruby"; typedef vector vector_type; - vector_type v(1, 'x', 3.3, "Ruby"); + vector_type v(1, 'x', 3.3, ruby); for_each(v, increment()); + BOOST_TEST_EQ(v, vector_type(2, 'y', 4.3, ruby + 1)); + std::cout << v << std::endl; + } + + { + char const ruby[] = "Ruby"; + typedef vector vector_type; + vector_type v(1, 'x', 3.3, ruby); + for_each(v, mutable_increment()); + BOOST_TEST_EQ(v, vector_type(2, 'y', 4.3, ruby + 1)); std::cout << v << std::endl; } diff --git a/test/algorithm/segmented_for_each.cpp b/test/algorithm/segmented_for_each.cpp index 84260a68b..d1f4fe6ad 100644 --- a/test/algorithm/segmented_for_each.cpp +++ b/test/algorithm/segmented_for_each.cpp @@ -1,14 +1,17 @@ /*============================================================================= Copyright (c) 2001-2011 Joel de Guzman Copyright (c) 2011 Eric Niebler + Copyright (c) 2018 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) ==============================================================================*/ -#include +#include #include -#include #include +#include +#include +#include #include "../sequence/tree.hpp" struct print @@ -20,6 +23,31 @@ struct print } }; +struct increment +{ + template + void operator()(T& v) const + { + ++v; + } +}; + +struct mutable_increment : increment +{ + template + void operator()(T& v) + { + return increment::operator()(v); + } +}; + +template +void test(Tree tree, Tree const& expected) +{ + boost::fusion::for_each(tree, F()); + BOOST_TEST_EQ(tree, expected); +} + int main() { @@ -42,6 +70,69 @@ main() ) , print() ); + std::cout << std::endl; + } + + { + test( + make_tree( + make_vector(double(0),'B') + , make_tree( + make_vector(1,2,long(3)) + , make_tree(make_vector('a','b','c')) + , make_tree(make_vector(short('d'),'e','f')) + ) + , make_tree( + make_vector(4,5,6) + , make_tree(make_vector(float(1),'h','i')) + , make_tree(make_vector('j','k','l')) + ) + ) + , make_tree( + make_vector(double(1),'C') + , make_tree( + make_vector(2,3,long(4)) + , make_tree(make_vector('b','c','d')) + , make_tree(make_vector(short('e'),'f','g')) + ) + , make_tree( + make_vector(5,6,7) + , make_tree(make_vector(float(2),'i','j')) + , make_tree(make_vector('k','l','m')) + ) + ) + ); + } + + { + test( + make_tree( + make_vector(double(0),'B') + , make_tree( + make_vector(1,2,long(3)) + , make_tree(make_vector('a','b','c')) + , make_tree(make_vector(short('d'),'e','f')) + ) + , make_tree( + make_vector(4,5,6) + , make_tree(make_vector(float(1),'h','i')) + , make_tree(make_vector('j','k','l')) + ) + ) + , make_tree( + make_vector(double(1),'C') + , make_tree( + make_vector(2,3,long(4)) + , make_tree(make_vector('b','c','d')) + , make_tree(make_vector(short('e'),'f','g')) + ) + , make_tree( + make_vector(5,6,7) + , make_tree(make_vector(float(2),'i','j')) + , make_tree(make_vector('k','l','m')) + ) + ) + ); } return boost::report_errors();