MySQL 9.6.0
Source Code Documentation
map_boundary_storage.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_THROWING_MAP_BOUNDARY_STORAGE_H
25#define MYSQL_SETS_THROWING_MAP_BOUNDARY_STORAGE_H
26
27/// @file
28/// Experimental API header
29///
30/// This file contains the class Map_boundary_storage, which provides storage
31/// for a boundary container backed by a std::map.
32
33#include <map> // map
34#include "my_compiler.h" // MY_COMPILER_DIAGNOSTIC_PUSH
35#include "mysql/allocators/allocator.h" // Allocator
36#include "mysql/allocators/memory_resource.h" // Memory_resource
37#include "mysql/containers/basic_container_wrapper.h" // Basic_container_wrapper
38#include "mysql/containers/map_or_set_assign.h" // map_or_set_assign
39#include "mysql/iterators/iterator_interface.h" // Iterator_interface
40#include "mysql/iterators/meta.h" // Is_declared_legacy_bidirectional_iterator
41#include "mysql/meta/is_same_ignore_const.h" // Is_same_ignore_const
42#include "mysql/ranges/disjoint_pairs.h" // make_disjoint_pairs_iterator
43#include "mysql/ranges/meta.h" // Range_iterator_type
44#include "mysql/sets/boundary_set_meta.h" // Is_boundary_storage
45#include "mysql/sets/upper_lower_bound_interface.h" // Upper_lower_bound_interface
46
47/// @addtogroup GroupLibsMysqlSets
48/// @{
49
51
52/// Boundary_iterator based on a std::map iterator or const iterator.
53template <class Map_iterator_tp, class Mutable_map_iterator_tp = void>
56 Map_boundary_iterator<Map_iterator_tp, Mutable_map_iterator_tp>> {
57 using Map_iterator_t = Map_iterator_tp;
58 using Mutable_map_iterator_t = Mutable_map_iterator_tp;
59
60 public:
61 /// Default constructor. The resulting iterator is in a "meaningless" state,
62 /// where the only allowed operation is to assign to it.
63 constexpr Map_boundary_iterator() = default;
64
65 /// Construct an iterator at the given position, and at the given endpoint
66 /// state.
67 constexpr Map_boundary_iterator(const Map_iterator_t &position,
68 bool is_endpoint)
69 : m_position(position), m_is_endpoint(is_endpoint) {}
70
71 /// Converting constructor from the mutable iterator type, enabled if this is
72 /// a const iterator.
73 explicit constexpr Map_boundary_iterator(
75 requires(!std::same_as<Mutable_map_iterator_t, void>)
76 : m_position(other.map_iterator()), m_is_endpoint(other.is_endpoint()) {}
77
78 /// @return the current boundary.
79 [[nodiscard]] auto &get() const {
81#if __GNUC__ <= 12
82 // gcc 11.4.1 (on e.g. solaris11-sparc-64bit) gives a mysterious
83 // -Wmaybe-uninitialized warning on the following line. The warning does not
84 // appear in 12.2, so likely it was a compiler bug and was fixed. The gcc
85 // changelogs between those two versions mention at least one false positive
86 // for -Wmaybe-uninitialized,
87 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78993, so it could be that
88 // or something else.
89 MY_COMPILER_GCC_DIAGNOSTIC_IGNORE("-Wmaybe-uninitialized")
90#endif
91 return m_is_endpoint ? m_position->first : m_position->second;
93 }
94
95 /// Move forward one step.
96 constexpr void next() {
99 }
100
101 /// Move backward one step.
102 constexpr void prev() {
105 }
106
107 /// @return true if this object is equal to the other object.
108 [[nodiscard]] constexpr bool is_equal(
109 const Map_boundary_iterator &other) const {
110 return m_position == other.m_position &&
112 }
113
114 /// @return true if this is an endpoint.
115 [[nodiscard]] constexpr bool is_endpoint() const { return m_is_endpoint; }
116
117 /// @return the underlying std::map iterator.
118 [[nodiscard]] constexpr const Map_iterator_t &map_iterator() const {
119 return m_position;
120 }
121
122 private:
124 bool m_is_endpoint{false};
125}; // class Map_boundary_iterator
126
128 Map_boundary_iterator<std::map<int, int>::iterator>>);
129
130} // namespace mysql::sets::throwing::detail
131
132namespace mysql::sets::throwing {
133
134/// Storage for boundary points, backed by a std::map.
135///
136/// Internally, each interval is represented as a value pair in the map, where
137/// the key is the endpoint and the mapped value is the start. (This may appear
138/// "reversed". The reason is technical: some operations are faster this way.
139/// See comments in @c upper_bound_impl.)
140///
141/// Insertion is worst-case logarithmic-time, but amortized constant-time if an
142/// exact hint can be provided, which is possible when elements are inserted in
143/// order. Deletion is linear-time in the number of deleted elements, plus
144/// logarithmic-time in the total number of elements. upper_bound/lower_bound is
145/// worst-case logarithmic-time, but constant-time if given an exact hint. The
146/// iterator category is bidirectional_iterator.
147///
148/// @tparam Set_traits_tp Bounded set traits describing properties of the
149/// element type.
150///
151/// @tparam Map_tp Class for the map data structure, expected to have an API
152/// similar to `std::map<Set_traits_tp::Element_t, Set_traits_tp::Element_t>`.
153template <Is_bounded_set_traits Set_traits_tp, class Map_tp>
156 Map_boundary_storage<Set_traits_tp, Map_tp>, Map_tp>,
158 Map_boundary_storage<Set_traits_tp, Map_tp>, Set_traits_tp,
159 detail::Map_boundary_iterator<
160 mysql::ranges::Range_iterator_type<Map_tp>>,
161 detail::Map_boundary_iterator<
162 mysql::ranges::Range_const_iterator_type<Map_tp>,
163 mysql::ranges::Range_iterator_type<Map_tp>>,
164 Iterator_get_value> {
165 private:
167 template <class Type_t>
168 static constexpr std::pair<Type_t &, Type_t &> make_pair(Type_t &second,
169 Type_t &first) {
170 return {first, second};
171 }
172 template <class Type_t>
173 static constexpr std::pair<Type_t, Type_t> make_pair(const Type_t &second,
174 const Type_t &first) {
175 return {first, second};
176 }
177 };
178
180
181 public:
182 using Set_traits_t = Set_traits_tp;
183 using Map_t = Map_tp;
186
187 using Element_t = typename Set_traits_t::Element_t;
189
192
196 static_assert(std::bidirectional_iterator<Iterator_t>);
197 static_assert(
201
202 static_assert(
203 std::same_as<std::pair<const Element_t, Element_t>, Map_value_t>);
204
205 /// Declare that insertion is "fast", i.e., O(log(N)).
206 static constexpr bool has_fast_insertion = true;
207
208 /// Construct a new, empty object, with the given Memory_resource.
210 const Memory_resource_t &memory_resource = Memory_resource_t()) noexcept
211 : Basic_container_wrapper_t(Allocator_t(memory_resource)) {
212 static_assert(Is_boundary_storage<This_t>);
213 }
214
215 /// Constructor copying from another type, using the given Memory_resource.
218 const Memory_resource_t &memory_resource)
220 Allocator_t(memory_resource)) {}
221
222 /// Constructor copying both values and Memory_resource from another storage.
227
228 /// Constructor copying a range defined by the given iterators, using
229 /// memory_resource if given, or the default Memory_resource() otherwise.
230 template <std::input_iterator First_iterator_t>
232 const First_iterator_t &first,
233 const std::sentinel_for<First_iterator_t> auto &last,
234 const Memory_resource_t &memory_resource = Memory_resource_t())
237 first),
239 last),
240 Allocator_t(memory_resource)) {}
241
242 // use defaults for copy/move/destructor
244 Map_boundary_storage(Map_boundary_storage &&other) noexcept = default;
247 default;
249
250 /// Assignment operator copying from another type, preserving the existing
251 /// Memory_resource.
254 this->assign(source);
255 return *this;
256 }
257
258 [[nodiscard]] Map_t &map() { return this->wrapped(); }
259 [[nodiscard]] const Map_t &map() const { return this->wrapped(); }
260
261 /// Assign from another type, preserving the existing Memory_resource.
263 &other) {
264 assign(other.begin(), other.end());
265 }
266
267 /// Assign from the range defined by the given iterators, preserving the
268 /// existing Memory_resource.
269 template <std::input_iterator First_iterator_t>
270 void assign(const First_iterator_t &first,
271 const std::sentinel_for<First_iterator_t> auto &last) {
273 map(),
274 mysql::ranges::make_disjoint_pairs_iterator<Make_pair_reverse>(first),
275 mysql::ranges::make_disjoint_pairs_iterator<Make_pair_reverse>(last));
276 }
277
278 /// @return const iterator to the beginning.
279 [[nodiscard]] auto begin() const {
280 return Const_iterator_t(map().begin(), false);
281 }
282
283 /// @return const iterator to the end.
284 [[nodiscard]] auto end() const {
285 return Const_iterator_t(map().end(), false);
286 }
287
288 /// @return mutable iterator to the beginning.
289 [[nodiscard]] auto begin() { return Iterator_t(map().begin(), false); }
290
291 /// @return mutable iterator to the end.
292 [[nodiscard]] auto end() { return Iterator_t(map().end(), false); }
293
294 /// @return the number of boundary points.
295 [[nodiscard]] auto size() const { return 2 * map().size(); }
296
297 /// @return true if this object is empty.
298 [[nodiscard]] bool empty() const { return map().empty(); }
299
300 /// @return true if this object is nonempty.
301 [[nodiscard]] explicit operator bool() const { return (bool)map(); }
302
303 /// @return the upper bound for the given element in the given storage.
304 template <mysql::meta::Is_same_ignore_const<This_t> This_arg_t>
305 [[nodiscard]] static auto upper_bound_impl(This_arg_t &self,
306 const Element_t &element) {
307 auto map_position = self.map().upper_bound(element);
308 if (map_position == self.map().end()) return self.end();
309 // map::upper_bound finds an upper bound among *keys* only, not values.
310 // Since our keys are endpoints, it is possible that the real upper bound is
311 // the start of the same interval. Therefore, we check if the mapped value
312 // is an upper bound.
313 //
314 // This is where it is good that the map is ordered by endpoints. If we
315 // would order by start, map::upper_bound would find an upper bound that is
316 // a start of an interval, and the real upper bound may be the end of the
317 // preceding interval. That would be a little bit more costly (and
318 // complicated) to check.
320 map_position, le(map_position->second, element));
321 }
322
323 /// @return the lower bound for the given element in the given storage.
324 template <mysql::meta::Is_same_ignore_const<This_t> This_arg_t>
325 [[nodiscard]] static auto lower_bound_impl(This_arg_t &self,
326 const Element_t &element) {
327 auto map_position = self.map().lower_bound(element);
328 if (map_position == self.map().end()) return self.end();
330 map_position, lt(map_position->second, element));
331 }
332
333 /// Erase an even-length range of boundary points.
334 ///
335 /// This invalidates iterators to any removed elements, and also, if `left` is
336 /// an endpoint, invalidates iterators to std::prev(left).
337 ///
338 /// @param left The first boundary point to remove, inclusive.
339 ///
340 /// @param right The last boundary point to remove, exclusive.
341 ///
342 /// @return Iterator to the next point after the last removed point.
343 ///
344 /// @note It is required that left.is_endpoint() == right.is_endpoint().
345 [[nodiscard]] Iterator_t erase(const Iterator_t &left,
346 const Iterator_t &right) {
347 assert(left.is_endpoint() == right.is_endpoint());
348 assert(std::distance(left, right) % 2 == 0);
349 if (left == right || !left.is_endpoint()) {
350 // before: [{a, b}, {c, d}, {e, f}], *left==a, *right==e
351 // after: [{e, f}]
352
353 // When left==right, it is tempting to have a special case `return left`.
354 // However, left is a const iterator and the return type for this function
355 // is non-const. Therefore we call erase with two equal iterators, which
356 // is a no-op, and returns the non-const iterator type as needed. Cf.
357 // https://stackoverflow.com/questions/765148/how-to-remove-constness-of-const-iterator
358 auto interval_iterator =
359 map().erase(left.map_iterator(), right.map_iterator());
360 return Iterator_t(interval_iterator, left.is_endpoint());
361 } else {
362 // before: [{a, b}, {c, d}, {e, f}], *left==b, *right==f
363 // after: [{a, f}]
364 auto map_iterator = left.map_iterator();
365 auto left_start = map_iterator->second;
366 map_iterator = map().erase(map_iterator, right.map_iterator());
367 map_iterator->second = left_start;
368 return Iterator_t(map_iterator, true);
369 }
370 }
371
372 /// Insert two boundary points by allocating a new element.
373 ///
374 /// @param position Insertion point.
375 ///
376 /// @param v1 The first boundary point to insert.
377 ///
378 /// @param v2 The second boundary point to insert.
379 ///
380 /// @return Iterator to the next point after the inserted point.
381 ///
382 /// @throws bad_alloc on OOM.
383 [[nodiscard]] Iterator_t insert(const Iterator_t &position,
384 const Element_t &v1, const Element_t &v2) {
385 return do_insert(
386 position, v1, v2,
387 [this](const auto &map_iterator, const auto &e1, const auto &e2) {
388 this->map().emplace_hint(map_iterator, e1, e2);
389 });
390 }
391
392 /// Insert two boundary points, stealing the first element from given source
393 /// object (which must be nonempty).
394 ///
395 /// @param position Insertion point.
396 ///
397 /// @param v1 The first boundary point to insert.
398 ///
399 /// @param v2 The second boundary point to insert.
400 ///
401 /// @param source other Map_boundary_storage from which we may steal an
402 /// element.
403 ///
404 /// @return Iterator to the next point after the inserted point.
405 [[nodiscard]] Iterator_t steal_and_insert(const Iterator_t &position,
406 const Element_t &v1,
407 const Element_t &v2,
408 This_t &source) noexcept {
409 return do_insert(position, v1, v2,
410 [this, &source](const auto &map_iterator, const auto &e1,
411 const auto &e2) {
412 auto node_handle =
413 source.map().extract(source.map().begin());
414 node_handle.key() = e1;
415 node_handle.mapped() = e2;
416 this->map().insert(map_iterator, std::move(node_handle));
417 });
418 }
419
420 /// Modify the boundary that the iterator points to.
421 ///
422 /// @param position Element to update.
423 ///
424 /// @param element New value.
425 ///
426 /// @return iterator to the next element. Note that this is different from
427 /// `position`, and that `position` has been invalidated, in case
428 /// `position.is_endpoint()==true`.
429 [[nodiscard]] Iterator_t update_point(const Iterator_t &position,
430 const Element_t &element) {
431 assert(position == begin() || lt(*std::prev(position), element));
432 assert(position == end() || std::next(position) == end() ||
433 lt(element, *std::next(position)));
434 auto map_iterator = position.map_iterator();
435 if (position.is_endpoint()) {
436 // before: [{a, b}], *position==b
437 // after: [{a, element}]
438 auto next_map_iterator = std::next(map_iterator);
439 Map_const_iterator_t map_const_iterator = map_iterator;
440 auto node_handle = map().extract(map_const_iterator);
441 node_handle.key() = element;
442 auto it = map().insert(next_map_iterator, std::move(node_handle));
443 return Iterator_t(std::next(it), false);
444 } else {
445 // before: [{a, b}], *position==a
446 // after: [{element, b}]
447 map_iterator->second = element;
448 return Iterator_t(map_iterator, true);
449 }
450 }
451
452 private:
453 /// Insert two boundary points. This is the common worker function for the
454 /// three-argument and four-argument public insert functions.
455 ///
456 /// @param position Insertion point.
457 ///
458 /// @param v1 The first boundary point to insert.
459 ///
460 /// @param v2 The second boundary point to insert.
461 ///
462 /// @param inserter Callable that will insert two boundary points with a given
463 /// iterator hint.
464 ///
465 /// @return Iterator to the next point after the inserted point.
466 [[nodiscard]] Iterator_t do_insert(const Iterator_t &position,
467 const Element_t &v1, const Element_t &v2,
468 const auto &inserter) {
469 // Verify the position is correct: prev(position) < v1 < v2 < position
470 assert(position == begin() || lt(*std::prev(position), v1));
471 assert(lt(v1, v2));
472 assert(position == end() || lt(v2, *position));
473 auto map_iterator = position.map_iterator();
474 if (position.is_endpoint()) {
475 // before: [{a, b}], *position==b
476 // after: [{a, v1}, {v2, b}]
477 auto &element_a = map_iterator->second;
478 inserter(map_iterator, v1, element_a);
479 element_a = v2;
480 } else {
481 // before: [{a, b}], *position==a
482 // after: [{v1, v2}, {a, b}]
483 inserter(map_iterator, v2, v1);
484 }
485 return position;
486 }
487
488 /// Return true if "left < right", according to the order defined by
489 /// Set_traits_t.
490 [[nodiscard]] static constexpr bool lt(const Element_t &left,
491 const Element_t &right) {
492 return Set_traits_t::lt(left, right);
493 }
494
495 /// Return true if "left <= right", according to the order defined by
496 /// Set_traits_t.
497 [[nodiscard]] static constexpr bool le(const Element_t &left,
498 const Element_t &right) {
499 return Set_traits_t::le(left, right);
500 }
501}; // class Map_boundary_storage
502
503} // namespace mysql::sets::throwing
504
505// addtogroup GroupLibsMysqlSets
506/// @}
507
508#endif // ifndef MYSQL_SETS_THROWING_MAP_BOUNDARY_STORAGE_H
Experimental API header.
Experimental API header.
Allocator using a Memory_resource to do the allocation.
Definition: allocator.h:52
Polymorphism-free memory resource class with custom allocator and deallocator functions.
Definition: memory_resource.h:88
CRTP base class (mixin) to define a wrapper around a container.
Definition: basic_container_wrapper.h:59
auto get_memory_resource() const noexcept
Return the memory resource used by the wrapped object.
Definition: basic_container_wrapper.h:137
CRTP base class (mixin) that makes your class a standard-compliant iterator, given only a minimal set...
Definition: iterator_interface.h:370
CRTP base class (mixin) to define a set that has upper_bound and lower_bound members.
Definition: upper_lower_bound_interface.h:193
Storage for boundary points, backed by a std::map.
Definition: map_boundary_storage.h:164
Map_boundary_storage(const Is_readable_boundary_storage_over_traits< Set_traits_t > auto &source, const Memory_resource_t &memory_resource)
Constructor copying from another type, using the given Memory_resource.
Definition: map_boundary_storage.h:216
auto end() const
Definition: map_boundary_storage.h:284
Map_boundary_storage & operator=(const Map_boundary_storage &other)=default
static auto upper_bound_impl(This_arg_t &self, const Element_t &element)
Definition: map_boundary_storage.h:305
Map_boundary_storage & operator=(const Is_boundary_storage_over_traits< Set_traits_t > auto &source)
Assignment operator copying from another type, preserving the existing Memory_resource.
Definition: map_boundary_storage.h:252
void assign(const Is_readable_boundary_storage_over_traits< Set_traits_t > auto &other)
Assign from another type, preserving the existing Memory_resource.
Definition: map_boundary_storage.h:262
Map_boundary_storage & operator=(Map_boundary_storage &&other) noexcept=default
const Map_t & map() const
Definition: map_boundary_storage.h:259
detail::Map_boundary_iterator< Map_const_iterator_t, Map_iterator_t > Const_iterator_t
Definition: map_boundary_storage.h:200
Map_boundary_storage(const First_iterator_t &first, const std::sentinel_for< First_iterator_t > auto &last, const Memory_resource_t &memory_resource=Memory_resource_t())
Constructor copying a range defined by the given iterators, using memory_resource if given,...
Definition: map_boundary_storage.h:231
Map_boundary_storage(const Is_readable_boundary_storage_over_traits< Set_traits_t > auto &source)
Constructor copying both values and Memory_resource from another storage.
Definition: map_boundary_storage.h:223
Set_traits_tp Set_traits_t
Definition: map_boundary_storage.h:182
static constexpr bool lt(const Element_t &left, const Element_t &right)
Return true if "left < right", according to the order defined by Set_traits_t.
Definition: map_boundary_storage.h:490
static constexpr bool le(const Element_t &left, const Element_t &right)
Return true if "left <= right", according to the order defined by Set_traits_t.
Definition: map_boundary_storage.h:497
detail::Map_boundary_iterator< Map_iterator_t > Iterator_t
Definition: map_boundary_storage.h:195
Map_boundary_storage(const Map_boundary_storage &other)=default
mysql::ranges::Range_value_type< Map_t > Map_value_t
Definition: map_boundary_storage.h:188
bool empty() const
Definition: map_boundary_storage.h:298
Map_boundary_storage(Map_boundary_storage &&other) noexcept=default
auto size() const
Definition: map_boundary_storage.h:295
mysql::ranges::Range_iterator_type< Map_t > Map_iterator_t
Definition: map_boundary_storage.h:193
mysql::ranges::Range_const_iterator_type< Map_t > Map_const_iterator_t
Definition: map_boundary_storage.h:194
auto begin() const
Definition: map_boundary_storage.h:279
Map_t & map()
Definition: map_boundary_storage.h:258
Map_tp Map_t
Definition: map_boundary_storage.h:183
Map_boundary_storage(const Memory_resource_t &memory_resource=Memory_resource_t()) noexcept
Construct a new, empty object, with the given Memory_resource.
Definition: map_boundary_storage.h:209
auto begin()
Definition: map_boundary_storage.h:289
Iterator_t update_point(const Iterator_t &position, const Element_t &element)
Modify the boundary that the iterator points to.
Definition: map_boundary_storage.h:429
mysql::allocators::Memory_resource Memory_resource_t
Definition: map_boundary_storage.h:190
auto end()
Definition: map_boundary_storage.h:292
static auto lower_bound_impl(This_arg_t &self, const Element_t &element)
Definition: map_boundary_storage.h:325
void assign(const First_iterator_t &first, const std::sentinel_for< First_iterator_t > auto &last)
Assign from the range defined by the given iterators, preserving the existing Memory_resource.
Definition: map_boundary_storage.h:270
static constexpr bool has_fast_insertion
Declare that insertion is "fast", i.e., O(log(N)).
Definition: map_boundary_storage.h:206
Iterator_t erase(const Iterator_t &left, const Iterator_t &right)
Erase an even-length range of boundary points.
Definition: map_boundary_storage.h:345
Iterator_t insert(const Iterator_t &position, const Element_t &v1, const Element_t &v2)
Insert two boundary points by allocating a new element.
Definition: map_boundary_storage.h:383
typename Set_traits_t::Element_t Element_t
Definition: map_boundary_storage.h:187
Iterator_t steal_and_insert(const Iterator_t &position, const Element_t &v1, const Element_t &v2, This_t &source) noexcept
Insert two boundary points, stealing the first element from given source object (which must be nonemp...
Definition: map_boundary_storage.h:405
Iterator_t do_insert(const Iterator_t &position, const Element_t &v1, const Element_t &v2, const auto &inserter)
Insert two boundary points.
Definition: map_boundary_storage.h:466
Boundary_iterator based on a std::map iterator or const iterator.
Definition: map_boundary_storage.h:56
Map_iterator_tp Map_iterator_t
Definition: map_boundary_storage.h:57
constexpr Map_boundary_iterator(const Map_iterator_t &position, bool is_endpoint)
Construct an iterator at the given position, and at the given endpoint state.
Definition: map_boundary_storage.h:67
constexpr Map_boundary_iterator()=default
Default constructor.
constexpr bool is_equal(const Map_boundary_iterator &other) const
Definition: map_boundary_storage.h:108
bool m_is_endpoint
Definition: map_boundary_storage.h:124
constexpr void next()
Move forward one step.
Definition: map_boundary_storage.h:96
Mutable_map_iterator_tp Mutable_map_iterator_t
Definition: map_boundary_storage.h:58
auto & get() const
Definition: map_boundary_storage.h:79
constexpr bool is_endpoint() const
Definition: map_boundary_storage.h:115
constexpr Map_boundary_iterator(const Map_boundary_iterator< Mutable_map_iterator_t > &other)
Converting constructor from the mutable iterator type, enabled if this is a const iterator.
Definition: map_boundary_storage.h:73
Map_iterator_t m_position
Definition: map_boundary_storage.h:123
constexpr const Map_iterator_t & map_iterator() const
Definition: map_boundary_storage.h:118
constexpr void prev()
Move backward one step.
Definition: map_boundary_storage.h:102
True if the iterator is declared to meet LegacyBidirectionalIterator requirements.
Definition: meta.h:83
True if Test is a boundary point iterator and a bidirectional iterator.
Definition: boundary_set_meta.h:105
True if Test is a boundary storage over the given Set traits.
Definition: boundary_set_meta.h:350
True if Test is a readable boundary storage, i.e., an object that can be used as the back-end storage...
Definition: boundary_set_meta.h:342
True if Test is a boundary storage over the given Set traits.
Definition: boundary_set_meta.h:313
Experimental API header.
Experimental API header.
Experimental API header.
Allocator class that uses a polymorphic Memory_resource to allocate memory.
Experimental API header.
Experimental API header.
Experimental API header.
Class that wraps resources in a polymorphic manner.
Header for compiler-dependent features.
#define MY_COMPILER_GCC_DIAGNOSTIC_IGNORE(X)
Definition: my_compiler.h:242
#define MY_COMPILER_DIAGNOSTIC_PUSH()
save the compiler's diagnostic (enabled warnings, errors, ...) state
Definition: my_compiler.h:277
#define MY_COMPILER_DIAGNOSTIC_POP()
restore the compiler's diagnostic (enabled warnings, errors, ...) state
Definition: my_compiler.h:278
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
void right(std::string *to_trim)
Definition: trim.h:41
void left(std::string *to_trim)
Definition: trim.h:35
void map_or_set_assign(Map_or_set_t &map_or_set, const Source_iterator_t &first, const std::sentinel_for< Source_iterator_t > auto &last)
Replace the contents of container with that of the range given by the two iterators,...
Definition: map_or_set_assign.h:107
std::remove_cvref_t< decltype(std::declval< const Range_t >().begin())> Range_const_iterator_type
Gives the const_iterator type, deduced from the begin() const member.
Definition: meta.h:47
auto make_disjoint_pairs_iterator(const Iterator_t &position)
Factory function to create a Disjoint_pairs_iterator.
Definition: disjoint_pairs.h:181
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
Iterator_value_type< Range_iterator_type< Range_t > > Range_value_type
Gives the value type for any collection, deduced from *begin().
Definition: meta.h:67
Definition: aliases.h:73
Definition: aliases.h:73
noexcept
The return type for any call_and_catch(f, args...) call where f(args...) returns Type.
Definition: call_and_catch.h:76
Definition: instrumented_condition_variable.h:32
repeated Source source
Definition: replication_asynchronous_connection_failover.proto:42
static constexpr std::pair< Type_t &, Type_t & > make_pair(Type_t &second, Type_t &first)
Definition: map_boundary_storage.h:168
static constexpr std::pair< Type_t, Type_t > make_pair(const Type_t &second, const Type_t &first)
Definition: map_boundary_storage.h:173
Experimental API header.