/*============================================================================= Copyright (c) 2001-2011 Joel de Guzman Copyright (c) 2007 Dan Marsden 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 #include #include #include #include #include #include #include #include using boost::mpl::if_; using boost::mpl::int_; using boost::is_same; struct add_ints_only { template struct result; template struct result { typedef typename boost::remove_const< typename boost::remove_reference::type>::type type; }; template State operator()(State const& state, T const& /*x*/) const { return state; } int operator()(int state, int x) const { return x + state; } }; struct count_ints { template struct result; template struct result { typedef typename boost::remove_const< typename boost::remove_reference::type>::type state; typedef typename boost::remove_const< typename boost::remove_reference::type>::type elem; typedef typename if_< is_same , typename boost::mpl::next::type , state >::type type; }; template typename result::type operator()(CountT const&, T const&) const { typedef typename result::type result_; return result_(); } }; struct appender { typedef std::string result_type; std::string operator()(std::string const& str, char c) const { return str + c; } }; struct lvalue_adder { template struct result; template struct result { // Second argument still needs to support rvalues - see definition of fusion::fold typedef T1 type; }; template T1 operator()(T0 const& lhs, T1& rhs) const { return lhs + rhs; } }; int add(int lhs, int rhs) { return lhs + rhs; } struct functor { template int operator() (int hitherho, T const& cur) const { return int(hitherho + cur); } }; struct visitor { typedef int result_type; int operator()(int sum, long&) { return sum; } }; int main() { using namespace boost::fusion; namespace fusion = boost::fusion; { typedef vector vector_type; vector_type v(12345, 'x', 678910, 3.36); int result = fold(v, 0, add_ints_only()); std::cout << result << std::endl; BOOST_TEST(result == 12345+678910); } { typedef vector vector_type; vector_type v(12345); int n = fusion::fold(v, int_<0>(), count_ints()); std::cout << n << std::endl; BOOST_TEST(n == 1); } { typedef vector vector_type; vector_type v(12345, 'x', 678910, 3.36, 8756); int n = fusion::fold(v, int_<0>(), count_ints()); std::cout << n << std::endl; BOOST_TEST(n == 3); } { typedef boost::mpl::vector mpl_vec; int n = fusion::fold(mpl_vec(), int_<0>(), count_ints()); std::cout << n << std::endl; BOOST_TEST(n == 3); } { BOOST_TEST(fusion::fold(fusion::make_vector('a','b','c','d','e'), std::string(""), appender()) == "abcde"); } { vector vec(1,2); BOOST_TEST(fusion::fold(vec, 0, lvalue_adder()) == 3); } { vector vec(1,2); BOOST_TEST(fusion::fold(vec, 0, add) == 3); } { typedef vector vector_type; vector_type v(12345, 'x', 678910, 3.36); int result = accumulate(v, 0, add_ints_only()); std::cout << result << std::endl; BOOST_TEST(result == 12345+678910); } { typedef vector vector_type; vector_type v(12345); int n = fusion::accumulate(v, int_<0>(), count_ints()); std::cout << n << std::endl; BOOST_TEST(n == 1); } { typedef vector vector_type; vector_type v(12345, 'x', 678910, 3.36, 8756); int n = fusion::accumulate(v, int_<0>(), count_ints()); std::cout << n << std::endl; BOOST_TEST(n == 3); } { typedef boost::mpl::vector mpl_vec; int n = fusion::accumulate(mpl_vec(), int_<0>(), count_ints()); std::cout << n << std::endl; BOOST_TEST(n == 3); } { BOOST_TEST(fusion::accumulate(fusion::make_vector('a','b','c','d','e'), std::string(""), appender()) == "abcde"); } { vector vec(1,2); BOOST_TEST(fusion::accumulate(vec, 0, add) == 3); } { #if defined(BOOST_RESULT_OF_USE_DECLTYPE) { boost::fusion::vector container{1, 2, 3}; functor f; boost::fusion::fold(container, 0, f); } #endif { boost::fusion::vector vec; visitor v; boost::fusion::fold(vec, 0, v); } } return boost::report_errors(); }