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:
parent
9bba366763
commit
e6888f7b83
2 changed files with 76 additions and 0 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue