Stroika Library 3.0d23
 
Loading...
Searching...
No Matches
IterableFromIterator.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Traversal_IterableFromIterator_h_
5#define _Stroika_Foundation_Traversal_IterableFromIterator_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include "Stroika/Foundation/Common/Common.h"
14
15/**
16 * \file
17 *
18 * TODO:
19 *
20 */
21
22namespace Stroika::Foundation::Traversal {
23
24 /**
25 * Helper class to make it a little easier to wrap an Iterable<> around an Iterator class.
26 *
27 * Template Paraemters:
28 * T is the type of Iterator/Iterable (thing iterated
29 * over). Parameter
30 * CONTEXT_FOR_EACH_ITERATOR is an optional context object you can provide in the
31 * constructor for the iterable, a copy of which is
32 * passed to each constructed iterator.
33 * NEW_ITERATOR_REP_TYPE is the (OPTIONAL) type of the iterator rep to construct
34 * in the provided Iterable<T>::MakeIterator() method.
35 * Note - if you leave this to the default of void,
36 * then your subclass must explicitly override the
37 * Iterator<T>::IRep_::MakeIterator() method.
38 *
39 * \par Example Usage
40 * \code
41 * template <typename T>
42 * struct MyIterable_ : public Iterable<T> {
43 * struct Rep : public IterableFromIterator<T>::_Rep {
44 * Iterator<T> fOriginalIterator;
45 * Rep (const Iterator<T>& originalIterator)
46 * : fOriginalIterator{originalIterator}
47 * {
48 * }
49 * virtual Iterator<T> MakeIterator () const override
50 * {
51 * return fOriginalIterator;
52 * }
53 * virtual typename Iterable<T>::_SharedPtrIRep Clone () const override
54 * {
55 * return Memory::MakeSharedPtr<Rep> (*this);
56 * }
57 * };
58 * MyIterable_ (const Iterator<T>& originalIterator)
59 * : Iterable<T>{Memory::MakeSharedPtr<Rep> (originalIterator)}
60 * {
61 * }
62 * };
63 * \endcode
64 *
65 * Note _Rep is an abstract class, and you MUST provide your own Clone () method, and often will
66 * want to override to provide a more efficient empty () and size () implementation.
67 *
68 * @see MakeIterableFromIterator
69 *
70 */
71 template <typename T, typename NEW_ITERATOR_REP_TYPE = void, typename CONTEXT_FOR_EACH_ITERATOR = void>
72 class IterableFromIterator : public Iterable<T> {
73 public:
74 using value_type = typename Iterable<T>::value_type;
75
76 public:
77 class _Rep : public Iterable<T>::_IRep {
78 private:
79 using inherited = typename Iterable<T>::_IRep;
80
81 protected:
82 using _ContextObjectType = conditional_t<same_as<CONTEXT_FOR_EACH_ITERATOR, void>, Common::Empty, CONTEXT_FOR_EACH_ITERATOR>;
83
84 protected:
85 // FAILED: Assert; *fCountRunning == 0;Stroika::Foundation::Traversal::IterableFromIterator<struct Stroika::Foundation::Common::CountedValue<int,unsigned int>,void,void>::_Rep::_IteratorTracker::~_IteratorTracker;C:\Sandbox\Stroika\DevRoot\Library\Sources\Stroika\Foundation\Traversal\IterableFromIterator.inl: 18
86 qStroika_ATTRIBUTE_NO_UNIQUE_ADDRESS_VCBUGGY _ContextObjectType _fContextForEachIterator;
87
88#if qStroika_Foundation_Debug_AssertionsChecked
89 protected:
90 // @todo clarify, but I think this is just a debugging hack to make sure the underlying itertor
91 // lifetime is long enough for any iterators generated from this iterable.
92 // But I'm not clear this makes sense anymore after all the recent (--LGP 2021-11-23) iterable threading/lifetime
93 // changes. Not sure this really does anything useful, but we can revisit later since it doesn't appear to cause any harm either (besides
94 // possibly pointless complexity and a little rare speed in the debug code).
95 struct _IteratorTracker {
96 shared_ptr<unsigned int> fCountRunning = make_shared<unsigned int> (0);
97 ~_IteratorTracker ();
98 Iterator<T> MakeDelegatedIterator (const Iterator<T>& sourceIterator);
99 };
100
101 private:
102 mutable _IteratorTracker fIteratorTracker_;
103#endif
104
105 public:
106 _Rep ()
107 requires (same_as<CONTEXT_FOR_EACH_ITERATOR, void>)
108 = default;
109
110 protected:
111 _Rep (const _ContextObjectType& contextForEachIterator)
112 requires (same_as<void, CONTEXT_FOR_EACH_ITERATOR>);
113
114 public:
115 virtual Iterator<T> MakeIterator () const override;
116 };
117 };
118
119 /**
120 * This makes a copy of the given iterator, and wraps it in an iterable. That iterable then makes
121 * additional copies of that (argument) iterator as needed.
122 *
123 * \em Important Note
124 * The original Iterator<T> will have lifetime == the constructed Iterable<> - so be careful - that
125 * the thing the Iterator<T> came from has long enough lifetime!
126 *
127 * @see IterableFromIterator
128 */
129 template <typename T>
131
132}
133
134/*
135 ********************************************************************************
136 ******************************* Implementation Details *************************
137 ********************************************************************************
138 */
139#include "IterableFromIterator.inl"
140
141#endif /*_Stroika_Foundation_Traversal_IterableFromIterator_h_ */
Iterable< T > MakeIterableFromIterator(const Iterator< T > &iterator)
#define qStroika_ATTRIBUTE_NO_UNIQUE_ADDRESS_VCBUGGY
qStroika_ATTRIBUTE_NO_UNIQUE_ADDRESS_VCBUGGY same as qStroika_ATTRIBUTE_NO_UNIQUE_ADDRESS
Definition StdCompat.h:454
Implementation detail for iterator implementors.
Definition Iterable.h:1564
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:237
T value_type
value_type is an alias for the type iterated over - like vector<T>::value_type
Definition Iterable.h:250
An Iterator<T> is a copyable object which allows traversing the contents of some container....
Definition Iterator.h:225