diff --git a/include/boost/fusion/algorithm/iteration/detail/fold.hpp b/include/boost/fusion/algorithm/iteration/detail/fold.hpp index 98c78aaf..9b819954 100644 --- a/include/boost/fusion/algorithm/iteration/detail/fold.hpp +++ b/include/boost/fusion/algorithm/iteration/detail/fold.hpp @@ -13,6 +13,9 @@ #include #include +#include +#include + namespace boost { namespace fusion { namespace result_of { @@ -32,8 +35,11 @@ namespace detail template struct fold_apply - : boost::result_of::type, State)> - {}; + { + typedef typename result_of::deref::type dereferenced; + typedef typename add_reference::type>::type lvalue_state; + typedef typename boost::result_of::type type; + }; template struct static_fold; diff --git a/include/boost/fusion/algorithm/transformation/detail/replace.hpp b/include/boost/fusion/algorithm/transformation/detail/replace.hpp index edaa74f5..9e20f79f 100644 --- a/include/boost/fusion/algorithm/transformation/detail/replace.hpp +++ b/include/boost/fusion/algorithm/transformation/detail/replace.hpp @@ -9,6 +9,7 @@ #include #include +#include namespace boost { namespace fusion { namespace detail { @@ -43,14 +44,15 @@ namespace boost { namespace fusion { namespace detail replacer(T const& old_value, T const& new_value) : old_value(old_value), new_value(new_value) {} - template + template struct result; template struct result(U2)> { + typedef typename remove_reference::type value; typedef typename - mpl::if_, U2, U2 const&>::type + mpl::if_, value, value const&>::type type; }; diff --git a/include/boost/fusion/algorithm/transformation/detail/replace_if.hpp b/include/boost/fusion/algorithm/transformation/detail/replace_if.hpp index 0de8d2d6..db0434c6 100644 --- a/include/boost/fusion/algorithm/transformation/detail/replace_if.hpp +++ b/include/boost/fusion/algorithm/transformation/detail/replace_if.hpp @@ -9,6 +9,7 @@ #include #include +#include namespace boost { namespace fusion { namespace detail { @@ -49,8 +50,9 @@ namespace boost { namespace fusion { namespace detail template struct result(U)> { + typedef typename remove_reference::type value; typedef typename - mpl::if_, U, U const&>::type + mpl::if_, value, value const&>::type type; }; diff --git a/include/boost/fusion/sequence/view/transform_view/detail/deref_impl.hpp b/include/boost/fusion/sequence/view/transform_view/detail/deref_impl.hpp index 0d3b8fc7..d466cfd3 100644 --- a/include/boost/fusion/sequence/view/transform_view/detail/deref_impl.hpp +++ b/include/boost/fusion/sequence/view/transform_view/detail/deref_impl.hpp @@ -30,7 +30,7 @@ namespace boost { namespace fusion struct apply { typedef typename - result_of::value_of::type + result_of::deref::type value_type; typedef detail::apply_transform_result transform_type; @@ -52,10 +52,10 @@ namespace boost { namespace fusion struct apply { typedef typename - result_of::value_of::type + result_of::deref::type value1_type; typedef typename - result_of::value_of::type + result_of::deref::type value2_type; typedef detail::apply_transform_result transform_type; diff --git a/include/boost/fusion/sequence/view/zip_view/detail/advance_impl.hpp b/include/boost/fusion/sequence/view/zip_view/detail/advance_impl.hpp index 2e89b1da..36da0444 100644 --- a/include/boost/fusion/sequence/view/zip_view/detail/advance_impl.hpp +++ b/include/boost/fusion/sequence/view/zip_view/detail/advance_impl.hpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace boost { namespace fusion { @@ -21,13 +22,15 @@ namespace boost { namespace fusion { template struct poly_advance { - template + template struct result; template struct result(It)> - : result_of::advance - {}; + { + typedef typename remove_reference::type it; + typedef typename result_of::advance::type type; + }; template typename result::type diff --git a/include/boost/fusion/sequence/view/zip_view/detail/deref_impl.hpp b/include/boost/fusion/sequence/view/zip_view/detail/deref_impl.hpp index cb4c5445..70b95d55 100644 --- a/include/boost/fusion/sequence/view/zip_view/detail/deref_impl.hpp +++ b/include/boost/fusion/sequence/view/zip_view/detail/deref_impl.hpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include namespace boost { namespace fusion { @@ -25,15 +27,19 @@ namespace boost { namespace fusion { { struct poly_deref { - template + template struct result; template struct result - : mpl::eval_if, - mpl::identity, - result_of::deref > - {}; + { + typedef typename remove_const< + typename remove_reference::type>::type it; + + typedef typename mpl::eval_if, + mpl::identity, + result_of::deref >::type type; + }; template typename result::type diff --git a/include/boost/fusion/sequence/view/zip_view/detail/next_impl.hpp b/include/boost/fusion/sequence/view/zip_view/detail/next_impl.hpp index 0cec2882..cae95eec 100644 --- a/include/boost/fusion/sequence/view/zip_view/detail/next_impl.hpp +++ b/include/boost/fusion/sequence/view/zip_view/detail/next_impl.hpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include namespace boost { namespace fusion { @@ -24,15 +26,19 @@ namespace boost { namespace fusion { { struct poly_next { - template + template struct result; template struct result - : mpl::eval_if, - mpl::identity, - result_of::next > - {}; + { + typedef typename remove_const< + typename remove_reference::type>::type it; + + typedef typename mpl::eval_if, + mpl::identity, + result_of::next >::type type; + }; template typename result::type diff --git a/include/boost/fusion/sequence/view/zip_view/detail/prior_impl.hpp b/include/boost/fusion/sequence/view/zip_view/detail/prior_impl.hpp index fdc409ca..787eb4f9 100644 --- a/include/boost/fusion/sequence/view/zip_view/detail/prior_impl.hpp +++ b/include/boost/fusion/sequence/view/zip_view/detail/prior_impl.hpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include namespace boost { namespace fusion { @@ -24,15 +26,18 @@ namespace boost { namespace fusion { { struct poly_prior { - template + template struct result; template struct result - : mpl::eval_if, - mpl::identity, - result_of::prior > - {}; + { + typedef typename remove_const< + typename remove_reference::type>::type it; + typedef typename mpl::eval_if, + mpl::identity, + result_of::prior >::type type; + }; template typename result::type diff --git a/include/boost/fusion/sequence/view/zip_view/detail/strictest_traversal.hpp b/include/boost/fusion/sequence/view/zip_view/detail/strictest_traversal.hpp index d7c922ac..60abb57c 100644 --- a/include/boost/fusion/sequence/view/zip_view/detail/strictest_traversal.hpp +++ b/include/boost/fusion/sequence/view/zip_view/detail/strictest_traversal.hpp @@ -39,15 +39,17 @@ namespace boost { namespace fusion { struct strictest_traversal_impl { - template + template struct result; template struct result { - typedef StrictestSoFar tag1; - typedef typename traits::category_of< - typename remove_reference::type>::type tag2; + typedef typename remove_reference::type next_value; + typedef typename remove_reference::type strictest_so_far; + + typedef strictest_so_far tag1; + typedef typename traits::category_of::type tag2; typedef typename stricter_traversal::type type; }; diff --git a/include/boost/fusion/sequence/view/zip_view/zip_view.hpp b/include/boost/fusion/sequence/view/zip_view/zip_view.hpp index d23cb4df..23ef2e05 100644 --- a/include/boost/fusion/sequence/view/zip_view/zip_view.hpp +++ b/include/boost/fusion/sequence/view/zip_view/zip_view.hpp @@ -73,8 +73,11 @@ namespace boost { namespace fusion { template struct result - : mpl::min - {}; + { + typedef typename remove_reference::type lhs; + typedef typename remove_reference::type rhs; + typedef typename mpl::min::type type; + }; }; template diff --git a/test/Jamfile b/test/Jamfile index b1967f19..f70629b8 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -145,4 +145,3 @@ import testing ; run sequence/ext_/iterator_range_s.cpp ; explicit iterator_range_s ; } - diff --git a/test/algorithm/fold.cpp b/test/algorithm/fold.cpp index 627ca01f..9545cd0e 100644 --- a/test/algorithm/fold.cpp +++ b/test/algorithm/fold.cpp @@ -19,6 +19,10 @@ #include #include +#include +#include +#include + #include using boost::mpl::if_; @@ -33,7 +37,8 @@ struct add_ints_only template struct result { - typedef State type; + typedef typename boost::remove_const< + typename boost::remove_reference::type>::type type; }; template @@ -58,11 +63,16 @@ struct count_ints template struct result { + typedef typename boost::remove_const< + typename boost::remove_reference::type>::type elem; + typedef typename boost::remove_const< + typename boost::remove_reference::type>::type state; + typedef typename if_< - is_same - , typename boost::mpl::next::type - , CountT + is_same + , typename boost::mpl::next::type + , state >::type type; }; @@ -86,6 +96,25 @@ struct appender } }; +struct lvalue_adder +{ + template + struct result; + + template + struct result + { + // Second argument still needs to support rvalues - see definition of fusion::fold + typedef T0 type; + }; + + template + T0 operator()(T0& lhs, T1 const& rhs) const + { + return lhs + rhs; + } +}; + int main() { @@ -130,6 +159,11 @@ main() == "abcde"); } + { + vector vec(1,2); + BOOST_TEST(fusion::fold(vec, 0, lvalue_adder()) == 3); + } + { typedef vector vector_type; vector_type v(12345, 'x', 678910, 3.36); diff --git a/test/algorithm/transform.cpp b/test/algorithm/transform.cpp index eec0942d..24cccd83 100644 --- a/test/algorithm/transform.cpp +++ b/test/algorithm/transform.cpp @@ -19,13 +19,12 @@ struct square { - template + template struct result; template struct result { - BOOST_STATIC_ASSERT(!boost::is_reference::value); typedef int type; }; @@ -38,7 +37,7 @@ struct square struct add { - template + template struct result; template @@ -54,6 +53,42 @@ struct add } }; +struct unary_lvalue_transform +{ + template + struct result; + + template + struct result + { + typedef T* type; + }; + + template + T* operator()(T& t) const + { + return &t; + } +}; + +struct binary_lvalue_transform +{ + template + struct result; + + template + struct result + { + typedef T0* type; + }; + + template + T0* operator()(T0& t0, T1&) const + { + return &t0; + } +}; + int main() { @@ -92,6 +127,20 @@ main() BOOST_TEST((transform(tup1, tup2, add()) == make_vector(5, 7, 9))); } + { + // Unary transform that requires lvalues, just check compilation + vector tup1(1, 2, 3); + BOOST_TEST(at_c<0>(transform(tup1, unary_lvalue_transform())) == &at_c<0>(tup1)); + BOOST_TEST(*begin(transform(tup1, unary_lvalue_transform())) == &at_c<0>(tup1)); + } + + { + vector tup1(1, 2, 3); + vector tup2(4, 5, 6); + BOOST_TEST(at_c<0>(transform(tup1, tup2, binary_lvalue_transform())) == &at_c<0>(tup1)); + BOOST_TEST(*begin(transform(tup1, tup2, binary_lvalue_transform())) == &at_c<0>(tup1)); + } + return boost::report_errors(); }