From a2749adbc90ce32437dd86317e0225a6c4fc435b Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 21 Mar 2024 19:57:05 +0100 Subject: [PATCH] Library: also cover the smart-ptr usage variant The way I've written this helper template, as a byproduct it is also possible to maintain the back-refrence to the container through a smart-ptr. In this case, the iterator-handle also manages the ownership automatically. --- src/lib/iter-adapter.hpp | 7 ++--- src/lib/iter-index.hpp | 30 ++++++++++++++-------- tests/library/iter-cursor-test.cpp | 2 +- tests/library/iter-index-test.cpp | 41 +++++++++++++++++++++++++----- wiki/thinkPad.ichthyo.mm | 24 +++++++++-------- 5 files changed, 69 insertions(+), 35 deletions(-) diff --git a/src/lib/iter-adapter.hpp b/src/lib/iter-adapter.hpp index 23f29865e..d745fbcf9 100644 --- a/src/lib/iter-adapter.hpp +++ b/src/lib/iter-adapter.hpp @@ -407,11 +407,8 @@ namespace lib { /** allow derived classes to * access state representation */ - ST & - stateCore() - { - return core_; - } + ST & stateCore() { return core_; } + ST const& stateCore() const { return core_; } void __throw_if_empty() const diff --git a/src/lib/iter-index.hpp b/src/lib/iter-index.hpp index 93b058289..388f6829f 100644 --- a/src/lib/iter-index.hpp +++ b/src/lib/iter-index.hpp @@ -28,12 +28,12 @@ ** to a processing algorithm while abstracting away the actual data storage. Besides usage ** as »Lumiera Forward Iterator«, the current access position can be retrieved directly ** and it can be relocated to another valid index position; this implies also the ability - ** to re-set the iteration to the container's start. + ** to re-set the iteration to the container's start. Optionally, a smart-ptr can be + ** embedded, allowing the handle also to owns and manage the data container. ** ** @see IterIndex_test ** @see iter-adapter.hpp ** @see [usage example](\ref lib::TextTemplate::InstanceCore) - ** */ @@ -43,9 +43,6 @@ #include "lib/iter-adapter.hpp" -//#include -//#include - namespace lib { @@ -100,12 +97,22 @@ namespace lib { return not (c1 == c2); } }; - + // }//(End)Implementation + /** - * + * Subscript-index based access to a container, packaged as iterator. + * This is a copyable and assignable value object (handle), referring to some + * data container maintained elsewhere. The container must provide an `operator[]`. + * This handle can be used as »Lumiera Forward Iterator«, but with the additional + * capability to retrieve and re-set the current index position. + * @tparam CON a container with `operator[]` and a function `size()` + * @tparam PTR how to refer to this container; can be defined as smart-ptr, + * additionally allowing to manage this container automatically. + * @remark while a default constructed IterIndex and some _exhausted_ IterIndex + * compare equal, only the latter can be re-set into active state. */ template class IterIndex @@ -116,8 +123,9 @@ namespace lib { public: IterIndex() = default; - IterIndex (CON& dataContainer) - : _Par{_Cor{&dataContainer, 0}} + IterIndex (CON& container) : IterIndex{&container}{ }; + IterIndex (PTR pContainer) + : _Par{_Cor{pContainer, 0}} { } @@ -125,13 +133,13 @@ namespace lib { getIDX() const { _Par::__throw_if_empty(); - return const_cast(this)->stateCore().idx_; + return _Par::stateCore().idx_; } void setIDX (size_t newIDX) { - auto& core = _Par::stateCore(); + auto& core = _Par::stateCore(); if (not core.isValidIDX (newIDX)) throw lumiera::error::Invalid ("Attempt to set index out of bounds", lumiera::error::LUMIERA_ERROR_INDEX_BOUNDS); diff --git a/tests/library/iter-cursor-test.cpp b/tests/library/iter-cursor-test.cpp index f02db4856..7f95dbdee 100644 --- a/tests/library/iter-cursor-test.cpp +++ b/tests/library/iter-cursor-test.cpp @@ -200,7 +200,7 @@ namespace test{ - /** @test verify the const and dereferencing variants, + /** @test verify variant created from a const_iterator, * based on the const-ness of the underlying STL iterator */ void diff --git a/tests/library/iter-index-test.cpp b/tests/library/iter-index-test.cpp index 611fb617a..8122a876e 100644 --- a/tests/library/iter-index-test.cpp +++ b/tests/library/iter-index-test.cpp @@ -34,6 +34,7 @@ #include "lib/util.hpp" #include +#include @@ -44,6 +45,8 @@ namespace test{ using util::join; using util::isnil; using std::vector; + using std::shared_ptr; + using std::make_shared; using LERR_(ITER_EXHAUST); using LERR_(INDEX_BOUNDS); @@ -56,6 +59,7 @@ namespace test{ using Numz = vector; using Iter = IterIndex; using CIter = IterIndex; + using SMIter = IterIndex>; inline Numz makeNumz() @@ -179,7 +183,8 @@ namespace test{ void iterTypeVariations () { - Numz numz{makeNumz()}; + auto smartNumz = make_shared (makeNumz()); + Numz & numz{*smartNumz}; Numz const& const_numz{numz}; uint i = 0; @@ -202,21 +207,43 @@ namespace test{ CHECK (iter); CHECK (iter != CIter()); CHECK (*iter == i-1); - - // note: the previous run indeed modified - // the elements within the container. - - // ++(*iter); // doesn't compile, because it yields a "* const" + // Note: the preceding loop has indeed modified the contents +// ++(*iter); // but this doesn't compile, because the CIter yields a _const_ } verifyComparisons (CIter{numz}); + + CHECK (1 == smartNumz.use_count()); + { + SMIter smIter{smartNumz}; + CIter cIter{*smartNumz}; + CHECK (*cIter == uint(-1)); + for (i=0; smIter; ++smIter, ++i) + { + CHECK (smIter); + CHECK (smIter != SMIter()); + CHECK (*smIter == i-1); + ++(*smIter); + CHECK (*smIter == i); + } + CHECK (isnil (smIter)); + CHECK (smIter == SMIter()); + cIter.setIDX(5); + smIter.setIDX(5); + CHECK (*smIter == *cIter); + + verifyComparisons (smIter); + + CHECK (5 == *cIter); // shared data modified + CHECK (2 == smartNumz.use_count()); + } + CHECK (1 == smartNumz.use_count()); } - /** @test verify equality handling and NIL detection * for the given iterator/wrapper handed in. * @note the argument is not altered; rather we create diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index fdad6391e..c3fd19b75 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -112839,8 +112839,8 @@ std::cout << tmpl.render({"what", "World"}) << s - - + + @@ -112939,10 +112939,10 @@ std::cout << tmpl.render({"what", "World"}) << s - - - - + + + + @@ -112984,15 +112984,17 @@ std::cout << tmpl.render({"what", "World"}) << s - - - + + + - - + + + +