Library: integrate strategy for acceptable element types
Draft skeleton of the logic for element creation. This turns out to be a rather challenging piece of code, since we have to rely on logical reasoning about properties of the element types in order to decide if and how these elements can be emplaced, including the possibility to re-allocate and move existing data to a new location. - if we know the exact element type, we can handle any copyable or movable object - however, if the container is filled with a mixture of types, we can not re-allocate or grow dynamically, unless all data is trivially copyable (and can thus be handled through memmove) - moreover we must ensure the ability to invoke the proper destructor
This commit is contained in:
parent
bbec35ce65
commit
0a788570a9
2 changed files with 137 additions and 13 deletions
|
|
@ -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<cnt; ++idx)
|
||||
|
|
@ -220,6 +222,37 @@ namespace lib {
|
|||
bool disposable :1 ;
|
||||
bool wild_move :1 ;
|
||||
|
||||
MemStrategy (bool unmanaged)
|
||||
: disposable{unmanaged or (is_trivially_destructible_v<E> and
|
||||
is_trivially_destructible_v<I>)}
|
||||
, 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<typename TY>
|
||||
bool
|
||||
markWildMovePossibility()
|
||||
{
|
||||
if (wild_move and not isWildMoveCapable<TY>())
|
||||
return false; // must reject, since it can not wild-moved
|
||||
if (isWildMoveCapable<TY>()
|
||||
and is_trivially_move_constructible_v<E>
|
||||
and is_trivially_move_constructible_v<I>)
|
||||
wild_move = true;
|
||||
return true; // accept anyway (not sure yet if it must be moved)
|
||||
}
|
||||
|
||||
template<typename TY>
|
||||
bool
|
||||
isWildMoveCapable()
|
||||
{
|
||||
return not (is_same_v<TY,E> or is_same_v<TY,I>)
|
||||
and is_trivially_move_constructible_v<TY>;
|
||||
}
|
||||
|
||||
|
||||
template<typename TY>
|
||||
bool
|
||||
canDestroy()
|
||||
|
|
@ -241,10 +274,9 @@ namespace lib {
|
|||
auto
|
||||
getDeleter()
|
||||
{
|
||||
if constexpr (disposable or
|
||||
(is_trivially_destructible_v<E> and is_trivially_destructible_v<I>))
|
||||
if (disposable)
|
||||
return nullptr;
|
||||
if constexpr (has_virtual_destructor_v<I>)
|
||||
if (has_virtual_destructor_v<I>)
|
||||
return nullptr;
|
||||
else
|
||||
return nullptr;
|
||||
|
|
@ -267,6 +299,8 @@ namespace lib {
|
|||
{
|
||||
using Coll = Several<I>;
|
||||
|
||||
MemStrategy<I,E> 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<class IT>
|
||||
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<typename IT::value_type>;
|
||||
emplaceElm<Val> (*dataSrc);
|
||||
}
|
||||
|
||||
template<class TY, typename...ARGS>
|
||||
void
|
||||
emplaceElm (ARGS&& ...args)
|
||||
{
|
||||
if (not memStrategy_.template canDestroy<TY>())
|
||||
throw err::Invalid{_Fmt{"Unable to handle destructor for element type %s"}
|
||||
% util::typeStr<TY>()};
|
||||
|
||||
// mark acceptance of trivially movable arbitrary data types
|
||||
if (not memStrategy_.template markWildMovePossibility<TY>())
|
||||
throw err::Invalid{_Fmt{"Unable to trivially move element type %s, "
|
||||
"while other elements in this container are trivially movable."}
|
||||
% util::typeStr<TY>()};
|
||||
|
||||
////////////////////////////////////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<TY> (Coll::data_, Coll::size(), forward<ARGS> (args)...);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
|
|
|||
|
|
@ -82606,8 +82606,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717794532666" ID="ID_1285152534" MODIFIED="1717794548161" TEXT="Implementierungs-Logik aufbauen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1717794532666" ID="ID_1285152534" MODIFIED="1717810981399" TEXT="Implementierungs-Logik aufbauen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1717794550220" ID="ID_1034302214" MODIFIED="1717794631737" TEXT="das ist hier eine besondere Herausforderung....">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
|
@ -82653,7 +82653,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1717795620731" ID="ID_635123753" MODIFIED="1717795661252" TEXT="Fall-1+2 : re-alloc mit typisiertem Umkopieren"/>
|
||||
<node CREATED="1717795703860" ID="ID_541950278" MODIFIED="1717795768841" TEXT="Fall-3+4 : ablehnen falls nicht zusätzlich Fall-5"/>
|
||||
<node CREATED="1717795883682" ID="ID_1529197297" MODIFIED="1717795899091" TEXT="Fall-5 : re-allok mit wildem Umkopieren"/>
|
||||
<node CREATED="1717795900408" ID="ID_511193542" MODIFIED="1717796123193" TEXT="Fall-2 nachdem Fall-3∨4∨5 akzeptiert wurden"/>
|
||||
<node CREATED="1717795900408" ID="ID_511193542" MODIFIED="1717796123193" TEXT="Fall-2 nachdem Fall-3∨4∨5 akzeptiert wurden">
|
||||
<node CREATED="1717800522402" ID="ID_853857173" MODIFIED="1717805830912" TEXT="⟵ nur möglich wenn I-virtual ∨ E ebenfalls Fall-4∨5 erfüllt"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1717796225594" ID="ID_1719530802" MODIFIED="1717796230333" TEXT="shrink">
|
||||
<node CREATED="1717796237416" ID="ID_1428799342" MODIFIED="1717796241988" TEXT="Fall-1+2"/>
|
||||
|
|
@ -82671,6 +82673,71 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1717796446579" ID="ID_229190267" MODIFIED="1717796449135" TEXT="unmanaged"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717805473588" ID="ID_1414521671" MODIFIED="1717806898610" TEXT="Logik für Element-Konstruktion">
|
||||
<icon BUILTIN="info"/>
|
||||
<node COLOR="#338800" CREATED="1717805494018" ID="ID_1249779598" MODIFIED="1717810959882" TEXT="Element-Typ ist akzepabel">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1717805516839" ID="ID_1524408217" MODIFIED="1717805522450" TEXT="TY == I"/>
|
||||
<node CREATED="1717805523590" ID="ID_307320865" MODIFIED="1717805528066" TEXT="TY == E"/>
|
||||
<node CREATED="1717806217762" ID="ID_1169925633" MODIFIED="1717806234202" TEXT="Fall-3 ∨ Fall-4"/>
|
||||
<node CREATED="1717806316316" ID="ID_1171052734" MODIFIED="1717806320847" TEXT="oder: unmanaged"/>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1717806321954" ID="ID_2309043" MODIFIED="1717810962987" TEXT="⟺ äquivalent Strategy::canDelete<TY>"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1717807261874" ID="ID_1786086824" MODIFIED="1717810956332" TEXT="Fall-5-Erkennung">
|
||||
<linktarget COLOR="#712925" DESTINATION="ID_1786086824" ENDARROW="Default" ENDINCLINATION="-23;57;" ID="Arrow_ID_1218222484" SOURCE="ID_1054193038" STARTARROW="None" STARTINCLINATION="-323;21;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1717807209678" HGAP="22" ID="ID_1392228010" MODIFIED="1717807293995" TEXT="d.h. nicht I und nicht E" VSHIFT="9"/>
|
||||
<node CREATED="1717807297399" ID="ID_1804457131" MODIFIED="1717807324080" TEXT="und trivially_move_constructible"/>
|
||||
<node CREATED="1717808984189" ID="ID_1035267118" MODIFIED="1717809129192" TEXT="und: I ∧ E sind ebenfalls trivially_move_constructible">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Vorsicht Falle!
|
||||
</p>
|
||||
<p>
|
||||
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
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1717809142579" ID="ID_528651025" MODIFIED="1717809223883" TEXT="Vorsicht: auch Ausschluß prüfen falls wild-move-Flag gesetzt"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717806413974" ID="ID_174948167" MODIFIED="1717810968198" TEXT="spread">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1717806419241" ID="ID_756384981" MODIFIED="1717806423193" TEXT="ist ausreichend"/>
|
||||
<node CREATED="1717806423863" ID="ID_1855708298" MODIFIED="1717806461147" TEXT="∨ container leer ⟹ Spread redefinieren"/>
|
||||
<node CREATED="1717806462116" ID="ID_88555748" MODIFIED="1717806508162" TEXT="∨ Fall-5 ⟹ Spread rejustieren"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717806648902" ID="ID_31178019" MODIFIED="1717810970218" TEXT="storage">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1717806656110" ID="ID_620814998" MODIFIED="1717806658963" TEXT="ist ausreichend"/>
|
||||
<node CREATED="1717806666956" ID="ID_1772310323" MODIFIED="1717806751117" TEXT="∨ Strategy::canDynGrow<TY>">
|
||||
<node CREATED="1717806757128" ID="ID_1234267874" MODIFIED="1717806762203" TEXT="TY == E (oder I)"/>
|
||||
<node CREATED="1717806781292" ID="ID_1519435147" MODIFIED="1717806785968" TEXT="∨ Fall-5"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717806899733" ID="ID_1104689236" MODIFIED="1717806906392" TEXT="Fall-5-Behandlung">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1717806920506" ID="ID_200574355" MODIFIED="1717806935142" TEXT="⟹ setzen der wild-move-Flag"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1717806977490" ID="ID_901373417" MODIFIED="1717807004591" TEXT="aber nur falls der Typ tatsächlich akzeptiert wird">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1717807023866" ID="ID_1721210839" MODIFIED="1717807027244" TEXT="relevant?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1717807029327" ID="ID_1277661282" MODIFIED="1717807037454" TEXT="ist wohl eine Tautologie"/>
|
||||
<node CREATED="1717807038066" ID="ID_530732635" MODIFIED="1717807078709" TEXT="nicht akzeptiert ⟹ ↯ ⟹ ��"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717807152128" ID="ID_1054193038" MODIFIED="1717810946694" TEXT="Aber: reiner Fall-5 muß erkannt werden">
|
||||
<arrowlink COLOR="#712925" DESTINATION="ID_1786086824" ENDARROW="Default" ENDINCLINATION="-23;57;" ID="Arrow_ID_1218222484" STARTARROW="None" STARTINCLINATION="-323;21;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715625082614" ID="ID_1575150785" MODIFIED="1715625089779" TEXT="SeveralBuilder_test">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue