Library: reassess logic to reject some types for existing container
`lib::Several` is designed to be highly adaptable, allowing for several quite distinct usage styles. On the downside, this requires to perform some checks at runtime only, since the ability to handle some element depends on specific circumstances. This is a notable difference to `std::vector`, which is simply not capable of handling ''non-copyable'' types, even if given an up-front memory reservation. The last test case provided with the previous changeset did not trigger an exception, but closer investigation revealed that this is correct, since in this specific situation the container can accept this object type, thereby just loosing the ability to move-relocate further objects. A slightly re-arranged test scenario can be used to demonstrate this fine point.
This commit is contained in:
parent
d9f86ad891
commit
85e3780a34
3 changed files with 184 additions and 21 deletions
|
|
@ -89,10 +89,12 @@ namespace lib {
|
|||
using util::max;
|
||||
using util::min;
|
||||
using util::_Fmt;
|
||||
using std::is_nothrow_move_constructible_v;
|
||||
using std::is_trivially_move_constructible_v;
|
||||
using std::is_trivially_destructible_v;
|
||||
using std::has_virtual_destructor_v;
|
||||
using std::is_trivially_copyable_v;
|
||||
using std::is_copy_constructible_v;
|
||||
using std::is_object_v;
|
||||
using std::is_volatile_v;
|
||||
using std::is_const_v;
|
||||
|
|
@ -241,11 +243,21 @@ namespace lib {
|
|||
std::memmove (newPos, oldPos, amount);
|
||||
}
|
||||
else
|
||||
if constexpr (is_nothrow_move_constructible_v<E>
|
||||
or is_copy_constructible_v<E>)
|
||||
{
|
||||
E& oldElm = reinterpret_cast<E&> (src->subscript (idx));
|
||||
Fac::template createAt<E> (tar, idx
|
||||
,std::move_if_noexcept (oldElm));
|
||||
}
|
||||
else
|
||||
{
|
||||
NOTREACHED("realloc immovable type (neither trivially nor typed movable)");
|
||||
// this alternative code section is very important, because it allows
|
||||
// to instantiate this code even for »noncopyable« types, assuming that
|
||||
// sufficient storage is reserved beforehand, and thus copying is irrelevant.
|
||||
// For context: the std::vector impl. from libStdC++ is lacking this option.
|
||||
}
|
||||
tar->cnt = idx+1; // mark fill continuously for proper clean-up after exception
|
||||
}
|
||||
};
|
||||
|
|
@ -516,7 +528,7 @@ namespace lib {
|
|||
*/
|
||||
template<typename TY>
|
||||
Deleter
|
||||
selectDestructor ()
|
||||
selectDestructor()
|
||||
{
|
||||
typename POL::Fac& factory(*this);
|
||||
|
||||
|
|
|
|||
|
|
@ -288,6 +288,12 @@ SHOW_EXPR(ne5.getVal())
|
|||
builder.fillElm(5);
|
||||
CHECK (5 == builder.size());
|
||||
|
||||
// trigger re-alloc by moving into larger memory block
|
||||
builder.fillElm(14);
|
||||
CHECK (19 == builder.size());
|
||||
|
||||
builder.emplace<short>();
|
||||
|
||||
builder.emplace<Num<1>>(); ///////////////////////////////////OOO this should trigger an exception -> need to code an explicit check right at the start of emplaceNewElm()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82741,24 +82741,81 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1717980838451" ID="ID_123345043" MODIFIED="1717980849735" TEXT="hab es jetzt vorerst doch wieder dorthin geschoben"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717980850354" ID="ID_1951694568" MODIFIED="1718158733534" TEXT="TODO: bessere Lösung finden">
|
||||
<linktarget COLOR="#ea004d" DESTINATION="ID_1951694568" ENDARROW="Default" ENDINCLINATION="456;43;" ID="Arrow_ID_13456577" SOURCE="ID_1048202028" STARTARROW="None" STARTINCLINATION="325;-27;"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717980850354" ID="ID_1951694568" MODIFIED="1718200585346" TEXT="diese Lösung nochmal überprüfen">
|
||||
<linktarget COLOR="#77334a" DESTINATION="ID_1951694568" ENDARROW="Default" ENDINCLINATION="466;38;" ID="Arrow_ID_13456577" SOURCE="ID_1048202028" STARTARROW="None" STARTINCLINATION="325;-27;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1718200372590" HGAP="61" ID="ID_523646974" MODIFIED="1718200393353" TEXT="möglicherweise wird die Lösung sehr Kontext-abhängig" VSHIFT="11">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1718200410241" HGAP="22" ID="ID_341859477" MODIFIED="1718200510931" TEXT="unter Umständen muß man gar nicht unterbinden, was kein Problem darstellt" VSHIFT="9"/>
|
||||
<node CREATED="1718200437669" ID="ID_332242965" MODIFIED="1718200499116" TEXT="solange Objekte nicht verschoben werden müssen, ist der konkrete Typ irrelevant">
|
||||
<linktarget COLOR="#fdfac6" DESTINATION="ID_332242965" ENDARROW="Default" ENDINCLINATION="-228;8;" ID="Arrow_ID_950941369" SOURCE="ID_534883946" STARTARROW="None" STARTINCLINATION="266;9;"/>
|
||||
</node>
|
||||
<node CREATED="1718200462555" ID="ID_1692266338" MODIFIED="1718200470609" TEXT="nur den Destruktor muß man aufrufen können"/>
|
||||
<node CREATED="1718201691476" HGAP="3" ID="ID_357179310" MODIFIED="1718201781484" TEXT="überprüft und getestet: ist korrekt" VSHIFT="13">
|
||||
<arrowlink COLOR="#51b6cc" DESTINATION="ID_1592892204" ENDARROW="Default" ENDINCLINATION="281;-14;" ID="Arrow_ID_517622740" STARTARROW="None" STARTINCLINATION="313;27;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1717894410331" ID="ID_732905043" MODIFIED="1717894437670" TEXT="es genügt, die move_lock-Flag zu prüfen">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1717894472499" ID="ID_534883946" MODIFIED="1717894525092" TEXT="Aber: wird erst relevant wenn tatsächlich Objekte verschoben werden müssen">
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1717894472499" ID="ID_534883946" MODIFIED="1718200561076" TEXT="Aber: wird erst relevant wenn tatsächlich Objekte verschoben werden müssen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...und das kann vom Allokator abhängen
|
||||
...und das kann vom Allokator abhängen — sollte also in den meisten für Lumiera wirklich relevanten Fällen gar nicht vorkommen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#fdfac6" DESTINATION="ID_332242965" ENDARROW="Default" ENDINCLINATION="-228;8;" ID="Arrow_ID_950941369" STARTARROW="None" STARTINCLINATION="266;9;"/>
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node CREATED="1718202386482" HGAP="264" ID="ID_875355344" MODIFIED="1718202419463" TEXT="außerdem: sicherstellen daß nur valider Copy/Move-Code generiert wird" VSHIFT="38">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1718202425005" ID="ID_787831291" MODIFIED="1718202718252" TEXT="extrem wichtig — das ist eine Schwäche von std::vector">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...nicht nur eine Schwäche, sondern ein ausgewachsenes Ärgerniss. Allerdings betrifft das strenggenommen nur die libStc++
|
||||
</p>
|
||||
<p>
|
||||
Und zwar ist es so: man könnte einen Vector per resize() vordimensionieren, so daß die Storage nicht per alloc-and-copy wachsen muß; danach könnte man eigentlich ohne Weiteres auch non-copyable-Objekte im Vector haben — solange man den Vector selber ebenfalls nicht kopiert (Verschieben wäre möglich).
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Soweit <i>die Theorie...</i> in der Praxis aber <b>scheitert das</b>, weil der Compiler versucht, den realloc-Code zu instantiieren und dafür keinen Copy/Move-Konstruktor findet
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1718202443155" ID="ID_1046115206" MODIFIED="1718202851765" TEXT="wir wollen definitiv auch non-copyable-Objekte handhaben können">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Und dazu sind wir im Stande...
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
wir haben entsprechende Prüf-Logik, die zur Laufzeit eine Exception wirft, wenn die Kapazität nicht reicht. Da Objekte nur im Builder hinzugefügt werden, ist das hier viel akzeptabler als für std::vector, der durch ein solches Verhalten ja doch massiv unzuverlässig würde.
|
||||
</li>
|
||||
<li>
|
||||
wir müssen dann nur sicherstellen, daß der typisierte copy-Code in unserer realloc()-Funktion ebenfalls einen statischen Guard hat, und damit auch überhaupt nicht emittiert wird, wenn wir ihn ohnehin nicht nutzen können
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1718202456849" ID="ID_1146034926" MODIFIED="1718202534877" TEXT="das auch testen!">
|
||||
<arrowlink COLOR="#638ad5" DESTINATION="ID_247674037" ENDARROW="Default" ENDINCLINATION="-635;-37;" ID="Arrow_ID_10606647" STARTARROW="None" STARTINCLINATION="-429;58;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -82894,6 +82951,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node CREATED="1718202490965" ID="ID_247674037" MODIFIED="1718202528909" TEXT="Handhabung von non-copyable-Objekten">
|
||||
<linktarget COLOR="#638ad5" DESTINATION="ID_247674037" ENDARROW="Default" ENDINCLINATION="-635;-37;" ID="Arrow_ID_10606647" SOURCE="ID_1146034926" STARTARROW="None" STARTINCLINATION="-429;58;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1717771640460" ID="ID_1646507168" MODIFIED="1717771661118" TEXT="weil die Datenstruktur doch so schön elegant sein sollte....">
|
||||
<icon BUILTIN="smiley-oh"/>
|
||||
|
|
@ -83110,9 +83170,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1718151025411" ID="ID_1523821713" MODIFIED="1718151039915" TEXT="die wäre nur erlaubt bei (bisher) leerem Builder"/>
|
||||
<node COLOR="#5b280f" CREATED="1718151047944" ID="ID_1701216144" MODIFIED="1718151087039" TEXT="(theoretisch könnte man auch umkopieren, allerdings nur manchmal)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...also ist das keine gute Idee, da verwirrend
|
||||
|
|
@ -83349,9 +83407,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node CREATED="1718146553609" ID="ID_543025538" MODIFIED="1718146642666" TEXT="kann kein char[] direkt erstellen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...und zwar, weil man ein (language)-Array mit operator new[] allozieren muß
|
||||
|
|
@ -83384,9 +83440,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#761b6d" CREATED="1718158901756" ID="ID_1578123647" MODIFIED="1718158939699">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
und der von Dummy muß <b>noexcept</b> sein
|
||||
|
|
@ -83397,22 +83451,113 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1718122077386" ID="ID_959961694" MODIFIED="1718122087388" TEXT="kann keinen anderen Typ platzieren (selbst wenn kleiner)">
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1718157829884" ID="ID_1228814618" MODIFIED="1718157836660" TEXT="spricht nicht an">
|
||||
<node COLOR="#865c48" CREATED="1718122077386" ID="ID_959961694" MODIFIED="1718201948324" TEXT="kann keinen anderen Typ platzieren (selbst wenn kleiner)">
|
||||
<icon BUILTIN="closed"/>
|
||||
<node COLOR="#5b280f" CREATED="1718157829884" ID="ID_1228814618" MODIFIED="1718201060734" TEXT="spricht nicht an">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1718157847914" ID="ID_1926254706" MODIFIED="1718157851469" TEXT="Beobachtungen">
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1718157852441" ID="ID_1384707564" MODIFIED="1718157871000" TEXT="probeMoveCapability<TY>() setzt gleich zu Beginn die move-Sperre">
|
||||
<node COLOR="#435e98" CREATED="1718157852441" ID="ID_1384707564" MODIFIED="1718201634118" TEXT="probeMoveCapability<TY>() setzt gleich zu Beginn die move-Sperre">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1718158012556" ID="ID_240735780" MODIFIED="1718158019734" TEXT="das ist logisch falsch...."/>
|
||||
<node CREATED="1718158020275" ID="ID_1916533180" MODIFIED="1718158029781" TEXT="wir dürften diesen Punkt gar nicht erreichen"/>
|
||||
<node COLOR="#5b280f" CREATED="1718158012556" ID="ID_240735780" MODIFIED="1718200763841" TEXT="das ist logisch falsch....">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1718200610682" ID="ID_425914071" MODIFIED="1718200632697" TEXT="wirklich?">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1718158031369" ID="ID_1048202028" MODIFIED="1718158733534" TEXT="Ja... hier fehlt ein expliziter Check">
|
||||
<arrowlink COLOR="#ea004d" DESTINATION="ID_1951694568" ENDARROW="Default" ENDINCLINATION="456;43;" ID="Arrow_ID_13456577" STARTARROW="None" STARTINCLINATION="325;-27;"/>
|
||||
<node CREATED="1718200615784" ID="ID_1636929590" MODIFIED="1718200869840" TEXT="genau genommen ist es korrekt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Es ist nämlich so: wenn wir gleich die Move-Sperre setzen, können wir ansonsten das Objekt durchaus reinlassen — vorausgesetzt das mit dem Destruktor bleibt OK — und letzteres prüfen wir ja auch, nur eben später (aus Gründen der einfachen Formulierung im Code, weil wir den Rückgabewert von dieser Prüfung erst später brauchen)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1718158020275" ID="ID_1916533180" MODIFIED="1718201643476" TEXT="wir dürften diesen Punkt gar nicht erreichen">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1718201646955" HGAP="31" ID="ID_100839325" MODIFIED="1718201656323" TEXT="doch: man kann es so machen" VSHIFT="14"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1718158031369" ID="ID_1048202028" MODIFIED="1718201789622" TEXT="Ja... hier fehlt ein expliziter Check">
|
||||
<arrowlink COLOR="#77334a" DESTINATION="ID_1951694568" ENDARROW="Default" ENDINCLINATION="466;38;" ID="Arrow_ID_13456577" STARTARROW="None" STARTINCLINATION="325;-27;"/>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node COLOR="#5b280f" CREATED="1718200660533" HGAP="30" ID="ID_1440476684" MODIFIED="1718200699309" TEXT="nicht klar ob der tatsächlich notwendig ist..." VSHIFT="18">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
<node CREATED="1718200685242" HGAP="32" ID="ID_722777194" MODIFIED="1718200696765" TEXT="es sind zwei getrennte Belange" VSHIFT="-1">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1718200700899" ID="ID_203165643" MODIFIED="1718200720954" TEXT="ein Objekt destruieren können ⟵ stets verbindilch"/>
|
||||
<node CREATED="1718200722421" ID="ID_1426680364" MODIFIED="1718200751665" TEXT="ein Objekt per copy/move-ctor verschieben ⟵ optional"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1718201054552" ID="ID_1583618556" MODIFIED="1718201621216" TEXT="Analyse-Fazit">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1718201064639" ID="ID_536767559" MODIFIED="1718201202494">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
das im Test beobachtete Verhalten <b>ist korrekt</b>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...es spricht tatsächlich nichts dagegen, diesen Fall auch nachträglich noch zuzulassen — man gibt dann eben die Möglichkeit für re-Allocations auf (und wenn <i>das</i> ein Problem darstellt, macht sich das zu gegebener Zeit <i>eindeutig bemerkbar</i>)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1718201084309" ID="ID_1592892204" MODIFIED="1718201766838" TEXT="die Prüf-Logik im Code ist bereits vollständig und gut angeordnet">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<ul>
|
||||
<li>
|
||||
gleich zu Beginn — noch vor allen Storage-Prüfungen — stellen wir fest, ob wir (noch) Ojbekte verschieben können. Wenn das für <i>ein einziges Objekt </i>nicht mehr gilt, dann gilt es eben für den gesamten Container nicht mehr. Es ist zu dem Zeitpunkt noch nicht klar, ob das überhaupt ein Problem darstellt.
|
||||
</li>
|
||||
<li>
|
||||
als Nächstes prüfen wir die Speicheranforderungen; wenn der Speicher <i>nicht reicht</i> und wir zudem <i>nicht verschieben können, </i>dann staubt's
|
||||
</li>
|
||||
<li>
|
||||
nur wenn nötig <b>und möglich</b> wird die Allokation vergrößert. An dem Punkt ist alles wieder sauber <i>für die bestehenden Elemente</i>
|
||||
</li>
|
||||
<li>
|
||||
erst danach müssen wir die Destruktor-Möglichkeit <b>für das neue Element</b> prüfen. Wenn hier ein Fehler auftritt, wurde zwar ggfs der Puffer (unnötigerweise) vergrößert, aber es hat noch keine Objekt-Konstruktion stattgefunden, und wir die Gesamtsituation ist weiterhin konsistent
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#51b6cc" DESTINATION="ID_1592892204" ENDARROW="Default" ENDINCLINATION="281;-14;" ID="Arrow_ID_517622740" SOURCE="ID_357179310" STARTARROW="None" STARTINCLINATION="313;27;"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718201601397" ID="ID_782023787" MODIFIED="1718201981335" TEXT="entsprechend den Test umformulieren">
|
||||
<arrowlink COLOR="#6079c7" DESTINATION="ID_357857724" ENDARROW="Default" ENDINCLINATION="192;-8;" ID="Arrow_ID_654254378" STARTARROW="None" STARTINCLINATION="-163;11;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1718201827718" ID="ID_357857724" MODIFIED="1718201975615">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
kann keinen <i>ganz anderen </i>Typ platzieren (der nicht Subklasse ist)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#6079c7" DESTINATION="ID_357857724" ENDARROW="Default" ENDINCLINATION="192;-8;" ID="Arrow_ID_654254378" SOURCE="ID_782023787" STARTARROW="None" STARTINCLINATION="-163;11;"/>
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
</node>
|
||||
<node CREATED="1718201899221" ID="ID_1719848161" MODIFIED="1718201919629" TEXT="wenn man eine Subklasse platziert, wird die Möglichkeit für Wachstum beschnitten"/>
|
||||
</node>
|
||||
<node CREATED="1718122252659" ID="ID_616405505" MODIFIED="1718122291873" TEXT="Triviale Typen">
|
||||
<node CREATED="1718122293022" ID="ID_697520417" MODIFIED="1718122302248" TEXT="kann wachsen"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue