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