MySQL 9.6.0
Source Code Documentation
upper_lower_bound_interface.h
Go to the documentation of this file.
1// Copyright (c) 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_UPPER_LOWER_BOUND_INTERFACE_H
25#define MYSQL_SETS_UPPER_LOWER_BOUND_INTERFACE_H
26
27/// @file
28/// Experimental API header
29
30#include <concepts> // derived_from
31#include <iterator> // forward_iterator
32#include "mysql/ranges/meta.h" // Is_iterator_for_range
33#include "mysql/sets/set_traits.h" // Is_ordered_set_traits
34
35/// @addtogroup GroupLibsMysqlSets
36/// @{
37
38namespace mysql::sets::detail {
39
40/// True if Test::lower_bound_impl(test, hint, element) is defined.
41template <class Test, class Iterator_t, class Element_t>
43 requires(Test test, Iterator_t hint, Element_t element) {
44 {
45 Test::lower_bound_impl(test, hint, element)
46 } -> std::same_as<Iterator_t>;
47 };
48
49/// True if Test::lower_bound_impl(test, element) is defined.
50template <class Test, class Iterator_t, class Element_t>
51concept Has_lower_bound_impl_without_hint = // this comment helps clang-format
52 requires(Test test, Element_t element) {
53 { Test::lower_bound_impl(test, element) } -> std::same_as<Iterator_t>;
54 };
55
56/// True if one of the lower bound functions is defined.
57template <class Test, class Iterator_t, class Element_t>
61
62/// True if Test::upper_bound_impl(test, hint, element) is defined.
63template <class Test, class Iterator_t, class Element_t>
65 requires(Test test, Iterator_t hint, Element_t element) {
66 {
67 Test::upper_bound_impl(test, hint, element)
68 } -> std::same_as<Iterator_t>;
69 };
70
71/// True if Test::upper_bound_impl(test, element) is defined.
72template <class Test, class Iterator_t, class Element_t>
73concept Has_upper_bound_impl_without_hint = // this comment helps clang-format
74 requires(Test test, Element_t element) {
75 { Test::upper_bound_impl(test, element) } -> std::same_as<Iterator_t>;
76 };
77
78/// True if one of the upper bound functions is defined.
79template <class Test, class Iterator_t, class Element_t>
83
84} // namespace mysql::sets::detail
85
86namespace mysql::sets {
87
88/// True if Test is a *getter* for Iterator_t, i.e., Test::get(Iterator_t) is
89/// defined.
90///
91/// An iterator getter returns a a value from an iterator. This is useful in
92/// generic code that may need to either extract the value from an iterator over
93/// a sequence container such as std::vector, or extract just the key or just
94/// the mapped value from an iterator over an associative container such as
95/// std::map.
96///
97/// @see Upper_lower_bound_interface
98template <class Test, class Iterator_t>
100 requires(Iterator_t iterator) { Test::get(iterator); };
101
102/// Iterator getter that returns `*iterator`.
104 [[nodiscard]] static decltype(auto) get(
105 const std::input_iterator auto &iterator) {
106 return *iterator;
107 }
108};
109
110/// Iterator getter that returns `iterator->first`.
112 [[nodiscard]] static const auto &get(
113 const std::input_iterator auto &iterator) {
114 return iterator->first;
115 }
116};
117
118/// True if Test satisfies the requirements for being a subclass of
119/// Upper_lower_bound_interface.
120///
121/// It must define the following member functions. In each prototype, the hint
122/// parameter may be omitted.
123///
124/// @code
125/// // Iterator to the first element.
126/// Iterator_t begin() const;
127///
128/// // Iterator to sentinel.
129/// Iterator_t end() const;
130///
131/// // Return an iterator to the smallest element greater than or equal to
132/// // `element` in `self`, with the hint that the correct answer is greater
133/// // than or equal to `*hint`.
134/// static constexpr Iterator_t
135/// lower_bound_impl(Test &self, const Iterator_t &hint,
136/// const Element_t &element);
137///
138/// // See above. This is the const version. (Can usually have a common
139/// // implementation using `auto` for the first parameter.)
140/// static constexpr Const_iterator_t
141/// lower_bound_impl(const Test &self, const Const_iterator_t &hint,
142/// const Element_t &element);
143///
144/// // Return an iterator to the smallest element strictly greater than
145/// // `element` in `self`, with the hint that the correct answer is greater
146/// // than or equal to `*hint`.
147/// static constexpr Iterator_t
148/// upper_bound_impl(Test &self, const Iterator_t &hint,
149/// const Element_t &element);
150///
151/// // See above. This is the const version. (Can usually have a common
152/// // implementation using `auto` for the first parameter.)
153/// static constexpr Const_iterator_t
154/// upper_bound_impl(const Test &self, const Const_iterator_t &hint,
155/// const Element_t &element);
156/// @endcode
157template <class Test, class Iterator_t, class Const_iterator_t, class Element_t>
159 std::forward_iterator<Iterator_t> &&
160 std::forward_iterator<Const_iterator_t> &&
161 requires(Test implementation, const Test const_implementation,
162 Iterator_t iterator, Const_iterator_t const_iterator,
163 Element_t element) {
164 { implementation.begin() } -> std::same_as<Iterator_t>;
165 { implementation.end() } -> std::same_as<Iterator_t>;
166 { const_implementation.begin() } -> std::same_as<Const_iterator_t>;
167 { const_implementation.end() } -> std::same_as<Const_iterator_t>;
168 } &&
173
174/// CRTP base class (mixin) to define a set that has upper_bound and lower_bound
175/// members.
176///
177/// Typically, the implementation defines two member functions: the static
178/// member functions upper_bound_impl and lower_bound_impl taking a hint, and
179/// this class provides all the other 12 functions.
180///
181/// The implementation needs to satisfy Is_upper_lower_bound_implementation.
182/// This class will provide const/non-const upper_bound/lower_bound member
183/// functions that take/don't take iterator hints.
184///
185/// It also provides static member functions
186/// upper_bound_dispatch/lower_bound_dispatch, which take either a const or a
187/// non-const instance in the first argument, and which take/don't take iterator
188/// hints.
189template <class Self_tp, Is_ordered_set_traits Set_traits_tp,
190 std::forward_iterator Iterator_tp,
191 std::forward_iterator Const_iterator_tp,
192 Is_getter_for_iterator<Iterator_tp> Iterator_getter_tp>
194 using Self_t = Self_tp;
195
196 public:
197 using Iterator_t = Iterator_tp;
198 using Const_iterator_t = Const_iterator_tp;
199 using Set_traits_t = Set_traits_tp;
200 using Iterator_getter_t = Iterator_getter_tp;
201
202 using Element_t = typename Set_traits_t::Element_t;
203
204 /// Return the lower bound for @c element, using an iterator @c hint known to
205 /// be less than or equal to the correct result. This is the non-const version
206 /// of the function.
207 ///
208 /// The hint may allow for optimizations. If no hint is known, use the
209 /// hint-less function instead.
210 ///
211 /// @param hint Iterator hint. This must be less than or equal to the correct
212 /// result.
213 ///
214 /// @param element Value to query.
215 ///
216 /// @return Iterator to the first lower bound for @c element, i.e., the first
217 /// element that is greater than or equal to @c element, or to the end if no
218 /// such element exists.
219 [[nodiscard]] constexpr Iterator_t lower_bound(const Iterator_t &hint,
220 const Element_t &element) {
221 return lower_bound_dispatch(self(), hint, element);
222 }
223
224 /// Return the lower bound for @c element, using an iterator @c hint known to
225 /// be less than or equal to the correct result. This is the const version of
226 /// the function.
227 ///
228 /// The hint may allow for optimizations. If no hint is known, use the
229 /// hint-less function instead.
230 ///
231 /// @param hint Iterator hint. This must be less than or equal to the correct
232 /// result.
233 ///
234 /// @param element Value to query.
235 ///
236 /// @return Iterator to the first lower bound for @c element, i.e., the first
237 /// element that is greater than or equal to @c element, or to the end if no
238 /// such element exists.
239 [[nodiscard]] constexpr Const_iterator_t lower_bound(
240 const Const_iterator_t &hint, const Element_t &element) const {
241 return lower_bound_dispatch(self(), hint, element);
242 }
243
244 /// Return the lower bound for @c element. This is the non-const version of
245 /// the function.
246 ///
247 /// @param element Value to query.
248 ///
249 /// @return Iterator to the first lower bound for @c element, i.e., the first
250 /// element that is greater than or equal to @c element, or to the end if no
251 /// such element exists.
252 [[nodiscard]] constexpr Iterator_t lower_bound(const Element_t &element) {
253 return lower_bound_dispatch(self(), element);
254 }
255
256 /// Return the lower bound for @c element. This is the const version of the
257 /// function.
258 ///
259 /// @param element Value to query.
260 ///
261 /// @return Iterator to the first lower bound for @c element, i.e., the first
262 /// element that is greater than or equal to @c element, or to the end if no
263 /// such element exists.
264 [[nodiscard]] constexpr Const_iterator_t lower_bound(
265 const Element_t &element) const {
266 return lower_bound_dispatch(self(), element);
267 }
268
269 /// Return the upper bound for @c element, using an iterator @c hint known to
270 /// be less than or equal to the correct result. This is the non-const version
271 /// of the function.
272 ///
273 /// The hint may allow for optimizations. If no hint is known, use the
274 /// hint-less function instead.
275 ///
276 /// @param hint Iterator hint. This must be less than or equal to the correct
277 /// result.
278 ///
279 /// @param element Value to query.
280 ///
281 /// @return Iterator to the first upper bound for @c element, i.e., the first
282 /// element that is strictly greater than @c element, or to the end if no
283 /// such element exists.
284 [[nodiscard]] constexpr Iterator_t upper_bound(const Iterator_t &hint,
285 const Element_t &element) {
286 return upper_bound_dispatch(self(), hint, element);
287 }
288
289 /// Return the upper bound for @c element, using an iterator @c hint known to
290 /// be less than or equal to the correct result. This is the const version of
291 /// the function.
292 ///
293 /// The hint may allow for optimizations. If no hint is known, use the
294 /// hint-less function instead.
295 ///
296 /// @param hint Iterator hint. This must be less than or equal to the correct
297 /// result.
298 ///
299 /// @param element Value to query.
300 ///
301 /// @return Iterator to the first upper bound for @c element, i.e., the first
302 /// element that is strictly greater than @c element, or to the end if no
303 /// such element exists.
304 [[nodiscard]] constexpr Const_iterator_t upper_bound(
305 const Const_iterator_t &hint, const Element_t &element) const {
306 return upper_bound_dispatch(self(), hint, element);
307 }
308
309 /// Return the upper bound for @c element. This is the non-const version of
310 /// the function.
311 ///
312 /// @param element Value to query.
313 ///
314 /// @return Iterator to the first upper bound for @c element, i.e., the first
315 /// element that is strictly greater than @c element, or to the end if no
316 /// such element exists.
317 [[nodiscard]] constexpr Iterator_t upper_bound(const Element_t &element) {
318 return upper_bound_dispatch(self(), element);
319 }
320
321 /// Return the upper bound for @c element. This is the const version of
322 /// the function.
323 ///
324 /// @param element Value to query.
325 ///
326 /// @return Iterator to the first upper bound for @c element, i.e., the first
327 /// element that is strictly greater than @c element, or to the end if no
328 /// such element exists.
329 [[nodiscard]] constexpr Const_iterator_t upper_bound(
330 const Element_t &element) const {
331 return upper_bound_dispatch(self(), element);
332 }
333
334 /// Implements the lower_bound functions with hint defined above, checking if
335 /// the hint is already the correct answer, and otherwise delegating to the
336 /// implementing class.
337 template <std::derived_from<Self_t> Self_arg_t,
338 mysql::ranges::Is_iterator_for_range<Self_arg_t> Iter_t>
339 [[nodiscard]] static constexpr Iter_t lower_bound_dispatch(
340 Self_arg_t &self_arg, const Iter_t &hint, const Element_t &element) {
341 if (hint == self_arg.end() ||
342 Set_traits_t::ge(Iterator_getter_t::get(hint), element))
343 return hint;
344 if constexpr (detail::Has_lower_bound_impl_with_hint<Self_arg_t, Iter_t,
345 Element_t>) {
346 return Self_arg_t::lower_bound_impl(self_arg, hint, element);
347 } else {
348 return Self_arg_t::lower_bound_impl(self_arg, element);
349 }
350 }
351
352 /// Implements the lower_bound functions without hint defined above.
353 template <std::derived_from<Self_t> Self_arg_t>
354 [[nodiscard]] static constexpr auto lower_bound_dispatch(
355 Self_arg_t &self_arg, const Element_t &element) {
357 Self_arg_t,
359 Element_t>) {
360 return Self_arg_t::lower_bound_impl(self_arg, element);
361 } else {
362 return Self_arg_t::lower_bound_impl(self_arg, self_arg.begin(), element);
363 }
364 }
365
366 /// Implements the upper_bound functions with hint defined above, checking if
367 /// the hint is already the correct answer, and otherwise delegating to the
368 /// implementing class.
369 template <std::derived_from<Self_t> Self_arg_t,
370 mysql::ranges::Is_iterator_for_range<Self_arg_t> Iter_t>
371 [[nodiscard]] static constexpr Iter_t upper_bound_dispatch(
372 Self_arg_t &self_arg, const Iter_t &hint, const Element_t &element) {
373 if (hint == self_arg.end() ||
374 Set_traits_t::gt(Iterator_getter_t::get(hint), element))
375 return hint;
376 if constexpr (detail::Has_upper_bound_impl_with_hint<Self_arg_t, Iter_t,
377 Element_t>) {
378 return Self_arg_t::upper_bound_impl(self_arg, hint, element);
379 } else {
380 return Self_arg_t::upper_bound_impl(self_arg, element);
381 }
382 }
383
384 /// Implements the upper_bound functions without hint defined above.
385 template <std::derived_from<Self_t> Self_arg_t>
386 [[nodiscard]] static constexpr auto upper_bound_dispatch(
387 Self_arg_t &self_arg, const Element_t &element) {
389 Self_arg_t,
391 Element_t>) {
392 return Self_arg_t::upper_bound_impl(self_arg, element);
393 } else {
394 return Self_arg_t::upper_bound_impl(self_arg, self_arg.begin(), element);
395 }
396 }
397
398 private:
399 /// CRTP helper to return a const reference to the subclass on which the
400 /// function is invoked.
401 [[nodiscard]] constexpr const Self_t &self() const {
402 static_assert(
405 return static_cast<const Self_t &>(*this);
406 }
407
408 /// CRTP helper to return a non-const reference to the subclass on which the
409 /// function is invoked.
410 [[nodiscard]] constexpr Self_t &self() {
411 return static_cast<Self_t &>(*this);
412 }
413}; // class Upper_lower_bound_interface
414
415} // namespace mysql::sets
416
417// addtogroup GroupLibsMysqlSets
418/// @}
419
420#endif // ifndef MYSQL_SETS_UPPER_LOWER_BOUND_INTERFACE_H
CRTP base class (mixin) to define a set that has upper_bound and lower_bound members.
Definition: upper_lower_bound_interface.h:193
Iterator_getter_tp Iterator_getter_t
Definition: upper_lower_bound_interface.h:200
constexpr Iterator_t lower_bound(const Iterator_t &hint, const Element_t &element)
Return the lower bound for element, using an iterator hint known to be less than or equal to the corr...
Definition: upper_lower_bound_interface.h:219
constexpr Const_iterator_t lower_bound(const Element_t &element) const
Return the lower bound for element.
Definition: upper_lower_bound_interface.h:264
Const_iterator_tp Const_iterator_t
Definition: upper_lower_bound_interface.h:198
static constexpr auto lower_bound_dispatch(Self_arg_t &self_arg, const Element_t &element)
Implements the lower_bound functions without hint defined above.
Definition: upper_lower_bound_interface.h:354
static constexpr Iter_t upper_bound_dispatch(Self_arg_t &self_arg, const Iter_t &hint, const Element_t &element)
Implements the upper_bound functions with hint defined above, checking if the hint is already the cor...
Definition: upper_lower_bound_interface.h:371
typename Set_traits_t::Element_t Element_t
Definition: upper_lower_bound_interface.h:202
constexpr Iterator_t upper_bound(const Iterator_t &hint, const Element_t &element)
Return the upper bound for element, using an iterator hint known to be less than or equal to the corr...
Definition: upper_lower_bound_interface.h:284
Self_tp Self_t
Definition: upper_lower_bound_interface.h:194
static constexpr auto upper_bound_dispatch(Self_arg_t &self_arg, const Element_t &element)
Implements the upper_bound functions without hint defined above.
Definition: upper_lower_bound_interface.h:386
constexpr Const_iterator_t upper_bound(const Const_iterator_t &hint, const Element_t &element) const
Return the upper bound for element, using an iterator hint known to be less than or equal to the corr...
Definition: upper_lower_bound_interface.h:304
Iterator_tp Iterator_t
Definition: upper_lower_bound_interface.h:197
constexpr Const_iterator_t upper_bound(const Element_t &element) const
Return the upper bound for element.
Definition: upper_lower_bound_interface.h:329
static constexpr Iter_t lower_bound_dispatch(Self_arg_t &self_arg, const Iter_t &hint, const Element_t &element)
Implements the lower_bound functions with hint defined above, checking if the hint is already the cor...
Definition: upper_lower_bound_interface.h:339
constexpr Iterator_t lower_bound(const Element_t &element)
Return the lower bound for element.
Definition: upper_lower_bound_interface.h:252
Set_traits_tp Set_traits_t
Definition: upper_lower_bound_interface.h:199
constexpr Const_iterator_t lower_bound(const Const_iterator_t &hint, const Element_t &element) const
Return the lower bound for element, using an iterator hint known to be less than or equal to the corr...
Definition: upper_lower_bound_interface.h:239
constexpr Iterator_t upper_bound(const Element_t &element)
Return the upper bound for element.
Definition: upper_lower_bound_interface.h:317
True if Test is a getter for Iterator_t, i.e., Test::get(Iterator_t) is defined.
Definition: upper_lower_bound_interface.h:99
True if Test is an "ordered" Set traits class.
Definition: set_traits.h:88
True if Test satisfies the requirements for being a subclass of Upper_lower_bound_interface.
Definition: upper_lower_bound_interface.h:158
True if Test::lower_bound_impl(test, hint, element) is defined.
Definition: upper_lower_bound_interface.h:42
True if Test::lower_bound_impl(test, element) is defined.
Definition: upper_lower_bound_interface.h:51
True if one of the lower bound functions is defined.
Definition: upper_lower_bound_interface.h:58
True if Test::upper_bound_impl(test, hint, element) is defined.
Definition: upper_lower_bound_interface.h:64
True if Test::upper_bound_impl(test, element) is defined.
Definition: upper_lower_bound_interface.h:73
True if one of the upper bound functions is defined.
Definition: upper_lower_bound_interface.h:80
Experimental API header.
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
Definition: aliases.h:97
Definition: gtid_set.h:183
static mysql_service_status_t get(THD **thd) noexcept
Definition: mysql_current_thread_reader_all_empty.cc:31
Experimental API header.
Iterator getter that returns iterator->first.
Definition: upper_lower_bound_interface.h:111
static const auto & get(const std::input_iterator auto &iterator)
Definition: upper_lower_bound_interface.h:112
Iterator getter that returns *iterator.
Definition: upper_lower_bound_interface.h:103
static decltype(auto) get(const std::input_iterator auto &iterator)
Definition: upper_lower_bound_interface.h:104