Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
SortedAssociation.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4
5// Moved #includes outside #include guard to avoid deadly embrace
6#include "Stroika/Foundation/StroikaPreComp.h"
7
8#include "Stroika/Foundation/Common/Concepts.h"
9#include "Stroika/Foundation/Containers/Association.h"
10
11#ifndef _Stroika_Foundation_Containers_SortedAssociation_h_
12#define _Stroika_Foundation_Containers_SortedAssociation_h_ 1
13
14/**
15 * \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
16 */
17
19
20 using Common::ITotallyOrderingComparer;
21
22 /**
23 * A SortedAssociation is a Association<Key,T> which remains sorted (iterator) by the Key.
24 *
25 * @aliases Dictionary
26 *
27 * \note \em Iterators
28 * Note that iterators always run in sorted order, from least
29 * to largest. Items inserted before the current iterator index will not
30 * be encountered, and items inserted after the current index will be encountered.
31 * Items inserted at the current index remain undefined if they will
32 * be encountered or not.
33 *
34 * @see Association<Key,T>
35 *
36 * \note \em Thread-Safety <a href="Thread-Safety.md#C++-Standard-Thread-Safety">C++-Standard-Thread-Safety</a>
37 *
38 * \note See <a href="./ReadMe.md">ReadMe.md</a> for common features of all Stroika containers (especially
39 * constructors, iterators, etc)
40 *
41 * \em Concrete Implementations:
42 * o @see Concrete::SortedAssociation_stdmultimap<>
43 * o @see Concrete::SortedAssociation_SkipList<>
44 *
45 * \em Factory:
46 * @see SortedAssociation_Factory<> to see default implementations.
47 *
48 * \note <a href="ReadMe.md#Container Element comparisons">Container Element comparisons</a>:
49 * See about ElementInOrderComparerType, ElementThreeWayComparerType and GetElementThreeWayComparer etc
50 *
51 * \note <a href="Design-Overview.md#Comparisons">Comparisons</a>:
52 * o Associations (base class) are already intrinsically equals-comparable.
53 *
54 * o Since SortedAssociation implies an ordering on the elements of the Association, we can use this to define a
55 * compare_three_way ordering for SortedAssociation<>
56 *
57 * o Since this was never supported before (not a regression) - and close to end of C++17 specific development,
58 * only implementing three way compare for C++20 or later.
59 *
60 * o Note we don't need todo a comparison on value, since value uniquely defined by KEY, and we have a total ordering
61 * on the KEYS.
62 */
63 template <typename KEY_TYPE, typename MAPPED_VALUE_TYPE>
64 class [[nodiscard]] SortedAssociation : public Association<KEY_TYPE, MAPPED_VALUE_TYPE> {
65 private:
67
68 protected:
69 class _IRep;
70
71 public:
72 /**
73 * Use this typedef in templates to recover the basic functional container pattern of concrete types.
74 */
76
77 public:
78 /**
79 * \brief generic eStrictInOrder comparer (function) object for KEY_TYPE of the association.
80 *
81 * This CAN be used as the argument to a SortedAssociation<> as ElementInOrderComparerType
82 */
84 Common::ComparisonRelationDeclaration<Common::ComparisonRelationType::eStrictInOrder, function<bool (ArgByValueType<KEY_TYPE>, ArgByValueType<KEY_TYPE>)>>;
85
86 public:
87 /**
88 * \brief generic eThreeWayCompare comparer (function) object for KEY_TYPE of the association.
89 */
91 Common::ComparisonRelationDeclaration<Common::ComparisonRelationType::eThreeWayCompare,
92 function<strong_ordering (ArgByValueType<KEY_TYPE>, ArgByValueType<KEY_TYPE>)>>;
93
94 public:
95 /**
96 * This constructor creates a concrete sorted Association object, either empty,
97 * or initialized with any argument values.
98 *
99 * The underlying data structure of the Association is defined by @see Factory::SortedAssociation_Factory<>
100 *
101 * \par Example Usage
102 * \code
103 * Association<int, int> m{{1, 2}, {2, 4}};
104 * SortedAssociation<int, int> sm{m};
105 * \endcode
106 *
107 * \note <a href="ReadMe.md#Container Constructors">See general information about container constructors that applies here</a>
108 */
110 requires (ITotallyOrderingComparer<less<KEY_TYPE>, KEY_TYPE>);
111 template <ITotallyOrderingComparer<KEY_TYPE> KEY_COMPARER>
112 explicit SortedAssociation (KEY_COMPARER&& inorderComparer);
113 SortedAssociation (SortedAssociation&&) noexcept = default;
114 SortedAssociation (const SortedAssociation&) noexcept = default;
115 SortedAssociation (const initializer_list<KeyValuePair<KEY_TYPE, MAPPED_VALUE_TYPE>>& src)
116 requires (ITotallyOrderingComparer<less<KEY_TYPE>, KEY_TYPE>);
117 template <ITotallyOrderingComparer<KEY_TYPE> KEY_COMPARER>
118 SortedAssociation (KEY_COMPARER&& comparer, const initializer_list<KeyValuePair<KEY_TYPE, MAPPED_VALUE_TYPE>>& src);
119 template <IIterableOfTo<KeyValuePair<KEY_TYPE, MAPPED_VALUE_TYPE>> ITERABLE_OF_ADDABLE>
120 explicit SortedAssociation (ITERABLE_OF_ADDABLE&& src)
121 requires (ITotallyOrderingComparer<less<KEY_TYPE>, KEY_TYPE> and
122 not derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>, SortedAssociation<KEY_TYPE, MAPPED_VALUE_TYPE>>)
123#if qCompilerAndStdLib_RequiresNotMatchInlineOutOfLineForTemplateClassBeingDefined_Buggy
125 {
126 _AssertRepValidType ();
127 this->AddAll (forward<ITERABLE_OF_ADDABLE> (src));
128 _AssertRepValidType ();
129 }
130#endif
131 ;
132 template <ITotallyOrderingComparer<KEY_TYPE> KEY_COMPARER, IIterableOfTo<KeyValuePair<KEY_TYPE, MAPPED_VALUE_TYPE>> ITERABLE_OF_ADDABLE>
133 SortedAssociation (KEY_COMPARER&& comparer, ITERABLE_OF_ADDABLE&& src);
134 template <IInputIterator<KeyValuePair<KEY_TYPE, MAPPED_VALUE_TYPE>> ITERATOR_OF_ADDABLE>
135 SortedAssociation (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE&& end)
136 requires (ITotallyOrderingComparer<less<KEY_TYPE>, KEY_TYPE>);
137 template <ITotallyOrderingComparer<KEY_TYPE> KEY_COMPARER, IInputIterator<KeyValuePair<KEY_TYPE, MAPPED_VALUE_TYPE>> ITERATOR_OF_ADDABLE>
138 SortedAssociation (KEY_COMPARER&& comparer, ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE&& end);
139
140 protected:
141 explicit SortedAssociation (shared_ptr<_IRep>&& src) noexcept;
142 explicit SortedAssociation (const shared_ptr<_IRep>& src) noexcept;
143
144 public:
145 /**
146 */
147 nonvirtual SortedAssociation& operator= (SortedAssociation&&) noexcept = default;
148 nonvirtual SortedAssociation& operator= (const SortedAssociation&) = default;
149
150 public:
151 /**
152 * Return the function used to compare if two elements are in-order (sorted properly)
153 */
154 nonvirtual KeyInOrderComparerType GetKeyInOrderComparer () const;
155
156 public:
157 /**
158 * Return the function used to compare if two elements are in-order (sorted properly)
159 */
160 nonvirtual KeyThreeWayComparerType GetKeyThreeWayComparer () const;
161
162 public:
163 /**
164 * Compare sequentially using the associated GetKeyThreeWayComparer ()
165 */
166 nonvirtual strong_ordering operator<=> (const SortedAssociation& rhs) const;
167
168 public:
169 /**
170 * \brief 'override' Iterable<>::Map () function so RESULT_CONTAINER defaults to SortedAssociation, and improve that case to clone properties from this rep (such is rep type, ordering, etc).
171 */
172 template <typename RESULT_CONTAINER = SortedAssociation<KEY_TYPE, MAPPED_VALUE_TYPE>, invocable<KeyValuePair<KEY_TYPE, MAPPED_VALUE_TYPE>> ELEMENT_MAPPER>
173 nonvirtual RESULT_CONTAINER Map (ELEMENT_MAPPER&& elementMapper) const
174 requires (convertible_to<invoke_result_t<ELEMENT_MAPPER, KeyValuePair<KEY_TYPE, MAPPED_VALUE_TYPE>>, typename RESULT_CONTAINER::value_type> or
175 convertible_to<invoke_result_t<ELEMENT_MAPPER, KeyValuePair<KEY_TYPE, MAPPED_VALUE_TYPE>>, optional<typename RESULT_CONTAINER::value_type>>)
176 ;
177
178 public:
179 /**
180 * \brief subset of this SortedAssociation matching filter-function
181 *
182 * Identical to base class code, but for different RESULT_CONTAINER default.
183 */
184 template <derived_from<Iterable<KeyValuePair<KEY_TYPE, MAPPED_VALUE_TYPE>>> RESULT_CONTAINER = SortedAssociation<KEY_TYPE, MAPPED_VALUE_TYPE>, typename INCLUDE_PREDICATE>
185 nonvirtual RESULT_CONTAINER Where (INCLUDE_PREDICATE&& includeIfTrue) const
186 requires (predicate<INCLUDE_PREDICATE, KEY_TYPE> or predicate<INCLUDE_PREDICATE, KeyValuePair<KEY_TYPE, MAPPED_VALUE_TYPE>>);
187
188 protected:
189 /**
190 */
191 template <typename T2>
192 using _SafeReadRepAccessor = typename inherited::template _SafeReadRepAccessor<T2>;
193
194 protected:
195 /**
196 */
197 template <typename T2>
198 using _SafeReadWriteRepAccessor = typename inherited::template _SafeReadWriteRepAccessor<T2>;
199
200 protected:
201 nonvirtual void _AssertRepValidType () const;
202 };
203
204 /**
205 * \brief Implementation detail for SortedAssociation<T> implementors.
206 *
207 * Protected abstract interface to support concrete implementations of
208 * the SortedAssociation<T> container API.
209 */
210 template <typename KEY_TYPE, typename MAPPED_VALUE_TYPE>
211 class SortedAssociation<KEY_TYPE, MAPPED_VALUE_TYPE>::_IRep : public Association<KEY_TYPE, MAPPED_VALUE_TYPE>::_IRep {
212 private:
213 using inherited = typename Association<KEY_TYPE, MAPPED_VALUE_TYPE>::_IRep;
214
215 public:
216 virtual KeyThreeWayComparerType GetKeyThreeWayComparer () const = 0;
217 };
218
219}
220
221/*
222 ********************************************************************************
223 ******************************* Implementation Details *************************
224 ********************************************************************************
225 */
226#include "SortedAssociation.inl"
227
228#endif /*_Stroika_Foundation_Containers_SortedAssociation_h_ */
Implementation detail for Association<T> implementors.
An Association pairs key values with (possibly multiple or none) mapped_type values....
typename inherited::value_type value_type
Implementation detail for SortedAssociation<T> implementors.
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:237