diff --git a/src/lib/scoped-ptrvect.hpp b/src/lib/scoped-ptrvect.hpp index 932bcffb6..d01992edc 100644 --- a/src/lib/scoped-ptrvect.hpp +++ b/src/lib/scoped-ptrvect.hpp @@ -25,13 +25,14 @@ ** build and own a number of objects, including lifecycle management. ** For example, a service provider may need to maintain a number of individual ** 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 ** boost::ptr_vector, but doesn't require us to depend on boost-serialisation. ** ** Some details to note: ** - 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) ** ** @see scoped-ptrvect-test.cpp @@ -70,6 +71,12 @@ namespace lib { boost::noncopyable { typedef std::vector _Vec; + typedef typename _Vec::iterator VIter; + typedef typename _Vec::const_iterator VcIter; + + typedef RangeIter RIter; + typedef RangeIter RcIter; + public: typedef size_t size_type; @@ -118,7 +125,6 @@ namespace lib { void clear() { - typedef typename _Vec::iterator VIter; VIter e = _Vec::end(); for (VIter i = _Vec::begin(); i!=e; ++i) { @@ -144,11 +150,11 @@ namespace lib { return *get(i); } - typedef PtrDerefIter iterator; - typedef PtrDerefIter const_iterator; + typedef PtrDerefIter iterator; + typedef PtrDerefIter const_iterator; - iterator begin() { return iterator (_Vec::begin()); } - const_iterator begin() const { return const_iterator (_Vec::begin()); } + iterator begin() { return iterator (allPtrs()); } + const_iterator begin() const { return const_iterator (allPtrs()); } iterator end() { return iterator (); } const_iterator end() const { return const_iterator (); } @@ -164,8 +170,9 @@ namespace lib { private: - /** internal element access, including null check */ - T* get(size_type i) + /** @internal element access, including null check */ + T* + get (size_type i) { T* p (_Vec::at (i)); if (!p) @@ -173,6 +180,13 @@ namespace lib { else return p; } + + /** @internal access sequence of all managed pointers */ + RIter + allPtrs () + { + return RIter (_Vec::begin(), _Vec::end()); + } }; diff --git a/tests/lib/scoped-ptrvect-test.cpp b/tests/lib/scoped-ptrvect-test.cpp index 3bf539342..d718ddc31 100644 --- a/tests/lib/scoped-ptrvect-test.cpp +++ b/tests/lib/scoped-ptrvect-test.cpp @@ -40,6 +40,7 @@ namespace test{ /******************************************************************** * @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 { @@ -48,7 +49,7 @@ namespace test{ run (Arg) { simpleUsage(); -// iterating(); + iterating(); // detaching(); } @@ -92,6 +93,28 @@ namespace test{ 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"); diff --git a/tests/lib/testdummy.hpp b/tests/lib/testdummy.hpp index 99a5ee3c1..afa810f79 100644 --- a/tests/lib/testdummy.hpp +++ b/tests/lib/testdummy.hpp @@ -41,20 +41,19 @@ namespace test{ public: Dummy () : val_(1 + (rand() % 100000000)) - { - checksum += val_; - if (throw_in_ctor) - throw val_; - } + { init(); } + + Dummy (int v) + : val_(v) + { init(); } ~Dummy() { checksum -= val_; } - long add (int i) { return val_+i; } + long add (int i) { return val_+i; } - protected: int getVal() const { return val_; } void @@ -63,6 +62,16 @@ namespace test{ checksum += newVal - val_; val_ = newVal; } + + private: + void + init() + { + checksum += val_; + if (throw_in_ctor) + throw val_; + } + }; } // anonymous test dummy