diff --git a/src/lib/several-builder.hpp b/src/lib/several-builder.hpp index d97d1de28..5ba131650 100644 --- a/src/lib/several-builder.hpp +++ b/src/lib/several-builder.hpp @@ -155,6 +155,8 @@ namespace lib { using Fac::Fac; // pass-through ctor + const bool isDisposable{false}; ///< memory must be explicitly deallocated + Bucket* realloc (Bucket* data, size_t demand) { @@ -191,7 +193,7 @@ namespace lib { Bucket* newBucket{nullptr}; if (data) { - size_t cnt{data->cnt}; + size_t cnt{data->cnt}; ASSERT (cnt > 0); newBucket = Fac::create (cnt, data->spread); for (size_t idx=0; idx and + is_trivially_destructible_v)} + , wild_move{false} + { } + + /** mark that we're about to accept an otherwise unknown type, + * which can be trivially moved (by `memmove`). This irrevocably + * enables low-level`memove` usage for this container instance */ + template + bool + markWildMovePossibility() + { + if (wild_move and not isWildMoveCapable()) + return false; // must reject, since it can not wild-moved + if (isWildMoveCapable() + and is_trivially_move_constructible_v + and is_trivially_move_constructible_v) + wild_move = true; + return true; // accept anyway (not sure yet if it must be moved) + } + + template + bool + isWildMoveCapable() + { + return not (is_same_v or is_same_v) + and is_trivially_move_constructible_v; + } + + template bool canDestroy() @@ -241,10 +274,9 @@ namespace lib { auto getDeleter() { - if constexpr (disposable or - (is_trivially_destructible_v and is_trivially_destructible_v)) + if (disposable) return nullptr; - if constexpr (has_virtual_destructor_v) + if (has_virtual_destructor_v) return nullptr; else return nullptr; @@ -267,6 +299,8 @@ namespace lib { { using Coll = Several; + MemStrategy memStrategy_{POL::isDisposable}; + public: SeveralBuilder() = default; @@ -289,7 +323,7 @@ namespace lib { SeveralBuilder&& appendAll (IT&& data) { - explore(data).foreach ([this](auto it){ emplaceElm(it); }); + explore(data).foreach ([this](auto it){ emplaceCopy(it); }); return move(*this); } @@ -353,12 +387,35 @@ namespace lib { template void - emplaceElm (IT& dataSrc) + emplaceCopy (IT& dataSrc) { - using Val = typename IT::value_type; - size_t elmSiz = sizeof(Val); - adjustStorage (Coll::size()+1, requiredSpread(elmSiz)); - UNIMPLEMENTED ("emplace data"); + using Val = std::remove_cv_t; + emplaceElm (*dataSrc); + } + + template + void + emplaceElm (ARGS&& ...args) + { + if (not memStrategy_.template canDestroy()) + throw err::Invalid{_Fmt{"Unable to handle destructor for element type %s"} + % util::typeStr()}; + + // mark acceptance of trivially movable arbitrary data types + if (not memStrategy_.template markWildMovePossibility()) + throw err::Invalid{_Fmt{"Unable to trivially move element type %s, " + "while other elements in this container are trivially movable."} + % util::typeStr()}; + + ////////////////////////////////////OOO check here for suitable spread + + ////////////////////////////////////OOO check here for sufficient space + + size_t elmSiz = sizeof(TY); + size_t newCnt = Coll::size()+1; + adjustStorage (newCnt, requiredSpread(elmSiz)); + Coll::data_->cnt = newCnt; + POL::template createAt (Coll::data_, Coll::size(), forward (args)...); } size_t diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 1c0a84cd0..e5e5af37f 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -82606,8 +82606,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -82653,7 +82653,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + @@ -82671,6 +82673,71 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + + + +

+ Vorsicht Falle! +

+

+ Ohne diesen Check würden wir uns in den Fuß schießen, wenn wir den Container in den wild-move-Modus schalten, denn Elemente vom Typ E oder I könnten stets ohne Weiteres noch dazukommen +

+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +