24#ifndef MYSQL_SETS_NESTED_CONTAINER_H
25#define MYSQL_SETS_NESTED_CONTAINER_H
55template <Is_nested_storage Storage_tp>
81 template <
class... Args_t>
84 :
Base_t(std::forward<Args_t>(args)...) {}
154 template <
class... Mapped_args_t>
156 const Key_t &
key, Mapped_args_t &&...mapped_args)
noexcept {
158 [](
Mapped_t &mapped_set, Mapped_args_t &&...mapped_args_fwd) {
159 return mapped_set.insert(
160 std::forward<Mapped_args_t>(mapped_args_fwd)...);
162 storage().emplace(
key), std::forward<Mapped_args_t>(mapped_args)...);
183 if (it != this->
end()) {
184 auto ret = it->second.remove(
value...);
209 template <
class... Mapped_args_t>
211 Mapped_args_t &&...mapped_args)
noexcept {
213 [](
Mapped_t &mapped_set, Mapped_args_t &&...mapped_args_fwd) {
214 return mapped_set.inplace_union(
215 std::forward<Mapped_args_t>(mapped_args_fwd)...);
217 storage().emplace(
key), std::forward<Mapped_args_t>(mapped_args)...);
242 template <
class... Mapped_args_t>
244 Mapped_args_t &&...mapped_args)
noexcept {
246 [](
Mapped_t &mapped_set, Mapped_args_t &&...mapped_args_fwd) {
247 return mapped_set.inplace_union(
248 std::forward<Mapped_args_t>(mapped_args_fwd)...);
251 std::forward<Mapped_args_t>(mapped_args)...);
276 template <Is_nested_set_over_traits_unqualified<Set_traits_t> Other_set_t>
278 if (detail::handle_inplace_op_trivial_cases<Binary_operation::op_union>(
279 *
this, std::forward<Other_set_t>(other_set)))
281 constexpr bool types_allow_donation =
284 bool can_donate =
false;
285 if constexpr (types_allow_donation) {
286 can_donate = (this->
get_allocator() == other_set.get_allocator());
289 auto this_cursor = this->
begin();
290 auto other_it = other_set.begin();
291 while (other_it != other_set.end()) {
292 auto &&[other_key, other_mapped] = *other_it;
293 auto next_other_it = std::next(other_it);
294 auto this_it = this->
find(this_cursor, other_key);
295 if (this_it == this->
end()) {
301 if constexpr (types_allow_donation) {
302 this_cursor =
storage().steal_and_insert(
303 this_cursor, other_set.storage(), other_it);
307 auto ret =
inplace_union(this_cursor, other_key, other_mapped);
312 auto ret = this_it->second.inplace_union(
313 mysql::utils::forward_like<Other_set_t>(*other_it).second);
316 other_it = next_other_it;
328 if (it != this->
end()) {
345 template <
class... Mapped_args_t>
347 Mapped_args_t &&...mapped_args)
noexcept {
348 auto cursor = this->
begin();
350 std::forward<Mapped_args_t>(mapped_args)...);
370 template <
class... Mapped_args_t>
372 Mapped_args_t &&...mapped_args)
noexcept {
376 using Return_t =
decltype(std::declval<Mapped_t>().inplace_subtract(
377 std::declval<Mapped_args_t &&>()...));
378 constexpr bool can_fail = !std::same_as<Return_t, void>;
382 if (it != this->
end()) {
384 return it->second.inplace_subtract(
385 std::forward<Mapped_args_t>(mapped_args)...);
390 if constexpr (can_fail) {
418 template <Is_nested_set_over_traits_unqualified<Set_traits_t> Other_set_t>
422 *
this, std::forward<Other_set_t>(other_set)))
426 auto do_subtract = [
this](
auto &this_it,
auto &other_it) {
427 auto ret = this_it->second.inplace_subtract(
428 mysql::utils::forward_like<Other_set_t>(*other_it).second);
433 auto other_cursor = other_set.begin();
434 auto cursor = this->
begin();
435 while (cursor != this->
end()) {
436 auto other_it = other_set.find(other_cursor, cursor->first);
437 if (other_it != other_set.end()) {
439 auto ret = do_subtract(cursor, other_it);
446 if (other_cursor == other_set.end())
return return_ok;
450 auto it = this->
find(cursor, other_cursor->first);
451 if (it != this->
end()) {
452 auto ret = do_subtract(it, other_cursor);
490 template <
class... Mapped_args_t>
492 const Key_t &
key, Mapped_args_t &&...mapped_args)
noexcept {
496 using Return_t =
decltype(std::declval<Mapped_t>().inplace_intersect(
497 std::declval<Mapped_args_t>()...));
498 constexpr bool can_fail = !std::same_as<Return_t, void>;
503 auto &&mapped =
storage().begin()->second;
505 return mapped.inplace_intersect(
506 std::forward<Mapped_args_t>(mapped_args)...);
508 if (mapped.empty())
storage().clear();
510 if constexpr (can_fail) {
532 template <Is_nested_set_over_traits_unqualified<Set_traits_t> Other_set_t>
536 *
this, std::forward<Other_set_t>(other_set)))
539 auto it = this->
begin();
540 auto other_cursor = other_set.begin();
541 while (it != this->
end()) {
542 auto other_it = other_set.find(other_cursor, it->first);
543 if (other_it == other_set.end()) {
550 auto ret = it->second.inplace_intersect(
551 mysql::utils::forward_like<Other_set_t>(*other_it).second);
580 template <
class... Mapped_args_t>
582 Mapped_args_t &&...mapped_args)
noexcept {
584 auto &it = opt_it.value();
585 auto &mapped_set = it->second;
587 func, mapped_set, std::forward<Mapped_args_t>(mapped_args)...);
588 if (mapped_set.empty()) {
605 if (iterator->second.empty()) {
606 iterator =
storage().erase(iterator);
Polymorphism-free memory resource class with custom allocator and deallocator functions.
Definition: memory_resource.h:88
CRTP base class (mixin) to define a wrapper around a container.
Definition: basic_container_wrapper.h:59
auto begin() noexcept
Definition: basic_container_wrapper.h:164
auto empty() const noexcept
Definition: basic_container_wrapper.h:176
auto end() noexcept
Definition: basic_container_wrapper.h:167
auto & wrapped() &noexcept
Definition: basic_container_wrapper.h:183
auto get_allocator() const noexcept
Return the allocator used by the wrapped object.
Definition: basic_container_wrapper.h:159
CRTP base class/mixin, used to implement Nested Sets that are container wrappers.
Definition: nested_set_interface.h:156
Definition: basic_set_container_wrapper.h:47
Represents the subset of a Cartesian product "L x R" of two sets, using a map data structure that map...
Definition: nested_container.h:58
void inplace_subtract(const Key_t &key) noexcept
Inplace-remove the given key and associated mapped set.
Definition: nested_container.h:326
auto inplace_intersect(Other_set_t &&other_set) noexcept
Inplace-intersect this set with the given set.
Definition: nested_container.h:533
Nested_container< Storage_t > This_t
Definition: nested_container.h:61
auto inplace_union(Iterator_t &cursor, const Key_t &key, Mapped_args_t &&...mapped_args) noexcept
Insert the given set (inplace union), reading and updating the given cursor.
Definition: nested_container.h:243
Iterator_t find(Iterator_t &cursor, const Key_t &key) noexcept
Return iterator to the pair having the given key in the first component, or end() if the key is not i...
Definition: nested_container.h:133
Const_iterator_t find(Const_iterator_t &cursor, const Key_t &key) const noexcept
Return const iterator to the pair having the given key in the first component, or end() if the key is...
Definition: nested_container.h:118
Storage_tp Storage_t
Definition: nested_container.h:60
Const_iterator_t find(const Key_t &key) const noexcept
Return const iterator to the pair having the given key in the first component, or end() if the key is...
Definition: nested_container.h:96
Iterator_t find(const Key_t &key) noexcept
Return iterator to the pair having the given key in the first component, or end() if the key is not i...
Definition: nested_container.h:104
void advance_and_erase_if_empty(Iterator_t &iterator) noexcept
Helper that will erase the value pair that the iterator points to if it is empty, and,...
Definition: nested_container.h:604
auto & storage() noexcept
Return non-const reference to the underlying storage.
Definition: nested_container.h:87
Basic_nested_container_wrapper< Nested_container< Storage_tp >, Storage_tp > Base_t
Definition: nested_container.h:63
const auto & storage() const noexcept
Return const reference to the underlying storage.
Definition: nested_container.h:90
auto inplace_union(const Key_t &key, Mapped_args_t &&...mapped_args) noexcept
Insert the given set (inplace union).
Definition: nested_container.h:210
auto inplace_union(Other_set_t &&other_set) noexcept
Inplace-insert the given set (inplace union) into this container.
Definition: nested_container.h:277
Return_status_t remove(const Key_t &key, const auto &...value) noexcept
Remove the given element from the set, if it is there.
Definition: nested_container.h:181
Nested_container(Args_t &&...args) noexcept
Construct a new, empty Nested_container.
Definition: nested_container.h:83
auto insert_or_union(const auto &func, const auto &opt_it, Mapped_args_t &&...mapped_args) noexcept
Common implementation for insert and several of the inplace_union operations: it performs the inserti...
Definition: nested_container.h:581
auto inplace_subtract(Iterator_t &cursor, const Key_t &key, Mapped_args_t &&...mapped_args) noexcept
Inplace-remove the given mapped set from the mapped set associated with the given key,...
Definition: nested_container.h:371
Return_status_t insert(const Key_t &key, Mapped_args_t &&...mapped_args) noexcept
Insert the given element (inplace union).
Definition: nested_container.h:155
void inplace_intersect(const Key_t &key) noexcept
Inplace-remove all value pairs, except the one for the given key.
Definition: nested_container.h:466
auto inplace_subtract(const Key_t &key, Mapped_args_t &&...mapped_args) noexcept
Inplace-remove the given mapped set from the mapped set associated with the given key.
Definition: nested_container.h:346
auto inplace_intersect(const Key_t &key, Mapped_args_t &&...mapped_args) noexcept
Inplace-remove all value pairs, except the one for the given key, and inplace-intersect the mapped co...
Definition: nested_container.h:491
auto inplace_subtract(Other_set_t &&other_set) noexcept
Inplace-remove the given set from this container.
Definition: nested_container.h:419
static constexpr Return_status_t return_ok
Definition: nested_container.h:76
Set_traits_tp Set_traits_t
Definition: nested_set_interface.h:69
typename Key_traits_t::Element_t Key_t
Definition: nested_set_interface.h:71
Iterator_tp Iterator_t
Definition: nested_set_interface.h:64
typename Iterator_value_t::second_type Mapped_t
Definition: nested_set_interface.h:74
mysql::ranges::Iterator_value_type< Iterator_t > Iterator_value_t
Definition: nested_set_interface.h:67
Const_iterator_tp Const_iterator_t
Definition: nested_set_interface.h:65
True if move-semantics has been declared as enabled for inplace_union/inplace_intersect/inplace_subtr...
Definition: meta.h:114
Class that wraps resources in a polymorphic manner.
ValueType value(const std::optional< ValueType > &v)
Definition: gtid.h:83
bool handle_inplace_op_trivial_cases(Target_t &target, Source_t &&source)
Handle the trivial cases of inplace union/intersection/subtraction where either both operands refer t...
Definition: set_container_helpers.h:45
Definition: gtid_set.h:183
decltype(call_function()) Return_t
Definition: call_and_catch.h:80
Return_status
Simple, strongly-typed enumeration to indicate internal status: ok, error.
Definition: return_status.h:40
Return_t void_to_ok(const Func_t &func, Args_t &&...args)
Helper that calls the given function and returns its result, or returns Return_status::ok if the func...
Definition: return_status.h:113
noexcept
The return type for any call_and_catch(f, args...) call where f(args...) returns Type.
Definition: call_and_catch.h:76
required string key
Definition: replication_asynchronous_connection_failover.proto:60
Tag to identify a class as a Nested set.
Definition: nested_set_category.h:41