From 690304f9bcf307c018dc3b214ac329227d7df205 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 4 Jan 2012 04:05:03 +0100 Subject: [PATCH] get the simple and iteration unit tests to pass --- src/lib/error.hpp | 1 + src/lib/exception.cpp | 1 + src/lib/scoped-collection.hpp | 130 ++++++++++++++++++++++++--- src/lib/scoped-ptrvect.hpp | 2 + tests/lib/scoped-collection-test.cpp | 9 +- 5 files changed, 125 insertions(+), 18 deletions(-) diff --git a/src/lib/error.hpp b/src/lib/error.hpp index 1677557be..364fd1fe6 100644 --- a/src/lib/error.hpp +++ b/src/lib/error.hpp @@ -125,6 +125,7 @@ namespace lumiera { LUMIERA_ERROR_DECLARE (LIFECYCLE); ///< Lifecycle assumptions violated LUMIERA_ERROR_DECLARE (WRONG_TYPE); ///< runtime type mismatch LUMIERA_ERROR_DECLARE (ITER_EXHAUST); ///< end of sequence reached + LUMIERA_ERROR_DECLARE (CAPACITY); ///< predefined fixed storage capacity LUMIERA_ERROR_DECLARE (INDEX_BOUNDS); ///< index out of bounds LUMIERA_ERROR_DECLARE (BOTTOM_VALUE); ///< invalid or NIL value LUMIERA_ERROR_DECLARE (UNCONNECTED); ///< missing connection diff --git a/src/lib/exception.cpp b/src/lib/exception.cpp index 26ddaadb2..53d068899 100644 --- a/src/lib/exception.cpp +++ b/src/lib/exception.cpp @@ -82,6 +82,7 @@ namespace lumiera { LUMIERA_ERROR_DEFINE (LIFECYCLE, "Lifecycle assumptions violated"); LUMIERA_ERROR_DEFINE (WRONG_TYPE, "runtime type mismatch"); LUMIERA_ERROR_DEFINE (ITER_EXHAUST, "end of sequence reached"); + LUMIERA_ERROR_DEFINE (CAPACITY, "predefined fixed storage capacity"); LUMIERA_ERROR_DEFINE (INDEX_BOUNDS, "index out of bounds"); LUMIERA_ERROR_DEFINE (BOTTOM_VALUE, "invalid or NIL value"); LUMIERA_ERROR_DEFINE (UNCONNECTED, "missing connection"); diff --git a/src/lib/scoped-collection.hpp b/src/lib/scoped-collection.hpp index d9b80b469..adc2339f5 100644 --- a/src/lib/scoped-collection.hpp +++ b/src/lib/scoped-collection.hpp @@ -31,6 +31,8 @@ ** ** - TODO: retro-fit with RefArray interface ** + ** @warning deliberately \em not threadsafe + ** ** @see ScopedCollection_test ** @see scoped-ptrvect.hpp quite similar, but using individual heap pointers */ @@ -55,6 +57,7 @@ namespace lib { namespace error = lumiera::error; + using error::LUMIERA_ERROR_CAPACITY; using error::LUMIERA_ERROR_INDEX_BOUNDS; @@ -75,9 +78,10 @@ namespace lib { { /** - * Wrapper to hold one Child object. + * Storage Frame to hold one Child object. * The storage will be an heap allocated * array of such Wrapper objects. + * @note doesn't manage the Child */ class ElementHolder : boost::noncopyable @@ -86,11 +90,6 @@ namespace lib { mutable char buf_[siz]; public: - ElementHolder () { } - ~ElementHolder () - { - destroy(); - } I& accessObj() const @@ -198,11 +197,18 @@ namespace lib { /* ==== internal callback API for the iterator ==== */ friend void - iterNext (const ScopedCollection*, const I* & pos) + iterNext (const ScopedCollection*, I* & pos) { ElementHolder* & storageLocation = reinterpret_cast (pos); ++storageLocation; } + + friend void + iterNext (const ScopedCollection*, const I* & pos) + { + const ElementHolder* & storageLocation = reinterpret_cast (pos); + ++storageLocation; + } /** Implementation of Iteration-logic: detect iteration end. * @note the problem here is that this implementation chooses @@ -212,8 +218,9 @@ namespace lib { * iteration end by internal logic (\c numberz_.end() ), we * immediately transform this into the official "bottom" */ + template friend bool - hasNext (const ScopedCollection* src, const I* & pos) + hasNext (const ScopedCollection* src, POS & pos) { REQUIRE (src); if ((pos) && (pos < src->_access_end())) @@ -224,8 +231,8 @@ namespace lib { return false; } } - I* _access_begin() { return &elements_[0]; } - I* _access_end() { return &elements_[level_]; } + I* _access_begin() const { return & elements_[0].accessObj(); } + I* _access_end() const { return & elements_[level_].accessObj(); } @@ -292,6 +299,98 @@ namespace lib { } + /** push a new element of default type + * to the end of this container + * @note EX_STRONG */ + I& appendNewElement() { return appendNew(); } + + + template< class TY > + TY& //_________________________________________ + appendNew () ///< add object of type TY, using 0-arg ctor + { + __ensureSufficientCapacity(); + TY& newElm = elements_[level_].template create(); + ++level_; + return newElm; + } + + + template< class TY + , typename A1 + > + TY& //_________________________________________ + appendNew (A1& a1) ///< add object of type TY, using 1-arg ctor + { + __ensureSufficientCapacity(); + TY& newElm = elements_[level_].template create(a1); + ++level_; + return newElm; + } + + + template< class TY + , typename A1 + , typename A2 + > + TY& //_________________________________________ + appendNew (A1& a1, A2& a2) ///< add object of type TY, using 2-arg ctor + { + __ensureSufficientCapacity(); + TY& newElm = elements_[level_].template create(a1,a2); + ++level_; + return newElm; + } + + + template< class TY + , typename A1 + , typename A2 + , typename A3 + > + TY& //_________________________________________ + appendNew (A1& a1, A2& a2, A3& a3) ///< add object of type TY, using 3-arg ctor + { + __ensureSufficientCapacity(); + TY& newElm = elements_[level_].template create(a1,a2,a3); + ++level_; + return newElm; + } + + + template< class TY + , typename A1 + , typename A2 + , typename A3 + , typename A4 + > + TY& //_________________________________________ + appendNew (A1& a1, A2& a2, A3& a3, A4& a4) ///< add object of type TY, using 4-arg ctor + { + __ensureSufficientCapacity(); + TY& newElm = elements_[level_].template create(a1,a2,a3,a4); + ++level_; + return newElm; + } + + + template< class TY + , typename A1 + , typename A2 + , typename A3 + , typename A4 + , typename A5 + > + TY& //_________________________________________ + appendNew (A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) ///< add object of type TY, using 5-arg ctor + { + __ensureSufficientCapacity(); + TY& newElm = elements_[level_].template create(a1,a2,a3,a4,a5); + ++level_; + return newElm; + } + + /* === Element access and iteration === */ I& @@ -317,9 +416,9 @@ namespace lib { /* ====== proxied vector functions ==================== */ - size_t size () const { return level_; } + size_t size () const { return level_; } // size_type max_size () const { return _Vec::max_size(); } -// size_type capacity () const { return _Vec::capacity(); } + size_t capacity () const { return capacity_; } bool empty () const { return 0 == level_; } @@ -330,6 +429,13 @@ namespace lib { // { // UNIMPLEMENTED("raw element access"); // } + void + __ensureSufficientCapacity() + { + if (level_ >= capacity_) + throw error::State ("ScopedCollection exceeding the initially defined capacity" + , LUMIERA_ERROR_CAPACITY); + } }; diff --git a/src/lib/scoped-ptrvect.hpp b/src/lib/scoped-ptrvect.hpp index dd04492a6..37dff93dd 100644 --- a/src/lib/scoped-ptrvect.hpp +++ b/src/lib/scoped-ptrvect.hpp @@ -35,6 +35,8 @@ ** - TODO: detaching of objects... ** - TODO: retro-fit with RefArray interface ** + ** @warning deliberately \em not threadsafe + ** ** @see scoped-ptrvect-test.cpp ** @see scoped-holder.hpp ** @see gui::DisplayService usage example diff --git a/tests/lib/scoped-collection-test.cpp b/tests/lib/scoped-collection-test.cpp index 8847ee15f..c79f74e89 100644 --- a/tests/lib/scoped-collection-test.cpp +++ b/tests/lib/scoped-collection-test.cpp @@ -137,9 +137,8 @@ namespace test{ { CHECK (0 == Dummy::checksum()); { -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #877 CollD coll(50); - for (int i=0; i(i); int check=0; @@ -154,8 +153,9 @@ namespace test{ // Test the const iterator + CollD const& const_coll (coll); check = 0; - CollD::const_iterator cii = coll.begin(); + CollD::const_iterator cii = const_coll.begin(); while (cii) { CHECK (check == cii->getVal()); @@ -176,7 +176,6 @@ namespace test{ VERIFY_ERROR (ITER_EXHAUST, ++ii ); VERIFY_ERROR (ITER_EXHAUST, ++cii ); -#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #877 } CHECK (0 == Dummy::checksum()); } @@ -185,7 +184,6 @@ namespace test{ void building_RAII_Style() { - UNIMPLEMENTED ("building all at once"); CHECK (0 == Dummy::checksum()); { #if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #877 @@ -252,7 +250,6 @@ namespace test{ void building_StackStyle() { - UNIMPLEMENTED ("pushing new objects successively"); CHECK (0 == Dummy::checksum()); { #if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #877