now able to implement ScopedPtrVect iteration properly

This commit is contained in:
Fischlurch 2009-07-16 19:36:01 +02:00
parent a0187847da
commit 4f5fca6858
3 changed files with 63 additions and 17 deletions

View file

@ -25,13 +25,14 @@
** build and own a number of objects, including lifecycle management. ** build and own a number of objects, including lifecycle management.
** For example, a service provider may need to maintain a number of individual ** For example, a service provider may need to maintain a number of individual
** process handles. The solution here is deliberately kept simple, it is ** process handles. The solution here is deliberately kept simple, it is
** similar to using a stl container with shared_ptr(s), but behaves rather ** similar to using a STL container with shared_ptr(s), but behaves rather
** like boost::scoped_ptr. It provides the same basic functionality as ** like boost::scoped_ptr. It provides the same basic functionality as
** boost::ptr_vector, but doesn't require us to depend on boost-serialisation. ** boost::ptr_vector, but doesn't require us to depend on boost-serialisation.
** **
** Some details to note: ** Some details to note:
** - contained objects accessed by reference, never NULL. ** - contained objects accessed by reference, never NULL.
** - TODO: iterators, detaching of objects... ** - the exposed iterator automatically dereferences
** - TODO: detaching of objects...
** - TODO: retro-fit with refarray interface (--> builder branch) ** - TODO: retro-fit with refarray interface (--> builder branch)
** **
** @see scoped-ptrvect-test.cpp ** @see scoped-ptrvect-test.cpp
@ -70,6 +71,12 @@ namespace lib {
boost::noncopyable boost::noncopyable
{ {
typedef std::vector<T*> _Vec; typedef std::vector<T*> _Vec;
typedef typename _Vec::iterator VIter;
typedef typename _Vec::const_iterator VcIter;
typedef RangeIter<VIter> RIter;
typedef RangeIter<VcIter> RcIter;
public: public:
typedef size_t size_type; typedef size_t size_type;
@ -118,7 +125,6 @@ namespace lib {
void void
clear() clear()
{ {
typedef typename _Vec::iterator VIter;
VIter e = _Vec::end(); VIter e = _Vec::end();
for (VIter i = _Vec::begin(); i!=e; ++i) for (VIter i = _Vec::begin(); i!=e; ++i)
{ {
@ -144,11 +150,11 @@ namespace lib {
return *get(i); return *get(i);
} }
typedef PtrDerefIter<typename _Vec::iterator> iterator; typedef PtrDerefIter<RIter> iterator;
typedef PtrDerefIter<typename _Vec::const_iterator> const_iterator; typedef PtrDerefIter<RcIter> const_iterator;
iterator begin() { return iterator (_Vec::begin()); } iterator begin() { return iterator (allPtrs()); }
const_iterator begin() const { return const_iterator (_Vec::begin()); } const_iterator begin() const { return const_iterator (allPtrs()); }
iterator end() { return iterator (); } iterator end() { return iterator (); }
const_iterator end() const { return const_iterator (); } const_iterator end() const { return const_iterator (); }
@ -164,8 +170,9 @@ namespace lib {
private: private:
/** internal element access, including null check */ /** @internal element access, including null check */
T* get(size_type i) T*
get (size_type i)
{ {
T* p (_Vec::at (i)); T* p (_Vec::at (i));
if (!p) if (!p)
@ -173,6 +180,13 @@ namespace lib {
else else
return p; return p;
} }
/** @internal access sequence of all managed pointers */
RIter
allPtrs ()
{
return RIter (_Vec::begin(), _Vec::end());
}
}; };

View file

@ -40,6 +40,7 @@ namespace test{
/******************************************************************** /********************************************************************
* @test ScopedPtrVect manages the lifecycle of a number of objects. * @test ScopedPtrVect manages the lifecycle of a number of objects.
* @todo cover the const iterator and implement detaching of objects
*/ */
class ScopedPtrVect_test : public Test class ScopedPtrVect_test : public Test
{ {
@ -48,7 +49,7 @@ namespace test{
run (Arg) run (Arg)
{ {
simpleUsage(); simpleUsage();
// iterating(); iterating();
// detaching(); // detaching();
} }
@ -92,6 +93,28 @@ namespace test{
ASSERT (0==checksum); ASSERT (0==checksum);
} }
void
iterating()
{
ASSERT (0==checksum);
{
VectD holder;
for (int i=0; i<16; ++i)
holder.manage(new Dummy(i));
int check=0;
VectD::iterator ii = holder.begin();
while (ii)
{
ASSERT (check == ii->getVal());
++check;
++ii;
}
}
ASSERT (0==checksum);
}
}; };
LAUNCHER (ScopedPtrVect_test, "unit common"); LAUNCHER (ScopedPtrVect_test, "unit common");

View file

@ -41,20 +41,19 @@ namespace test{
public: public:
Dummy () Dummy ()
: val_(1 + (rand() % 100000000)) : val_(1 + (rand() % 100000000))
{ { init(); }
checksum += val_;
if (throw_in_ctor) Dummy (int v)
throw val_; : val_(v)
} { init(); }
~Dummy() ~Dummy()
{ {
checksum -= val_; checksum -= val_;
} }
long add (int i) { return val_+i; } long add (int i) { return val_+i; }
protected:
int getVal() const { return val_; } int getVal() const { return val_; }
void void
@ -63,6 +62,16 @@ namespace test{
checksum += newVal - val_; checksum += newVal - val_;
val_ = newVal; val_ = newVal;
} }
private:
void
init()
{
checksum += val_;
if (throw_in_ctor)
throw val_;
}
}; };
} // anonymous test dummy } // anonymous test dummy