supplement direct support for populating by member function

this turns out to be the typical usage scenario
for ScopedCollection: a manager object owning
the collection will populate it with specially
crafted components and invoke a member function
for creating the individual components.

This shortcut avoids using tr1::bind alltogether
This commit is contained in:
Fischlurch 2012-01-07 04:11:39 +01:00
parent 9bba366763
commit e6888f7b83
2 changed files with 76 additions and 0 deletions

View file

@ -257,6 +257,33 @@ namespace lib {
throw;
} }
/** variation of RAII-style: using a builder function,
* which is a member of some object. This supports the
* typical usage situation, where a manager object builds
* a ScopedCollection of some components
* @param builder member function used to create the elements
* @param instance the owning class instance, on which the
* builder member function will be invoked ("this").
*/
template<class TY>
ScopedCollection (size_t maxElements, void (TY::*builder) (ElementHolder&), TY * const instance)
: level_(0)
, capacity_(maxElements)
, elements_(new ElementHolder[maxElements])
{
try {
while (level_ < capacity_)
{
ElementHolder& storageFrame (elements_[level_]);
(instance->*builder) (storageFrame);
++level_;
}}
catch(...)
{
clear();
throw;
} }
/* == some pre-defined Builders == */
class FillAll; ///< fills the ScopedCollection with default constructed I-instances

View file

@ -111,6 +111,7 @@ namespace test{
iterating();
verify_defaultPopulator();
verify_iteratorPopulator();
verify_embeddedCollection();
}
@ -416,6 +417,54 @@ namespace test{
// note: the iterator is assumed to deliver a sufficient amount of elements
VERIFY_ERROR (ITER_EXHAUST, CollI (50, CollI::pull (source.begin())));
}
/** @test simulate the typical situation of a manager
* owning some embedded components. Here, our ManagerDemo
* instance owns a collection of numbers 50..1. They are
* created right while initialising the manager, and this
* initialisation is done by invoking a member function
* of the manager
*/
void
verify_embeddedCollection()
{
ManagerDemo object_with_embedded_Collection(50);
CHECK (sum(50) == object_with_embedded_Collection.useMyNumbers());
}
class ManagerDemo
{
typedef ScopedCollection<uint> CollI;
uint memberVar_;
const CollI my_own_Numbers_;
void
buildNumbers (CollI::ElementHolder& storage)
{
storage.create<uint>(memberVar_);
--memberVar_;
}
public:
ManagerDemo(uint cnt)
: memberVar_(cnt)
, my_own_Numbers_(cnt, &ManagerDemo::buildNumbers, this)
{
CHECK (0 == memberVar_);
CHECK (cnt == my_own_Numbers_.size());
}
uint
useMyNumbers()
{
uint sum(0);
for (CollI::const_iterator ii = my_own_Numbers_.begin(); ii; ++ii)
sum += *ii;
return sum;
}
};
};