diff --git a/src/lib/scoped-ptrvect.hpp b/src/lib/scoped-ptrvect.hpp index c00456b31..5dd87678d 100644 --- a/src/lib/scoped-ptrvect.hpp +++ b/src/lib/scoped-ptrvect.hpp @@ -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 ScopedPtrVect - : util::NonCopyable + : util::MoveAssign { using _Vec = std::vector; 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 diff --git a/tests/library/scoped-ptrvect-test.cpp b/tests/library/scoped-ptrvect-test.cpp index c8bfb6307..b14a3cba8 100644 --- a/tests/library/scoped-ptrvect-test.cpp +++ b/tests/library/scoped-ptrvect-test.cpp @@ -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()); + } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index e45fc2ba5..7efa2c6d8 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -52278,7 +52278,7 @@ - + @@ -163658,7 +163658,8 @@ Since then others have made contributions, see the log for the history. - + + @@ -163679,7 +163680,8 @@ Since then others have made contributions, see the log for the history. - + + @@ -163711,6 +163713,122 @@ Since then others have made contributions, see the log for the history. + + + + + + + + + + + + + + + +

+ 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) +

+ + +
+ + +
+ + + + + + + + + + + + + + + + + + + + +

+ hatte das zwar geschaffen, um non-copyable Objekte in einen Vector packen zu können — aber es ist kein Container, sondern lediglich ein inline-Buffer +

+ + +
+ + +
+ + + + + + + + + + + +

+ 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 Extents  haben (größere Speicherblöcke, aus denen dann kleinere Allokationen ausgegeben werden) +

+ + +
+ +
+ + + + + + + + + +

+ dann könnte man ihn nämlich ohne weiteres direkt in jedem STL-Container per emplace einbringen, selbst in std::vector +

+ + +
+ +
+ + + + + + +

+ unique_ptr kann das ja auc +

+ + +
+ + + + + +
+
+ + + + + + + +