diff --git a/include/boost/function/function_base.hpp b/include/boost/function/function_base.hpp index 064fdde..8c8ad3b 100644 --- a/include/boost/function/function_base.hpp +++ b/include/boost/function/function_base.hpp @@ -99,12 +99,12 @@ namespace boost { // For pointers to std::type_info objects struct type_t { // (get_functor_type_tag, check_functor_type_tag). - const std::type_info* type; + const BOOST_FUNCTION_STD_NS::type_info* type; // Whether the type is const-qualified. - bool const_qualified : 1; + bool const_qualified; // Whether the type is volatile-qualified. - bool volatile_qualified : 1; + bool volatile_qualified; } type; // For function pointers of all kinds @@ -120,8 +120,8 @@ namespace boost { // track of the cv-qualifiers on the object referenced. struct obj_ref_t { mutable void* obj_ptr; - bool is_const : 1; - bool is_volatile : 1; + bool is_const_qualified; + bool is_volatile_qualified; } obj_ref; // To relax aliasing constraints @@ -217,9 +217,9 @@ namespace boost { // Check whether we have the same type. We can add // cv-qualifiers, but we can't take them away. if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(F)) - && (!in_buffer.obj_ref.is_const + && (!in_buffer.obj_ref.is_const_qualified || out_buffer.type.const_qualified) - && (!in_buffer.obj_ref.is_volatile + && (!in_buffer.obj_ref.is_volatile_qualified || out_buffer.type.volatile_qualified)) out_buffer.obj_ptr = in_buffer.obj_ref.obj_ptr; else @@ -229,8 +229,8 @@ namespace boost { case get_functor_type_tag: out_buffer.type.type = &typeid(F); - out_buffer.type.const_qualified = in_buffer.obj_ref.is_const; - out_buffer.type.volatile_qualified = in_buffer.obj_ref.is_volatile; + out_buffer.type.const_qualified = in_buffer.obj_ref.is_const_qualified; + out_buffer.type.volatile_qualified = in_buffer.obj_ref.is_volatile_qualified; return; } } diff --git a/include/boost/function/function_template.hpp b/include/boost/function/function_template.hpp index a3ee7c1..7730903 100644 --- a/include/boost/function/function_template.hpp +++ b/include/boost/function/function_template.hpp @@ -517,8 +517,8 @@ namespace boost { { if (!boost::detail::function::has_empty_target(f.get_pointer())) { functor.obj_ref.obj_ptr = (void *)f.get_pointer(); - functor.obj_ref.is_const = is_const::value; - functor.obj_ref.is_volatile = is_volatile::value; + functor.obj_ref.is_const_qualified = is_const::value; + functor.obj_ref.is_volatile_qualified = is_volatile::value; return true; } else { return false; @@ -801,6 +801,7 @@ namespace boost { this->vtable = f.vtable; f.vtable->manager(f.functor, this->functor, boost::detail::function::move_functor_tag); + f.vtable = 0; #if !defined(BOOST_NO_EXCEPTIONS) } else { clear(); diff --git a/test/function_n_test.cpp b/test/function_n_test.cpp index 14439a8..5d8d0d5 100644 --- a/test/function_n_test.cpp +++ b/test/function_n_test.cpp @@ -636,6 +636,52 @@ test_ref() } } +static unsigned construction_count = 0; +static unsigned destruction_count = 0; + +struct MySmallFunctor { + MySmallFunctor() { ++construction_count; } + MySmallFunctor(const MySmallFunctor &) { ++construction_count; } + ~MySmallFunctor() { ++destruction_count; } + int operator()() { return 0; } + }; + +struct MyLargeFunctor { + MyLargeFunctor() { ++construction_count; } + MyLargeFunctor(const MyLargeFunctor &) { ++construction_count; } + ~MyLargeFunctor() { ++destruction_count; } + int operator()() { return 0; } + }; + +void test_construct_destroy_count() +{ + { + boost::function0 f; + boost::function0 g; + f = MySmallFunctor(); + g = MySmallFunctor(); + f.swap(g); + } + + // MySmallFunctor objects should be constructed as many times as + // they are destroyed. + BOOST_CHECK(construction_count == destruction_count); + + construction_count = 0; + destruction_count = 0; + { + boost::function0 f; + boost::function0 g; + f = MyLargeFunctor(); + g = MyLargeFunctor(); + f.swap(g); + } + + // MyLargeFunctor objects should be constructed as many times as + // they are destroyed. + BOOST_CHECK(construction_count == destruction_count); +} + int test_main(int, char* []) { test_zero_args(); @@ -644,5 +690,6 @@ int test_main(int, char* []) test_emptiness(); test_member_functions(); test_ref(); + test_construct_destroy_count(); return 0; }