Iros
 
Loading...
Searching...
No Matches
set_interface.h
Go to the documentation of this file.
1#pragma once
2
10#include "di/math/to_unsigned.h"
11#include "di/meta/core.h"
12#include "di/util/clone.h"
14
15namespace di::container {
16template<typename Self, typename Value, typename Iterator, typename ConstIterator,
17 template<typename> typename ValidForLookup, bool is_multi>
19private:
20 template<typename T>
21 constexpr static bool valid = ValidForLookup<T>::value;
22
23 constexpr auto self() -> Self& { return static_cast<Self&>(*this); }
24 constexpr auto self() const -> Self const& { return static_cast<Self const&>(*this); }
25
26 constexpr auto unconst_iterator(ConstIterator it) -> Iterator { return self().unconst_iterator(util::move(it)); }
27
28 constexpr auto begin() -> Iterator { return self().begin(); }
29 constexpr auto end() -> Iterator { return self().end(); }
30
31 constexpr auto begin() const -> ConstIterator { return self().begin(); }
32 constexpr auto end() const -> ConstIterator { return self().end(); }
33
34 constexpr auto size() const -> size_t { return self().size(); }
35
36 template<concepts::ContainerCompatible<Value> Con, typename... Args>
37 requires(concepts::ConstructibleFrom<Self, Args...>)
39 Args&&... args) {
40 auto result = Self(util::forward<Args>(args)...);
41 result.insert_container(util::forward<Con>(container));
42 return result;
43 }
44
45public:
46 constexpr auto empty() const -> bool { return size() == 0; }
47
48 constexpr void clear() { erase(this->begin(), this->end()); }
49
50 constexpr auto insert(Value const& value)
52 {
53 return self().insert_with_factory(value, [&] {
54 return util::clone(value);
55 });
56 }
57
58 constexpr auto insert(Value&& value) {
59 return self().insert_with_factory(value, [&] {
60 return util::move(value);
61 });
62 }
63
64 template<typename U>
65 requires(valid<U> && concepts::CreatableFrom<Value, U>)
66 constexpr auto insert(U&& value) {
67 return self().insert_with_factory(value, [&] {
68 return util::create<Value>(util::forward<U>(value));
69 });
70 }
71
72 constexpr auto insert(ConstIterator hint, Value const& value)
74 {
75 return self().insert_with_factory(hint, value, [&] {
76 return util::clone(value);
77 });
78 }
79
80 constexpr auto insert(ConstIterator hint, Value&& value) {
81 return self().insert_with_factory(hint, value, [&] {
82 return util::move(value);
83 });
84 }
85
86 template<typename U>
87 requires(valid<U> && concepts::CreatableFrom<Value, U>)
88 constexpr auto insert(ConstIterator hint, U&& value) {
89 return self().insert_with_factory(hint, value, [&] {
90 return util::create<Value>(util::forward<U>(value));
91 });
92 }
93
94 template<typename... Args>
95 requires(concepts::ConstructibleFrom<Value, Args...>)
96 constexpr auto emplace(Args&&... args) {
97 return insert(Value(util::forward<Args>(args)...));
98 }
99
100 template<typename... Args>
101 requires(concepts::ConstructibleFrom<Value, Args...>)
102 constexpr auto emplace_hint(ConstIterator hint, Args&&... args) {
103 return insert(util::move(hint), Value(util::forward<Args>(args)...));
104 }
105
106 template<concepts::ContainerCompatible<Value> Con>
107 constexpr auto insert_container(Con&& container) {
108 if constexpr (concepts::Expected<decltype(insert(*container::begin(container)))>) {
109 auto temp_container = Self {};
110 return container::sequence(util::forward<Con>(container),
111 [&]<typename X>(X&& value) {
112 return temp_container.insert(util::forward<X>(value));
113 }) >>
114 [&] {
115 return invoke_as_fallible([&] {
116 return self().merge_impl(util::move(temp_container));
117 });
118 };
119 } else {
120 auto first = container::begin(container);
121 auto last = container::end(container);
122 for (; first != last; ++first) {
123 insert(*first);
124 }
125 }
126 }
127
128 template<concepts::ContainerCompatible<Value> Con>
129 constexpr void insert_container(ConstIterator hint, Con&& container) {
130 if constexpr (concepts::Expected<decltype(insert(hint, *container::begin(container)))>) {
131 return insert_container(util::forward<Con>(container));
132 } else {
133 auto first = container::begin(container);
134 auto last = container::end(container);
135 for (; first != last; ++first) {
136 hint = insert(hint, *first);
137 }
138 }
139 }
140
141 constexpr auto merge(Self& self) { return self().merge_impl(util::move(self)); }
142 constexpr auto merge(Self&& self) { return self().merge_impl(util::move(self)); }
143
144 constexpr auto erase(Iterator position) { return self().erase_impl(util::move(position)); }
145
146 constexpr auto erase(Iterator first, Iterator last) -> Iterator {
147 while (first != last) {
148 first = self().erase_impl(first);
149 }
150 return last;
151 }
152
153 constexpr auto erase(Value const& needle) -> size_t {
154 if constexpr (!is_multi) {
155 auto it = this->find(needle);
156 if (it == end()) {
157 return 0;
158 }
159 self().erase_impl(util::move(it));
160 return 1;
161 } else {
162 auto [first, last] = this->equal_range(needle);
163 size_t result = 0;
164 for (; first != last; ++result) {
165 first = self().erase_impl(first);
166 }
167 return result;
168 }
169 }
170
171 template<typename U>
172 requires(valid<U>)
173 constexpr auto erase(U&& needle) -> size_t {
174 if constexpr (!is_multi) {
175 auto it = this->find(needle);
176 if (it == end()) {
177 return 0;
178 }
179 self().erase_impl(util::move(it));
180 return 1;
181 } else {
182 auto [first, last] = this->equal_range(needle);
183 size_t result = 0;
184 for (; first != last; ++result) {
185 first = self().erase_impl(first);
186 }
187 return result;
188 }
189 }
190
191 constexpr auto front() -> Optional<Value&> {
192 return lift_bool(!empty()) % [&] {
193 return util::ref(*begin());
194 };
195 }
196 constexpr auto front() const -> Optional<Value const&> {
197 return lift_bool(!empty()) % [&] {
198 return util::cref(*begin());
199 };
200 }
201
202 constexpr auto back() -> Optional<Value&> {
203 return lift_bool(!empty()) % [&] {
204 return util::ref(*container::prev(end()));
205 };
206 }
207 constexpr auto back() const -> Optional<Value const&> {
208 return lift_bool(!empty()) % [&] {
209 return util::cref(*container::prev(end()));
210 };
211 }
212
213 constexpr auto at(Value const& needle) -> Optional<Value&> {
214 auto it = this->find(needle);
215 return lift_bool(it != end()) % [&] {
216 return util::ref(*it);
217 };
218 }
219 constexpr auto at(Value const& needle) const -> Optional<Value const&> {
220 auto it = this->find(needle);
221 return lift_bool(it != end()) % [&] {
222 return util::cref(*it);
223 };
224 }
225
226 template<typename U>
227 requires(valid<U>)
228 constexpr auto at(U&& needle) -> Optional<Value&> {
229 auto it = this->find(needle);
230 return lift_bool(it != end()) % [&] {
231 return util::ref(*it);
232 };
233 }
234 template<typename U>
235 requires(valid<U>)
236 constexpr auto at(U&& needle) const -> Optional<Value const&> {
237 auto it = this->find(needle);
238 return lift_bool(it != end()) % [&] {
239 return util::cref(*it);
240 };
241 }
242
243 constexpr auto find(Value const& needle) -> Iterator { return unconst_iterator(self().find_impl(needle)); }
244 constexpr auto find(Value const& needle) const -> ConstIterator { return self().find_impl(needle); }
245
246 template<typename U>
247 requires(valid<U>)
248 constexpr auto find(U&& needle) -> Iterator {
249 return unconst_iterator(self().find_impl(needle));
250 }
251 template<typename U>
252 requires(valid<U>)
253 constexpr auto find(U&& needle) const -> ConstIterator {
254 return self().find_impl(needle);
255 }
256
257 constexpr auto contains(Value const& needle) const -> bool { return this->find(needle) != end(); }
258 template<typename U>
259 requires(valid<U>)
260 constexpr auto contains(U&& needle) const -> bool {
261 return this->find(needle) != end();
262 }
263
264 constexpr auto count(Value const& needle) const -> size_t {
265 if constexpr (!is_multi) {
266 return this->contains(needle) ? 1 : 0;
267 } else {
269 }
270 }
271
272 template<typename U>
273 requires(valid<U>)
274 constexpr auto count(U&& needle) const -> size_t {
275 if constexpr (!is_multi) {
276 return this->contains(needle) ? 1 : 0;
277 } else {
279 }
280 }
281
282 constexpr auto equal_range(Value const& needle) -> View<Iterator> {
283 if constexpr (!is_multi) {
284 auto it = this->find(needle);
285 return { it, container::next(it, 1, end()) };
286 } else {
287 auto [start, last] = self().equal_range_impl(needle);
288 return { unconst_iterator(util::move(start)), unconst_iterator(util::move(last)) };
289 }
290 }
291 template<typename U>
292 requires(valid<U>)
293 constexpr auto equal_range(U&& needle) -> View<Iterator> {
294 if constexpr (!is_multi) {
295 auto it = this->find(needle);
296 return { it, container::next(it, 1, end()) };
297 } else {
298 return self().equal_range_impl(needle);
299 }
300 }
301
302 constexpr auto equal_range(Value const& needle) const -> View<ConstIterator> {
303 if constexpr (!is_multi) {
304 auto it = this->find(needle);
305 return { it, container::next(it, 1, end()) };
306 } else {
307 return self().equal_range_impl(needle);
308 }
309 }
310 template<typename U>
311 requires(valid<U>)
312 constexpr auto equal_range(U&& needle) const -> View<ConstIterator> {
313 if constexpr (!is_multi) {
314 auto it = this->find(needle);
315 return { it, container::next(it, 1, end()) };
316 } else {
317 return self().equal_range_impl(needle);
318 }
319 }
320
321 constexpr auto lower_bound(Value const& needle) -> Iterator
322 requires(requires {
323 { self().lower_bound_impl(needle) } -> concepts::SameAs<ConstIterator>;
324 })
325 {
326 return unconst_iterator(self().lower_bound_impl(needle));
327 }
328 constexpr auto lower_bound(Value const& needle) const -> ConstIterator
329 requires(requires {
330 { self().lower_bound_impl(needle) } -> concepts::SameAs<ConstIterator>;
331 })
332 {
333 return self().lower_bound_impl(needle);
334 }
335
336 template<typename U>
337 requires(valid<U>)
338 constexpr auto lower_bound(U&& needle) -> Iterator
339 requires(requires {
340 { self().lower_bound_impl(needle) } -> concepts::SameAs<ConstIterator>;
341 })
342 {
343 return unconst_iterator(self().lower_bound_impl(needle));
344 }
345 template<typename U>
346 requires(valid<U>)
347 constexpr auto lower_bound(U&& needle) const -> ConstIterator
348 requires(requires {
349 { self().lower_bound_impl(needle) } -> concepts::SameAs<ConstIterator>;
350 })
351 {
352 return self().lower_bound_impl(needle);
353 }
354
355 constexpr auto upper_bound(Value const& needle) -> Iterator
356 requires(requires {
357 { self().upper_bound_impl(needle) } -> concepts::SameAs<ConstIterator>;
358 })
359 {
360 return unconst_iterator(self().upper_bound_impl(needle));
361 }
362 constexpr auto upper_bound(Value const& needle) const -> ConstIterator
363 requires(requires {
364 { self().upper_bound_impl(needle) } -> concepts::SameAs<ConstIterator>;
365 })
366 {
367 return self().upper_bound_impl(needle);
368 }
369
370 template<typename U>
371 requires(valid<U>)
372 constexpr auto upper_bound(U&& needle) -> Iterator
373 requires(requires {
374 { self().upper_bound_impl(needle) } -> concepts::SameAs<ConstIterator>;
375 })
376 {
377 return unconst_iterator(self().upper_bound_impl(needle));
378 }
379 template<typename U>
380 requires(valid<U>)
381 constexpr auto upper_bound(U&& needle) const -> ConstIterator
382 requires(requires {
383 { self().upper_bound_impl(needle) } -> concepts::SameAs<ConstIterator>;
384 })
385 {
386 return self().upper_bound_impl(needle);
387 }
388
389 constexpr void intersect(Self const& b)
390 requires(!is_multi)
391 {
392 auto it = begin();
393 auto last = end();
394 while (it != last) {
395 auto save = it++;
396 if (!b.contains(*save)) {
397 erase(save);
398 }
399 }
400 }
401
402 constexpr void subtract(Self const& b)
403 requires(!is_multi)
404 {
405 auto it = begin();
406 auto last = end();
407 while (it != last) {
408 auto save = it++;
409 if (b.contains(*save)) {
410 erase(save);
411 }
412 }
413 }
414
415private:
416 // Set union.
417 constexpr friend auto operator|(Self&& a, Self&& b) {
418 return invoke_as_fallible([&] {
419 return a.merge(util::move(b));
420 }) |
421 [&] {
422 return util::move(a);
423 } |
425 }
426
427 constexpr friend auto operator|=(Self& a, Self&& b) -> decltype(auto) {
428 return invoke_as_fallible([&] {
429 return a.merge(util::move(b));
430 }) |
431 [&] {
432 return util::ref(a);
433 } |
435 }
436
437 // Set intersection.
438 constexpr friend auto operator&(Self&& a, Self const& b)
439 requires(!is_multi)
440 {
441 a.intersect(b);
442 return util::move(a);
443 }
444
445 constexpr friend auto operator&=(Self& a, Self const& b) -> Self& requires(!is_multi) {
446 a.intersect(b);
447 return a;
448 }
449
450 // Set differerce.
451 constexpr friend auto operator-(Self&& a, Self const& b)
452 requires(!is_multi)
453 {
454 a.subtract(b);
455 return util::move(a);
456 }
457
458 constexpr friend auto operator-=(Self& a, Self const& b) -> Self& requires(!is_multi) {
459 a.subtract(b);
460 return a;
461 }
462
463 template<typename F, SameAs<Tag<erase_if>> T = Tag<erase_if>>
465 constexpr friend auto tag_invoke(T, Self& self, F&& function) -> usize {
466 auto it = self.begin();
467 auto result = 0ZU;
468 while (it != self.end()) {
469 if (function(*it)) {
470 it = self.erase(it);
471 ++result;
472 } else {
473 ++it;
474 }
475 }
476 return result;
477 }
478};
479}
Definition set_interface.h:18
constexpr auto merge(Self &self)
Definition set_interface.h:141
constexpr auto back() const -> Optional< Value const & >
Definition set_interface.h:207
constexpr auto at(U &&needle) const -> Optional< Value const & >
Definition set_interface.h:236
constexpr auto insert(Value const &value)
Definition set_interface.h:50
constexpr auto insert(ConstIterator hint, Value &&value)
Definition set_interface.h:80
constexpr auto merge(Self &&self)
Definition set_interface.h:142
constexpr auto lower_bound(Value const &needle) -> Iterator requires(
Definition set_interface.h:321
constexpr auto at(Value const &needle) const -> Optional< Value const & >
Definition set_interface.h:219
constexpr friend auto operator-=(Self &a, Self const &b) -> Self &requires(!is_multi)
Definition set_interface.h:458
constexpr friend auto operator-(Self &&a, Self const &b)
Definition set_interface.h:451
constexpr auto lower_bound(U &&needle) -> Iterator requires(
Definition set_interface.h:338
constexpr auto upper_bound(Value const &needle) const -> ConstIterator requires(
Definition set_interface.h:362
constexpr auto back() -> Optional< Value & >
Definition set_interface.h:202
constexpr friend auto operator&(Self &&a, Self const &b)
Definition set_interface.h:438
constexpr auto insert(U &&value)
Definition set_interface.h:66
constexpr auto equal_range(U &&needle) const -> View< ConstIterator >
Definition set_interface.h:312
constexpr auto find(U &&needle) -> Iterator
Definition set_interface.h:248
constexpr auto erase(U &&needle) -> size_t
Definition set_interface.h:173
constexpr auto find(U &&needle) const -> ConstIterator
Definition set_interface.h:253
constexpr auto erase(Iterator first, Iterator last) -> Iterator
Definition set_interface.h:146
constexpr friend auto operator&=(Self &a, Self const &b) -> Self &requires(!is_multi)
Definition set_interface.h:445
constexpr auto insert(ConstIterator hint, Value const &value)
Definition set_interface.h:72
constexpr auto emplace_hint(ConstIterator hint, Args &&... args)
Definition set_interface.h:102
constexpr auto find(Value const &needle) const -> ConstIterator
Definition set_interface.h:244
constexpr void subtract(Self const &b)
Definition set_interface.h:402
constexpr void intersect(Self const &b)
Definition set_interface.h:389
constexpr auto emplace(Args &&... args)
Definition set_interface.h:96
constexpr auto at(Value const &needle) -> Optional< Value & >
Definition set_interface.h:213
constexpr auto erase(Iterator position)
Definition set_interface.h:144
constexpr auto upper_bound(U &&needle) -> Iterator requires(
Definition set_interface.h:372
constexpr auto at(U &&needle) -> Optional< Value & >
Definition set_interface.h:228
constexpr auto front() -> Optional< Value & >
Definition set_interface.h:191
constexpr void insert_container(ConstIterator hint, Con &&container)
Definition set_interface.h:129
constexpr auto count(U &&needle) const -> size_t
Definition set_interface.h:274
constexpr auto front() const -> Optional< Value const & >
Definition set_interface.h:196
constexpr auto insert(Value &&value)
Definition set_interface.h:58
constexpr auto count(Value const &needle) const -> size_t
Definition set_interface.h:264
constexpr auto equal_range(U &&needle) -> View< Iterator >
Definition set_interface.h:293
constexpr friend auto tag_invoke(types::Tag< util::create_in_place >, InPlaceType< Self >, Con &&container, Args &&... args)
Definition set_interface.h:38
constexpr auto erase(Value const &needle) -> size_t
Definition set_interface.h:153
constexpr friend auto tag_invoke(T, Self &self, F &&function) -> usize
Definition set_interface.h:465
constexpr auto find(Value const &needle) -> Iterator
Definition set_interface.h:243
constexpr auto upper_bound(Value const &needle) -> Iterator requires(
Definition set_interface.h:355
constexpr auto upper_bound(U &&needle) const -> ConstIterator requires(
Definition set_interface.h:381
constexpr auto lower_bound(U &&needle) const -> ConstIterator requires(
Definition set_interface.h:347
constexpr auto lower_bound(Value const &needle) const -> ConstIterator requires(
Definition set_interface.h:328
constexpr void clear()
Definition set_interface.h:48
constexpr auto insert(ConstIterator hint, U &&value)
Definition set_interface.h:88
constexpr auto equal_range(Value const &needle) -> View< Iterator >
Definition set_interface.h:282
constexpr auto empty() const -> bool
Definition set_interface.h:46
constexpr friend auto operator|(Self &&a, Self &&b)
Definition set_interface.h:417
constexpr auto equal_range(Value const &needle) const -> View< ConstIterator >
Definition set_interface.h:302
constexpr auto contains(Value const &needle) const -> bool
Definition set_interface.h:257
constexpr auto insert_container(Con &&container)
Definition set_interface.h:107
constexpr friend auto operator|=(Self &a, Self &&b) -> decltype(auto)
Definition set_interface.h:427
constexpr auto contains(U &&needle) const -> bool
Definition set_interface.h:260
Definition view.h:35
Definition optional_forward_declaration.h:5
Definition clone.h:44
Definition operations.h:11
Definition create.h:10
Definition vocab.h:30
Definition relation.h:7
Definition core.h:114
Definition sequence.h:12
constexpr auto prev
Definition prev.h:28
constexpr auto next
Definition next.h:35
constexpr auto find
Definition find.h:35
constexpr auto sequence
Definition sequence.h:34
constexpr auto distance
Definition distance.h:44
constexpr auto erase
Definition erase.h:76
constexpr auto equal_range
Definition equal_range.h:39
constexpr auto end
Definition end.h:47
constexpr auto begin
Definition begin.h:44
constexpr auto contains
Definition contains.h:24
Definition as_bool.h:8
constexpr auto to_unsigned
Definition to_unsigned.h:16
Conditional< concepts::ConstantIterator< Iter >, Iter, container::ConstIteratorImpl< Iter > > ConstIterator
Definition const_iterator.h:8
size_t usize
Definition integers.h:33
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
constexpr auto ref
Definition reference_wrapper.h:98
constexpr auto cref
Definition reference_wrapper.h:99
constexpr auto clone
Definition clone.h:39
constexpr auto create(Args &&... args)
Definition create.h:21
constexpr auto invoke_as_fallible
Definition invoke_as_fallible.h:37
constexpr auto try_infallible
Definition try_infallible.h:31
constexpr auto lift_bool
Definition lift_bool.h:13
@ Self
Definition local_apic.h:126
Definition in_place_type.h:5