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:
Fischlurch 2024-06-08 01:51:32 +02:00
parent bbec35ce65
commit 0a788570a9
2 changed files with 137 additions and 13 deletions

View file

@ -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

View file

@ -82606,8 +82606,8 @@ Date:&#160;&#160;&#160;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:&#160;&#160;&#160;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&#xe4;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&#x2228;4&#x2228;5 akzeptiert wurden"/>
<node CREATED="1717795900408" ID="ID_511193542" MODIFIED="1717796123193" TEXT="Fall-2 nachdem Fall-3&#x2228;4&#x2228;5 akzeptiert wurden">
<node CREATED="1717800522402" ID="ID_853857173" MODIFIED="1717805830912" TEXT="&#x27f5; nur m&#xf6;glich wenn I-virtual &#x2228; E ebenfalls Fall-4&#x2228;5 erf&#xfc;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:&#160;&#160;&#160;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&#xfc;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 &#x2228; 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="&#x27fa; &#xe4;quivalent Strategy::canDelete&lt;TY&gt;"/>
</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 &#x2227; E sind ebenfalls trivially_move_constructible">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
Vorsicht Falle!
</p>
<p>
Ohne diesen Check w&#252;rden wir uns in den Fu&#223; schie&#223;en, wenn wir den Container in den wild-move-Modus schalten, denn Elemente vom Typ E oder I k&#246;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&#xdf; pr&#xfc;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="&#x2228; container leer &#x27f9; Spread redefinieren"/>
<node CREATED="1717806462116" ID="ID_88555748" MODIFIED="1717806508162" TEXT="&#x2228; Fall-5 &#x27f9; 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="&#x2228; Strategy::canDynGrow&lt;TY&gt;">
<node CREATED="1717806757128" ID="ID_1234267874" MODIFIED="1717806762203" TEXT="TY == E (oder I)"/>
<node CREATED="1717806781292" ID="ID_1519435147" MODIFIED="1717806785968" TEXT="&#x2228; 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="&#x27f9; 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&#xe4;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 &#x27f9; &#x21af; &#x27f9; &#xd83d;&#xdc80;"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717807152128" ID="ID_1054193038" MODIFIED="1717810946694" TEXT="Aber: reiner Fall-5 mu&#xdf; 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"/>