deleter memorising component passes unit test (#629)

This commit is contained in:
Fischlurch 2010-06-07 03:32:41 +02:00
parent 9aca348870
commit eb19f59ba0
3 changed files with 50 additions and 27 deletions

View file

@ -55,6 +55,8 @@
namespace lib { namespace lib {
using boost::disable_if_c;
using boost::is_same;
/** /**
* Manage a collection of deleter functions. * 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 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_t
size () const 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<boost::is_same<TY,void> >::type* =0 #define __DONT_USE_THIS_OVERLOAD_FOR_VOID_POINTER_ \
typename disable_if_c< is_same<TY,void>::value \
||is_same<TY,void*>::value>::type* =0
template<typename TY> template<typename TY>
void void
manage (TY* obj, __DONT_USE_THIS_OVERLOAD_FOR_VOID_POINTER_) manage (TY* obj, __DONT_USE_THIS_OVERLOAD_FOR_VOID_POINTER_)
{ {
if (!obj) return;
REQUIRE (!isRegistered (obj)); REQUIRE (!isRegistered (obj));
killers_.push_back (Killer (how_to_kill<TY>, obj)); killers_.push_back (Killer (how_to_kill<TY>, obj));
} }
template<typename TY> template<typename TY>
void void
manage (TY& obj) manage (TY& obj, __DONT_USE_THIS_OVERLOAD_FOR_VOID_POINTER_)
{ {
REQUIRE (!isRegistered (&obj)); REQUIRE (!isRegistered (&obj));
killers_.push_back (Killer (how_to_kill<TY>, &obj)); killers_.push_back (Killer (how_to_kill<TY>, &obj));
@ -152,6 +168,7 @@ namespace lib {
void void
manage (void *obj) manage (void *obj)
{ {
if (!obj) return;
REQUIRE (!isRegistered (obj)); REQUIRE (!isRegistered (obj));
killers_.push_back (Killer (how_to_kill<TY>, obj)); killers_.push_back (Killer (how_to_kill<TY>, obj));
} }
@ -175,11 +192,9 @@ namespace lib {
void void
killAll () killAll ()
{ {
size_t i = size(); size_t i = killers_.size();
while (i) while (i)
{ killers_[--i].trigger();
killers_[i].trigger();
}
} }

View file

@ -226,7 +226,7 @@ return: 0
END END
PLANNED "Deleter function collection" DelStash_test <<END TEST "Deleter function collection" DelStash_test <<END
return: 0 return: 0
END END

View file

@ -22,10 +22,8 @@
#include "lib/test/run.hpp" #include "lib/test/run.hpp"
#include "lib/del-stash.hpp" #include "lib/del-stash.hpp"
#include <tr1/functional>
#include <cstdlib> #include <cstdlib>
@ -33,14 +31,13 @@
namespace lib { namespace lib {
namespace test{ namespace test{
using std::tr1::function;
using std::rand; using std::rand;
namespace { // probe victims 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; ulong checksum = 0;
@ -73,13 +70,21 @@ namespace test{
}; };
template<uint i> template<uint x>
Probe<i>* inline Probe<x>*
makeViktim () makeViktim ()
{ {
return new Probe<i>(); return new Probe<x>();
} }
template<uint x>
inline void
feedViktim (DelStash& killer)
{
killer.manage (new Probe<x>());
}
}//(End) test data }//(End) test data
@ -88,6 +93,10 @@ namespace test{
/**************************************************************************** /****************************************************************************
* @test create a bunch of objects with varying type and size, memorising * @test create a bunch of objects with varying type and size, memorising
* how to kill them properly. Verify everyone is dead after mass-kill. * 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 * @see lib::DelStash
*/ */
@ -130,8 +139,8 @@ namespace test{
killer.kill (p); killer.kill (p);
CHECK (1 == killer.size()); CHECK (1 == killer.size());
killer.kill (p); // ignores spurious kill requests killer.kill (p);
CHECK (1 == killer.size()); CHECK (1 == killer.size()); // spurious kill requests ignored
killer.kill (v); killer.kill (v);
CHECK (0 == killer.size()); CHECK (0 == killer.size());
@ -142,15 +151,14 @@ namespace test{
void void
feedViktims (DelStash& killer) feedViktims (DelStash& killer)
{ {
function<void*(void)> 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) 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); CHECK (0 == checksum);
feedViktims (killer); feedViktims (killer);
void * individuum = makeViktim<444>(); Probe<444> * individuum = makeViktim<444>();
killer.manage (individuum); killer.manage (individuum);
feedViktims (killer); feedViktims (killer);
killer.manage (makeViktim<5555>()); killer.manage (makeViktim<5555>());