From 3b929cf014d45ca2430e86debec661f6a76aa87c Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 11 Jul 2023 01:53:14 +0200 Subject: [PATCH] Block-Flow: better setup for iterator implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using a Storage* within a wrapper as "pos" will work, but is borderline trickery, since it amounts to subverting the idea behind IterAdapter (which is to encapsulate a target pointer with some control-logic in the managing container). Using the same storage size and implementation overhead, it is much more straight-forward to package the complete iteration logic into a »State Core«, which in this case however maintains a back-link to the ExtentFamily. --- src/lib/iter-adapter.hpp | 10 ++- src/vault/mem/extent-family.hpp | 78 ++++++++++---------- wiki/thinkPad.ichthyo.mm | 126 ++++++++++++++++++++++++++++++-- 3 files changed, 166 insertions(+), 48 deletions(-) diff --git a/src/lib/iter-adapter.hpp b/src/lib/iter-adapter.hpp index 261ce63ab..a0ce46003 100644 --- a/src/lib/iter-adapter.hpp +++ b/src/lib/iter-adapter.hpp @@ -53,8 +53,10 @@ ** There are many further ways of building a Lumiera Forward Iterator. ** For example, lib::IterSource exposes a "iterable" source of data elements, ** while hiding the actual container or generator implementation behind a - ** VTable call. Besides, there are adapters for the most common usages - ** with STL containers, and such iterators can also be combined and + ** VTable call. Furthermore, complex processing chains with recursive + ** expansion can be built with the \ref IterExporer builder function. + ** Besides, there are adapters for the most common usages with STL + ** containers, and such iterators can also be combined and ** extended with the help of \ref itertools.hpp ** ** Basically every class in compliance with our specific iterator concept @@ -141,7 +143,7 @@ namespace lib { * @note it is possible to "hide" a smart-ptr within the CON template parameter. * * @tparam POS pointer or similar mutable link to the _current value_. - * Will be `bool()` checked to detect iteration end + * Will be `bool()` checked to detect iteration end, end else dereferenced. * @tparam CON type of the backing container, which needs to implement two * extension point functions for iteration control * @@ -472,7 +474,7 @@ namespace lib { public: using IT::IT; - /* === state protocol API for IterStateWrapper === */ + /* === state protocol API for IterStateWrapper === */ bool checkPoint() const { diff --git a/src/vault/mem/extent-family.hpp b/src/vault/mem/extent-family.hpp index 170ecd1ac..12f4e69e4 100644 --- a/src/vault/mem/extent-family.hpp +++ b/src/vault/mem/extent-family.hpp @@ -109,31 +109,46 @@ namespace mem { ENSURE (get() != nullptr); return reinterpret_cast (*get()); } - - struct iterator - { - using value_type = Extent; - using reference = Extent&; - using pointer = Extent*; - - Storage* storageSlot; - - explicit - operator bool() const - { - return bool(storageSlot); - } - - Extent& - operator* () - { - REQUIRE (storageSlot and *storageSlot); - return storageSlot->access(); - } - }; }; using Extents = std::vector; - using RawIter = typename Storage::iterator; + + + /** + * Iteration »State Core« based on Extents index position. + * @remark builds upon the specific wrap-around logic for + * cyclic reuse of extent storage and allocation. + */ + struct IdxLink + { + ExtentFamily* exFam{nullptr}; + size_t index{0}; + + /* === state protocol API for IterStateWrapper === */ + bool + checkPoint() const + { + return exFam and index != exFam->after_; + } + + Extent& + yield() const + { + UNIMPLEMENTED ("resolve index"); + } + + void + iterNext() + { + UNIMPLEMENTED ("Iterate with wrap-around"); + } + + bool + operator== (IdxLink const& oi) const + { + return exFam == oi.exFam + and index == oi.index; + } + }; /* ==== Management Data ==== */ @@ -194,7 +209,7 @@ namespace mem { /** allow transparent iteration of Extents, expanding storage on demand */ - using iterator = lib::IterAdapter; ////////////////////OOO consider to use a Extent* instead of the RawIter?? + using iterator = lib::IterStateWrapper; iterator @@ -247,21 +262,6 @@ namespace mem { } - /* == Iteration control API (used by IterAdapter via ADL) == */ - - friend bool - checkPoint (ExtentFamily* exFam, RawIter& pos) - { - UNIMPLEMENTED ("ExtentFamily iteration control: check and adapt position"); - } - - friend void - iterNext (ExtentFamily* exFam, RawIter& pos) - { - UNIMPLEMENTED ("ExtentFamily iteration control: access next Extent, possibly expand allocation"); - } - - /// „backdoor“ to watch internals from tests friend class ExtentDiagnostic; }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 8e0d87ea6..b746f2cda 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -79162,17 +79162,133 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ ‖ StateCore ‖ +

+

+ (Backlink, Index) +

+ +
+ + + +

+ Begründung: +

+
    +
  • + der direkte Zugang zum Index ist natürlich und leicht verständlich +
  • +
  • + Performance ist gleich (nicht besonders toll aber voll OK) wie eine Pointer-Lösung +
  • +
  • + und mit dem Marker-Wert muß ich dann halt leben; Konstante definieren +
  • +
+ +
+ + + + + + + + + + + + + + + + + + + + +

+ Damit vermeide ich, einen speziellen Marker-Wert zu verwenden; +

+

+ In der Tat darf der Index für einen aktiven und gültigen Extent niemals after_ sein, er muß entweder davor stehen, oder start_ == after_ und der Container ist leer +

+ +
+
+
+ - - - + - + + + + + + + +