diff --git a/src/lib/scoped-collection.hpp b/src/lib/scoped-collection.hpp index b4662c48b..3cfc985a6 100644 --- a/src/lib/scoped-collection.hpp +++ b/src/lib/scoped-collection.hpp @@ -42,8 +42,8 @@ ** ctor just to specify the maximum size). The storage to hold up to this ** number of objects is (heap) allocated right away, but no objects are ** created. Later on, individual objects are "pushed" into the collection - ** by invoking #appendNewElement() to create a new element of the default - ** type `I`) or #appendNew(args) to create some subtype. This way, + ** by invoking #emplaceElement() to create a new element of the default + ** type `I`) or #emplace(args) to create some subtype. This way, ** the container is being filled successively. ** - the "RAII style" usage strives to create all of the content objects ** right away, immediately after the memory allocation. This usage pattern @@ -73,10 +73,7 @@ #include "lib/iter-adapter.hpp" #include -#include -#include -#include -#include +#include namespace lib { @@ -134,83 +131,18 @@ namespace lib { -#define TYPE_AND_STORAGE_SANITY_CHECK \ - BOOST_STATIC_ASSERT (((boost::is_same::value \ - ||boost::is_base_of::value)\ - && sizeof(TY) <= siz)) - - /** Abbreviation for placement new */ -#define EMBEDDED_ELEMENT_CTOR(_CTOR_CALL_) \ - TYPE_AND_STORAGE_SANITY_CHECK; \ - return *new(&buf_) _CTOR_CALL_; \ - - - template + /** place object of type TY, forwarding ctor arguments */ + template TY& - create () + create (ARGS&& ...args) { - EMBEDDED_ELEMENT_CTOR ( TY() ) + static_assert ( (std::is_same::value + ||std::is_base_of::value) + && sizeof(TY) <= siz, + "ElementHolder buffer to small"); + + return *new(&buf_) TY (std::forward (args)...); } - - - template - TY& //___________________________________________ - create (A1 a1) ///< place object of type TY, using 1-arg ctor - { - EMBEDDED_ELEMENT_CTOR ( TY(a1) ) - } - - - template< class TY - , typename A1 - , typename A2 - > - TY& //___________________________________________ - create (A1 a1, A2 a2) ///< place object of type TY, using 2-arg ctor - { - EMBEDDED_ELEMENT_CTOR ( TY(a1,a2) ) - } - - - template< class TY - , typename A1 - , typename A2 - , typename A3 - > - TY& //___________________________________________ - create (A1 a1, A2 a2, A3 a3) ///< place object of type TY, using 3-arg ctor - { - EMBEDDED_ELEMENT_CTOR ( TY(a1,a2,a3) ) - } - - - template< class TY - , typename A1 - , typename A2 - , typename A3 - , typename A4 - > - TY& //___________________________________________ - create (A1 a1, A2 a2, A3 a3, A4 a4) ///< place object of type TY, using 4-arg ctor - { - EMBEDDED_ELEMENT_CTOR ( TY(a1,a2,a3,a4) ) - } - - - template< class TY - , typename A1 - , typename A2 - , typename A3 - , typename A4 - , typename A5 - > - TY& //___________________________________________ - create (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) ///< place object of type TY, using 5-arg ctor - { - EMBEDDED_ELEMENT_CTOR ( TY(a1,a2,a3,a4,a5) ) - } -#undef TYPE_AND_STORAGE_SANITY_CHECK -#undef EMBEDDED_ELEMENT_CTOR }; @@ -362,94 +294,26 @@ namespace lib { - ///////////////////////////////////////////////////////TICKET #967 : the following can be written better now. Also should be named 'emplace' /** 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 + I& + emplaceElement() { - __ensureSufficientCapacity(); - TY& newElm = elements_[level_].template create(); - ++level_; - return newElm; + return emplace(); } - template< class TY - , typename A1 - > - TY& //_________________________________________ - appendNew (A1 a1) ///< add object of type TY, using 1-arg ctor + /** + * push new entry at the end of this container + * and build object of type TY in place there + */ + template + TY& + emplace (ARGS&& ...args) { __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); + TY& newElm = elements_[level_].template create(std::forward (args)...); ++level_; return newElm; } @@ -489,7 +353,7 @@ namespace lib { private: /* ==== Storage: heap allocated array of element buffers ==== */ - typedef boost::scoped_array ElementStorage; + typedef std::unique_ptr ElementStorage; size_t level_; size_t capacity_; diff --git a/tests/library/scoped-collection-test.cpp b/tests/library/scoped-collection-test.cpp index 48735dc94..1473d4b90 100644 --- a/tests/library/scoped-collection-test.cpp +++ b/tests/library/scoped-collection-test.cpp @@ -157,7 +157,7 @@ namespace test{ { CollD coll(50); for (uint i=0; i(i); + coll.emplace(i); int check=0; CollD::iterator ii = coll.begin(); @@ -235,28 +235,28 @@ namespace test{ CHECK (0 == coll.size()); CHECK (0 == Dummy::checksum()); - Dummy& d0 = coll.appendNewElement(); + Dummy& d0 = coll.emplaceElement(); CHECK (1 == coll.size()); - Dummy& d1 = coll.appendNew (rr); + Dummy& d1 = coll.emplace (rr); CHECK (2 == coll.size()); int sum = Dummy::checksum(); // trigger the bomb - VERIFY_ERROR (SUBVERSIVE, coll.appendNew(rr,rr) ); + VERIFY_ERROR (SUBVERSIVE, coll.emplace(rr,rr) ); CHECK ( 2 == coll.size()); // the other objects survived CHECK (sum == Dummy::checksum()); - Dummy& d2 = coll.appendNew (rr, rr+1); + Dummy& d2 = coll.emplace (rr, rr+1); CHECK (3 == coll.size()); CHECK (sum + rr == Dummy::checksum()); - VERIFY_ERROR (CAPACITY, coll.appendNewElement()); - VERIFY_ERROR (CAPACITY, coll.appendNewElement()); - VERIFY_ERROR (CAPACITY, coll.appendNewElement()); + VERIFY_ERROR (CAPACITY, coll.emplaceElement()); + VERIFY_ERROR (CAPACITY, coll.emplaceElement()); + VERIFY_ERROR (CAPACITY, coll.emplaceElement()); CHECK (3 == coll.size()); CHECK (sum + rr == Dummy::checksum()); @@ -269,7 +269,7 @@ namespace test{ // returns the trigger value, when the argument is zero coll.clear(); - coll.appendNew (11,22); + coll.emplace (11,22); CHECK ( 1 == coll.size()); CHECK (11 == Dummy::checksum()); @@ -426,7 +426,7 @@ namespace test{ CollI source (25); for (uint i=0; i < source.capacity(); ++i) - source.appendNew(i); // holding the numbers 0..24 + source.emplace(i); // holding the numbers 0..24 CollI coll (20, CollI::pull(source.begin())); // this immediately pulls in the first 20 elements