Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
IterableFromIterator.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. 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 [[no_unique_address]] _ContextObjectType _fContextForEachIterator;
86
87#if qStroika_Foundation_Debug_AssertionsChecked
88 protected:
89 // @todo clarify, but I think this is just a debugging hack to make sure the underlying itertor
90 // lifetime is long enough for any iterators generated from this iterable.
91 // But I'm not clear this makes sense anymore after all the recent (--LGP 2021-11-23) iterable threading/lifetime
92 // changes. Not sure this really does anything useful, but we can revisit later since it doesn't appear to cause any harm either (besides
93 // possibly pointless complexity and a little rare speed in the debug code).
94 struct _IteratorTracker {
95 shared_ptr<unsigned int> fCountRunning = make_shared<unsigned int> (0);
96 ~_IteratorTracker ();
97 Iterator<T> MakeDelegatedIterator (const Iterator<T>& sourceIterator);
98 };
99
100 private:
101 mutable _IteratorTracker fIteratorTracker_;
102#endif
103
104 public:
105 _Rep ()
106 requires (same_as<CONTEXT_FOR_EACH_ITERATOR, void>)
107 = default;
108
109 protected:
110 _Rep (const _ContextObjectType& contextForEachIterator)
111 requires (same_as<void, CONTEXT_FOR_EACH_ITERATOR>);
112
113 public:
114 virtual Iterator<T> MakeIterator () const override;
115 };
116 };
117
118 /**
119 * This makes a copy of the given iterator, and wraps it in an iterable. That iterable then makes
120 * additional copies of that (argument) iterator as needed.
121 *
122 * \em Important Note
123 * The original Iterator<T> will have lifetime == the constructed Iterable<> - so be careful - that
124 * the thing the Iterator<T> came from has long enough lifetime!
125 *
126 * @see IterableFromIterator
127 */
128 template <typename T>
130
131}
132
133/*
134 ********************************************************************************
135 ******************************* Implementation Details *************************
136 ********************************************************************************
137 */
138#include "IterableFromIterator.inl"
139
140#endif /*_Stroika_Foundation_Traversal_IterableFromIterator_h_ */
Iterable< T > MakeIterableFromIterator(const Iterator< T > &iterator)
Implementation detail for iterator implementors.
Definition Iterable.h:1569
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:248
An Iterator<T> is a copyable object which allows traversing the contents of some container....
Definition Iterator.h:225