MySQL 9.6.0
Source Code Documentation
collection_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_RANGES_COLLECTION_INTERFACE_H
25#define MYSQL_RANGES_COLLECTION_INTERFACE_H
26/// @file
27/// Experimental API header
28
29/// @addtogroup GroupLibsMysqlRanges
30/// @{
31
32#include <iterator> // contiguous_iterator
33#include "mysql/ranges/meta.h" // Range_iterator_type
34
35namespace mysql::ranges {
36
37/// CRTP base class to provide members of a *collection* based on an
38/// implementation that provides begin/end iterators.
39///
40/// The implementation must implement either `begin()` and `end()`, or `begin()
41/// const` and `end() const` (or all four). It may also override `size() const`
42/// and `empty() const`, if that is faster than the default implementations,
43/// `std::ranges::distance(begin(), end())` and `begin()==end()`.
44///
45/// The collection provides the following functionality:
46///
47/// @code
48/// begin(); // from the implementation
49/// begin() const; // from the implementation
50/// end(); // from the implementation
51/// end() const; // from the implementation
52/// cbegin() const; // begin() const
53/// cend() const; // end() const
54///
55/// front() const; // *begin()
56/// size() const; // (size_t)std::ranges::distance(begin(), end())
57/// ssize() const; // (ptrdiff_t)size()
58/// empty() const; // begin() == end()
59/// operator!() const; // empty()
60/// operator bool() const; // !empty()
61///
62/// // If the iterators are bidirectional:
63/// rbegin(); // make_reverse_iterator(end())
64/// rbegin() const; // make_reverse_iterator(end())
65/// rend(); // make_reverse_iterator(begin())
66/// rend() const; // make_reverse_iterator(begin())
67/// rcbegin() const; // make_reverse_iterator(end())
68/// rcend() const; // make_reverse_iterator(begin())
69/// back() const; // *std::ranges::prev(end())
70///
71/// // If the iterators are random_access:
72/// operator[](size_t n); // begin()[n]
73/// operator[](size_t n) const; // begin()[n]
74///
75/// // If the iterators are contiguous:
76/// data(); // &*begin()
77/// data() const; // &*begin()
78/// @endcode
79///
80/// This is similar to the C++20 feature `std::ranges::view_interface`. However,
81/// not all compilers we build on as of 2025 had implemented view_interface even
82/// in C++20 mode. Also, `cbegin` and `cend` are C++23 features, and
83/// rbegin/rend/rcbegin/rcend/ssize are non-standard.
84///
85/// Despite the similarity with `std::ranges::view_interface`, we avoid word
86/// "view" because C++ defines that to be objects for which copy and move is
87/// cheap (https://en.cppreference.com/w/cpp/ranges/view), whereas this class is
88/// usable for anything that provides iterators, cheap-copyable or not.
89template <class Self_tp>
91 using Self_t = Self_tp;
92 template <class Range_t>
94
95 public:
96 /// Return constant iterator to the beginning.
97 [[nodiscard]] constexpr auto cbegin() const { return self().begin(); }
98
99 /// Return constant iterator to the end.
100 [[nodiscard]] constexpr auto cend() const { return self().end(); }
101
102 /// Return reverse iterator to the beginning.
103 [[nodiscard]] constexpr auto rbegin() {
104 return std::make_reverse_iterator(self().end());
105 }
106
107 /// Return reverse iterator to the end.
108 [[nodiscard]] constexpr auto rend() {
109 return std::make_reverse_iterator(self().begin());
110 }
111
112 /// Return const reverse iterator to the beginning.
113 [[nodiscard]] constexpr auto rbegin() const {
114 return std::make_reverse_iterator(self().end());
115 }
116
117 /// Return const reverse iterator to the end.
118 [[nodiscard]] constexpr auto rend() const {
119 return std::make_reverse_iterator(self().begin());
120 }
121
122 /// Return const reverse iterator to the beginning.
123 [[nodiscard]] constexpr auto crbegin() const {
124 return std::make_reverse_iterator(self().end());
125 }
126
127 /// Return const reverse iterator to the end.
128 [[nodiscard]] constexpr auto crend() const {
129 return std::make_reverse_iterator(self().begin());
130 }
131
132 /// Return true if the range is empty, i.e., begin() == end().
133 [[nodiscard]] constexpr bool empty() const {
134 return self().begin() == self().end();
135 }
136
137 /// Return true if the range is non-empty, i.e., begin() != end().
138 [[nodiscard]] constexpr explicit operator bool() const { return !empty(); }
139
140 /// Return true if the range is empty, i.e., begin() == end().
141 [[nodiscard]] constexpr bool operator!() const { return empty(); }
142
143 /// Return the number of elements in this view, unsigned (size_t), by
144 /// computing std::ranges::distance(begin, end)
145 [[nodiscard]] constexpr auto size() const {
146 // Not std::distance, since that would take linear time for iterators whose
147 // value type is not a reference, since they don't model
148 // LegacyRandomAccessIterator.
149 return std::size_t(std::ranges::distance(self().begin(), self().end()));
150 }
151
152 /// Return the number of elements in this view, signed (ptrdiff_t).
153 [[nodiscard]] constexpr auto ssize() const { return std::ptrdiff_t(size()); }
154
155 /// Return the first element.
156 [[nodiscard]] constexpr decltype(auto) front() const {
157 return *self().begin();
158 }
159
160 /// Return the last element. Enabled if we have bidirectional iterators.
161 [[nodiscard]] constexpr decltype(auto) back() const
162 requires(std::bidirectional_iterator<Iterator_for<Self_t>> &&
163 std::same_as<Iterator_for<Self_t>,
164 decltype(std::declval<Self_t>().end())>)
165 {
166 // Not std::prev, since that is undefined for iterators whose value type is
167 // not a reference, since they don't model LegacyBidirectionalIterator.
168 return *std::ranges::prev(self().end());
169 }
170
171 /// Return the n'th element, possibly mutable. Enabled if we have random
172 /// access iterators.
173 [[nodiscard]] constexpr decltype(auto) operator[](std::ptrdiff_t n)
174 requires std::random_access_iterator<Iterator_for<Self_t>>
175 {
176 return self().begin()[n];
177 }
178
179 /// Return the n'th element, const. Enabled if we have random access
180 /// iterators.
181 [[nodiscard]] constexpr decltype(auto) operator[](std::ptrdiff_t n) const
182 requires std::random_access_iterator<Iterator_for<Self_t>>
183 {
184 return self().begin()[n];
185 }
186
187 /// Return pointer to underlying contiguous memory. Enabled if we have
188 /// contiguous iterators.
189 [[nodiscard]] constexpr auto *data()
190 requires std::contiguous_iterator<Iterator_for<Self_t>>
191 {
192 return &*self().begin();
193 }
194
195 /// Return const pointer to underlying contiguous memory. Enabled if we have
196 /// contiguous iterators.
197 [[nodiscard]] constexpr auto *data() const
198 requires std::contiguous_iterator<Iterator_for<Self_t>>
199 {
200 return &*self().begin();
201 }
202
203 private:
204 /// Return reference to the implementation class.
205 [[nodiscard]] Self_t &self() { return static_cast<Self_t &>(*this); }
206
207 /// Return const reference to the implementation class.
208 [[nodiscard]] const Self_t &self() const {
209 return static_cast<const Self_t &>(*this);
210 }
211}; // class Collection_interface
212
213} // namespace mysql::ranges
214
215// addtogroup GroupLibsMysqlRanges
216/// @}
217
218#endif // ifndef MYSQL_RANGES_COLLECTION_INTERFACE_H
CRTP base class to provide members of a collection based on an implementation that provides begin/end...
Definition: collection_interface.h:90
constexpr auto * data()
Return pointer to underlying contiguous memory.
Definition: collection_interface.h:189
constexpr auto * data() const
Return const pointer to underlying contiguous memory.
Definition: collection_interface.h:197
mysql::ranges::Range_iterator_type< Range_t > Iterator_for
Definition: collection_interface.h:93
constexpr auto rbegin() const
Return const reverse iterator to the beginning.
Definition: collection_interface.h:113
constexpr auto crend() const
Return const reverse iterator to the end.
Definition: collection_interface.h:128
constexpr auto cend() const
Return constant iterator to the end.
Definition: collection_interface.h:100
constexpr auto rend()
Return reverse iterator to the end.
Definition: collection_interface.h:108
constexpr bool operator!() const
Return true if the range is empty, i.e., begin() == end().
Definition: collection_interface.h:141
constexpr auto ssize() const
Return the number of elements in this view, signed (ptrdiff_t).
Definition: collection_interface.h:153
constexpr auto rend() const
Return const reverse iterator to the end.
Definition: collection_interface.h:118
constexpr auto size() const
Return the number of elements in this view, unsigned (size_t), by computing std::ranges::distance(beg...
Definition: collection_interface.h:145
constexpr decltype(auto) back() const
Return the last element. Enabled if we have bidirectional iterators.
Definition: collection_interface.h:161
constexpr decltype(auto) front() const
Return the first element.
Definition: collection_interface.h:156
constexpr auto cbegin() const
Return constant iterator to the beginning.
Definition: collection_interface.h:97
constexpr bool empty() const
Return true if the range is empty, i.e., begin() == end().
Definition: collection_interface.h:133
constexpr auto rbegin()
Return reverse iterator to the beginning.
Definition: collection_interface.h:103
Self_tp Self_t
Definition: collection_interface.h:91
constexpr auto crbegin() const
Return const reverse iterator to the beginning.
Definition: collection_interface.h:123
Experimental API header.
bool distance(const dd::Spatial_reference_system *srs, const Geometry *g1, const Geometry *g2, double *distance, bool *is_null) noexcept
Computes the distance between two geometries.
Definition: distance.cc:40
Definition: buffer_interface.h:40
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
const char * begin(const char *const c)
Definition: base64.h:44
Define std::hash<Gtid>.
Definition: gtid.h:355
int n
Definition: xcom_base.cc:509