MySQL 9.6.0
Source Code Documentation
interval.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_INTERVAL_H
25#define MYSQL_SETS_INTERVAL_H
26
27/// @file
28/// Experimental API header
29
30/// @addtogroup GroupLibsMysqlSets
31/// @{
32
33#include <cassert> // assert
34#include <stdexcept> // domain_error
35#include <utility> // forward
36#include "mysql/meta/not_decayed.h" // Not_decayed
37#include "mysql/sets/set_traits.h" // Is_bounded_set_traits
38#include "mysql/utils/call_and_catch.h" // call_and_catch
39#include "mysql/utils/return_status.h" // Return_status
40
41namespace mysql::sets::detail {
42
43/// Holds the start boundary and endpoint boundary of an interval. The endpoint
44/// is always exclusive.
45///
46/// This base class stores the two values and provides getters, but has all
47/// setter functions protected. The protected setter functions do not check that
48/// values are in order or in range.
49///
50/// @tparam Set_traits_tp Bounded set traits describing properties of the
51/// element type.
52template <Is_bounded_set_traits Set_traits_tp>
54 public:
55 using Set_traits_t = Set_traits_tp;
56 using Element_t = Set_traits_t::Element_t;
57
58 protected:
59 // Default-construct an interval. The resulting interval has a single element,
60 // the smallest value in the Set traits.
61 ///
62 /// This is enabled if Set_traits_t are *discrete* set traits.
63 constexpr Interval_base()
65 : Interval_base(Set_traits_t::min()) {}
66
67 /// Construct an interval with the given inclusive start and exclusive end.
68 constexpr Interval_base(const Element_t &start,
71
72 /// Construct a singleton interval.
73 ///
74 /// This is enabled if Set_traits_t are *discrete* set traits.
75 explicit constexpr Interval_base(Element_t singleton)
77 : Interval_base(singleton, Set_traits_t::next(singleton)) {}
78
79 // Default rule-of-5
80
81 /// Set both boundaries to the given values, without validating the range.
82 ///
83 /// @param start_arg The new value for the start boundary.
84 ///
85 /// @param exclusive_end_arg The new value for the exclusive_end boundary.
86 void assign(const Element_t &start_arg, const Element_t &exclusive_end_arg) {
87 m_values[0] = start_arg;
88 m_values[1] = exclusive_end_arg;
89 }
90
91 /// Set the value for the start boundary, without validating the range.
92 ///
93 /// @param start_arg The new value for the start boundary.
94 void set_start(Element_t start_arg) { m_values[0] = start_arg; }
95
96 /// Set the value for the exclusive_end boundary, without validating the
97 /// range.
98 ///
99 /// @param exclusive_end_arg The new value for the exclusive_end boundary.
100 void set_exclusive_end(Element_t exclusive_end_arg) {
101 m_values[1] = exclusive_end_arg;
102 }
103
104 public:
105 /// Return const reference to the starting point of the interval
106 /// (inclusive).
107 [[nodiscard]] constexpr const Element_t &start() const { return m_values[0]; }
108
109 /// Return const reference to the exclusive endpoint of the interval.
110 [[nodiscard]] constexpr const Element_t &exclusive_end() const {
111 return m_values[1];
112 }
113
114 private:
115 /// The start boundary at index 0, the exclusive end boundary at index 1.
117}; // class Interval_base
118
119/// Return true if both start-point and end-point are equal for the
120/// intervals.
121template <Is_bounded_set_traits Set_traits_tp>
122[[nodiscard]] bool operator==(const Interval_base<Set_traits_tp> &a,
124 return a.start() == b.start() && a.exclusive_end() == b.exclusive_end();
125}
126
127/// Holds the start boundary and endpoint boundary of an interval. The endpoint
128/// is always exclusive. The boundaries do not have to be in range and do not
129/// have to be in order.
130///
131/// This is mainly intended for internal use while handling user input. All data
132/// structures should contain consistent intervals only.
133///
134/// This is implemented by inheriting from Interval_base and making the setters
135/// public.
136///
137/// @tparam Set_traits_tp Bounded set traits describing properties of the
138/// element type.
139template <Is_bounded_set_traits Set_traits_tp>
140class Relaxed_interval : public Interval_base<Set_traits_tp> {
141 private:
144
145 public:
146 /// Enable all the (protected) constructors from the base class.
147 template <class... Args_t>
148 requires mysql::meta::Not_decayed<This_t, Args_t...>
149 explicit Relaxed_interval(Args_t &&...args)
150 : Base_t(std::forward<Args_t>(args)...) {}
151
152 // Use unchecked versions from the base class.
153 using Base_t::assign;
155 using Base_t::set_start;
156};
157
158} // namespace mysql::sets::detail
159
160namespace mysql::sets {
161
162/// Holds the start boundary and endpoint boundary of an interval. The endpoint
163/// is always exclusive. This class maintains that the boundaries are in range
164/// and in order, i.e.:
165///
166/// Set_traits_tp::min() <= start < max_exclusive <=
167/// Set_traits_tp::max_exclusive()
168///
169/// The setter functions come in two flavors: one whose name begins with
170/// `throwing_`, which throws an exception if the boundaries are out-of-range or
171/// out-of-order; one without the prefix that returns a success status. There
172/// are also two factory functions, `throwing_make`, which create an interval
173/// and throws an exception if the boundaries are out-of-range or out-of-order.
174///
175/// @tparam Set_traits_tp Bounded set traits describing properties of the
176/// element type.
177template <Is_bounded_set_traits Set_traits_tp>
178class Interval : public detail::Interval_base<Set_traits_tp> {
179 public:
180 using Set_traits_t = Set_traits_tp;
181 using Element_t = Set_traits_t::Element_t;
183
184 private:
186
187 // NOLINTBEGIN(performance-enum-size): silence clang-tidy's pointless hint
188
189 /// Whether assert_consistent needs to check the start boundary
190 enum class Check_start { no, yes };
191
192 /// Whether assert_consistent needs to check the end boundary
193 enum class Check_end { no, yes };
194
195 // NOLINTEND(performance-enum-size)
196
197 protected:
198 /// Construct an interval with the given values for start and exclusive end.
199 ///
200 /// @throw std::domain_error if the values are out of range or out of order.
201 explicit Interval(const Element_t &start_arg,
202 const Element_t &exclusive_end_arg)
203 : Base_t(start_arg, exclusive_end_arg) {
204 assert_consistent(this->start(), this->exclusive_end());
205 }
206
207 /// Construct a singleton interval.
208 ///
209 /// @throw std::domain_error if the value is out of range.
210 explicit Interval(const Element_t &singleton) : Base_t(singleton) {
211 assert_consistent(this->start(), this->exclusive_end());
212 }
213
214 public:
215 // Default-construct an interval. The resulting interval has a single element,
216 // the smallest value in the Set traits.
218
219 // default rule-of-5
220
221 /// Construct an interval with the given values for start and exclusive end.
222 ///
223 /// @throw std::domain_error if the values are out of range or out of order.
224 static Interval throwing_make(const Element_t &start_arg,
225 const Element_t &exclusive_end_arg) {
226 return Interval(start_arg, exclusive_end_arg);
227 }
228
229 /// Construct a singleton interval.
230 ///
231 /// @throw std::domain_error if the value is out of range.
232 static Interval throwing_make(const Element_t &singleton) {
233 return Interval(singleton);
234 }
235
236 /// Set the start and exclusive end to the given values.
237 ///
238 /// @throw std::domain_error if the values are out of range or out of order.
239 void throwing_assign(const Element_t &start_arg,
240 const Element_t &exclusive_end_arg) {
241 assert_consistent(start_arg, exclusive_end_arg);
242 Base_t::assign(start_arg, exclusive_end_arg);
243 }
244
245 /// Set the start to the given value.
246 ///
247 /// @throw std::domain_error if the value is out of range or out of order.
248 void throwing_set_start(const Element_t &start_arg) {
249 assert_consistent<Check_start::yes, Check_end::no>(start_arg,
250 this->exclusive_end());
251 Base_t::set_start(start_arg);
252 }
253
254 /// Set the exclusive end to the given value.
255 ///
256 /// @throw std::domain_error if the value is out of range or out of order.
257 void throwing_set_exclusive_end(const Element_t &exclusive_end_arg) {
258 assert_consistent<Check_start::no, Check_end::yes>(this->start(),
259 exclusive_end_arg);
260 Base_t::set_exclusive_end(exclusive_end_arg);
261 }
262
263 /// Set the start and exclusive end to the given values.
264 ///
265 /// @return ok on success, error if the values are out of range or out of
266 /// order.
267 [[nodiscard]] Return_status_t assign(const Element_t &start_arg,
268 const Element_t &exclusive_end_arg) {
269 return mysql::utils::call_and_catch(
270 [&] { throwing_assign(start_arg, exclusive_end_arg); });
271 }
272
273 /// Set the start to the given value.
274 ///
275 /// @return ok on success, error if the value is out of range or out of
276 /// order.
277 [[nodiscard]] Return_status_t set_start(const Element_t &start_arg) {
278 return mysql::utils::call_and_catch([&] { throwing_set_start(start_arg); });
279 }
280
281 /// Set the exclusive end to the given value.
282 ///
283 /// @return ok on success, error if the value is out of range or out of
284 /// order.
286 const Element_t &exclusive_end_arg) {
287 return mysql::utils::call_and_catch(
288 [&] { throwing_set_exclusive_end(exclusive_end_arg); });
289 }
290
291 private:
292 /// Check that the given values are in range and in order.
293 ///
294 /// @tparam check_start If yes, check that the start value is in range.
295 ///
296 /// @tparam check_end If yes, check that the end value is in range.
297 ///
298 /// @throw std::domain_error if the values are out of range or out of order.
299 template <Check_start check_start = Check_start::yes,
300 Check_end check_end = Check_end::yes>
301 void assert_consistent(Element_t start_arg, Element_t exclusive_end_arg) {
302 if constexpr (check_start == Check_start::yes) {
303 if (!Set_traits_t::le(Set_traits_t::min(), start_arg)) {
304 throw std::domain_error{"Out-of-range: start < minimum"};
305 }
306 }
307 if (!Set_traits_t::lt(start_arg, exclusive_end_arg)) {
308 throw std::domain_error{"Out-of-order: end <= start"};
309 }
310 if constexpr (check_end == Check_end::yes) {
311 if (!Set_traits_t::le(exclusive_end_arg, Set_traits_t::max_exclusive())) {
312 throw std::domain_error{"Out-of-range: end > maximum"};
313 }
314 }
315 }
316};
317
318} // namespace mysql::sets
319
320// addtogroup GroupLibsMysqlSets
321/// @}
322
323#endif // ifndef MYSQL_SETS_INTERVAL_H
Experimental API header.
Holds the start boundary and endpoint boundary of an interval.
Definition: interval.h:178
Return_status_t set_start(const Element_t &start_arg)
Set the start to the given value.
Definition: interval.h:277
void throwing_set_start(const Element_t &start_arg)
Set the start to the given value.
Definition: interval.h:248
Return_status_t set_exclusive_end(const Element_t &exclusive_end_arg)
Set the exclusive end to the given value.
Definition: interval.h:285
Check_end
Whether assert_consistent needs to check the end boundary.
Definition: interval.h:193
Interval(const Element_t &start_arg, const Element_t &exclusive_end_arg)
Construct an interval with the given values for start and exclusive end.
Definition: interval.h:201
Check_start
Whether assert_consistent needs to check the start boundary.
Definition: interval.h:190
Interval()
Definition: interval.h:217
Return_status_t assign(const Element_t &start_arg, const Element_t &exclusive_end_arg)
Set the start and exclusive end to the given values.
Definition: interval.h:267
void throwing_set_exclusive_end(const Element_t &exclusive_end_arg)
Set the exclusive end to the given value.
Definition: interval.h:257
Interval(const Element_t &singleton)
Construct a singleton interval.
Definition: interval.h:210
void assert_consistent(Element_t start_arg, Element_t exclusive_end_arg)
Check that the given values are in range and in order.
Definition: interval.h:301
void throwing_assign(const Element_t &start_arg, const Element_t &exclusive_end_arg)
Set the start and exclusive end to the given values.
Definition: interval.h:239
static Interval throwing_make(const Element_t &start_arg, const Element_t &exclusive_end_arg)
Construct an interval with the given values for start and exclusive end.
Definition: interval.h:224
static Interval throwing_make(const Element_t &singleton)
Construct a singleton interval.
Definition: interval.h:232
Holds the start boundary and endpoint boundary of an interval.
Definition: interval.h:53
void set_start(Element_t start_arg)
Set the value for the start boundary, without validating the range.
Definition: interval.h:94
constexpr const Element_t & exclusive_end() const
Return const reference to the exclusive endpoint of the interval.
Definition: interval.h:110
Set_traits_tp Set_traits_t
Definition: interval.h:55
void set_exclusive_end(Element_t exclusive_end_arg)
Set the value for the exclusive_end boundary, without validating the range.
Definition: interval.h:100
constexpr Interval_base()
This is enabled if Set_traits_t are discrete set traits.
Definition: interval.h:63
constexpr const Element_t & start() const
Return const reference to the starting point of the interval (inclusive).
Definition: interval.h:107
Element_t m_values[2]
The start boundary at index 0, the exclusive end boundary at index 1.
Definition: interval.h:116
constexpr Interval_base(const Element_t &start, const Element_t &exclusive_end)
Construct an interval with the given inclusive start and exclusive end.
Definition: interval.h:68
Set_traits_t::Element_t Element_t
Definition: interval.h:56
void assign(const Element_t &start_arg, const Element_t &exclusive_end_arg)
Set both boundaries to the given values, without validating the range.
Definition: interval.h:86
constexpr Interval_base(Element_t singleton)
Construct a singleton interval.
Definition: interval.h:75
Holds the start boundary and endpoint boundary of an interval.
Definition: interval.h:140
Relaxed_interval(Args_t &&...args)
Enable all the (protected) constructors from the base class.
Definition: interval.h:149
Relaxed_interval< Set_traits_tp > This_t
Definition: interval.h:143
false if Args is exactly one type, say A, and std::decay_t<A> equals Type.
Definition: not_decayed.h:84
True if Test is a "discrete" Set traits class, i.e., it bounded, and it is possible to compute succes...
Definition: set_traits.h:119
Definition: aliases.h:97
bool operator==(const Interval_base< Set_traits_tp > &a, const Interval_base< Set_traits_tp > &b)
Return true if both start-point and end-point are equal for the intervals.
Definition: interval.h:122
Definition: gtid_set.h:183
Return_status
Simple, strongly-typed enumeration to indicate internal status: ok, error.
Definition: return_status.h:40
Define std::hash<Gtid>.
Definition: gtid.h:355
Experimental API header.
Experimental API header.
Experimental API header.