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:
Douglas Gregor
2002-10-08 02:32:38 +00:00
parent 300fde19a1
commit 374711d2c6
4 changed files with 54 additions and 31 deletions

View File

@ -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

View File

@ -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;

View File

@ -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) {
} }

View File

@ -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.");