clean-up: make ScopedPtrVect move-assignable to use it in STL containers
This was a pre-C++11 implementation, and at that time, I developed the ScopedHolder to allow handling non-copyable objects in STL containers Meanwhile we have move semantics to achieve the same goal; and since `ScopedPtrVect` shall be retained, it should be upgraded, using the copy-and-swap approach
This commit is contained in:
parent
071ab82a7a
commit
2bec3ccd4e
3 changed files with 183 additions and 5 deletions
|
|
@ -22,6 +22,7 @@
|
|||
** Some details to note:
|
||||
** - contained objects accessed by reference, never NULL.
|
||||
** - the exposed iterator automatically dereferences
|
||||
** - can be move-assigned and move constructed, like `unique_ptr`
|
||||
**
|
||||
** @warning deliberately **not threadsafe**
|
||||
** @remark This library class provides the same basic functionality as
|
||||
|
|
@ -64,7 +65,7 @@ namespace lib {
|
|||
*/
|
||||
template<class T>
|
||||
class ScopedPtrVect
|
||||
: util::NonCopyable
|
||||
: util::MoveAssign
|
||||
{
|
||||
using _Vec = std::vector<T*>;
|
||||
using VIter = typename _Vec::iterator;
|
||||
|
|
@ -101,6 +102,23 @@ namespace lib {
|
|||
vec_.reserve (capacity);
|
||||
}
|
||||
|
||||
ScopedPtrVect (ScopedPtrVect && src)
|
||||
: vec_{std::move (src.vec_)}
|
||||
{ }
|
||||
|
||||
friend void
|
||||
swap (ScopedPtrVect& left, ScopedPtrVect& right)
|
||||
{
|
||||
swap (left.vec_, right.vec_);
|
||||
}
|
||||
|
||||
ScopedPtrVect&
|
||||
operator= (ScopedPtrVect && other)
|
||||
{
|
||||
swap (*this, other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/** take ownership of the given object,
|
||||
* adding it at the end of the collection
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ namespace test{
|
|||
simpleUsage();
|
||||
iterating();
|
||||
detaching();
|
||||
moving();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -145,7 +146,7 @@ namespace test{
|
|||
detaching()
|
||||
{
|
||||
int id2, id3;
|
||||
Dummy* extracted(0);
|
||||
Dummy* extracted{nullptr};
|
||||
CHECK (0 == Dummy::checksum());
|
||||
{
|
||||
VectD holder;
|
||||
|
|
@ -177,6 +178,47 @@ namespace test{
|
|||
delete extracted;
|
||||
CHECK (0 == Dummy::checksum());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
moving()
|
||||
{ {
|
||||
VectD org;
|
||||
VectD left;
|
||||
CHECK (0 == Dummy::checksum());
|
||||
|
||||
org.manage (new Dummy);
|
||||
org.manage (new Dummy);
|
||||
org.manage (new Dummy);
|
||||
|
||||
CHECK (not isnil (org));
|
||||
CHECK ( isnil (left));
|
||||
auto sum = Dummy::checksum();
|
||||
CHECK (sum > 0);
|
||||
int id0 = org[0].getVal(),
|
||||
id1 = org[1].getVal(),
|
||||
id2 = org[2].getVal();
|
||||
|
||||
// create by move
|
||||
VectD right{std::move (org)};
|
||||
CHECK ( isnil (org));
|
||||
CHECK ( isnil (left));
|
||||
CHECK (not isnil (right));
|
||||
CHECK (sum == Dummy::checksum());
|
||||
|
||||
// move-assignment
|
||||
left = std::move (right);
|
||||
CHECK ( isnil (org));
|
||||
CHECK (not isnil (left));
|
||||
CHECK ( isnil (right));
|
||||
CHECK (sum == Dummy::checksum());
|
||||
CHECK (id0 == left[0].getVal());
|
||||
CHECK (id1 == left[1].getVal());
|
||||
CHECK (id2 == left[2].getVal());
|
||||
|
||||
}
|
||||
CHECK (0 == Dummy::checksum());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -52278,7 +52278,7 @@
|
|||
</body>
|
||||
</html></richcontent>
|
||||
<node CREATED="1732337022157" ID="ID_544252009" MODIFIED="1732337084587" TEXT="das könnte dann weiteres Verschieben sperren"/>
|
||||
<node CREATED="1732337085316" ID="ID_487485041" MODIFIED="1732337105606" TEXT="zumindest darf Invarianten-Processing erst mit diesem Schirt passieren"/>
|
||||
<node CREATED="1732337085316" ID="ID_487485041" MODIFIED="1732337085316" TEXT="zumindest darf Invarianten-Processing erst mit diesem Schritt passieren"/>
|
||||
<node CREATED="1732372728476" ID="ID_1531001529" MODIFIED="1732373067818" TEXT="ärgerlich: bläht Storage auf und bricht Invarianten"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1732377283840" ID="ID_1863518121" MODIFIED="1732378140499" TEXT="versuche Workaround: re-engage">
|
||||
|
|
@ -163658,7 +163658,8 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
<node COLOR="#435e98" CREATED="1748647039941" ID="ID_1043849033" MODIFIED="1748648221837" TEXT="ItemWrapper dagegen wird extrem viel verwendet">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1748648193159" ID="ID_777661860" MODIFIED="1748648215385" TEXT="ScopedPtrvect : sinnnvoll und ein wenig verwendet">
|
||||
<node COLOR="#435e98" CREATED="1748648193159" ID="ID_777661860" MODIFIED="1748707165077" TEXT="ScopedPtrVect : sinnnvoll und ein wenig verwendet">
|
||||
<linktarget COLOR="#548bc6" DESTINATION="ID_777661860" ENDARROW="Default" ENDINCLINATION="-16;39;" ID="Arrow_ID_5941421" SOURCE="ID_896065065" STARTARROW="None" STARTINCLINATION="-387;-18;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1748648315357" ID="ID_789031781" MODIFIED="1748648433360" TEXT="eine sinnvolle Variante ohne offensichtlichen Ersatz">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -163679,7 +163680,8 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
<node CREATED="1748648447725" ID="ID_1000331471" MODIFIED="1748648471427" TEXT="und dann ist da auch noch die elegante Integration mit unserem Iterator-Framework">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node CREATED="1748648474000" ID="ID_778015068" MODIFIED="1748648486629" TEXT="einziger Schmerz: wozu private inheritance?">
|
||||
<node COLOR="#5b280f" CREATED="1748648474000" ID="ID_778015068" MODIFIED="1748651087573" TEXT="einziger Schmerz: wozu private inheritance?">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1748649227483" ID="ID_295400455" MODIFIED="1748649267708" TEXT="private inheritance wäre nur in zwei Fällen zu rechtfertigen">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1748649241937" ID="ID_1876085509" MODIFIED="1748649307945" TEXT="wenn man das Template-Method-Pattern verwendet"/>
|
||||
|
|
@ -163711,6 +163713,122 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1748651090099" ID="ID_1759532502" MODIFIED="1748651108454" TEXT="also: umgeschrieben auf has-a private vector">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1748711055481" ID="ID_165954046" MODIFIED="1748711081730" TEXT="und move-assignable machen (incl Test)">
|
||||
<linktarget COLOR="#8198b2" DESTINATION="ID_165954046" ENDARROW="Default" ENDINCLINATION="511;33;" ID="Arrow_ID_1516296474" SOURCE="ID_1603400780" STARTARROW="None" STARTINCLINATION="331;-41;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1748652139435" ID="ID_1800650777" MODIFIED="1748652144635" TEXT="ScopedHolder">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#a10043" CREATED="1748652280157" ID="ID_1235606498" MODIFIED="1748652472016" TEXT="jedesmal wenn ich den sehe, sage ich »wäääh«">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
allein schon wenn man so viel Kommentar zur Rechtfertigung schreiben muß; und dann ist das Ganze auch noch stateful, und es führte zu einer Erweiterun, ScopedHolderTransfer, mit noch viel mehr Kommentar und Erläuterung und umständlichen Tests (und dann wird das am Ende doch fast nicht verwendet)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="smiley-angry"/>
|
||||
</node>
|
||||
<node CREATED="1748652489024" ID="ID_1954563627" MODIFIED="1748652500133" TEXT="leider ist das Thema aber trotz C++11 nicht ganz trivial">
|
||||
<node CREATED="1748654242179" ID="ID_844246830" MODIFIED="1748654269356" TEXT="These: im Grunde geht es um non-copyable-Objekte"/>
|
||||
<node CREATED="1748654281813" ID="ID_1594859729" MODIFIED="1748654308952" TEXT="und die Verlockung der „Effizienz“ eines Vectors"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1748654312219" ID="ID_1611256541" MODIFIED="1748654329986" TEXT="könnte man das nicht einfach durch eine Deque lösen?">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node CREATED="1748654337002" ID="ID_328246402" MODIFIED="1748654355692" TEXT="verwirrend ist der Umstand, daß ich eigenes API geschaffen habe">
|
||||
<node CREATED="1748654397040" ID="ID_1618042684" MODIFIED="1748654407036" TEXT="con.create()"/>
|
||||
<node CREATED="1748654436059" ID="ID_1168980803" MODIFIED="1748654438504" TEXT="bool(con)"/>
|
||||
<node CREATED="1748654407777" ID="ID_210801942" MODIFIED="1748654427694" TEXT="*con">
|
||||
<node CREATED="1748654428486" ID="ID_57633774" MODIFIED="1748654432849" TEXT="was soll denn das?"/>
|
||||
</node>
|
||||
<node CREATED="1748654479683" ID="ID_1589998526" MODIFIED="1748654524092" TEXT="con->..."/>
|
||||
</node>
|
||||
<node CREATED="1748654893223" ID="ID_1967446266" MODIFIED="1748655021163" TEXT="langsam dämmert mir's: das ist eigentlich ein Item-Wrapper">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
hatte das zwar geschaffen, um non-copyable Objekte in einen Vector packen zu können — aber es <i>ist kein Container,</i> sondern lediglich ein inline-Buffer
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<node CREATED="1748707079815" ID="ID_643047944" MODIFIED="1748707091410" TEXT="und die transfer_control ist eine move-Operation"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1748652500812" ID="ID_1634636436" MODIFIED="1748652506226" TEXT="verbleibende Usages">
|
||||
<node CREATED="1748655144495" ID="ID_1838839217" MODIFIED="1748655183316" TEXT="ScopedPtrHolder ist ohne Verwendungen ⟹ ignorieren">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1748652522844" ID="ID_1491633267" MODIFIED="1748652533235" TEXT="tracking-heap-block-provider.cpp">
|
||||
<node CREATED="1748707113641" ID="ID_896065065" MODIFIED="1748707243639" TEXT="verwendet für die Speicherblöcke selber einen ScopedPtrVect">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
für einen Test / Diagnose-Container ist das in der Tat sinnvoll, denn man möchte da nicht die Komplexität mit der Verwaltung von <i>Extents</i>  haben (größere Speicherblöcke, aus denen dann kleinere Allokationen ausgegeben werden)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<arrowlink COLOR="#548bc6" DESTINATION="ID_777661860" ENDARROW="Default" ENDINCLINATION="-16;39;" ID="Arrow_ID_5941421" STARTARROW="None" STARTINCLINATION="-387;-18;"/>
|
||||
</node>
|
||||
<node CREATED="1748707246896" ID="ID_1809312961" MODIFIED="1748707251960" TEXT="dieser ist aber non-copyable"/>
|
||||
<node CREATED="1748707257052" ID="ID_541151098" MODIFIED="1748707269497" TEXT="⟹ also wird er in einen ScopedHolder eingewickelt"/>
|
||||
<node CREATED="1748707382005" ID="ID_69938178" MODIFIED="1748707397135" TEXT="wäre eigentlich hier gar nicht notwendig: der BlockPool kommt dann in eine Map"/>
|
||||
<node CREATED="1748707601579" ID="ID_800614981" MODIFIED="1748711042415" TEXT="man könnte ScopedPtrVect move-only machen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
dann könnte man ihn nämlich ohne weiteres direkt in jedem STL-Container per emplace einbringen, selbst in std::vector
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1748709078635" ID="ID_503264993" MODIFIED="1748711030534" TEXT="sogar MoveAssign wäre sinnvoll">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
unique_ptr kann das ja auc
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node COLOR="#435e98" CREATED="1748709096713" ID="ID_1603400780" MODIFIED="1748711086783" TEXT="dann copy-and-swap">
|
||||
<arrowlink COLOR="#8198b2" DESTINATION="ID_165954046" ENDARROW="Default" ENDINCLINATION="511;33;" ID="Arrow_ID_1516296474" STARTARROW="None" STARTINCLINATION="331;-41;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1748652534162" ID="ID_562424850" MODIFIED="1748652540893" TEXT="time-control-test.cpp">
|
||||
<node CREATED="1748707494159" ID="ID_1077262401" MODIFIED="1748707538467" TEXT="der TestListener wird informiert über neue Time-Elemente"/>
|
||||
<node CREATED="1748707539616" ID="ID_1362948341" MODIFIED="1748707577729" TEXT="er verwendet ScopedHolder, um die die Immutabilitä zu umgehen"/>
|
||||
<node CREATED="1748707580758" ID="ID_1042435059" MODIFIED="1748707593581" TEXT="das könnte man auch per ItemWrapper machen">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue