Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
SortedSet.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Containers_SortedSet_h_
5#define _Stroika_Foundation_Containers_SortedSet_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include "Stroika/Foundation/Common/Concepts.h"
10#include "Stroika/Foundation/Containers/Set.h"
11
12/**
13 *
14 * \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
15 *
16 *
17 * TODO:
18 * @todo Support Iterable<>::Where overload?
19 * @todo Could optimize Equals() test for if both sorted, faster way to compare.
20 */
21
23
24 using Common::ITotallyOrderingComparer;
25
26 /**
27 * A SortedSet is a Set<T> which remains sorted (iteration order).
28 *
29 * \note \em Iterators
30 * Note that iterators always run in sorted order, from least
31 * to largest. Items inserted before the current iterator index will not
32 * be encountered, and items inserted after the current index will be encountered.
33 * Items inserted at the current index remain undefined if they will
34 * be encountered or not.
35 *
36 * \note \em Thread-Safety <a href="Thread-Safety.md#C++-Standard-Thread-Safety">C++-Standard-Thread-Safety</a>
37 *
38 * \em Concrete Implementations:
39 * o @see Concrete::SortedSet_SkipList<>
40 * o @see Concrete::SortedSet_stdset<>
41 *
42 * \em Factory:
43 * @see SortedSet_Factory<> to see default implementations.
44 *
45 * \note See <a href="./ReadMe.md">ReadMe.md</a> for common features of all Stroika containers (especially
46 * constructors, iterators, etc)
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 Set (base class) are already intrinsically equals-comparable.
53 *
54 * o Since SortedSet implies an ordering on the elements of the Set, we can use this to define a
55 * compare_three_way ordering for SortedSet<>
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 template <typename T>
61 class [[nodiscard]] SortedSet : public Set<T> {
62 private:
63 using inherited = Set<T>;
64
65 public:
66 /**
67 * Use this typedef in templates to recover the basic functional container pattern of concrete types.
68 */
70
71 protected:
72 class _IRep;
73
74 public:
75 /**
76 */
78 Common::ComparisonRelationDeclaration<Common::ComparisonRelationType::eStrictInOrder, function<bool (ArgByValueType<T>, ArgByValueType<T>)>>;
79
80 public:
81 /**
82 */
84 Common::ComparisonRelationDeclaration<Common::ComparisonRelationType::eThreeWayCompare, function<strong_ordering (ArgByValueType<T>, ArgByValueType<T>)>>;
85
86 public:
87 /**
88 * All constructors either copy their source comparer (copy/move CTOR), or use the default INORDER comparer for 'T'.
89 *
90 * The (element) COMPARER must be provided (if not explicitly, then implicitly via defaults) at construction time. This
91 * is key to differentiating SortedSet from Set construction (where you specify an IEqualsComparer). Here the IEqualsComparer
92 * is implicitly defined by the supposed ITotallyOrderingComparer.
93 *
94 * \pre ITotallyOrderingComparer<COMPARER,T> - for constructors with that type parameter
95 *
96 * \note <a href="ReadMe.md#Container Constructors">See general information about container constructors that applies here</a>
97 */
98 SortedSet ()
99 requires (ITotallyOrderingComparer<less<T>, T>);
100 template <ITotallyOrderingComparer<T> COMPARER>
101 explicit SortedSet (COMPARER&& comparer);
102 SortedSet (SortedSet&& src) noexcept = default;
103 SortedSet (const SortedSet& src) noexcept = default;
104 SortedSet (const initializer_list<T>& src)
105 requires (ITotallyOrderingComparer<less<T>, T>);
106 template <ITotallyOrderingComparer<T> COMPARER>
107 SortedSet (COMPARER&& comparer, const initializer_list<T>& src);
108 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
109 explicit SortedSet (ITERABLE_OF_ADDABLE&& src)
110 requires (ITotallyOrderingComparer<less<T>, T> and not derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>, SortedSet<T>>)
111#if qCompilerAndStdLib_RequiresNotMatchInlineOutOfLineForTemplateClassBeingDefined_Buggy
112 : SortedSet{}
113 {
114 this->AddAll (forward<ITERABLE_OF_ADDABLE> (src));
115 _AssertRepValidType ();
116 }
117#endif
118 ;
119 template <ITotallyOrderingComparer<T> COMPARER, IIterableOfTo<T> ITERABLE_OF_ADDABLE>
120 SortedSet (COMPARER&& comparer, ITERABLE_OF_ADDABLE&& src);
121 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
122 SortedSet (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
123 requires (ITotallyOrderingComparer<less<T>, T>);
124 template <ITotallyOrderingComparer<T> COMPARER, IInputIterator<T> ITERATOR_OF_ADDABLE>
125 SortedSet (COMPARER&& comparer, ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE&& end);
126
127 protected:
128 explicit SortedSet (shared_ptr<_IRep>&& src) noexcept;
129 explicit SortedSet (const shared_ptr<_IRep>& src) noexcept;
130
131 public:
132 /**
133 */
134 nonvirtual SortedSet& operator= (SortedSet&& rhs) noexcept = default;
135 nonvirtual SortedSet& operator= (const SortedSet& rhs) = default;
136
137 public:
138 /**
139 * Return the function used to compare if two elements are in-order (sorted properly)
140 *
141 * \note - this is a function-object wrapper on the underlying comparer, so use will work, but isn't as optimized
142 * as already directly knowing the function object via 'other means'
143 */
144 nonvirtual ElementInOrderComparerType GetElementInOrderComparer () const;
145
146 public:
147 /**
148 * Return the function used to compare if two elements returning strong_ordering (sorted properly)
149 *
150 * \note - this is a function-object wrapper on the underlying comparer, so use will work, but isn't as optimized
151 * as already directly knowing the function object via 'other means'
152 */
153 nonvirtual ElementThreeWayComparerType GetElementThreeWayComparer () const;
154
155 public:
156 /**
157 * Compare sequentially using the associated GetElementThreeWayComparer ()
158 */
159 nonvirtual strong_ordering operator<=> (const SortedSet& rhs) const;
160
161 public:
162 /**
163 * \brief 'override' Iterable<>::Map () function so RESULT_CONTAINER defaults to SortedSet, and improve that case to clone properties from this rep (such is rep type, ordering, etc).
164 */
165 template <typename RESULT_CONTAINER = SortedSet<T>, invocable<T> ELEMENT_MAPPER>
166 nonvirtual RESULT_CONTAINER Map (ELEMENT_MAPPER&& elementMapper) const
167 requires (convertible_to<invoke_result_t<ELEMENT_MAPPER, T>, typename RESULT_CONTAINER::value_type> or
168 convertible_to<invoke_result_t<ELEMENT_MAPPER, T>, optional<typename RESULT_CONTAINER::value_type>>);
169
170 public:
171 /**
172 */
173 template <derived_from<Iterable<T>> RESULT_CONTAINER = SortedSet<T>, predicate<T> INCLUDE_PREDICATE>
174 nonvirtual RESULT_CONTAINER Where (INCLUDE_PREDICATE&& includeIfTrue) const;
175
176 protected:
177 /**
178 */
179 template <typename T2>
180 using _SafeReadRepAccessor = typename inherited::template _SafeReadRepAccessor<T2>;
181
182 protected:
183 /**
184 */
185 template <typename T2>
186 using _SafeReadWriteRepAccessor = typename inherited::template _SafeReadWriteRepAccessor<T2>;
187
188 protected:
189 nonvirtual void _AssertRepValidType () const;
190 };
191
192 /**
193 * \brief Implementation detail for SortedSet<T> implementors.
194 *
195 * Protected abstract interface to support concrete implementations of
196 * the SortedSet<T> container API.
197 *
198 * \note for some scenarios, it might be more efficient to have both a GetElementInOrderComparer and GetElementThreeWayComparer
199 * method, but at the cost of modest code bloat and additional complexity. Callers who really care about this performance
200 * difference can count on other application logic to assure an even better compare function is used to compare usages.
201 * On clang++ on macOS, this was about 50 bytes per class/instantiation. Not much, but for practically zero value added.
202 */
203 template <typename T>
204 class SortedSet<T>::_IRep : public Set<T>::_IRep {
205 public:
207 };
208
209}
210
211/*
212 ********************************************************************************
213 ******************************* Implementation Details *************************
214 ********************************************************************************
215 */
216#include "SortedSet.inl"
217
218#endif /*_Stroika_Foundation_Containers_SortedSet_h_ */
Set<T> is a container of T, where once an item is added, additionally adds () do nothing.
Definition Set.h:105
Implementation detail for SortedSet<T> implementors.
Definition SortedSet.h:204
nonvirtual RESULT_CONTAINER Map(ELEMENT_MAPPER &&elementMapper) const
'override' Iterable<>::Map () function so RESULT_CONTAINER defaults to SortedSet, and improve that ca...
nonvirtual ElementThreeWayComparerType GetElementThreeWayComparer() const