diff --git a/include/boost/function/function_template.hpp b/include/boost/function/function_template.hpp index 72b7fab..81f5f0a 100644 --- a/include/boost/function/function_template.hpp +++ b/include/boost/function/function_template.hpp @@ -26,7 +26,13 @@ #define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY) -#define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a) +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a) +#else +# include +# define BOOST_FUNCTION_ARG(J,I,D) ::boost::forward< BOOST_PP_CAT(T,I) >(BOOST_PP_CAT(a,I)) +# define BOOST_FUNCTION_ARGS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG,BOOST_PP_EMPTY) +#endif #define BOOST_FUNCTION_ARG_TYPE(J,I,D) \ typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type); @@ -1176,6 +1182,9 @@ public: #undef BOOST_FUNCTION_TEMPLATE_ARGS #undef BOOST_FUNCTION_PARMS #undef BOOST_FUNCTION_PARM +#ifdef BOOST_FUNCTION_ARG +# undef BOOST_FUNCTION_ARG +#endif #undef BOOST_FUNCTION_ARGS #undef BOOST_FUNCTION_ARG_TYPE #undef BOOST_FUNCTION_ARG_TYPES diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 68895fa..5a2dbad 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -61,6 +61,8 @@ import testing ; [ run libs/function/test/nothrow_swap.cpp : : : : ] + [ run libs/function/test/rvalues_test.cpp : : : : ] + [ compile libs/function/test/function_typeof_test.cpp ] ; } diff --git a/test/rvalues_test.cpp b/test/rvalues_test.cpp new file mode 100644 index 0000000..50c1f7f --- /dev/null +++ b/test/rvalues_test.cpp @@ -0,0 +1,79 @@ +// Copyright 2014 Antony Polukhin. +// +// 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) + +// For more information, see http://www.boost.org + +#include +#include + +#include +#include +#include + +class only_movable { +private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(only_movable) + int value_; + bool moved_; + +public: + only_movable(BOOST_RV_REF(only_movable) x) + : value_(x.value_) + , moved_(false) + { + x.moved_ = true; + } + + only_movable& operator=(BOOST_RV_REF(only_movable) x) { + value_ = x.value_; + x.moved_ = true; + moved_ = false; + return *this; + } + + explicit only_movable(int value = 0) : value_(value), moved_(false) {} + int get_value() const { return value_; } + bool is_moved() const { return moved_; } +}; + + +int one(BOOST_RV_REF(only_movable) v) { return v.get_value(); } +only_movable two(BOOST_RV_REF(only_movable) t) { + only_movable t1 = boost::move(t); + return BOOST_MOVE_RET(only_movable, t1); +} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +int three(std::string&&) { return 1; } +std::string&& four(std::string&& s) { return boost::move(s); } +#endif + +int test_main(int, char*[]) +{ + using boost::function; + + function f1 = one; + + only_movable om1(1); + BOOST_CHECK(f1(boost::move(om1)) == 1); + + function f2 = two; + + only_movable om2(2); + only_movable om2_2 = f2(boost::move(om2)); + BOOST_CHECK(om2_2.get_value() == 2); + BOOST_CHECK(om2.is_moved()); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + function f3 = three; + function f4 = four; + + f3(std::string("Hello")); + BOOST_CHECK(f4(std::string("world")) == "world"); +#endif + + return 0; +}