Skip to content

Commit

Permalink
Merge pull request #183 from boostorg/mutable_for_each
Browse files Browse the repository at this point in the history
Fixed for_each parameter type to accept mutable functor
  • Loading branch information
Flast committed Jul 3, 2018
2 parents afb8b15 + 0e4c512 commit 102588a
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 41 deletions.
16 changes: 8 additions & 8 deletions include/boost/fusion/algorithm/iteration/detail/for_each.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace detail
template <typename First, typename Last, typename F>
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,
Expand All @@ -41,7 +41,7 @@ namespace detail
template <typename Sequence, typename F, typename Tag>
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)
Expand All @@ -57,7 +57,7 @@ namespace detail
{
template<typename I0, typename F>
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<I0>::type I1;
Expand All @@ -78,7 +78,7 @@ namespace detail
{
template<typename I0, typename F>
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<I0>::type I1;
Expand All @@ -95,7 +95,7 @@ namespace detail
{
template<typename I0, typename F>
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<I0>::type I1;
Expand All @@ -109,7 +109,7 @@ namespace detail
{
template<typename I0, typename F>
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);
}
Expand All @@ -128,7 +128,7 @@ namespace detail
template <typename Sequence, typename F>
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<Sequence>::type begin;
typedef typename result_of::end<Sequence>::type end;
Expand All @@ -138,7 +138,7 @@ namespace detail
template <typename Sequence, typename F>
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<Sequence>::type());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename Sequence, typename State, typename Context>
struct apply
Expand All @@ -43,7 +43,7 @@ namespace boost { namespace fusion { namespace detail
template <typename Sequence, typename F>
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>(f));
}
Expand Down
19 changes: 6 additions & 13 deletions include/boost/fusion/algorithm/iteration/for_each.hpp
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -13,7 +14,7 @@
#include <boost/fusion/algorithm/iteration/detail/segmented_for_each.hpp>
#include <boost/fusion/support/is_segmented.hpp>
#include <boost/fusion/support/is_sequence.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/core/enable_if.hpp>

namespace boost { namespace fusion
{
Expand All @@ -28,24 +29,16 @@ namespace boost { namespace fusion

template <typename Sequence, typename F>
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
inline typename
enable_if<
traits::is_sequence<Sequence>
, void
>::type
for_each(Sequence& seq, F const& f)
inline typename enable_if<traits::is_sequence<Sequence> >::type
for_each(Sequence& seq, F f)
{
detail::for_each(seq, f, typename traits::is_segmented<Sequence>::type());
}

template <typename Sequence, typename F>
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
inline typename
enable_if<
traits::is_sequence<Sequence>
, void
>::type
for_each(Sequence const& seq, F const& f)
inline typename enable_if<traits::is_sequence<Sequence> >::type
for_each(Sequence const& seq, F f)
{
detail::for_each(seq, f, typename traits::is_segmented<Sequence>::type());
}
Expand Down
19 changes: 6 additions & 13 deletions include/boost/fusion/algorithm/iteration/for_each_fwd.hpp
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -9,7 +10,7 @@

#include <boost/fusion/support/config.hpp>
#include <boost/fusion/support/is_sequence.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/core/enable_if.hpp>

namespace boost { namespace fusion
{
Expand All @@ -21,21 +22,13 @@ namespace boost { namespace fusion

template <typename Sequence, typename F>
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
inline typename
enable_if<
traits::is_sequence<Sequence>
, void
>::type
for_each(Sequence& seq, F const& f);
inline typename enable_if<traits::is_sequence<Sequence> >::type
for_each(Sequence& seq, F f);

template <typename Sequence, typename F>
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
inline typename
enable_if<
traits::is_sequence<Sequence>
, void
>::type
for_each(Sequence const& seq, F const& f);
inline typename enable_if<traits::is_sequence<Sequence> >::type
for_each(Sequence const& seq, F f);
}}

#endif
26 changes: 24 additions & 2 deletions test/algorithm/for_each.cpp
Original file line number Diff line number Diff line change
@@ -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 <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/adapted/mpl.hpp>
#include <boost/fusion/sequence/io/out.hpp>
#include <boost/fusion/sequence/comparison/equal_to.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/mpl/vector_c.hpp>

Expand All @@ -29,6 +31,15 @@ struct increment
}
};

struct mutable_increment : increment
{
template <typename T>
void operator()(T& v)
{
return increment::operator()(v);
}
};

int
main()
{
Expand All @@ -44,9 +55,20 @@ main()
}

{
char const ruby[] = "Ruby";
typedef vector<int, char, double, char const*> 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<int, char, double, char const*> 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;
}

Expand Down
95 changes: 93 additions & 2 deletions test/algorithm/segmented_for_each.cpp
Original file line number Diff line number Diff line change
@@ -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 <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/container/generation/make_vector.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/sequence/comparison/equal_to.hpp>
#include <boost/fusion/sequence/io/out.hpp>
#include "../sequence/tree.hpp"

struct print
Expand All @@ -20,6 +23,31 @@ struct print
}
};

struct increment
{
template <typename T>
void operator()(T& v) const
{
++v;
}
};

struct mutable_increment : increment
{
template <typename T>
void operator()(T& v)
{
return increment::operator()(v);
}
};

template <typename F, typename Tree>
void test(Tree tree, Tree const& expected)
{
boost::fusion::for_each(tree, F());
BOOST_TEST_EQ(tree, expected);
}

int
main()
{
Expand All @@ -42,6 +70,69 @@ main()
)
, print()
);
std::cout << std::endl;
}

{
test<increment>(
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<mutable_increment>(
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();
Expand Down

0 comments on commit 102588a

Please sign in to comment.