7#include "Stroika/Foundation/Containers/Private/IteratorImplHelper.h"
18 template <
typename T,
typename... INDEXES>
19 class SparseDataHyperRectangle_stdmap<T, INDEXES...>::Rep_ :
public DataHyperRectangle<T, INDEXES...>::_IRep,
20 public Memory::UseBlockAllocationIfAppropriate<Rep_> {
25 Rep_ (Common::ArgByValueType<T> defaultItem)
26 : fDefaultValue_{defaultItem}
29 Rep_ (
const Rep_& from) =
default;
32 nonvirtual Rep_& operator= (
const Rep_&) =
delete;
36 virtual shared_ptr<
typename Iterable<tuple<T, INDEXES...>>::_IRep> Clone ()
const override
39 return Memory::MakeSharedPtr<Rep_> (*
this);
41 virtual Iterator<tuple<T, INDEXES...>>
MakeIterator ()
const override
44 return Iterator<value_type>{make_unique<IteratorRep_> (&fData_, &fChangeCounts_)};
46 virtual size_t size ()
const override
49 return fData_.size ();
51 virtual bool empty ()
const override
54 return fData_.empty ();
56 virtual void Apply (
const function<
void (ArgByValueType<value_type> item)>& doToElement, [[maybe_unused]]
Execution::SequencePolicy seq)
const override
59 fData_.Apply ([&] (
const pair<tuple<INDEXES...>, T>& item) { doToElement (tuple_cat (tuple<T>{item.second}, item.first)); });
61 virtual Iterator<tuple<T, INDEXES...>>
Find (
const function<
bool (ArgByValueType<value_type> item)>& that,
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 ();
71 unique_ptr<IteratorRep_> resultRep = make_unique<IteratorRep_> (&fData_, &fChangeCounts_);
72 resultRep->fIterator.SetUnderlyingIteratorRep (iLink);
73 return RESULT_TYPE{move (resultRep)};
78 virtual shared_ptr<
typename DataHyperRectangle<T, INDEXES...>::_IRep> CloneEmpty ()
const override
81 return Memory::MakeSharedPtr<Rep_> (fDefaultValue_);
83 virtual T GetAt (INDEXES... indexes)
const override
86 auto i = fData_.find (tuple<INDEXES...>{indexes...});
87 if (i != fData_.end ()) {
90 return fDefaultValue_;
92 virtual void SetAt (INDEXES... indexes, Common::ArgByValueType<T> v)
override
95 if (v == fDefaultValue_) {
96 auto i = fData_.find (tuple<INDEXES...>{indexes...});
97 if (i != fData_.end ()) {
107#if qCompilerAndStdLib_template_map_tuple_insert_Buggy
108 if (not fData_.insert (make_pair (tuple<INDEXES...>{indexes...}, v)).second) {
110 auto i = fData_.find (tuple<INDEXES...>{indexes...});
111 Assert (i != fData_.end ());
115 fData_.insert_or_assign (tuple<INDEXES...>{indexes...}, v);
118 fChangeCounts_.PerformedChange ();
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>> {
128 using inherited =
typename Iterator<tuple<T, INDEXES...>>::IRep;
134 MyIteratorImplHelper_ () =
delete;
135 MyIteratorImplHelper_ (
const MyIteratorImplHelper_&) =
default;
136 explicit MyIteratorImplHelper_ (
const PATCHABLE_CONTAINER* data,
137 [[maybe_unused]]
const Private::ContainerDebugChangeCounts_* changeCounter =
nullptr)
145 virtual ~MyIteratorImplHelper_ () =
default;
149 virtual unique_ptr<inherited> Clone ()
const override
151 return make_unique<MyIteratorImplHelper_> (*
this);
153 virtual void More (optional<tuple<T, INDEXES...>>* result,
bool advance)
override
156 if (advance) [[likely]] {
157 Require (not fIterator.Done ());
160 if (fIterator.Done ()) [[unlikely]] {
164 auto tmp = *fIterator;
165 *result = tuple_cat (tuple<T>{tmp.second}, tmp.first);
168 virtual bool Equals (
const typename Iterator<tuple<T, INDEXES...>>::IRep* rhs)
const override
171 using ActualIterImplType_ = MyIteratorImplHelper_<PATCHABLE_CONTAINER, PATCHABLE_CONTAINER_ITERATOR>;
172 const ActualIterImplType_* rrhs = Debug::UncheckedDynamicCast<const ActualIterImplType_*> (rhs);
174 return fIterator == rrhs->fIterator;
178 mutable PATCHABLE_CONTAINER_ITERATOR fIterator;
182 using DataStructureImplType_ = DataStructures::STLContainerWrapper<map<tuple<INDEXES...>, T>>;
183 using IteratorRep_ = MyIteratorImplHelper_<DataStructureImplType_>;
187 DataStructureImplType_ fData_;
188 [[no_unique_address]] Private::ContainerDebugChangeCounts_ fChangeCounts_;
196 template <
typename T,
typename... INDEXES>
198 :
inherited{Memory::MakeSharedPtr<Rep_> (defaultItem)}
200 AssertRepValidType_ ();
202 template <
typename T,
typename... INDEXES>
204 : inherited{static_cast<const inherited&> (src)}
206 AssertRepValidType_ ();
208 template <
typename T,
typename... INDEXES>
209 inline SparseDataHyperRectangle_stdmap<T, INDEXES...>&
210 SparseDataHyperRectangle_stdmap<T, INDEXES...>::operator= (
const SparseDataHyperRectangle_stdmap<T, INDEXES...>& rhs)
212 AssertRepValidType_ ();
213 inherited::operator= (
static_cast<const inherited&
> (rhs));
214 AssertRepValidType_ ();
217 template <
typename T,
typename... INDEXES>
218 inline void SparseDataHyperRectangle_stdmap<T, INDEXES...>::AssertRepValidType_ ()
const
221 typename inherited::template _SafeReadRepAccessor<Rep_> tmp{
this};
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
#define RequireNotNull(p)
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.
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.
nonvirtual Iterator< T > MakeIterator() const
Create an iterator object which can be used to traverse the 'Iterable'.
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.
SequencePolicy
equivalent which of 4 types being used std::execution::sequenced_policy, parallel_policy,...