MySQL 9.6.0
Source Code Documentation
boundary_set_meta.h
Go to the documentation of this file.
1// Copyright (c) 2024, 2025, Oracle and/or its affiliates.
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License, version 2.0,
5// as published by the Free Software Foundation.
6//
7// This program is designed to work with certain software (including
8// but not limited to OpenSSL) that is licensed under separate terms,
9// as designated in a particular file or component or in included license
10// documentation. The authors of MySQL hereby grant you an additional
11// permission to link the program and your derivative works with the
12// separately licensed software that they have either included with
13// the program or referenced in the documentation.
14//
15// This program is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License, version 2.0, for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with this program; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23
24#ifndef MYSQL_SETS_BOUNDARY_SET_META_H
25#define MYSQL_SETS_BOUNDARY_SET_META_H
26
27/// @file
28/// Experimental API header
29///
30/// This file defines the category tag class and the type traits (concepts)
31/// related to boundary sets.
32///
33/// The main traits are the following:
34///
35/// - Is_boundary_iterator<T>: true if T is a boundary iterator (essentially, an
36/// iterator with an is_endpoint member).
37///
38/// - Is_boundary_set<T>: true if T is a boundary set: essentially
39/// has the members defined by std::view_interface, and in addition the
40/// special upper_bound/lower_bound members, and the iterators satisfy
41/// Is_boundary_iterator.
42///
43/// - Is_boundary_storage<T>: true if T is a boundary storage, i.e. satisfies
44/// the requirements for the backing storage of a boundary container. This
45/// essentially needs insert, delete, update_point, upper_bound, and
46/// lower_bound members.
47///
48/// - Is_boundary_container<T>: true if T is a boundary container: this is a
49/// boundary set with additional members assign, clear, insert, remove,
50/// inplace_union, inplace_subtract, inplace_intersect.
51///
52/// In addition, many of these have variants which require particular Set traits
53/// or element types.
54
55#include <iterator> // forward_iterator
56#include "mysql/meta/is_same_as_all.h" // Is_same_as_all
57#include "mysql/ranges/meta.h" // Is_collection_over
58#include "mysql/sets/boundary_set_category.h" // Boundary_set_category_tag
59#include "mysql/sets/meta.h" // Enable_donate_set
61#include "mysql/sets/set_traits.h" // Has_set_traits
62#include "mysql/sets/upper_lower_bound_interface.h" // Is_upper_lower_bound_implementation
63
64/// @addtogroup GroupLibsMysqlSets
65/// @{
66
67namespace mysql::sets {
68
69// ==== Is_boundary_iterator ====
70
71/// True if Test is a *boundary point iterator*, i.e.:
72///
73/// - Test is a forward iterator (or stronger)
74/// - Test has a member `is_endpoint()` that returns bool
75///
76/// In addition, the following semantic requirements must hold:
77/// - `is_endpoint()` returns true for every second element and false for every
78/// second element. It is allowed to call is_endpoint() even for the end
79/// iterator, and then it must return false.
80/// - values are strictly increasing, i.e., if j == std::next(i), and both *i
81/// and *j are defined, then *j > *i.
82template <class Test>
84 std::forward_iterator<Test> && // this comment helps clang-format
85 requires(const Test iterator) {
86 { iterator.is_endpoint() } -> std::convertible_to<bool>;
87 // Semantic requirements holding for all `iterator` where *iterator and
88 // *std::next(iterator) are defined:
89 //
90 // iterator.is_endpoint() != std::next(iterator).is_endpoint();
91 //
92 // *iterator < *std::next(iterator);
93 };
94
95/// True if Test is a boundary point iterator over values of type Value_t.
96///
97/// @see Is_boundary_iterator.
98template <class Test, class Value_t>
101 std::same_as<mysql::ranges::Iterator_value_type<Test>, Value_t>;
102
103/// True if Test is a boundary point iterator and a bidirectional iterator.
104template <class Test>
106 Is_boundary_iterator<Test> && std::bidirectional_iterator<Test>;
107
108/// True if Test is a boundary point iterator and a random access iterator.
109template <class Test>
111 Is_boundary_iterator<Test> && std::random_access_iterator<Test>;
112
113/// True if Test is a boundary point iterator and a contiguous iterator.
114template <class Test>
116 Is_boundary_iterator<Test> && std::contiguous_iterator<Test>;
117
118} // namespace mysql::sets
119
120// ==== Is_boundary_set ====
121
122namespace mysql::sets::detail {
123
124template <class Test, class Iterator_t, class Const_iterator_t, class Element_t>
127 requires(const Test &ct, Test &t, const Iterator_t &i,
128 const Const_iterator_t &ci, const Element_t &e) {
129 { t.upper_bound(e) } -> std::same_as<Iterator_t>;
130 { t.upper_bound(i, e) } -> std::same_as<Iterator_t>;
131 { t.lower_bound(e) } -> std::same_as<Iterator_t>;
132 { t.lower_bound(i, e) } -> std::same_as<Iterator_t>;
133 { ct.upper_bound(e) } -> std::same_as<Const_iterator_t>;
134 { ct.upper_bound(ci, e) } -> std::same_as<Const_iterator_t>;
135 { ct.lower_bound(e) } -> std::same_as<Const_iterator_t>;
136 { ct.lower_bound(ci, e) } -> std::same_as<Const_iterator_t>;
137 // Semantic requirements which must hold for all t, e, i and i', where i
138 // is a lower bound for e, i.e.,
139 // i==t.begin() || (i==std::next(i') && *i' < e):
140 //
141 // t.upper_bound(e) == t.upper_bound(i, e);
142 // t.upper_bound(e) == t.end() || *t.upper_bound(e) > e;
143 // t.upper_bound(e) == t.begin() ||
144 // *std::advance(t.begin(),
145 // std::distance(t.begin(), t.upper_bound(e)) - 1) <=
146 // *t.upper_bound(e);
147 //
148 // t.lower_bound(e) == t.lower_bound(i, e);
149 // t.lower_bound(e) == t.end() || *t.lower_bound(e) >= e;
150 // t.lower_bound(e) == t.begin() ||
151 // *std::advance(t.begin(),
152 // std::distance(t.begin(), t.lower_bound(e)) - 1) <
153 // *t.lower_bound(e);
154 };
155
156/// True if `Test` is an interval set with `Element_t` as its element type,
157/// assuming that `Iterator_t` is its iterator type and Const_iterator_t its
158/// const iterator type.
159template <class Test, class Iterator_t, class Const_iterator_t, class Element_t>
163 mysql::meta::Is_same_as_all<typename Test::Element_t,
164 typename Test::Set_traits_t::Element_t,
165 Element_t> &&
168 Const_iterator_t, Element_t>;
169// Semantic requirements which must hold for all t and i:
170//
171// t.size() % 2 == 0;
172// t.size() == std::distance(t.begin(), t.end());
173// t.begin().is_endpoint() == false;
174// i == t.end() || std::next(i).is_endpoint() != i.is_endpoint();
175
176} // namespace mysql::sets::detail
177
178namespace mysql::sets {
179
180/// True if `Test` is an *interval set*, i.e., provides a view
181/// over intervals sorted by their endpoints, where each interval is nonempty,
182/// disjoint from other intervals, and even does not share endpoint with
183/// adjacent intervals. It also provides ways to compute upper bounds of values,
184/// i.e., minimal boundary points in the set which are strictly greater than a
185/// given value, respectively greater than or equal to a given value.
186///
187/// This requires, given `Test set`, `Test::iterator iterator`, and
188/// `Test::value_type value`:
189/// - Test satisfies mysql::containers::Is_set.
190/// - Test::iterator satisfies Is_boundary_iterator_over<Test::value_type>.
191/// - set.upper_bound(value), set.lower_bound(value) return Test::iterator.
192/// - set.upper_bound(iterator, value), set.lower_bound(iterator, value)
193/// return Test::iterator.
194///
195/// In addition, the following semantic requirements must hold:
196/// - set.size() is even.
197/// - set.begin()->is_endpoint() == false.
198/// - set.upper_bound(value) returns an iterator to the first point
199/// strictly greater than value, or set.end() if no such point exists.
200/// - set.lower_bound(value) returns an iterator ot the first point
201/// greater than or equal to value, or set.end() if no such point exists.
202/// - If iterator is before or equal to set.upper_bound(value), then
203/// set.upper_bound(iterator, value) == set.upper_bound(value). (Otherwise, the
204/// result is undefined.)
205/// - If iterator is before or equal to set.lower_bound(value), then
206/// set.lower_bound(iterator, value) == set.lower_bound(value). (Otherwise, the
207/// result is undefined.)
208template <class Test>
211 mysql::ranges::Range_const_iterator_type<Test>, typename Test::Element_t>;
212
213/// True if `Test` is an interval set over the given Set traits.
214///
215/// @see Is_boundary_set
216template <class Test, class Set_traits_t>
220
221/// True if `Test` is a reference to a boundary set.
222///
223/// @see Is_boundary_set
224template <class Test>
226 Is_boundary_set<std::remove_reference_t<Test>> && std::is_reference_v<Test>;
227
228/// True if `Test` is a reference to a boundary set.
229///
230/// @see Is_boundary_set_over_traits
231template <class Test, class Set_traits_t>
234 std::is_reference_v<Test>;
235
236// True if std::remove_cvref_t<Test> is a boundary set over the given Set
237// traits.
238template <class Test, class Set_traits_t>
241
242} // namespace mysql::sets
243
244// ==== Is_boundary_storage ====
245
246namespace mysql::sets::detail {
247
248/// True if `Test satisfies `Is_readable_boundary_storage` with `Element_t` as
249/// its element type, assuming that `Iterator_t` and `Const_iterator_t` are its
250/// iterator/const iterator types.
251///
252/// @see Is_readable_boundary_storage
253template <class Test, class Iterator_t, class Const_iterator_t, class Element_t>
256 mysql::meta::Is_same_as_all<typename Test::Set_traits_t::Element_t,
257 typename Test::Element_t, Element_t> &&
261 Is_upper_lower_bound_implementation<Test, Iterator_t, Const_iterator_t,
262 Element_t>;
263
264/// True if `Test satisfies `Is_boundary_storage` with `Element_t` as its
265/// element type, assuming that `Iterator_t` and `Const_iterator_t` are its
266/// iterator/const iterator types.
267///
268/// @see Is_boundary_storage
269template <class Test, class Iterator_t, class Const_iterator_t, class Element_t>
271 Is_readable_boundary_storage_helper<Test, Iterator_t, Const_iterator_t,
272 Element_t> &&
273 requires(Test t, const Test ct, const Iterator_t i1, const Iterator_t i2,
274 const Element_t e1, const Element_t e2) {
275 t.assign(ct);
276 t.clear();
277 { t.update_point(i1, e1) } -> std::same_as<Iterator_t>;
278 { t.insert(i1, e1, e2) } -> std::same_as<Iterator_t>;
279 { t.erase(i1, i2) } -> std::same_as<Iterator_t>;
280 { Test::has_fast_insertion } -> std::convertible_to<bool>;
281 };
282
283} // namespace mysql::sets::detail
284
285namespace mysql::sets {
286
287/// True if `Test` is a *readable boundary storage*, i.e., an object that can
288/// be used as the back-end storage for a boundary container, without the
289/// requirement to have altering operations.
290///
291/// Normally, use Is_boundary_storage instead. This weaker form is usable when
292/// constraining parameters of the altering operations themselves, to prevent
293/// circular dependencies among constraints.
294///
295/// This requires the following:
296/// - `Test` satisfies `Is_collection` and
297/// `Is_upper_lower_bound_implementation`.
298/// - `Test::Set_traits_t` satisfies `Is_bounded_set_traits`
299/// - The iterators for `Test` satisfy `Is_boundary_iterator`.
300/// - The value types for the iterators equal `Test::Element_t` and
301/// `Test::Set_traits_t::Element_t`.
302template <class Test>
307 typename Test::Element_t>;
308
309/// True if Test is a boundary storage over the given Set traits.
310///
311/// @see Is_boundary_storage
312template <class Test, class Set_traits_t>
316
317/// True if `Test` is a *readable boundary storage*, i.e., an object that can
318/// be used as the back-end storage for a boundary container.
319///
320/// This requires the following, where `storage` is an object of type
321/// `Test`:
322/// - `Is_readable_boundary_storage<Test>`.
323/// - `storage.clear()`, `storage.insert(i, v1, v2)`, `storage.erase(i1,
324/// i2)`, and `storage.update_point(i, v1)` are defined.
325/// - Test::has_fast_insertion is a static constexpr bool member variable.
326///
327/// In addition, the following semantic requirements must hold:
328/// - After `storage.clear()`, `storage.empty()` is true.
329/// - `storage.insert(i, v1, v2)` shall insert v1 and v2 just before i, provided
330/// all the following are true:
331/// - v1 < v2
332/// - i==begin() or the element preceding i is strictly less than v1.
333/// - i==end() or *i > v2.
334/// (Otherwise the effect of `storage.insert(i, v1, v2)` is undefined.)
335/// - `storage.erase(i1, i2)` shall remove all elements between i1, inclusive,
336/// and i2, exclusive, provided std::ranges::distance(i1, i2) is even. (If
337/// the distance is odd, `storage.insert(i, v1, v2)` is undefined.)
338/// - has_fast_insertion is true if insertion at a random position has time and
339/// space complexity O(log(N)) (possibly expected, amortized); false
340/// otherwise.
341template <class Test>
344 mysql::ranges::Range_const_iterator_type<Test>, typename Test::Element_t>;
345
346/// True if Test is a boundary storage over the given Set traits.
347///
348/// @see Is_boundary_storage
349template <class Test, class Set_traits_t>
353
354} // namespace mysql::sets
355
356namespace mysql::sets::detail {
357
358/// Helper to define Storage_or_void.
359///
360/// Has type member `Type`, which equals: (1) `Container_t::Storage_t` if such a
361/// member exists; (2) `void` otherwise.
362template <class Container_t>
364 using Type = void;
365};
366template <class Container_t>
367 requires requires { typename Container_t::Storage_t; }
368struct Storage_or_void_helper<Container_t> {
369 using Type = typename Container_t::Storage_t;
370};
371
372} // namespace mysql::sets::detail
373
374namespace mysql::sets {
375
376/// Type alias for Container_t::Storage_t if that exists, or void otherwise.
377template <class Container_t>
379
380} // namespace mysql::sets
381
382// ==== Is_boundary_container ====
383
384namespace mysql::sets::detail {
385
386/// Helper to implement Is_boundary_container and Is_interval_container.
387///
388/// tparam Test class to test
389///
390/// tparam Element_t Element_t type passed to insert and remove members.
391///
392/// tparam Interval_t... Parameter type(s) passed to inplace_union,
393/// inplace_subtract, and inplace_intersect with a single interval argument.
394template <class Test, class Element_t, class... Interval_t>
396 std::is_nothrow_move_assignable_v<Test> &&
397 std::is_nothrow_move_constructible_v<Test> &&
398 requires(Test t, Test other, Element_t value, Interval_t... interval) {
399 t.assign(other);
400 t.clear();
401 t.insert(value);
402 t.remove(value);
403 t.inplace_union(other);
404 t.inplace_union(interval...);
405 t.inplace_subtract(other);
406 t.inplace_subtract(interval...);
407 t.inplace_intersect(other);
408 t.inplace_intersect(interval...);
409 };
410
411} // namespace mysql::sets::detail
412
413namespace mysql::sets {
414
415/// True if `Test` is a Boundary container.
416///
417/// This requires that the container is a boundary set, has nothrow move
418/// constructor/assignment operator, and that it has the following members:
419///
420/// @code
421/// test.assign(source);
422/// test.clear();
423/// test.insert(value);
424/// test.remove(value);
425/// test.inplace_union(source);
426/// test.inplace_union(start, exclusive_end);
427/// test.inplace_union(cursor, start, exclusive_end);
428/// test.inplace_subtract(source);
429/// test.inplace_subtract(start, exclusive_end);
430/// test.inplace_subtract(cursor, start, exclusive_end);
431/// test.inplace_intersect(source);
432/// test.inplace_intersect(start, exclusive_end);
433/// @endcode
434template <class Test>
438 Test, typename Test::Set_traits_t::Element_t,
439 typename Test::Set_traits_t::Element_t,
440 typename Test::Set_traits_t::Element_t> &&
441 requires(Test t, typename Test::Set_traits_t::Element_t start,
442 typename Test::Set_traits_t::Element_t exclusive_end,
444 t.inplace_union(it, start, exclusive_end);
445 t.inplace_subtract(it, start, exclusive_end);
446 };
447
448/// True if `Test` is a reference to a Boundary_container.
449template <class Test>
452 std::is_reference_v<Test>;
453
454// ==== Enable_donate_set[_elements] ====
455
456namespace detail {
457
458/// Helper concept to define the condition when Enable_donate_set_elements shall
459/// be defined for Boundary Storage types.
460template <class Source_t, class Target_t>
463 requires(Source_t source, Target_t target,
467 {
468 target.steal_and_insert(it, e1, e2, source)
469 } noexcept
470 -> std::same_as<mysql::ranges::Range_iterator_type<Target_t>>;
471 };
472
473/// Helper concept to define the condition when Enable_donate_set_elements shall
474/// be defined for Boundary Container types.
475template <class Source_t, class Target_t>
478 Can_donate_set_elements_unqualified<typename Source_t::Storage_t,
479 typename Target_t::Storage_t>;
480
481} // namespace detail
482
483/// Declare that move-semantics is supported for element operations on Boundary
484/// Storage types, whenever full-set-copy is enabled and the function
485/// `steal_and_insert` is defined.
486template <class Source_t, class Target_t>
488 Source_t, Target_t>
489struct Enable_donate_set_elements<Source_t, Target_t> : public std::true_type {
490};
491
492/// Declare that move-semantics is supported for element operations on
493/// compatible Boundary Set container types, whenever the storage supports it,
494/// and full-set-copy is enabled.
495template <class Source_t, class Target_t>
497 Source_t, Target_t>
498struct Enable_donate_set_elements<Source_t, Target_t> : public std::true_type {
499};
500
501} // namespace mysql::sets
502
503// addtogroup GroupLibsMysqlSets
504/// @}
505
506#endif // ifndef MYSQL_SETS_BOUNDARY_SET_META_H
Experimental API header.
True if all the given types are equal (like a vararg version of std::same_as).
Definition: is_same_as_all.h:64
True if Test models Is_collection, with Value_t as its value type.
Definition: meta.h:131
True if move-semantics has been declared as enabled for inplace_union/inplace_intersect/inplace_subtr...
Definition: meta.h:107
True if Test has a member Set_category_t satisfying Is_set_category.
Definition: set_categories.h:55
True if Test has a member Set_traits_t.
Definition: set_traits.h:59
True if Test is a boundary point iterator and a bidirectional iterator.
Definition: boundary_set_meta.h:105
True if Test is a reference to a Boundary_container.
Definition: boundary_set_meta.h:450
True if Test is a Boundary container.
Definition: boundary_set_meta.h:435
True if Test is a boundary point iterator over values of type Value_t.
Definition: boundary_set_meta.h:99
True if Test is a boundary point iterator, i.e.
Definition: boundary_set_meta.h:83
Definition: boundary_set_meta.h:239
True if Test is an interval set over the given Set traits.
Definition: boundary_set_meta.h:217
True if Test is a reference to a boundary set.
Definition: boundary_set_meta.h:232
True if Test is a reference to a boundary set.
Definition: boundary_set_meta.h:225
True if Test is an interval set, i.e., provides a view over intervals sorted by their endpoints,...
Definition: boundary_set_meta.h:209
True if Test is a boundary storage over the given Set traits.
Definition: boundary_set_meta.h:350
True if Test is a readable boundary storage, i.e., an object that can be used as the back-end storage...
Definition: boundary_set_meta.h:342
True if Test is a "bounded" Set traits class.
Definition: set_traits.h:105
True if Test is a boundary point iterator and a contiguous iterator.
Definition: boundary_set_meta.h:115
True if Test is a boundary point iterator and a random access iterator.
Definition: boundary_set_meta.h:110
True if Test is a boundary storage over the given Set traits.
Definition: boundary_set_meta.h:313
True if Test is a readable boundary storage, i.e., an object that can be used as the back-end storage...
Definition: boundary_set_meta.h:303
True if Test is a set.
Definition: set_categories_and_traits.h:62
True if Test satisfies the requirements for being a subclass of Upper_lower_bound_interface.
Definition: upper_lower_bound_interface.h:158
Helper to implement Is_boundary_container and Is_interval_container.
Definition: boundary_set_meta.h:395
True if Test is an interval set with Element_t as its element type, assuming that Iterator_t is its i...
Definition: boundary_set_meta.h:160
True if Test satisfiesIs_boundary_storagewithElement_tas its element type, assuming thatIterator_tand...
Definition: boundary_set_meta.h:270
True if Test satisfiesIs_readable_boundary_storagewithElement_tas its element type,...
Definition: boundary_set_meta.h:254
Helper concept to define the condition when Enable_donate_set_elements shall be defined for Boundary ...
Definition: boundary_set_meta.h:476
Helper concept to define the condition when Enable_donate_set_elements shall be defined for Boundary ...
Definition: boundary_set_meta.h:461
static void start(mysql_harness::PluginFuncEnv *env)
Definition: http_auth_backend_plugin.cc:180
Experimental API header.
Experimental API header.
Experimental API header.
static int interval
Definition: mysqladmin.cc:72
Definition: fts0fts.cc:236
ValueType value(const std::optional< ValueType > &v)
Definition: gtid.h:83
std::remove_cvref_t< decltype(std::declval< const Range_t >().begin())> Range_const_iterator_type
Gives the const_iterator type, deduced from the begin() const member.
Definition: meta.h:47
std::remove_cvref_t< decltype(std::declval< Range_t >().begin())> Range_iterator_type
Gives the iterator type, deduced from the begin() member.
Definition: meta.h:42
Iterator_value_type< Range_iterator_type< Range_t > > Range_value_type
Gives the value type for any collection, deduced from *begin().
Definition: meta.h:67
Definition: aliases.h:97
Definition: gtid_set.h:183
detail::Storage_or_void_helper< Container_t >::Type Storage_or_void
Type alias for Container_t::Storage_t if that exists, or void otherwise.
Definition: boundary_set_meta.h:378
repeated Source source
Definition: replication_asynchronous_connection_failover.proto:42
Experimental API header.
Experimental API header.
Customization point that set container types can use to indicate that they support noexcept move-sema...
Definition: meta.h:101
typename Container_t::Storage_t Type
Definition: boundary_set_meta.h:369
Helper to define Storage_or_void.
Definition: boundary_set_meta.h:363
void Type
Definition: boundary_set_meta.h:364
Experimental API header.