4#include "Stroika/Foundation/Common/Concepts.h"
6#include "Stroika/Foundation/Containers/Private/IteratorImplHelper.h"
17 template <
typename T,
typename KEY_TYPE,
typename TRAITS>
18 template <qCompilerAndStdLib_Constra
intDiffersInTemplateRedeclaration_BWA (KeyedCollection_HashTable_Support::IVal
idHashTableTraits<T, KEY_TYPE>) HASH_TABLE_TRAITS>
19 class KeyedCollection_HashTable<T, KEY_TYPE, TRAITS>::Rep_
20 :
public Private::HashTableBasedContainerRepImpl<KeyedCollection_HashTable<T, KEY_TYPE, TRAITS>::Rep_<HASH_TABLE_TRAITS>, IImplRepBase_>,
21 public Memory::UseBlockAllocationIfAppropriate<Rep_<HASH_TABLE_TRAITS>> {
25 Private::HashTableBasedContainerRepImpl<KeyedCollection_HashTable<T, KEY_TYPE, TRAITS>::Rep_<HASH_TABLE_TRAITS>, IImplRepBase_>;
29 [[no_unique_address]]
const KeyExtractorType fKeyExtractor_;
32 Rep_ (
const KeyExtractorType& keyExtractor, HASHTABLE<HASH_TABLE_TRAITS>&& src)
33 : fKeyExtractor_{keyExtractor}
37 Rep_ (
const Rep_& from) =
default;
40 nonvirtual Rep_& operator= (
const Rep_&) =
delete;
44 virtual shared_ptr<typename Iterable<T>::_IRep> Clone ()
const override
47 return Memory::MakeSharedPtr<Rep_> (*
this);
49 virtual Iterator<value_type> MakeIterator ()
const override
52 return Iterator<value_type>{make_unique<IteratorRep_> (&fData_, &fChangeCounts_)};
54 virtual size_t size ()
const override
57 return fData_.size ();
59 virtual bool empty ()
const override
62 return fData_.empty ();
64 virtual void Apply (
const function<
void (ArgByValueType<value_type> item)>& doToElement,
Execution::SequencePolicy seq)
const override
67 fData_.Apply ([&] (
auto i) { doToElement (i.fKey); }, seq);
69 virtual Iterator<T> Find (
const function<
bool (ArgByValueType<value_type> item)>& that,
Execution::SequencePolicy seq)
const override
72 return this->inherited::Find (that, seq);
74 virtual Iterator<value_type> Find_equal_to (
const ArgByValueType<value_type>& v, [[maybe_unused]]
Execution::SequencePolicy seq)
const override
77 auto found = fData_.find (v);
78 Ensure ((found == fData_.end () and this->inherited::Find_equal_to (v, seq) == Iterator<value_type>{nullptr}) or
79 (found == Debug::UncheckedDynamicCast<const IteratorRep_&> (this->inherited::Find_equal_to (v, seq).ConstGetRep ()).fIterator));
80 return Iterator<value_type>{make_unique<IteratorRep_> (&fData_, &fChangeCounts_, found.GetUnderlyingIteratorRep ())};
85 virtual KeyExtractorType GetKeyExtractor ()
const override
88 return fKeyExtractor_;
90 virtual KeyEqualityComparerType GetKeyEqualityComparer ()
const override
93 return fData_.key_eq ().fKeyComparer;
95 virtual shared_ptr<typename KeyedCollection<T, KEY_TYPE, TRAITS>::_IRep> CloneEmpty ()
const override
99 return Memory::MakeSharedPtr<Rep_> (this->fKeyExtractor_, HASHTABLE<HASH_TABLE_TRAITS>{fData_.hash_function (), fData_.key_eq ()});
101 virtual shared_ptr<typename KeyedCollection<T, KEY_TYPE, TRAITS>::_IRep> CloneAndPatchIterator (Iterator<value_type>* i)
const override
105 auto result = Memory::MakeSharedPtr<Rep_> (*
this);
106 const IteratorRep_& iteratorRep = Debug::UncheckedDynamicCast<const IteratorRep_&> (i->ConstGetRep ());
107 result->fData_.MoveIteratorHereAfterClone (&iteratorRep.fIterator, &fData_);
111 virtual bool Lookup (ArgByValueType<KeyType> key, optional<value_type>* item)
const override
114 static_assert (same_as<value_type, typename DataStructureImplType_::key_type>);
115 auto i = fData_.find (key);
116 if (i == fData_.end ()) {
117 if (item !=
nullptr) {
123 if (item !=
nullptr) {
130 virtual bool Add (ArgByValueType<value_type> item)
override
133 size_t oldSize = this->size ();
135 (void)fData_.Add (item);
136 bool newItemAdded = this->size () != oldSize;
137 fChangeCounts_.PerformedChange ();
140 virtual void Remove (
const Iterator<value_type>& i, Iterator<value_type>* nextI)
override
143 const IteratorRep_& iteratorRep = Debug::UncheckedDynamicCast<const IteratorRep_&> (i.ConstGetRep ());
144 auto nextStdI = fData_.erase (iteratorRep.fIterator.GetUnderlyingIteratorRep ());
145 fChangeCounts_.PerformedChange ();
146 if (nextI !=
nullptr) {
147 *nextI = Iterator<value_type>{make_unique<IteratorRep_> (&fData_, &fChangeCounts_, nextStdI)};
150 virtual bool RemoveIf (ArgByValueType<KEY_TYPE> key)
override
153 auto i = fData_.find (key);
154 if (i != fData_.end ()) {
162 static_assert (same_as<value_type, remove_cvref_t<value_type>>);
163 using DataStructureImplType_ = HASHTABLE<HASH_TABLE_TRAITS>;
164 struct IterTraits_ : Private::IteratorImplHelper_DefaultTraits<value_type, DataStructureImplType_> {
165 static_assert (same_as<typename DataStructureImplType_::value_type, Common::KeyValuePair<value_type, void>>);
166 static constexpr value_type ConvertDataStructureIterationResult2ContainerIteratorResult (
const typename DataStructureImplType_::value_type& t)
171 using IteratorRep_ = Private::IteratorImplHelper_<value_type, DataStructureImplType_, IterTraits_>;
174 DataStructureImplType_ fData_;
175 [[no_unique_address]] Private::ContainerDebugChangeCounts_ fChangeCounts_;
186 template <
typename T,
typename KEY_TYPE,
typename TRAITS>
193 template <
typename T,
typename KEY_TYPE,
typename TRAITS>
194 template <KeyedCollection_HashTable_Support::IVal
idHashTableTraits<T, KEY_TYPE> HASH_TABLE_TRAITS>
195 KeyedCollection_HashTable<T, KEY_TYPE, TRAITS>::KeyedCollection_HashTable (
const KeyExtractorType& keyExtractor, HASHTABLE<HASH_TABLE_TRAITS>&& src)
196 : inherited{Memory::MakeSharedPtr<Rep_<HASH_TABLE_TRAITS>> (keyExtractor, move (src))}
199 template <
typename T,
typename KEY_TYPE,
typename TRAITS>
200 template <KeyedCollection_HashTable_Support::IVal
idHashTableTraits<T, KEY_TYPE> HASH_TABLE_TRAITS>
202#if !qCompilerAndStdLib_template_ConstraintDiffersInTemplateRedeclaration_Buggy
203 requires (IKeyedCollection_ExtractorCanBeDefaulted<T, KEY_TYPE, TRAITS>)
205 : KeyedCollection_HashTable{KeyExtractorType{}, move (src)}
208 template <
typename T,
typename KEY_TYPE,
typename TRAITS>
209 template <Cryptography::Digest::IHashFunction<KEY_TYPE> KEY_HASH, IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER>
211 KEY_EQUALS_COMPARER&& keyComparer)
212 : KeyedCollection_HashTable{keyExtractor, DataStructures::HashTable<T, void, DefaultTraits<KEY_HASH, KEY_EQUALS_COMPARER>>{
213 ElementHash<KEY_HASH>{keyExtractor, keyHasher},
214 ElementEqualsComparer<KEY_EQUALS_COMPARER>{keyExtractor, keyComparer}}}
217 template <
typename T,
typename KEY_TYPE,
typename TRAITS>
218 inline void KeyedCollection_HashTable<T, KEY_TYPE, TRAITS>::AssertRepValidType_ ()
const
221 typename inherited::template _SafeReadRepAccessor<IImplRepBase_> tmp{
this};
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
#define RequireNotNull(p)
KeyedCollection_HashTable<T,KEY_TYPE> is a HashTable based concrete implementation of the KeyedCollec...
KeyedCollection_HashTable()
implement hash table support in a lightweight standard template library style. Use traits to describe...
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...
check argument FUNCTION is callable with a HASHABLE_T, and produces (something convertible to) size_t
SequencePolicy
equivalent which of 4 types being used std::execution::sequenced_policy, parallel_policy,...