/*============================================================================= Copyright (c) 2010 Christopher Schmidt 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 #include #include #include #include #include #include #include #include #include #include #include #include namespace mpl=boost::mpl; namespace fusion=boost::fusion; #ifdef BOOST_FUSION_TEST_REVERSE_FOLD # ifdef BOOST_FUSION_TEST_ITER_FOLD # define BOOST_FUSION_TEST_FOLD_NAME reverse_iter_fold # else # define BOOST_FUSION_TEST_FOLD_NAME reverse_fold # endif #else # ifdef BOOST_FUSION_TEST_ITER_FOLD # define BOOST_FUSION_TEST_FOLD_NAME iter_fold # else # define BOOST_FUSION_TEST_FOLD_NAME fold # endif #endif struct sum { template struct result; template struct result : boost::fusion::result_of::make_pair< mpl::int_< boost::remove_reference< State >::type::first_type::value+1 > , int > { BOOST_MPL_ASSERT((typename boost::is_reference::type)); BOOST_MPL_ASSERT((typename boost::is_reference::type)); }; #ifdef BOOST_FUSION_TEST_ITER_FOLD template typename result::type operator()(State const& state, It const& it)const { static const int n=State::first_type::value; return fusion::make_pair >( state.second+fusion::deref(it)*n); } #else template typename result::type operator()(State const& state, int const& e)const { static const int n=State::first_type::value; return fusion::make_pair >(state.second+e*n); } #endif }; struct meta_sum { template struct result; template struct result { BOOST_MPL_ASSERT((typename boost::is_reference::type)); BOOST_MPL_ASSERT((typename boost::is_reference::type)); typedef typename boost::remove_reference::type state; static const int n=mpl::front::type::value; #ifdef BOOST_FUSION_TEST_ITER_FOLD typedef typename boost::fusion::result_of::value_of< typename boost::remove_reference::type >::type t; #else typedef typename boost::remove_reference::type t; #endif typedef mpl::vector< mpl::int_ , mpl::int_< mpl::back::type::value+t::value*n > > type; }; template typename result::type operator()(State const&, T const&)const; }; struct fold_test_n { template void operator()(I)const { static const int n=I::value; typedef mpl::range_c range; static const int squares_sum=n*(n+1)*(2*n+1)/6; { mpl::range_c init_range; typename boost::fusion::result_of::as_vector< typename mpl::transform< range , mpl::always , mpl::back_inserter > >::type >::type vec( #ifdef BOOST_FUSION_TEST_REVERSE_FOLD fusion::reverse(init_range) #else init_range #endif ); int result=BOOST_FUSION_TEST_FOLD_NAME( vec, fusion::make_pair >(0), sum()).second; std::cout << n << ": " << result << std::endl; BOOST_TEST(result==squares_sum); } { typedef typename #ifdef BOOST_FUSION_TEST_REVERSE_FOLD boost::fusion::result_of::as_vector< typename mpl::copy< mpl::range_c , mpl::front_inserter > >::type >::type #else boost::fusion::result_of::as_vector >::type #endif vec; typedef boost::is_same< typename boost::fusion::result_of::BOOST_FUSION_TEST_FOLD_NAME< vec , mpl::vector, mpl::int_<0> > , meta_sum >::type , typename mpl::if_c< !n , mpl::vector, mpl::int_<0> >& , mpl::vector, mpl::int_ > >::type > result_test; BOOST_MPL_ASSERT((result_test)); } } }; int main() { mpl::for_each >(fold_test_n()); return boost::report_errors(); } #undef BOOST_FUSION_TEST_FOLD_NAME