MySQL 9.6.0
Source Code Documentation
ordered_set_traits_interface.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_ORDERED_SET_TRAITS_INTERFACE_H
25#define MYSQL_SETS_ORDERED_SET_TRAITS_INTERFACE_H
26
27/// @file
28/// Experimental API header
29
30#include <compare> // strong_ordering
31#include "mysql/sets/set_traits.h" // Base_set_traits
32
33/// @addtogroup GroupLibsMysqlSets
34/// @{
35
36namespace mysql::sets::detail {
37
38/// Helper class to define the `Ordered_set_traits_interface::Less_t` member.
39///
40/// This can be used by standard algorithms/classes such as std::set/std::sort
41/// that need a function object to compare elements.
42///
43/// @tparam Element_tp Type of values.
44///
45/// @tparam Impl_tp Set traits implementation class.
46template <class Impl_tp, class Element_tp>
47struct Less {
48 /// Return `Impl_tp::lt(left, right)`.
49 [[nodiscard]] constexpr bool operator()(const Element_tp &left,
50 const Element_tp &right) const {
51 return Impl_tp::lt(left, right);
52 }
53};
54
55} // namespace mysql::sets::detail
56
57namespace mysql::sets {
58
59template <class Test, class Element_t>
61 requires(Element_t e1, Element_t e2) {
62 { Test::lt_impl(e1, e2) } -> std::convertible_to<bool>;
63 } || // this comment helps clang-format
64 requires(Element_t e1, Element_t e2) {
65 { Test::cmp_impl(e1, e2) } -> std::convertible_to<std::strong_ordering>;
66 };
67
68/// Helper CRTP base class to define Ordered Set traits classes, which are
69/// optionally Bounded and/or Metric (cf
70/// Is_bounded_set_traits/Is_metric_set_traits).
71///
72/// The subclass is required to define the static member function `lt`, and this
73/// class provides the static member functions `gt`, `le`, `ge`, and the member
74/// type Less_t, defined in terms of `lt`.
75///
76/// If the user defines `min` and `max_exclusive`, this provides `in_range`,
77/// making the class satisfy Is_bounded_set_traits.
78///
79/// If the template parameter Difference_tp is given, this class also provides
80/// `add` and `sub`, defined in terms of + and -, making the class satisfy
81/// Is_metric_set_traits.
82///
83/// @tparam Self_tp The subclass that defines `lt`.
84///
85/// @tparam Element_tp The element type.
86///
87/// @tparam Difference_tp The difference type. This may be omitted, in which
88/// case this becomes a non-metric Set traits class.
89template <class Self_tp, class Element_tp, class Difference_tp = void>
91 private:
92 using Self_t = Self_tp;
93 using This_t =
95 // We allow Difference_t to be void, and then functions operating on
96 // Difference_t are disabled. However, that doesn't stop the compiler from
97 // emitting an error when the parameter type becomes reference to void. So we
98 // use this type instead, which is Difference_t whenever that is defined and
99 // (the arbitrarily chosen type) int when Difference_t is void.
101 std::conditional_t<std::same_as<Difference_tp, void>, int, Difference_tp>;
102
103 public:
104 using Element_t = Element_tp;
105 using Difference_t = Difference_tp;
107
108 /// @return true if min <= element < max_exclusive.
109 [[nodiscard]] static constexpr bool in_range(const Element_t &element) {
110 return ge(element, Self_t::min()) &&
111 Self_t::lt(element, Self_t::max_exclusive());
112 }
113
114 [[nodiscard]] static constexpr std::strong_ordering cmp(
115 const Element_t &left, const Element_t &right) {
116 if constexpr (requires { Self_t::cmp_impl(left, right); }) {
117 return Self_t::cmp_impl(left, right);
118 } else {
119 if (Self_t::lt(left, right)) return std::strong_ordering::less;
121 return std::strong_ordering::greater;
122 }
123 }
124
125 [[nodiscard]] static constexpr bool lt(const Element_t &left,
126 const Element_t &right) {
127 if constexpr (requires { Self_t::lt_impl(left, right); }) {
128 return Self_t::lt_impl(left, right);
129 } else {
130 return Self_t::cmp_impl(left, right) < 0;
131 }
132 }
133
134 /// @return true if left <= right
135 [[nodiscard]] static constexpr bool le(const Element_t &left,
136 const Element_t &right) {
137 // parameter order intentionally swapped
138 // NOLINTNEXTLINE(readability-suspicious-call-argument)
139 return !This_t::lt(right, left);
140 }
141
142 /// @return true if left > right
143 [[nodiscard]] static constexpr bool gt(const Element_t &left,
144 const Element_t &right) {
145 // parameter order intentionally swapped
146 // NOLINTNEXTLINE(readability-suspicious-call-argument)
147 return This_t::lt(right, left);
148 }
149
150 /// @return true if left >= right
151 [[nodiscard]] static constexpr bool ge(const Element_t &left,
152 const Element_t &right) {
153 return !This_t::lt(left, right);
154 }
155
156 /// @return The difference between two boundaries.
157 [[nodiscard]] static constexpr Difference_t sub(const Element_t &left,
158 const Element_t &right)
159 requires(!std::same_as<Difference_t, void>)
160 {
161 return Difference_t(left - right);
162 }
163
164 /// @return The sum of two boundary differences.
165 ///
166 /// We use nodiscard instead of nodiscard because nodiscard works when the
167 /// return type is void.
168 [[nodiscard]] static constexpr Difference_t add(
170 requires(!std::same_as<Difference_t, void>)
171 {
172 return left + right;
173 }
174
175 /// @return The sum of a boundary and a boundary difference.
176 [[nodiscard]] static constexpr Element_t add(const Element_t &left,
178 requires(!std::same_as<Difference_t, void> &&
179 !std::same_as<Element_t, Difference_t>)
180 {
181 return Element_t(left + right);
182 }
183
184 /// @return The sum of a boundary difference and a boundary.
185 [[nodiscard]] static constexpr Element_t add(const Difference_proxy_t &left,
186 const Element_t &right)
187 requires(!std::same_as<Difference_t, void> &&
188 !std::same_as<Element_t, Difference_t> &&
189 // dummy 'true' constraint, just to make the prototypes different
190 // in case Element_t and Difference_t are the same types.
191 // NOLINTNEXTLINE(readability-simplify-boolean-expr)
192 true)
193 {
194 return Element_t(left + right);
195 }
196}; // struct Ordered_set_traits_interface
197
198} // namespace mysql::sets
199
200// addtogroup GroupLibsMysqlSets
201/// @}
202
203#endif // ifndef MYSQL_SETS_ORDERED_SET_TRAITS_INTERFACE_H
Definition: ordered_set_traits_interface.h:60
static bool equal(const Item *i1, const Item *i2, const Field *f2)
Definition: sql_select.cc:3935
void right(std::string *to_trim)
Definition: trim.h:41
void left(std::string *to_trim)
Definition: trim.h:35
Definition: aliases.h:97
Definition: gtid_set.h:183
Experimental API header.
Base class for all Set_traits classes.
Definition: set_traits.h:46
Helper CRTP base class to define Ordered Set traits classes, which are optionally Bounded and/or Metr...
Definition: ordered_set_traits_interface.h:90
static constexpr bool gt(const Element_t &left, const Element_t &right)
Definition: ordered_set_traits_interface.h:143
static constexpr bool ge(const Element_t &left, const Element_t &right)
Definition: ordered_set_traits_interface.h:151
static constexpr Difference_t add(const Difference_proxy_t &left, const Difference_proxy_t &right)
Definition: ordered_set_traits_interface.h:168
static constexpr Element_t add(const Difference_proxy_t &left, const Element_t &right)
Definition: ordered_set_traits_interface.h:185
Element_tp Element_t
Definition: ordered_set_traits_interface.h:104
static constexpr Difference_t sub(const Element_t &left, const Element_t &right)
Definition: ordered_set_traits_interface.h:157
Difference_tp Difference_t
Definition: ordered_set_traits_interface.h:105
static constexpr Element_t add(const Element_t &left, const Difference_proxy_t &right)
Definition: ordered_set_traits_interface.h:176
static constexpr bool in_range(const Element_t &element)
Definition: ordered_set_traits_interface.h:109
Self_tp Self_t
Definition: ordered_set_traits_interface.h:92
static constexpr bool lt(const Element_t &left, const Element_t &right)
Definition: ordered_set_traits_interface.h:125
std::conditional_t< std::same_as< Difference_tp, void >, int, Difference_tp > Difference_proxy_t
Definition: ordered_set_traits_interface.h:101
static constexpr std::strong_ordering cmp(const Element_t &left, const Element_t &right)
Definition: ordered_set_traits_interface.h:114
static constexpr bool le(const Element_t &left, const Element_t &right)
Definition: ordered_set_traits_interface.h:135
Helper class to define the Ordered_set_traits_interface::Less_t member.
Definition: ordered_set_traits_interface.h:47
constexpr bool operator()(const Element_tp &left, const Element_tp &right) const
Return Impl_tp::lt(left, right).
Definition: ordered_set_traits_interface.h:49