Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
SparseDataHyperRectangle_stdmap.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include <map>
5
7#include "Stroika/Foundation/Containers/Private/IteratorImplHelper.h"
10
12
13 /*
14 ********************************************************************************
15 *********** SparseDataHyperRectangle_stdmap<T, INDEXES...>::Rep_ ***************
16 ********************************************************************************
17 */
18 template <typename T, typename... INDEXES>
19 class SparseDataHyperRectangle_stdmap<T, INDEXES...>::Rep_ : public DataHyperRectangle<T, INDEXES...>::_IRep,
20 public Memory::UseBlockAllocationIfAppropriate<Rep_> {
21 private:
22 using inherited = typename DataHyperRectangle<T, INDEXES...>::_IRep;
23
24 public:
25 Rep_ (Common::ArgByValueType<T> defaultItem)
26 : fDefaultValue_{defaultItem}
27 {
28 }
29 Rep_ (const Rep_& from) = default;
30
31 public:
32 nonvirtual Rep_& operator= (const Rep_&) = delete;
33
34 // Iterable<tuple<T, INDEXES...>>::_IRep overrides
35 public:
36 virtual shared_ptr<typename Iterable<tuple<T, INDEXES...>>::_IRep> Clone () const override
37 {
39 return Memory::MakeSharedPtr<Rep_> (*this);
40 }
41 virtual Iterator<tuple<T, INDEXES...>> MakeIterator () const override
42 {
44 return Iterator<value_type>{make_unique<IteratorRep_> (&fData_, &fChangeCounts_)};
45 }
46 virtual size_t size () const override
47 {
49 return fData_.size ();
50 }
51 virtual bool empty () const override
52 {
54 return fData_.empty ();
55 }
56 virtual void Apply (const function<void (ArgByValueType<value_type> item)>& doToElement, [[maybe_unused]] Execution::SequencePolicy seq) const override
57 {
59 fData_.Apply ([&] (const pair<tuple<INDEXES...>, T>& item) { doToElement (tuple_cat (tuple<T>{item.second}, item.first)); });
60 }
61 virtual Iterator<tuple<T, INDEXES...>> Find (const function<bool (ArgByValueType<value_type> item)>& that,
62 [[maybe_unused]] Execution::SequencePolicy seq) const override
63 {
65 using RESULT_TYPE = Iterator<tuple<T, INDEXES...>>;
66 auto iLink = const_cast<DataStructureImplType_&> (fData_).Find (
67 [&] (const pair<tuple<INDEXES...>, T>& item) { return that (tuple_cat (tuple<T>{item.second}, item.first)); });
68 if (iLink == fData_.end ()) {
69 return RESULT_TYPE::GetEmptyIterator ();
70 }
71 unique_ptr<IteratorRep_> resultRep = make_unique<IteratorRep_> (&fData_, &fChangeCounts_);
72 resultRep->fIterator.SetUnderlyingIteratorRep (iLink);
73 return RESULT_TYPE{move (resultRep)};
74 }
75
76 // DataHyperRectangle<T, INDEXES...>::_IRep overrides
77 public:
78 virtual shared_ptr<typename DataHyperRectangle<T, INDEXES...>::_IRep> CloneEmpty () const override
79 {
81 return Memory::MakeSharedPtr<Rep_> (fDefaultValue_); // keep default, but lose data
82 }
83 virtual T GetAt (INDEXES... indexes) const override
84 {
86 auto i = fData_.find (tuple<INDEXES...>{indexes...});
87 if (i != fData_.end ()) {
88 return i->second;
89 }
90 return fDefaultValue_;
91 }
92 virtual void SetAt (INDEXES... indexes, Common::ArgByValueType<T> v) override
93 {
95 if (v == fDefaultValue_) {
96 auto i = fData_.find (tuple<INDEXES...>{indexes...});
97 if (i != fData_.end ()) {
98 fData_.erase (i);
99 }
100 }
101 else {
102// fData_.insert_or_assign (tuple<INDEXES...>{indexes...}, v); // clang++-17 libstdc++ fails on this...
103// fData_.emplace (make_pair(tuple<INDEXES...>{indexes...}, v)); // compiles but wrong semantivcs
104//fData_.insert (make_pair(tuple<INDEXES...>{indexes...}, v));// compiles but wrong semantivcs
105//fData_[tuple<INDEXES...>{indexes...}] = v;// clang++-17 libstdc++ fails on this...
106//fData_[make_tuple (indexes...)] = v;
107#if qCompilerAndStdLib_template_map_tuple_insert_Buggy
108 if (not fData_.insert (make_pair (tuple<INDEXES...>{indexes...}, v)).second) {
109 // then its there and find works...
110 auto i = fData_.find (tuple<INDEXES...>{indexes...});
111 Assert (i != fData_.end ());
112 i->second = v;
113 }
114#else
115 fData_.insert_or_assign (tuple<INDEXES...>{indexes...}, v);
116#endif
117 }
118 fChangeCounts_.PerformedChange ();
119 }
120
121 private:
122 // @todo see why we cannot just use Private::IterorImplHelper version of this!!!
123 template <typename PATCHABLE_CONTAINER, typename PATCHABLE_CONTAINER_ITERATOR = typename PATCHABLE_CONTAINER::ForwardIterator>
124 class MyIteratorImplHelper_
125 : public Iterator<tuple<T, INDEXES...>>::IRep,
126 public Memory::UseBlockAllocationIfAppropriate<MyIteratorImplHelper_<PATCHABLE_CONTAINER, PATCHABLE_CONTAINER_ITERATOR>> {
127 private:
128 using inherited = typename Iterator<tuple<T, INDEXES...>>::IRep;
129
130 // public:
131 // using RepSmartPtr = typename Iterator<tuple<T, INDEXES...>>::RepSmartPtr;
132
133 public:
134 MyIteratorImplHelper_ () = delete;
135 MyIteratorImplHelper_ (const MyIteratorImplHelper_&) = default;
136 explicit MyIteratorImplHelper_ (const PATCHABLE_CONTAINER* data,
137 [[maybe_unused]] const Private::ContainerDebugChangeCounts_* changeCounter = nullptr)
138 : fIterator{data}
139 {
140 RequireNotNull (data);
141 //fIterator.More (nullptr, true); //tmphack cuz current backend iterators require a first more() - fix that!
142 }
143
144 public:
145 virtual ~MyIteratorImplHelper_ () = default;
146
147 // Iterator<tuple<T, INDEXES...>>::IRep
148 public:
149 virtual unique_ptr<inherited> Clone () const override
150 {
151 return make_unique<MyIteratorImplHelper_> (*this);
152 }
153 virtual void More (optional<tuple<T, INDEXES...>>* result, bool advance) override
154 {
155 RequireNotNull (result);
156 if (advance) [[likely]] {
157 Require (not fIterator.Done ()); // new requirement since Stroika 2.1b14
158 ++fIterator;
159 }
160 if (fIterator.Done ()) [[unlikely]] {
161 *result = nullopt;
162 }
163 else {
164 auto tmp = *fIterator;
165 *result = tuple_cat (tuple<T>{tmp.second}, tmp.first);
166 }
167 }
168 virtual bool Equals (const typename Iterator<tuple<T, INDEXES...>>::IRep* rhs) const override
169 {
170 RequireNotNull (rhs);
171 using ActualIterImplType_ = MyIteratorImplHelper_<PATCHABLE_CONTAINER, PATCHABLE_CONTAINER_ITERATOR>;
172 const ActualIterImplType_* rrhs = Debug::UncheckedDynamicCast<const ActualIterImplType_*> (rhs);
173 AssertNotNull (rrhs);
174 return fIterator == rrhs->fIterator;
175 }
176
177 public:
178 mutable PATCHABLE_CONTAINER_ITERATOR fIterator;
179 };
180
181 private:
182 using DataStructureImplType_ = DataStructures::STLContainerWrapper<map<tuple<INDEXES...>, T>>;
183 using IteratorRep_ = MyIteratorImplHelper_<DataStructureImplType_>;
184
185 private:
186 T fDefaultValue_;
187 DataStructureImplType_ fData_;
188 [[no_unique_address]] Private::ContainerDebugChangeCounts_ fChangeCounts_;
189 };
190
191 /*
192 ********************************************************************************
193 ************** SparseDataHyperRectangle_stdmap<T, INDEXES...> ******************
194 ********************************************************************************
195 */
196 template <typename T, typename... INDEXES>
198 : inherited{Memory::MakeSharedPtr<Rep_> (defaultItem)}
199 {
200 AssertRepValidType_ ();
201 }
202 template <typename T, typename... INDEXES>
204 : inherited{static_cast<const inherited&> (src)}
205 {
206 AssertRepValidType_ ();
207 }
208 template <typename T, typename... INDEXES>
209 inline SparseDataHyperRectangle_stdmap<T, INDEXES...>&
210 SparseDataHyperRectangle_stdmap<T, INDEXES...>::operator= (const SparseDataHyperRectangle_stdmap<T, INDEXES...>& rhs)
211 {
212 AssertRepValidType_ ();
213 inherited::operator= (static_cast<const inherited&> (rhs));
214 AssertRepValidType_ ();
215 return *this;
216 }
217 template <typename T, typename... INDEXES>
218 inline void SparseDataHyperRectangle_stdmap<T, INDEXES...>::AssertRepValidType_ () const
219 {
221 typename inherited::template _SafeReadRepAccessor<Rep_> tmp{this}; // for side-effect of AssertMember
222 }
223 }
224
225}
#define AssertNotNull(p)
Definition Assertions.h:333
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
Definition Assertions.h:48
#define RequireNotNull(p)
Definition Assertions.h:347
bool Equals(const T *lhs, const T *rhs)
strcmp or wsccmp() as appropriate == 0
SparseDataHyperRectangle_stdmap<T, INDEXES...> is an Dense Vector-based concrete implementation of th...
SparseDataHyperRectangle_stdmap(Common::ArgByValueType< T > defaultItem={})
STDMAP is std::map<> that can be used inside SparseDataHyperRectangle_stdmap.
nonvirtual void SetAt(INDEXES... indexes, Common::ArgByValueType< T > v)
DataHyperRectangle(const DataHyperRectangle< T, INDEXES... > &src) noexcept
shared_lock< const AssertExternallySynchronizedMutex > ReadContext
Instantiate AssertExternallySynchronizedMutex::ReadContext to designate an area of code where protect...
unique_lock< AssertExternallySynchronizedMutex > WriteContext
Instantiate AssertExternallySynchronizedMutex::WriteContext to designate an area of code where protec...
nonvirtual void Apply(const function< void(ArgByValueType< T > item)> &doToElement, Execution::SequencePolicy seq=Execution::SequencePolicy::eDEFAULT) const
Run the argument function (or lambda) on each element of the container.
nonvirtual Iterator< T > Find(THAT_FUNCTION &&that, Execution::SequencePolicy seq=Execution::SequencePolicy::eDEFAULT) const
Run the argument bool-returning function (or lambda) on each element of the container,...
nonvirtual size_t size() const
Returns the number of items contained.
Definition Iterable.inl:300
Iterable(const Iterable &) noexcept=default
Iterable are safely copyable (by value). Since Iterable uses COW, this just copies the underlying poi...
nonvirtual bool empty() const
Returns true iff size() == 0.
Definition Iterable.inl:306
nonvirtual Iterator< T > MakeIterator() const
Create an iterator object which can be used to traverse the 'Iterable'.
Definition Iterable.inl:294
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
SequencePolicy
equivalent which of 4 types being used std::execution::sequenced_policy, parallel_policy,...