forked from boostorg/function
Merge branch 'develop'
This commit is contained in:
@ -294,7 +294,7 @@ namespace boost {
|
|||||||
} else if (op == destroy_functor_tag)
|
} else if (op == destroy_functor_tag)
|
||||||
out_buffer.func_ptr = 0;
|
out_buffer.func_ptr = 0;
|
||||||
else if (op == check_functor_type_tag) {
|
else if (op == check_functor_type_tag) {
|
||||||
const detail::sp_typeinfo& check_type
|
const boost::detail::sp_typeinfo& check_type
|
||||||
= *out_buffer.type.type;
|
= *out_buffer.type.type;
|
||||||
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
|
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
|
||||||
out_buffer.obj_ptr = &in_buffer.func_ptr;
|
out_buffer.obj_ptr = &in_buffer.func_ptr;
|
||||||
|
@ -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)
|
||||||
|
|
||||||
#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 <boost/move/utility_core.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);
|
||||||
@ -914,10 +920,10 @@ namespace boost {
|
|||||||
template<typename Functor>
|
template<typename Functor>
|
||||||
void assign_to(Functor f)
|
void assign_to(Functor f)
|
||||||
{
|
{
|
||||||
using detail::function::vtable_base;
|
using boost::detail::function::vtable_base;
|
||||||
|
|
||||||
typedef typename detail::function::get_function_tag<Functor>::type tag;
|
typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
|
||||||
typedef detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
|
typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
|
||||||
typedef typename get_invoker::
|
typedef typename get_invoker::
|
||||||
template apply<Functor, R BOOST_FUNCTION_COMMA
|
template apply<Functor, R BOOST_FUNCTION_COMMA
|
||||||
BOOST_FUNCTION_TEMPLATE_ARGS>
|
BOOST_FUNCTION_TEMPLATE_ARGS>
|
||||||
@ -938,9 +944,9 @@ namespace boost {
|
|||||||
// coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
|
// coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
|
||||||
if (boost::has_trivial_copy_constructor<Functor>::value &&
|
if (boost::has_trivial_copy_constructor<Functor>::value &&
|
||||||
boost::has_trivial_destructor<Functor>::value &&
|
boost::has_trivial_destructor<Functor>::value &&
|
||||||
detail::function::function_allows_small_object_optimization<Functor>::value)
|
boost::detail::function::function_allows_small_object_optimization<Functor>::value)
|
||||||
value |= static_cast<std::size_t>(0x01);
|
value |= static_cast<std::size_t>(0x01);
|
||||||
vtable = reinterpret_cast<detail::function::vtable_base *>(value);
|
vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
|
||||||
} else
|
} else
|
||||||
vtable = 0;
|
vtable = 0;
|
||||||
}
|
}
|
||||||
@ -948,10 +954,10 @@ namespace boost {
|
|||||||
template<typename Functor,typename Allocator>
|
template<typename Functor,typename Allocator>
|
||||||
void assign_to_a(Functor f,Allocator a)
|
void assign_to_a(Functor f,Allocator a)
|
||||||
{
|
{
|
||||||
using detail::function::vtable_base;
|
using boost::detail::function::vtable_base;
|
||||||
|
|
||||||
typedef typename detail::function::get_function_tag<Functor>::type tag;
|
typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
|
||||||
typedef detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
|
typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
|
||||||
typedef typename get_invoker::
|
typedef typename get_invoker::
|
||||||
template apply_a<Functor, R BOOST_FUNCTION_COMMA
|
template apply_a<Functor, R BOOST_FUNCTION_COMMA
|
||||||
BOOST_FUNCTION_TEMPLATE_ARGS,
|
BOOST_FUNCTION_TEMPLATE_ARGS,
|
||||||
@ -973,9 +979,9 @@ namespace boost {
|
|||||||
// coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
|
// coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
|
||||||
if (boost::has_trivial_copy_constructor<Functor>::value &&
|
if (boost::has_trivial_copy_constructor<Functor>::value &&
|
||||||
boost::has_trivial_destructor<Functor>::value &&
|
boost::has_trivial_destructor<Functor>::value &&
|
||||||
detail::function::function_allows_small_object_optimization<Functor>::value)
|
boost::detail::function::function_allows_small_object_optimization<Functor>::value)
|
||||||
value |= static_cast<std::size_t>(0x01);
|
value |= static_cast<std::size_t>(0x01);
|
||||||
vtable = reinterpret_cast<detail::function::vtable_base *>(value);
|
vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
|
||||||
} else
|
} else
|
||||||
vtable = 0;
|
vtable = 0;
|
||||||
}
|
}
|
||||||
@ -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
|
||||||
|
18
meta/libraries.json
Normal file
18
meta/libraries.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"key": "function",
|
||||||
|
"name": "Function",
|
||||||
|
"authors": [
|
||||||
|
"Doug Gregor"
|
||||||
|
],
|
||||||
|
"description": "Function object wrappers for deferred calls or callbacks.",
|
||||||
|
"std": [
|
||||||
|
"tr1"
|
||||||
|
],
|
||||||
|
"category": [
|
||||||
|
"Function-objects",
|
||||||
|
"Programming"
|
||||||
|
],
|
||||||
|
"maintainers": [
|
||||||
|
"Douglas Gregor <dgregor -at- cs.indiana.edu>"
|
||||||
|
]
|
||||||
|
}
|
@ -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 ]
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
106
test/rvalues_test.cpp
Normal file
106
test/rvalues_test.cpp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
only_movable two_sum(BOOST_RV_REF(only_movable) t1, BOOST_RV_REF(only_movable) t2) {
|
||||||
|
only_movable ret(t1.get_value() + t2.get_value());
|
||||||
|
return BOOST_MOVE_RET(only_movable, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sum_struct {
|
||||||
|
only_movable operator()(BOOST_RV_REF(only_movable) t1, BOOST_RV_REF(only_movable) t2) const {
|
||||||
|
only_movable ret(t1.get_value() + t2.get_value());
|
||||||
|
return BOOST_MOVE_RET(only_movable, ret);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#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());
|
||||||
|
|
||||||
|
{
|
||||||
|
function <only_movable(BOOST_RV_REF(only_movable), BOOST_RV_REF(only_movable))> f2_sum = two_sum;
|
||||||
|
only_movable om1_sum(1), om2_sum(2);
|
||||||
|
only_movable om2_sum_2 = f2_sum(boost::move(om1_sum), boost::move(om2_sum));
|
||||||
|
BOOST_CHECK(om2_sum_2.get_value() == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
sum_struct s;
|
||||||
|
function <only_movable(BOOST_RV_REF(only_movable), BOOST_RV_REF(only_movable))> f2_sum = s;
|
||||||
|
only_movable om1_sum(1), om2_sum(2);
|
||||||
|
only_movable om2_sum_2 = f2_sum(boost::move(om1_sum), boost::move(om2_sum));
|
||||||
|
BOOST_CHECK(om2_sum_2.get_value() == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
Reference in New Issue
Block a user