diff --git a/src/lib/several-builder.hpp b/src/lib/several-builder.hpp index ceeee1732..a54036b87 100644 --- a/src/lib/several-builder.hpp +++ b/src/lib/several-builder.hpp @@ -77,6 +77,7 @@ namespace lib { using util::max; using util::min; using util::_Fmt; + using std::is_trivially_destructible_v; template class ALO> class ElementFactory @@ -140,13 +141,15 @@ namespace lib { destroy (ArrayBucket* bucket) { REQUIRE (bucket); - size_t cnt = bucket->cnt; + if (not is_trivially_destructible_v) + { + size_t cnt = bucket->cnt; + using ElmAlloT = typename AlloT::template rebind_traits; + auto elmAllo = adaptAllocator(); + for (size_t idx=0; idxsubscript(idx)); + } size_t storageBytes = bucket->buffSiz; - using ElmAlloT = typename AlloT::template rebind_traits; - auto elmAllo = adaptAllocator(); - for (size_t idx=0; idxsubscript(idx)); - std::byte* loc = reinterpret_cast (bucket); AlloT::deallocate (baseAllocator(), loc, storageBytes); }; @@ -227,12 +230,6 @@ namespace lib { return newBucket; } */ -// // ensure sufficient storage or verify the ability to re-allocate -// if (not (Coll::hasReserve(sizeof(TY)) -// or POL::canExpand(sizeof(TY)) -// or handling_.template canDynGrow())) -// throw err::Invalid{_Fmt{"Unable to accommodate further element of type %s "} -// % util::typeStr()}; } void @@ -250,7 +247,7 @@ namespace lib { Fac::template createAt (tar, idx ,std::move_if_noexcept (src->subscript(idx))); } - tar->cnt = idx+1; // mark fill continuously for proper clean-up after exception + tar->cnt = idx+1; // mark fill continuously for proper clean-up after exception } }; @@ -268,16 +265,16 @@ namespace lib { template struct HandlingStrategy { - enum DestructionMethod { UNKNOWN - , TRIVIAL - , ELEMENT - , VIRTUAL - }; + enum DestructionMethod{ UNKNOWN + , TRIVIAL + , ELEMENT + , VIRTUAL + }; static Literal - render(DestructionMethod m) + render (DestructionMethod m) { switch (m) - { + { case TRIVIAL: return "trivial"; case ELEMENT: return "fixed-element-type"; case VIRTUAL: return "virtual-baseclass"; @@ -289,6 +286,7 @@ namespace lib { DestructionMethod destructor{UNKNOWN}; bool lock_move{false}; + /** mark that we're about to accept an otherwise unknown type, * which can not be trivially moved. This irrevocably disables * relocations by low-level `memove` for this container instance */ @@ -306,37 +304,37 @@ namespace lib { return is_trivially_copyable_v and not lock_move; } - - template - std::function - selectDestructor() + template + typename ArrayBucket::Deleter + selectDestructor (FAC const& factory) { - if (is_trivially_destructible_v) + if (is_Subclass() and has_virtual_destructor_v) { - __ensureMark (TRIVIAL, util::typeStr()); - return [](auto){ /* calmness */ }; + __ensureMark (VIRTUAL); + return [factory](ArrayBucket* bucket){ unConst(factory).template destroy (bucket); }; } if (is_same_v and is_Subclass()) { - __ensureMark (ELEMENT, util::typeStr()); - return [](I& elm){ reinterpret_cast(elm).~E(); }; + __ensureMark (ELEMENT); + return [factory](ArrayBucket* bucket){ unConst(factory).template destroy (bucket); }; } - if (is_Subclass() and has_virtual_destructor_v) + if (is_trivially_destructible_v) { - __ensureMark (VIRTUAL, util::typeStr()); - return [](I& elm){ elm.~I(); }; + __ensureMark (TRIVIAL); + return [factory](ArrayBucket* bucket){ unConst(factory).template destroy (bucket); }; } throw err::Invalid{_Fmt{"Unsupported kind of destructor for element type %s."} % util::typeStr()}; } + template void - __ensureMark(DestructionMethod expectedKind, string typeID) + __ensureMark (DestructionMethod expectedKind) { if (destructor != UNKNOWN and destructor != expectedKind) throw err::Invalid{_Fmt{"Unable to handle destructor for element type %s, " "since this container has been primed to use %s-deleters."} - % typeID % render(expectedKind)}; + % util::typeStr() % render(expectedKind)}; destructor = expectedKind; } }; @@ -404,9 +402,6 @@ namespace lib { void emplaceElm (ARGS&& ...args) { - // ensure proper configuration of clean-up for the container - auto invokeDestructor = handling_.template selectDestructor(); - // mark when target type is not trivially movable handling_.template probeMoveCapability(); @@ -416,15 +411,32 @@ namespace lib { "into container for element size %d."} % util::typeStr() % sizeof(TY) % Coll::spread()}; + // ensure sufficient storage or verify the ability to re-allocate + if (not (Coll::hasReserve(sizeof(TY)) + or POL::canExpand(sizeof(TY)) + or not handling_.lock_move)) + throw err::Invalid{_Fmt{"Unable to accommodate further element of type %s "} + % util::typeStr()}; + size_t elmSiz = sizeof(TY); size_t newPos = Coll::size(); size_t newCnt = Coll::empty()? INITIAL_ELM_CNT : newPos+1; adjustStorage (newCnt, max (elmSiz, Coll::spread())); ENSURE (Coll::data_); - if (not Coll::data_->deleter) - UNIMPLEMENTED ("setup deleter trampoline"); - Coll::data_->cnt = newPos+1; + ensureDeleter(); POL::template createAt (Coll::data_, newPos, forward (args)...); + Coll::data_->cnt = newPos+1; + } + + template + void + ensureDeleter() + { + // ensure clean-up can be handled properly + typename POL::Fac& factory(*this); + typename ArrayBucket::Deleter deleterFunctor = handling_.template selectDestructor (factory); + if (Coll::data_->deleter) return; + Coll::data_->deleter = deleterFunctor; } void diff --git a/src/lib/several.hpp b/src/lib/several.hpp index b6a2db3eb..f17cd9f0f 100644 --- a/src/lib/several.hpp +++ b/src/lib/several.hpp @@ -68,6 +68,7 @@ #include "lib/iter-adapter.hpp" #include +#include namespace lib { @@ -84,7 +85,7 @@ namespace lib { , deleter{nullptr} { } - typedef void (*Deleter) (ArrayBucket*); + using Deleter = std::function; size_t cnt; size_t spread; @@ -119,7 +120,7 @@ namespace lib { destroy() { if (deleter) - (*deleter) (this); + deleter (this); } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 7620c655b..e6e91681a 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -82032,8 +82032,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -82274,8 +82274,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + @@ -82302,6 +82303,26 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + +

+ jetzt habe ich mich sowiso schon mal für die vorläufige Verschwendung entschieden +

+ + +
+ +
+ +
@@ -82328,12 +82349,49 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -82344,7 +82402,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + +
@@ -82423,7 +82483,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -82431,11 +82491,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - - - + + + + + @@ -82451,6 +82511,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + @@ -82468,6 +82531,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + @@ -82976,6 +83043,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + +