MySQL 9.6.0
Source Code Documentation
view_sources.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_RANGES_VIEW_SOURCES_H
25#define MYSQL_RANGES_VIEW_SOURCES_H
26
27/// @file
28/// Experimental API header
29
30#include <optional> // optional
31#include <ranges> // view
32#include <type_traits> // conditional_t
33#include "mysql/iterators/null_iterator.h" // null_iterator
34
35/// @addtogroup GroupLibsMysqlRanges
36/// @{
37
38namespace mysql::ranges {
39
40/// Type alias to represent the source of a view: resolves to `Type` if
41/// `std::ranges::view<Type>`, or to `Type &` otherwise. This is meant to be
42/// used by member variables of the view class, or the view's iterator class,
43/// that need to reference the source.
44///
45/// This intends to prevent dangling references by enforcing the following rule:
46///
47/// "Views and their iterators shall represent sources that are views
48/// by-value, and sources that are containers by-reference."
49///
50/// For full justification, see readme.md.
51///
52/// Since references are not default-constructible, a view or view iterator that
53/// has a member of this type becomes non-default-constructible when the source
54/// is not a view. If you need default-constructibility, use View_source
55/// instead. The benefit of this class is that it does not require indirection
56/// to access the T object.
57///
58/// Note that types need to be declared explicitly as views, using either
59/// `std::ranges::view_base` or `std::ranges::enable_range`.
60///
61/// @tparam Source_t The source type.
62///
63/// @tparam owns_source_t Determines if the object owns its source. By default,
64/// this is deduced from `std::ranges::view<Source_t>`.
65template <class Source_t, bool owns_source_t = std::ranges::view<Source_t>>
67 std::conditional_t<owns_source_t, Source_t, const Source_t &>;
68
69/// Wrapper around an object that is the source for a view: the wrapped object
70/// is owned by this object if the wrapped object's type satisfies
71/// `std::ranges::view`, and not owned otherwise. This is meant to be used by
72/// member variables of the view class, or the view's iterator class, that need
73/// to reference the source.
74///
75/// This intends to prevent dangling references by enforcing the following rule:
76///
77/// "Views and their iterators shall represent sources that are views
78/// by-value, and sources that are containers by-reference."
79///
80/// For full justification, see readme.md.
81///
82/// Internally, this class stores a source of type `T` using a member variable
83/// of type `T` if `std::ranges::view<T>`, or type `const T *` otherwise. It
84/// provides an API similar to `std::optional`, except this object is not
85/// optional.
86///
87/// This object is default-constructible if `T` is default-constructible
88/// (although the default-constructed object is in a singular state and can't be
89/// used for anything else than as the target of an assignment operation). If
90/// default-constructibility is not important, you may use `Raw_view_source`
91/// instead.
92///
93/// Note that types need to be declared explicitly as views, using either
94/// `std::ranges::view_base` or `std::ranges::enable_range`.
95///
96/// @tparam Source_tp The source type.
97///
98/// @tparam owns_source_tp Determines if the object owns its source. By default,
99/// this is deduced from `std::ranges::view<Source_tp>`.
100template <class Source_tp, bool owns_source_tp = std::ranges::view<Source_tp>>
102 public:
103 using Source_t = Source_tp;
104 /// True if this object owns a copy of its source; false if it holds a
105 /// reference to its source.
106 static constexpr bool owns_source = owns_source_tp;
107
108 /// Source_t if `owns_source`, otherwise `Source_t &`.
110
111 /// Internal representation of the source.
113 std::conditional_t<owns_source, Source_t, const Source_t *>;
114
115 /// Default-construct an object. If the source is not owned, this holds a
116 /// nullptr internally, so then the only things you can do with the object is
117 /// assign to it.
118 View_source() = default;
119
120 /// Construct from a const reference to the source.
122
123 /// Return a copy of the stored object if it is owned; otherwise a reference
124 /// to it. The behavior is undefined for default-constructed objects.
125 [[nodiscard]] const Raw_source_t &get() const { return reference(); }
126
127 /// Return a reference to the stored object. The behavior is undefined
128 /// for default-constructed objects. Note that the reference is
129 /// only valid as long as this object exists.
130 [[nodiscard]] const Source_t &reference() const {
131 if constexpr (owns_source)
132 return m_source;
133 else
134 return *m_source;
135 }
136
137 /// Arrow operator to access members of the source. The behavior is undefined
138 /// for default-constructed objects.
139 ///
140 /// @note To access begin/end iterators from the source when there is a
141 /// source, and objects that behave like end iterators when there is no
142 /// source, use `o.begin()` and `o.end()` instead of `o->begin()` and
143 /// `o->end()`.
144 [[nodiscard]] const Source_t *operator->() const { return &reference(); }
145
146 /// Return begin iterator to the source. The behavior is undefined for
147 /// default-constructed objects.
148 ///
149 /// `x.begin()` is equivalent to `x->begin()`; this function is provided for
150 /// API compatibility with Optional_view_source.
151 [[nodiscard]] auto begin() const { return reference().begin(); }
152
153 /// Return end iterator to the source. The behavior is undefined for
154 /// default-constructed non-owning objects.
155 ///
156 /// `x.end()` is equivalent to `x->end()`; this function is provided for API
157 /// compatibility with Optional_view_source.
158 [[nodiscard]] auto end() const { return reference().end(); }
159
160 private:
161 /// Return an `Source_ref_t` from the given pointer, holding no object if
162 /// the pointer is nullptr, and holding the pointed-to object otherwise.
163 [[nodiscard]] static decltype(auto) from_ref(const Source_t &object) {
164 if constexpr (owns_source) {
165 return object;
166 } else {
167 return &object;
168 }
169 }
170
171 /// The source.
173}; // class View_source
174
175/// `std::optional`-like wrapper around an object that is the source for a view:
176/// this may hold an object or not; and the wrapped object is owned by this
177/// object if the wrapped object's type satisfies `std::ranges::view`, and not
178/// owned otherwise. This is meant to be used by member variables of the view
179/// class, or the view's iterator class, that need to reference the source.
180///
181/// This intends to prevent dangling references by enforcing the following rule:
182///
183/// "Views and their iterators shall represent sources that are views
184/// by-value, and sources that are containers by-reference."
185///
186/// For full justification, see readme.md.
187///
188/// Internally, this class stores a source of type `T` using a member variable
189/// of type `std::optional<T>` if `std::ranges::view<T>`, or type `const T *`
190/// otherwise. It provides an API similar to `std::optional`.
191///
192/// Note that types need to be declared explicitly as views, using either
193/// `std::ranges::view_base` or `std::ranges::enable_range`.
194///
195/// @tparam Source_tp The source type.
196///
197/// @tparam owns_source_tp Determines if the object owns its source. By default,
198/// this is deduced from `std::ranges::view<Source_tp>`.
199template <class Source_tp, bool owns_source_tp = std::ranges::view<Source_tp>>
201 public:
202 using Source_t = Source_tp;
203
204 /// True if this object owns a copy of its source; false if it holds a
205 /// reference to its source.
206 static constexpr bool owns_source = owns_source_tp;
207
208 /// Source_t if `owns_source`, otherwise `Source_t &`.
210
211 /// Internal representation of the source.
213 std::conditional_t<owns_source, std::optional<Source_t>,
214 const Source_t *>;
215
216 /// Construct an objec that does not hold a source.
218
219 /// Construct from a const reference to the source.
221 : m_source(from_ptr(&source)) {}
222
223 /// Construct from a const pointer to the source. The source may be nullptr,
224 /// in which case this object will not hold any sourcd.
227
228 /// Return true if this object holds a source.
229 [[nodiscard]] bool has_object() const { return (bool)m_source; }
230
231 /// Return a copy of the stored object if it is owned; otherwise a reference
232 /// to it. The behavior is undefined if !has_object().
233 [[nodiscard]] const Raw_source_t &get() const { return *m_source; }
234
235 /// Return a reference to the stored object. The behavior is undefined if
236 /// !has_object(). Note that the reference is only valid as long as this
237 /// object exists.
238 [[nodiscard]] const Raw_source_t &reference() const { return *m_source; }
239
240 /// Return a pointer to the source if there is one, or nullptr otherwise. Note
241 /// that the pointer is only valid as long as this object exists.
242 [[nodiscard]] const Source_t *pointer() const {
243 return has_object() ? &reference() : nullptr;
244 }
245
246 /// Arrow operator to access members of the source. The behavior is undefined
247 /// if !has_object().
248 ///
249 /// @note To access begin/end iterators from the source when there is a
250 /// source, and objects that behave like end iterators when there is no
251 /// source, use `o.begin()` and `o.end()` instead of `o->begin()` and
252 /// `o->end()`.
253 [[nodiscard]] const Source_t *operator->() const { return &*m_source; }
254
255 /// Return a valid begin iterator, even if !has_object().
256 ///
257 /// If !has_object(), it is defined that the source is an empty range, so then
258 /// this function returns the end iterator to a default-constructed source.
259 ///
260 /// This requires std::ranges::common_range<Source_t>, i.e., begin() and end()
261 /// must return the same type.
262 [[nodiscard]] auto begin() const
263 requires std::ranges::common_range<Source_t>
264 {
265 if (!has_object()) return null_iterator();
266 return reference().begin();
267 }
268
269 /// Return a valid end iterator, even if !has_object().
270 ///
271 /// If !has_object(), this returns the end iterator to a default-constructed
272 /// source.
273 [[nodiscard]] auto end() const {
274 if (!has_object()) return null_iterator();
275 return reference().end();
276 }
277
278 protected:
279 [[nodiscard]] static auto null_iterator() {
280 return mysql::iterators::null_iterator<Source_t>();
281 }
282
283 private:
284 /// Return an `Optional_source_t` from the given pointer, holding no object if
285 /// the pointer is nullptr, and holding the pointed-to object otherwise.
286 [[nodiscard]] static decltype(auto) from_ptr(const Source_t *object) {
287 if constexpr (owns_source) {
288 if (object == nullptr) return Optional_source_t{};
289 return Optional_source_t(*object);
290 } else {
291 return object;
292 }
293 }
294
295 /// The source.
297}; // class Optional_view_source
298
299/// Factory function to create a View_source wrapping the given object.
300template <class Source_t>
301[[nodiscard]] auto make_view_source(const Source_t &source) {
303}
304
305/// Factory function to create an Optional_view_source wrapping the given
306/// object.
307template <class Source_t>
308[[nodiscard]] auto make_optional_view_source(const Source_t &source) {
310}
311
312/// Factory function to create an Optional_view_source wrapping the pointed-to
313/// object.
314template <class Source_t>
315[[nodiscard]] auto make_optional_view_source(const Source_t *source) {
317}
318
319} // namespace mysql::ranges
320
321// addtogroup GroupLibsMysqlRanges
322/// @}
323
324#endif // ifndef MYSQL_RANGES_VIEW_SOURCES_H
std::optional-like wrapper around an object that is the source for a view: this may hold an object or...
Definition: view_sources.h:200
Source_tp Source_t
Definition: view_sources.h:202
Optional_source_t m_source
The source.
Definition: view_sources.h:296
std::conditional_t< owns_source, std::optional< Source_t >, const Source_t * > Optional_source_t
Internal representation of the source.
Definition: view_sources.h:214
const Raw_source_t & get() const
Return a copy of the stored object if it is owned; otherwise a reference to it.
Definition: view_sources.h:233
auto begin() const
Return a valid begin iterator, even if !has_object().
Definition: view_sources.h:262
static constexpr bool owns_source
True if this object owns a copy of its source; false if it holds a reference to its source.
Definition: view_sources.h:206
Optional_view_source(const Source_t &source)
Construct from a const reference to the source.
Definition: view_sources.h:220
Raw_view_source< Source_t, owns_source > Raw_source_t
Source_t if owns_source, otherwise Source_t &.
Definition: view_sources.h:209
static decltype(auto) from_ptr(const Source_t *object)
Return an Optional_source_t from the given pointer, holding no object if the pointer is nullptr,...
Definition: view_sources.h:286
const Source_t * pointer() const
Return a pointer to the source if there is one, or nullptr otherwise.
Definition: view_sources.h:242
static auto null_iterator()
Definition: view_sources.h:279
auto end() const
Return a valid end iterator, even if !has_object().
Definition: view_sources.h:273
const Source_t * operator->() const
Arrow operator to access members of the source.
Definition: view_sources.h:253
const Raw_source_t & reference() const
Return a reference to the stored object.
Definition: view_sources.h:238
Optional_view_source(const Source_t *source)
Construct from a const pointer to the source.
Definition: view_sources.h:225
bool has_object() const
Return true if this object holds a source.
Definition: view_sources.h:229
Optional_view_source()=default
Construct an objec that does not hold a source.
Wrapper around an object that is the source for a view: the wrapped object is owned by this object if...
Definition: view_sources.h:101
Raw_view_source< Source_t, owns_source > Raw_source_t
Source_t if owns_source, otherwise Source_t &.
Definition: view_sources.h:109
Source_ref_t m_source
The source.
Definition: view_sources.h:172
auto begin() const
Return begin iterator to the source.
Definition: view_sources.h:151
auto end() const
Return end iterator to the source.
Definition: view_sources.h:158
const Source_t & reference() const
Return a reference to the stored object.
Definition: view_sources.h:130
static decltype(auto) from_ref(const Source_t &object)
Return an Source_ref_t from the given pointer, holding no object if the pointer is nullptr,...
Definition: view_sources.h:163
std::conditional_t< owns_source, Source_t, const Source_t * > Source_ref_t
Internal representation of the source.
Definition: view_sources.h:113
static constexpr bool owns_source
True if this object owns a copy of its source; false if it holds a reference to its source.
Definition: view_sources.h:106
View_source(const Source_t &source)
Construct from a const reference to the source.
Definition: view_sources.h:121
Source_tp Source_t
Definition: view_sources.h:103
View_source()=default
Default-construct an object.
const Raw_source_t & get() const
Return a copy of the stored object if it is owned; otherwise a reference to it.
Definition: view_sources.h:125
const Source_t * operator->() const
Arrow operator to access members of the source.
Definition: view_sources.h:144
Definition: buffer_interface.h:40
auto make_optional_view_source(const Source_t &source)
Factory function to create an Optional_view_source wrapping the given object.
Definition: view_sources.h:308
auto make_view_source(const Source_t &source)
Factory function to create a View_source wrapping the given object.
Definition: view_sources.h:301
std::conditional_t< owns_source_t, Source_t, const Source_t & > Raw_view_source
Type alias to represent the source of a view: resolves to Type if std::ranges::view<Type>,...
Definition: view_sources.h:67
Define std::hash<Gtid>.
Definition: gtid.h:355
Experimental API header.
repeated Source source
Definition: replication_asynchronous_connection_failover.proto:42