diff --git a/src/lib/del-stash.hpp b/src/lib/del-stash.hpp index 468e9d1c9..fa3c87eb5 100644 --- a/src/lib/del-stash.hpp +++ b/src/lib/del-stash.hpp @@ -55,6 +55,8 @@ namespace lib { + using boost::disable_if_c; + using boost::is_same; /** * Manage a collection of deleter functions. @@ -94,6 +96,12 @@ namespace lib { bool operator== (const void* target) const { return target_ == target; } bool operator!= (const void* target) const { return target_ != target; } + + bool + isActive() const + { + return bool(target_); + } }; @@ -125,24 +133,32 @@ namespace lib { size_t size () const { - return killers_.size(); + size_t activeEntries = 0; + size_t i = killers_.size(); + while (i) + if (killers_[--i].isActive()) + ++activeEntries; + return activeEntries; } -#define __DONT_USE_THIS_OVERLOAD_FOR_VOID_POINTER_ typename boost::disable_if >::type* =0 +#define __DONT_USE_THIS_OVERLOAD_FOR_VOID_POINTER_ \ + typename disable_if_c< is_same::value \ + ||is_same::value>::type* =0 template void manage (TY* obj, __DONT_USE_THIS_OVERLOAD_FOR_VOID_POINTER_) { + if (!obj) return; REQUIRE (!isRegistered (obj)); killers_.push_back (Killer (how_to_kill, obj)); } template void - manage (TY& obj) + manage (TY& obj, __DONT_USE_THIS_OVERLOAD_FOR_VOID_POINTER_) { REQUIRE (!isRegistered (&obj)); killers_.push_back (Killer (how_to_kill, &obj)); @@ -152,6 +168,7 @@ namespace lib { void manage (void *obj) { + if (!obj) return; REQUIRE (!isRegistered (obj)); killers_.push_back (Killer (how_to_kill, obj)); } @@ -175,11 +192,9 @@ namespace lib { void killAll () { - size_t i = size(); + size_t i = killers_.size(); while (i) - { - killers_[i].trigger(); - } + killers_[--i].trigger(); } diff --git a/tests/40components.tests b/tests/40components.tests index d729cc964..241606571 100644 --- a/tests/40components.tests +++ b/tests/40components.tests @@ -226,7 +226,7 @@ return: 0 END -PLANNED "Deleter function collection" DelStash_test < #include @@ -33,14 +31,13 @@ namespace lib { namespace test{ - using std::tr1::function; using std::rand; namespace { // probe victims - ulong MAX_MASS = 200; // number of victims for mass kill + ulong MAX_MASS = 200; // number of victims to kill at once ulong checksum = 0; @@ -73,13 +70,21 @@ namespace test{ }; - template - Probe* + template + inline Probe* makeViktim () { - return new Probe(); + return new Probe(); } + template + inline void + feedViktim (DelStash& killer) + { + killer.manage (new Probe()); + } + + }//(End) test data @@ -88,7 +93,11 @@ namespace test{ /**************************************************************************** * @test create a bunch of objects with varying type and size, memorising * how to kill them properly. Verify everyone is dead after mass-kill. - * + * Use a checksum not only to verify the number of objects created and + * destroyed, but also the individual (random) contents of the data + * within the objects, to ensure that the correct destructor + * actually is invoked for each type. + * * @see lib::DelStash */ class DelStash_test : public Test @@ -130,8 +139,8 @@ namespace test{ killer.kill (p); CHECK (1 == killer.size()); - killer.kill (p); // ignores spurious kill requests - CHECK (1 == killer.size()); + killer.kill (p); + CHECK (1 == killer.size()); // spurious kill requests ignored killer.kill (v); CHECK (0 == killer.size()); @@ -142,15 +151,14 @@ namespace test{ void feedViktims (DelStash& killer) { - function builder[5]; - builder[0] = makeViktim<12>; - builder[1] = makeViktim<23>; - builder[2] = makeViktim<34>; - builder[3] = makeViktim<45>; - builder[4] = makeViktim<56>; - for (uint i=1; i <= MAX_MASS; ++i) - killer.manage (builder[i % 5]()); + switch (i% 5) { + case 0: feedViktim<12> (killer); break; + case 1: feedViktim<23> (killer); break; + case 2: feedViktim<34> (killer); break; + case 3: feedViktim<45> (killer); break; + case 4: feedViktim<56> (killer); break; + } } @@ -181,7 +189,7 @@ namespace test{ CHECK (0 == checksum); feedViktims (killer); - void * individuum = makeViktim<444>(); + Probe<444> * individuum = makeViktim<444>(); killer.manage (individuum); feedViktims (killer); killer.manage (makeViktim<5555>());