Add support for function signatures with rvalue params

This commit is contained in:
Antony Polukhin
2014-09-29 20:14:06 +04:00
parent 02abccd686
commit 27e9e1e372
3 changed files with 91 additions and 1 deletions

View File

@ -26,7 +26,13 @@
#define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY) #define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
# define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a) # define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
#else
# include <boost/move/move.hpp>
# 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) \ #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); 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_TEMPLATE_ARGS
#undef BOOST_FUNCTION_PARMS #undef BOOST_FUNCTION_PARMS
#undef BOOST_FUNCTION_PARM #undef BOOST_FUNCTION_PARM
#ifdef BOOST_FUNCTION_ARG
# undef BOOST_FUNCTION_ARG
#endif
#undef BOOST_FUNCTION_ARGS #undef BOOST_FUNCTION_ARGS
#undef BOOST_FUNCTION_ARG_TYPE #undef BOOST_FUNCTION_ARG_TYPE
#undef BOOST_FUNCTION_ARG_TYPES #undef BOOST_FUNCTION_ARG_TYPES

View File

@ -61,6 +61,8 @@ import testing ;
[ run libs/function/test/nothrow_swap.cpp : : : : ] [ run libs/function/test/nothrow_swap.cpp : : : : ]
[ run libs/function/test/rvalues_test.cpp : : : : ]
[ compile libs/function/test/function_typeof_test.cpp ] [ compile libs/function/test/function_typeof_test.cpp ]
; ;
} }

79
test/rvalues_test.cpp Normal file
View File

@ -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 <iostream>
#include <cstdlib>
#include <boost/test/minimal.hpp>
#include <boost/function.hpp>
#include <boost/move/move.hpp>
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 <int(BOOST_RV_REF(only_movable))> f1 = one;
only_movable om1(1);
BOOST_CHECK(f1(boost::move(om1)) == 1);
function <only_movable(BOOST_RV_REF(only_movable))> 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 <int(std::string&&)> f3 = three;
function <std::string&& (std::string&& s)> f4 = four;
f3(std::string("Hello"));
BOOST_CHECK(f4(std::string("world")) == "world");
#endif
return 0;
}