From 374711d2c63a1a442f6389dce3bb489f0aea3a2f Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 8 Oct 2002 02:32:38 +0000 Subject: [PATCH] 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] --- include/boost/function/function_template.hpp | 41 +++++++++++++++----- test/function_test.cpp | 38 +++++++++--------- test/function_test_fail1.cpp | 4 +- test/function_test_fail2.cpp | 2 +- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/include/boost/function/function_template.hpp b/include/boost/function/function_template.hpp index 1a03093..0630ec8 100644 --- a/include/boost/function/function_template.hpp +++ b/include/boost/function/function_template.hpp @@ -533,6 +533,11 @@ class function BOOST_FUNCTION_COMMA Allocator> base_type; typedef function self_type; + struct clear_type {}; + + class holder; + friend class holder; + public: typedef typename base_type::allocator_type allocator_type; @@ -543,26 +548,44 @@ public: function(const self_type& f) : base_type(static_cast(f)){} - template - self_type& operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) + self_type& operator=(self_type& f) { self_type(f).swap(*this); return *this; } - self_type& operator=(const base_type& f) - { - self_type(f).swap(*this); - return *this; - } + inline self_type& operator=(holder h); - self_type& operator=(const self_type& f) + self_type& operator=(clear_type*) { - self_type(f).swap(*this); + this->clear(); return *this; } }; +template +class function::holder +{ +public: + template holder(F f) : func(f) {} + holder(const base_type& f) : func(f) {} + holder(const self_type& f) : func(f) {} + + self_type func; +}; + +template +function& +function::operator=(holder h) +{ + h.func.swap(*this); + return *this; +} + #undef BOOST_FUNCTION_PARTIAL_SPEC #endif // have partial specialization diff --git a/test/function_test.cpp b/test/function_test.cpp index 50a072f..01cb5b0 100644 --- a/test/function_test.cpp +++ b/test/function_test.cpp @@ -65,9 +65,9 @@ test_zero_args() func_void_type v1; BOOST_TEST(v1.empty()); - // Assignment to an empty function + // Assignment to an empty function v1 = five; - BOOST_TEST(!v1.empty()); + BOOST_TEST(v1 != 0); // Invocation of a function global_int = 0; @@ -76,7 +76,7 @@ test_zero_args() // clear() method v1.clear(); - BOOST_TEST(v1.empty()); + BOOST_TEST(v1 == 0); // Assignment to an empty function v1 = three; @@ -97,13 +97,13 @@ test_zero_args() v1(); BOOST_TEST(global_int == 5); - // clear() - v1.clear(); - BOOST_TEST(v1.empty()); + // clear + v1 = 0; + BOOST_TEST(0 == v1); // Assignment to an empty function from a free function v1 = BOOST_FUNCTION_TARGET_FIX(&) write_five; - BOOST_TEST(!v1.empty()); + BOOST_TEST(0 != v1); // Invocation global_int = 0; @@ -210,8 +210,8 @@ test_zero_args() // Assignment to a function from an empty function v2 = v1; - BOOST_TEST(v2.empty()); - + BOOST_TEST(v2.empty()); + // Assignment to a function from a function with a functor v1 = three; v2 = v1; @@ -245,7 +245,7 @@ test_zero_args() global_int = 0; v3(); BOOST_TEST(global_int == 5); - + // clear() method v3.clear(); BOOST_TEST(!v3? true : false); @@ -305,7 +305,7 @@ test_zero_args() global_int = 0; v4(); BOOST_TEST(global_int == 5); - + // clear() method v4.clear(); BOOST_TEST(v4.empty()); @@ -365,7 +365,7 @@ test_zero_args() global_int = 0; v5(); BOOST_TEST(global_int == 5); - + // clear() method v5.clear(); BOOST_TEST(v5.empty()); @@ -416,7 +416,7 @@ test_zero_args() // Invocation global_int = 0; v5(); - BOOST_TEST(global_int == 5); + BOOST_TEST(global_int == 5); // Construction of a function from a function func_void_type v6(&write_five); @@ -476,7 +476,7 @@ test_zero_args() // Invocation global_int = 0; v6(); - BOOST_TEST(global_int == 5); + BOOST_TEST(global_int == 5); // Const vs. non-const write_const_1_nonconst_2 one_or_two; @@ -486,7 +486,7 @@ test_zero_args() global_int = 0; v7(); BOOST_TEST(global_int == 2); - + global_int = 0; v8(); BOOST_TEST(global_int == 2); @@ -551,7 +551,7 @@ static void test_two_args() { function cat(&string_cat); - BOOST_TEST(cat("str", "ing") == "string"); + BOOST_TEST(cat("str", "ing") == "string"); function sum(&sum_ints); BOOST_TEST(sum(2, 3) == 5); @@ -585,7 +585,7 @@ static void test_member_functions() { boost::function f1(&X::twice); - + X one(1); X five(5); @@ -644,7 +644,7 @@ struct counting_allocator : public allocator typedef counting_allocator other; }; - + T* allocate(size_t n) { alloc_count++; @@ -688,7 +688,7 @@ static void test_allocator() fv.clear(); BOOST_TEST(alloc_count == 1); BOOST_TEST(dealloc_count == 1); - + alloc_count = 0; dealloc_count = 0; fv = &do_nothing; diff --git a/test/function_test_fail1.cpp b/test/function_test_fail1.cpp index 3f85e26..b09caeb 100644 --- a/test/function_test_fail1.cpp +++ b/test/function_test_fail1.cpp @@ -23,8 +23,8 @@ using namespace boost; int test_main(int, char*[]) { - function f1; - function f2; + function0 f1; + function0 f2; if (f1 == f2) { } diff --git a/test/function_test_fail2.cpp b/test/function_test_fail2.cpp index 620ba38..3fd4087 100644 --- a/test/function_test_fail2.cpp +++ b/test/function_test_fail2.cpp @@ -25,7 +25,7 @@ static int bad_fn(float f) { return static_cast(f); } int test_main(int, char*[]) { - function f1; + function0 f1; f1 = bad_fn; BOOST_CRITICAL_ERROR("This should not have compiled.");