diff --git a/src/lib/iter-source.hpp b/src/lib/iter-source.hpp index 8649ffc6e..5a4caec07 100644 --- a/src/lib/iter-source.hpp +++ b/src/lib/iter-source.hpp @@ -178,6 +178,10 @@ namespace lib { static iterator EMPTY_SOURCE; + using value_type = TY; + using reference = TY&; + using pointer = TY*; + private: diff --git a/src/lib/iter-tree-explorer.hpp b/src/lib/iter-tree-explorer.hpp index 801d969ec..b78cfd8b5 100644 --- a/src/lib/iter-tree-explorer.hpp +++ b/src/lib/iter-tree-explorer.hpp @@ -271,6 +271,40 @@ namespace lib { } }; + + /** + * Adapt an IterSource to make it iterable. As such, lib::IterSource is meant + * to be iterable, while only exposing a conventional VTable-based _iteration interface_. + * To support this usage, the library offers some builders to attach an iterator adapter. + * Two flavours need to be distinguished: + * - we get a _reference_ to something living elsewhere; all we know is it's iterable. + * - we get a pointer, indicating that we must take ownership and manage the lifetime. + * The iterable entity in this case can be assumed heap allocated, featuring a virtual + * destructor. + * The generated front-end has identical type in both cases; it is based on a shared_ptr, + * just a different deleter function is used in both cases. This design makes sense, + * since the protocol requires us to invoke virtual function IterSource::disconnect() + * when use count goes to zero. + */ + template + class IterSourceIter + : public ISO::iterator + { + public: + IterSourceIter() =default; + // standard copy operations + + /** link to existing IterSource (without memory management) */ + IterSourceIter (ISO& externalSource) + : ISO::iterator{ISO::build (externalSource)} + { } + + /** own and manage a heap allocated IterSource */ + IterSourceIter (ISO* heap_allocated_IterSource) + : ISO::iterator{ISO::build (heap_allocated_IterSource)} + { } + }; + }//(End) namespace iter_explorer : basic iterator wrappers @@ -366,6 +400,20 @@ namespace lib { using SrcVal = typename SrcIter::value_type; }; + template + struct _DecoratorTraits, ISO>>> + { + using SrcIter = iter_explorer::IterSourceIter; + using SrcVal = typename ISO::value_type; + }; + + template + struct _DecoratorTraits, ISO>>> + { + using SrcIter = iter_explorer::IterSourceIter; + using SrcVal = typename ISO::value_type; + }; + }//(End) TreeExplorer traits diff --git a/tests/library/iter-tree-explorer-test.cpp b/tests/library/iter-tree-explorer-test.cpp index f58fffe8c..d30cab277 100644 --- a/tests/library/iter-tree-explorer-test.cpp +++ b/tests/library/iter-tree-explorer-test.cpp @@ -885,31 +885,26 @@ namespace test{ }; - VerySpecivicIter vsit{5}; + // simple standard case: create a new heap allocated IterSource implementation. + // TreeExplorer will take ownership (by smart-ptr) and build a Lumiera Iterator front-End + CHECK ("7-6-5-4-3-2-1" == materialise ( + treeExplore(new VerySpecivicIter{7}))); + + + + VerySpecivicIter vsit{4}; -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888 + // attach to an IterSource living here in local scope... auto ii = treeExplore(vsit); CHECK (not isnil (ii)); - CHECK (5 == *ii); - ++ii; CHECK (4 == *ii); CHECK (4 == vsit.currentVal()); - - VerySpecivicIter* clone = new VerySpecivicIter(vsit); - - CHECK (4 == clone->currentVal()); - - cout << materialise( - treeExplore(clone) - - ) < - - + + @@ -7067,8 +7067,8 @@ - - + +