forked from boostorg/function
function_template.hpp:
- function partial specialization now allows assignment to zero (for clearing) and comparison against zero (for the empty check) (Brad King) function_test.cpp: - Check comparison against zero - Check assignment to zero function_test_fail1.cpp: function_test_fail2.cpp: - Make them fail for the right reasons [SVN r15803]
This commit is contained in:
@ -533,6 +533,11 @@ class function<BOOST_FUNCTION_PARTIAL_SPEC, Allocator>
|
|||||||
BOOST_FUNCTION_COMMA Allocator> base_type;
|
BOOST_FUNCTION_COMMA Allocator> base_type;
|
||||||
typedef function self_type;
|
typedef function self_type;
|
||||||
|
|
||||||
|
struct clear_type {};
|
||||||
|
|
||||||
|
class holder;
|
||||||
|
friend class holder;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename base_type::allocator_type allocator_type;
|
typedef typename base_type::allocator_type allocator_type;
|
||||||
|
|
||||||
@ -543,26 +548,44 @@ public:
|
|||||||
|
|
||||||
function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
|
function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
|
||||||
|
|
||||||
template<typename Functor>
|
self_type& operator=(self_type& f)
|
||||||
self_type& operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
|
|
||||||
{
|
{
|
||||||
self_type(f).swap(*this);
|
self_type(f).swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
self_type& operator=(const base_type& f)
|
inline self_type& operator=(holder h);
|
||||||
{
|
|
||||||
self_type(f).swap(*this);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
self_type& operator=(const self_type& f)
|
self_type& operator=(clear_type*)
|
||||||
{
|
{
|
||||||
self_type(f).swap(*this);
|
this->clear();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_PARMS,
|
||||||
|
typename Allocator>
|
||||||
|
class function<BOOST_FUNCTION_PARTIAL_SPEC, Allocator>::holder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template<typename F> holder(F f) : func(f) {}
|
||||||
|
holder(const base_type& f) : func(f) {}
|
||||||
|
holder(const self_type& f) : func(f) {}
|
||||||
|
|
||||||
|
self_type func;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_PARMS,
|
||||||
|
typename Allocator>
|
||||||
|
function<BOOST_FUNCTION_PARTIAL_SPEC, Allocator>&
|
||||||
|
function<BOOST_FUNCTION_PARTIAL_SPEC, Allocator>::operator=(holder h)
|
||||||
|
{
|
||||||
|
h.func.swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
#undef BOOST_FUNCTION_PARTIAL_SPEC
|
#undef BOOST_FUNCTION_PARTIAL_SPEC
|
||||||
#endif // have partial specialization
|
#endif // have partial specialization
|
||||||
|
|
||||||
|
@ -65,9 +65,9 @@ test_zero_args()
|
|||||||
func_void_type v1;
|
func_void_type v1;
|
||||||
BOOST_TEST(v1.empty());
|
BOOST_TEST(v1.empty());
|
||||||
|
|
||||||
// Assignment to an empty function
|
// Assignment to an empty function
|
||||||
v1 = five;
|
v1 = five;
|
||||||
BOOST_TEST(!v1.empty());
|
BOOST_TEST(v1 != 0);
|
||||||
|
|
||||||
// Invocation of a function
|
// Invocation of a function
|
||||||
global_int = 0;
|
global_int = 0;
|
||||||
@ -76,7 +76,7 @@ test_zero_args()
|
|||||||
|
|
||||||
// clear() method
|
// clear() method
|
||||||
v1.clear();
|
v1.clear();
|
||||||
BOOST_TEST(v1.empty());
|
BOOST_TEST(v1 == 0);
|
||||||
|
|
||||||
// Assignment to an empty function
|
// Assignment to an empty function
|
||||||
v1 = three;
|
v1 = three;
|
||||||
@ -97,13 +97,13 @@ test_zero_args()
|
|||||||
v1();
|
v1();
|
||||||
BOOST_TEST(global_int == 5);
|
BOOST_TEST(global_int == 5);
|
||||||
|
|
||||||
// clear()
|
// clear
|
||||||
v1.clear();
|
v1 = 0;
|
||||||
BOOST_TEST(v1.empty());
|
BOOST_TEST(0 == v1);
|
||||||
|
|
||||||
// Assignment to an empty function from a free function
|
// Assignment to an empty function from a free function
|
||||||
v1 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
|
v1 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
|
||||||
BOOST_TEST(!v1.empty());
|
BOOST_TEST(0 != v1);
|
||||||
|
|
||||||
// Invocation
|
// Invocation
|
||||||
global_int = 0;
|
global_int = 0;
|
||||||
@ -210,8 +210,8 @@ test_zero_args()
|
|||||||
|
|
||||||
// Assignment to a function from an empty function
|
// Assignment to a function from an empty function
|
||||||
v2 = v1;
|
v2 = v1;
|
||||||
BOOST_TEST(v2.empty());
|
BOOST_TEST(v2.empty());
|
||||||
|
|
||||||
// Assignment to a function from a function with a functor
|
// Assignment to a function from a function with a functor
|
||||||
v1 = three;
|
v1 = three;
|
||||||
v2 = v1;
|
v2 = v1;
|
||||||
@ -245,7 +245,7 @@ test_zero_args()
|
|||||||
global_int = 0;
|
global_int = 0;
|
||||||
v3();
|
v3();
|
||||||
BOOST_TEST(global_int == 5);
|
BOOST_TEST(global_int == 5);
|
||||||
|
|
||||||
// clear() method
|
// clear() method
|
||||||
v3.clear();
|
v3.clear();
|
||||||
BOOST_TEST(!v3? true : false);
|
BOOST_TEST(!v3? true : false);
|
||||||
@ -305,7 +305,7 @@ test_zero_args()
|
|||||||
global_int = 0;
|
global_int = 0;
|
||||||
v4();
|
v4();
|
||||||
BOOST_TEST(global_int == 5);
|
BOOST_TEST(global_int == 5);
|
||||||
|
|
||||||
// clear() method
|
// clear() method
|
||||||
v4.clear();
|
v4.clear();
|
||||||
BOOST_TEST(v4.empty());
|
BOOST_TEST(v4.empty());
|
||||||
@ -365,7 +365,7 @@ test_zero_args()
|
|||||||
global_int = 0;
|
global_int = 0;
|
||||||
v5();
|
v5();
|
||||||
BOOST_TEST(global_int == 5);
|
BOOST_TEST(global_int == 5);
|
||||||
|
|
||||||
// clear() method
|
// clear() method
|
||||||
v5.clear();
|
v5.clear();
|
||||||
BOOST_TEST(v5.empty());
|
BOOST_TEST(v5.empty());
|
||||||
@ -416,7 +416,7 @@ test_zero_args()
|
|||||||
// Invocation
|
// Invocation
|
||||||
global_int = 0;
|
global_int = 0;
|
||||||
v5();
|
v5();
|
||||||
BOOST_TEST(global_int == 5);
|
BOOST_TEST(global_int == 5);
|
||||||
|
|
||||||
// Construction of a function from a function
|
// Construction of a function from a function
|
||||||
func_void_type v6(&write_five);
|
func_void_type v6(&write_five);
|
||||||
@ -476,7 +476,7 @@ test_zero_args()
|
|||||||
// Invocation
|
// Invocation
|
||||||
global_int = 0;
|
global_int = 0;
|
||||||
v6();
|
v6();
|
||||||
BOOST_TEST(global_int == 5);
|
BOOST_TEST(global_int == 5);
|
||||||
|
|
||||||
// Const vs. non-const
|
// Const vs. non-const
|
||||||
write_const_1_nonconst_2 one_or_two;
|
write_const_1_nonconst_2 one_or_two;
|
||||||
@ -486,7 +486,7 @@ test_zero_args()
|
|||||||
global_int = 0;
|
global_int = 0;
|
||||||
v7();
|
v7();
|
||||||
BOOST_TEST(global_int == 2);
|
BOOST_TEST(global_int == 2);
|
||||||
|
|
||||||
global_int = 0;
|
global_int = 0;
|
||||||
v8();
|
v8();
|
||||||
BOOST_TEST(global_int == 2);
|
BOOST_TEST(global_int == 2);
|
||||||
@ -551,7 +551,7 @@ static void
|
|||||||
test_two_args()
|
test_two_args()
|
||||||
{
|
{
|
||||||
function<string (const string&, const string&)> cat(&string_cat);
|
function<string (const string&, const string&)> cat(&string_cat);
|
||||||
BOOST_TEST(cat("str", "ing") == "string");
|
BOOST_TEST(cat("str", "ing") == "string");
|
||||||
|
|
||||||
function<int (short, short)> sum(&sum_ints);
|
function<int (short, short)> sum(&sum_ints);
|
||||||
BOOST_TEST(sum(2, 3) == 5);
|
BOOST_TEST(sum(2, 3) == 5);
|
||||||
@ -585,7 +585,7 @@ static void
|
|||||||
test_member_functions()
|
test_member_functions()
|
||||||
{
|
{
|
||||||
boost::function<int (X*)> f1(&X::twice);
|
boost::function<int (X*)> f1(&X::twice);
|
||||||
|
|
||||||
X one(1);
|
X one(1);
|
||||||
X five(5);
|
X five(5);
|
||||||
|
|
||||||
@ -644,7 +644,7 @@ struct counting_allocator : public allocator<T>
|
|||||||
typedef counting_allocator<U> other;
|
typedef counting_allocator<U> other;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
T* allocate(size_t n)
|
T* allocate(size_t n)
|
||||||
{
|
{
|
||||||
alloc_count++;
|
alloc_count++;
|
||||||
@ -688,7 +688,7 @@ static void test_allocator()
|
|||||||
fv.clear();
|
fv.clear();
|
||||||
BOOST_TEST(alloc_count == 1);
|
BOOST_TEST(alloc_count == 1);
|
||||||
BOOST_TEST(dealloc_count == 1);
|
BOOST_TEST(dealloc_count == 1);
|
||||||
|
|
||||||
alloc_count = 0;
|
alloc_count = 0;
|
||||||
dealloc_count = 0;
|
dealloc_count = 0;
|
||||||
fv = &do_nothing;
|
fv = &do_nothing;
|
||||||
|
@ -23,8 +23,8 @@ using namespace boost;
|
|||||||
int
|
int
|
||||||
test_main(int, char*[])
|
test_main(int, char*[])
|
||||||
{
|
{
|
||||||
function<int> f1;
|
function0<int> f1;
|
||||||
function<int> f2;
|
function0<int> f2;
|
||||||
|
|
||||||
if (f1 == f2) {
|
if (f1 == f2) {
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ static int bad_fn(float f) { return static_cast<int>(f); }
|
|||||||
int
|
int
|
||||||
test_main(int, char*[])
|
test_main(int, char*[])
|
||||||
{
|
{
|
||||||
function<int> f1;
|
function0<int> f1;
|
||||||
f1 = bad_fn;
|
f1 = bad_fn;
|
||||||
|
|
||||||
BOOST_CRITICAL_ERROR("This should not have compiled.");
|
BOOST_CRITICAL_ERROR("This should not have compiled.");
|
||||||
|
Reference in New Issue
Block a user