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.
This commit is contained in:
Fischlurch 2024-03-21 19:57:05 +01:00
parent f716fb0bee
commit a2749adbc9
5 changed files with 69 additions and 35 deletions

View file

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

View file

@ -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 <type_traits>
//#include <utility>
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 CON, typename PTR = CON*>
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<IterIndex*>(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);

View file

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

View file

@ -34,6 +34,7 @@
#include "lib/util.hpp"
#include <vector>
#include <memory>
@ -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<uint>;
using Iter = IterIndex<Numz>;
using CIter = IterIndex<const Numz>;
using SMIter = IterIndex<Numz, shared_ptr<Numz>>;
inline Numz
makeNumz()
@ -179,7 +183,8 @@ namespace test{
void
iterTypeVariations ()
{
Numz numz{makeNumz()};
auto smartNumz = make_shared<Numz> (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

View file

@ -112839,8 +112839,8 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<node CREATED="1710802570304" ID="ID_348663664" MODIFIED="1710802576155" TEXT="empty-detector"/>
<node CREATED="1710802648966" ID="ID_307257971" MODIFIED="1710802653691" TEXT="sequence-extractor"/>
</node>
<node CREATED="1710802684313" ID="ID_1755236197" MODIFIED="1710802692132" TEXT="currInstruction">
<arrowlink COLOR="#b43057" DESTINATION="ID_647695428" ENDARROW="Default" ENDINCLINATION="-527;-17;" ID="Arrow_ID_660745747" STARTARROW="None" STARTINCLINATION="211;249;"/>
<node CREATED="1710802684313" ID="ID_1755236197" MODIFIED="1711046748762" TEXT="currInstruction">
<arrowlink COLOR="#7e4239" DESTINATION="ID_647695428" ENDARROW="Default" ENDINCLINATION="-527;-17;" ID="Arrow_ID_660745747" STARTARROW="None" STARTINCLINATION="211;249;"/>
<node CREATED="1710802696248" ID="ID_1500495122" MODIFIED="1710802702482" TEXT="der instruction pointer"/>
<node CREATED="1710802707078" ID="ID_1676117590" MODIFIED="1710802716696" TEXT="ist zuweisbar (random-access)"/>
</node>
@ -112939,10 +112939,10 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710978786840" ID="ID_647695428" MODIFIED="1710978844422" TEXT="brauche einen &#xbb;Cursor&#xab; f&#xfc;r aktuelle Action">
<linktarget COLOR="#b43057" DESTINATION="ID_647695428" ENDARROW="Default" ENDINCLINATION="-527;-17;" ID="Arrow_ID_660745747" SOURCE="ID_1755236197" STARTARROW="None" STARTINCLINATION="211;249;"/>
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1710978847288" ID="ID_1081341248" MODIFIED="1710978855055" TEXT="hatte ich sowas nicht schon mal?">
<node COLOR="#338800" CREATED="1710978786840" ID="ID_647695428" MODIFIED="1711046694334" TEXT="brauche einen &#xbb;Cursor&#xab; f&#xfc;r aktuelle Action">
<linktarget COLOR="#7e4239" DESTINATION="ID_647695428" ENDARROW="Default" ENDINCLINATION="-527;-17;" ID="Arrow_ID_660745747" SOURCE="ID_1755236197" STARTARROW="None" STARTINCLINATION="211;249;"/>
<icon BUILTIN="button_ok"/>
<node COLOR="#5b280f" CREATED="1710978847288" ID="ID_1081341248" MODIFIED="1711046705927" TEXT="hatte ich sowas nicht schon mal?">
<icon BUILTIN="help"/>
<node CREATED="1710979039184" ID="ID_1895789363" LINK="#ID_1801538785" MODIFIED="1710979356636" TEXT="CursorGear">
<icon BUILTIN="help"/>
@ -112984,15 +112984,17 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<icon BUILTIN="ksmiletris"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1710983365347" ID="ID_12713467" MODIFIED="1710986045325" TEXT="IterIndex_test">
<icon BUILTIN="pencil"/>
<node CREATED="1710983370851" ID="ID_929461554" MODIFIED="1710983390046" TEXT="verwende IterCursor_text als Vorlage">
<node COLOR="#338800" CREATED="1710983365347" ID="ID_12713467" MODIFIED="1711046686440" TEXT="IterIndex_test">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1710983370851" ID="ID_929461554" MODIFIED="1711046689862" TEXT="verwende IterCursor_text als Vorlage">
<icon BUILTIN="idea"/>
<node CREATED="1710983391672" ID="ID_201237845" MODIFIED="1710983405226" TEXT="der deckt n&#xe4;mlich eine ganze Menge ekelhafte Randf&#xe4;lle mit ab"/>
<node CREATED="1710983406078" ID="ID_252133900" MODIFIED="1710983436747" TEXT="auch die const-correctness und State-cloning"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1710986046845" ID="ID_1980706468" MODIFIED="1710986077126" TEXT="sollte noch eine smart-Ptr-Variante mit abdecken">
<icon BUILTIN="bell"/>
<node COLOR="#338800" CREATED="1710986046845" ID="ID_1980706468" MODIFIED="1711046669002" TEXT="eine smart-Ptr-Variante mit abgedeckt">
<icon BUILTIN="button_ok"/>
<node CREATED="1711046672031" ID="ID_452079779" MODIFIED="1711046674916" TEXT="shared-ptr"/>
<node CREATED="1711046675648" ID="ID_122061497" MODIFIED="1711046681859" TEXT="use_cnt() verifiziert"/>
</node>
</node>
</node>