Stroika Library 3.0d18
 
Loading...
Searching...
No Matches
STLContainerWrapper.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include <algorithm>
5
7
9
10 namespace Private_ {
11 template <typename T, typename A>
12 constexpr bool IsStdForwardList_ (forward_list<T, A>*)
13 {
14 return true;
15 }
16 constexpr bool IsStdForwardList_ (...)
17 {
18 return false;
19 }
20 template <typename T>
21 constexpr bool IsStdForwardList ()
22 {
23 return IsStdForwardList_ ((T*)nullptr);
24 }
25 }
26
27// Would like to leave on by default but we just added and cannot afford to have debug builds get that slow
28#ifndef qStroika_Foundation_Containers_DataStructures_STLContainerWrapper_IncludeSlowDebugChecks_
29#define qStroika_Foundation_Containers_DataStructures_STLContainerWrapper_IncludeSlowDebugChecks_ 0
30#endif
31
32 /*
33 ********************************************************************************
34 ******************* STLContainerWrapper<STL_CONTAINER_OF_T> ********************
35 ********************************************************************************
36 */
37 template <typename STL_CONTAINER_OF_T>
38 template <typename... EXTRA_ARGS>
40 : inherited{forward<EXTRA_ARGS> (args)...}
41 {
42 }
43 template <typename STL_CONTAINER_OF_T>
45 {
46 AssertExternallySynchronizedMutex::ReadContext declareContext{*this};
47 return this->find (item) != this->end ();
48 }
49 template <typename STL_CONTAINER_OF_T>
50 template <invocable<typename STL_CONTAINER_OF_T::const_iterator, typename STL_CONTAINER_OF_T::const_iterator> POINT_TO_SAME_THING>
51 void STLContainerWrapper<STL_CONTAINER_OF_T>::MoveIteratorHereAfterClone (ForwardIterator* pi, const STLContainerWrapper* movedFrom,
52 [[maybe_unused]] POINT_TO_SAME_THING&& pointToSameThingTester) const
53 requires (convertible_to<invoke_result_t<POINT_TO_SAME_THING, typename STL_CONTAINER_OF_T::const_iterator, typename STL_CONTAINER_OF_T::const_iterator>, bool>)
54 {
55 AssertExternallySynchronizedMutex::ReadContext declareContext{*this};
56 // TRICKY TODO - BUT MUST DO - MUST MOVE FROM OLD ITER TO NEW
57 // only way
58 //
59 // For STL containers, not sure how to find an equiv new iterator for an old one, but my best guess is to iterate through
60 // old for old, and when I match, stop on new
61 pi->AssertDataMatches (movedFrom);
62 auto newI = this->begin ();
63 [[maybe_unused]] auto newE = this->end ();
64 auto oldI = movedFrom->begin ();
65 [[maybe_unused]] auto oldE = movedFrom->end ();
66 while (not forward<POINT_TO_SAME_THING> (pointToSameThingTester) (oldI, newI)) {
67 Assert (newI != newE);
68 Assert (oldI != oldE);
69 ++newI;
70 ++oldI;
71 Assert (newI != newE);
72 Assert (oldI != oldE);
73 }
74 Assert (oldI == pi->fStdIterator_);
75 pi->fStdIterator_ = newI;
76 pi->fData_ = this;
77 }
78 template <typename STL_CONTAINER_OF_T>
79 template <invocable<typename STL_CONTAINER_OF_T::value_type> FUNCTION>
80 void STLContainerWrapper<STL_CONTAINER_OF_T>::Apply (FUNCTION&& doToElement) const
81 {
82 AssertExternallySynchronizedMutex::ReadContext declareContext{*this};
83 for (auto i = this->begin (); i != this->end (); ++i) {
84 (doToElement) (*i);
85 }
86 }
87 template <typename STL_CONTAINER_OF_T>
88 template <predicate<typename STL_CONTAINER_OF_T ::value_type> FUNCTION>
89 auto STLContainerWrapper<STL_CONTAINER_OF_T>::Find (FUNCTION&& firstThat) const -> const_iterator
90 {
91 AssertExternallySynchronizedMutex::ReadContext declareContext{*this};
92 for (auto i = this->begin (); i != this->end (); ++i) {
93 if (firstThat (*i)) {
94 return i;
95 }
96 }
97 return this->end ();
98 }
99 template <typename STL_CONTAINER_OF_T>
100 template <predicate<typename STL_CONTAINER_OF_T ::value_type> FUNCTION>
101 auto STLContainerWrapper<STL_CONTAINER_OF_T>::Find (FUNCTION&& firstThat) -> iterator
102 {
104 for (auto i = this->begin (); i != this->end (); ++i) {
105 if (firstThat (*i)) {
106 return i;
107 }
108 }
109 return this->end ();
110 }
111 template <typename STL_CONTAINER_OF_T>
112 template <predicate<typename STL_CONTAINER_OF_T::value_type> PREDICATE>
113 inline bool STLContainerWrapper<STL_CONTAINER_OF_T>::FindIf (PREDICATE&& pred) const
114 {
115 AssertExternallySynchronizedMutex::ReadContext declareContext{*this};
116 return find_if (this->begin (), this->end (), forward<PREDICATE> (pred)) != this->end ();
117 }
118 template <typename STL_CONTAINER_OF_T>
119 inline void STLContainerWrapper<STL_CONTAINER_OF_T>::Invariant () const noexcept
120 {
121 }
122 template <typename STL_CONTAINER_OF_T>
123 inline auto STLContainerWrapper<STL_CONTAINER_OF_T>::remove_constness (const_iterator it) -> iterator
124 {
125 // http://stackoverflow.com/questions/765148/how-to-remove-constness-of-const-iterator
126 if constexpr (Private_::IsStdForwardList<STL_CONTAINER_OF_T> ()) {
127 return this->erase_after (it, it);
128 }
129 else {
130 return this->erase (it, it);
131 }
132 }
133
134 /*
135 ********************************************************************************
136 *********** STLContainerWrapper<STL_CONTAINER_OF_T>::ForwardIterator ***********
137 ********************************************************************************
138 */
139 template <typename STL_CONTAINER_OF_T>
140 constexpr STLContainerWrapper<STL_CONTAINER_OF_T>::ForwardIterator::ForwardIterator (const STLContainerWrapper* data, UnderlyingIteratorRep startAt) noexcept
141 : fData_{data}
142 , fStdIterator_{startAt}
143 {
144 RequireNotNull (data);
145 }
146 template <typename STL_CONTAINER_OF_T>
147 constexpr STLContainerWrapper<STL_CONTAINER_OF_T>::ForwardIterator::ForwardIterator (const STLContainerWrapper* data) noexcept
148 : ForwardIterator{data, (RequireExpression (data != nullptr), data->cbegin ())}
149 {
150 }
151 template <typename STL_CONTAINER_OF_T>
153 {
154 return not Done ();
155 }
156 template <typename STL_CONTAINER_OF_T>
158 {
159#if qStroika_Foundation_Containers_DataStructures_STLContainerWrapper_IncludeSlowDebugChecks_
160 AssertExternallySynchronizedMutex::ReadContext declareContext{*fData_};
161#endif
162 AssertNotNull (fData_);
163 return fStdIterator_ == fData_->end ();
164 }
165 template <typename STL_CONTAINER_OF_T>
166 inline auto STLContainerWrapper<STL_CONTAINER_OF_T>::ForwardIterator::operator++ () noexcept -> ForwardIterator&
167 {
168 Require (not Done ());
169 ++fStdIterator_;
170 return *this;
171 }
172 template <typename STL_CONTAINER_OF_T>
173 inline auto STLContainerWrapper<STL_CONTAINER_OF_T>::ForwardIterator::operator* () const -> const value_type&
174 {
175 AssertExternallySynchronizedMutex::ReadContext declareContext{*fData_};
176 AssertNotNull (fData_);
177 Require (not Done ());
178 return *fStdIterator_;
179 }
180 template <typename STL_CONTAINER_OF_T>
181 inline auto STLContainerWrapper<STL_CONTAINER_OF_T>::ForwardIterator::operator->() const -> const value_type*
182 {
183 AssertExternallySynchronizedMutex::ReadContext declareContext{*fData_};
184 AssertNotNull (fData_);
185 Require (not Done ());
186 return &*fStdIterator_;
187 }
188 template <typename STL_CONTAINER_OF_T>
190 {
191 AssertExternallySynchronizedMutex::ReadContext declareContext{*fData_};
192 AssertNotNull (fData_);
193 return static_cast<size_t> (std::distance (fData_->begin (), fStdIterator_));
194 }
195 template <typename STL_CONTAINER_OF_T>
197 {
198 AssertExternallySynchronizedMutex::ReadContext declareContext{*fData_};
199 return fStdIterator_;
200 }
201 template <typename STL_CONTAINER_OF_T>
202 inline void STLContainerWrapper<STL_CONTAINER_OF_T>::ForwardIterator::SetUnderlyingIteratorRep (UnderlyingIteratorRep l)
203 {
204 AssertExternallySynchronizedMutex::ReadContext declareContext{*fData_}; // read lock on data, though writing to this iterator
205 fStdIterator_ = l;
206 }
207 template <typename STL_CONTAINER_OF_T>
209 {
210#if qStroika_Foundation_Debug_AssertionsChecked
211 Require (data == fData_);
212#endif
213 }
214 template <typename STL_CONTAINER_OF_T>
216 {
217 AssertExternallySynchronizedMutex::ReadContext declareContext{*fData_};
218 return fStdIterator_ == rhs.fStdIterator_;
219 }
221}
#define AssertNotNull(p)
Definition Assertions.h:333
#define RequireNotNull(p)
Definition Assertions.h:347
#define RequireExpression(c)
Definition Assertions.h:267
nonvirtual void Apply(FUNCTION &&doToElement) const
unique_lock< AssertExternallySynchronizedMutex > WriteContext
Instantiate AssertExternallySynchronizedMutex::WriteContext to designate an area of code where protec...
conditional_t<(sizeof(CHECK_T)<=2 *sizeof(void *)) and is_trivially_copyable_v< CHECK_T >, CHECK_T, const CHECK_T & > ArgByValueType
This is an alias for 'T' - but how we want to pass it on stack as formal parameter.
Definition TypeHints.h:32