MySQL 26.10.0
Source Code Documentation
ut0expected.h
Go to the documentation of this file.
1/*****************************************************************************
2Copyright (c) 2023, 2026, Oracle and/or its affiliates.
3
4This program is free software; you can redistribute it and/or modify it under
5the terms of the GNU General Public License, version 2.0, as published by the
6Free Software Foundation.
7
8This program is designed to work with certain software (including
9but not limited to OpenSSL) that is licensed under separate terms,
10as designated in a particular file or component or in included license
11documentation. The authors of MySQL hereby grant you an additional
12permission to link the program and your derivative works with the
13separately licensed software that they have either included with
14the program or referenced in the documentation.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
25*****************************************************************************/
26
27/** @file include/ut0expected.h
28 Minimal implementation of C++23 std::expected.
29
30 https://en.cppreference.com/w/cpp/utility/expected
31
32 ****************************************************************************/
33
34#ifndef ut0expected_h
35#define ut0expected_h
36
37#include <type_traits>
38#include <utility>
39#include <variant>
40
41#include "db0err.h" // dberr_t
42#include "ut0dbg.h"
43
44namespace ut {
45
46/** C++23 std::unexpected. */
47template <class E>
49 public:
50 template <class Err = E>
51 constexpr explicit Unexpected(Err &&e) : m_error(std::forward<Err>(e)) {}
52
53 constexpr const E &error() const &noexcept { return m_error; }
54
55 constexpr E &error() &noexcept { return m_error; }
56
57 constexpr const E &&error() const &&noexcept { return std::move(m_error); }
58
59 constexpr E &&error() &&noexcept { return std::move(m_error); }
60
61 private:
63};
64
65template <class E>
67
68/* Replace with std::expected once it is available in all supported compilers -
69the support for C++23 is not enough for some older gcc and clang that we still
70support. */
71
72/** C++23 std::expected. */
73template <class T, class E = dberr_t>
74class Expected : public std::variant<T, E> {
75 public:
76 using value_type = T;
77 using error_type = E;
78
79 public:
80 constexpr Expected(const Expected &other) = default;
81
82 constexpr Expected(Expected &&other) noexcept
83 : std::variant<T, E>(std::move(other)) {}
84
85 template <class U, std::enable_if_t<
86 !std::is_same_v<std::decay_t<U>, Expected>, int> = 0>
87 constexpr Expected(U &&u) noexcept
88 : std::variant<T, E>(std::in_place_index<0>, std::forward<U>(u)) {}
89
90 template <class U>
91 constexpr Expected(Unexpected<U> &&u)
92 : std::variant<T, E>(std::in_place_index<1>, std::move(u).error()) {}
93
94 constexpr Expected &operator=(const Expected &) = default;
95 constexpr Expected &operator=(Expected &&) = default;
96
97 constexpr const T *operator->() const noexcept {
98 ut_a(has_value());
99 return &std::get<0>(*this);
100 }
101
102 constexpr T *operator->() noexcept {
103 ut_a(has_value());
104 return &std::get<0>(*this);
105 }
106
107 constexpr const T &operator*() const &noexcept {
108 ut_a(has_value());
109 return std::get<0>(*this);
110 }
111
112 constexpr T &operator*() &noexcept {
113 ut_a(has_value());
114 return std::get<0>(*this);
115 }
116
117 constexpr const T &&operator*() const &&noexcept {
118 ut_a(has_value());
119 return std::move(std::get<0>(*this));
120 }
121
122 constexpr T &&operator*() &&noexcept {
123 ut_a(has_value());
124 return std::move(std::get<0>(*this));
125 }
126
127 constexpr explicit operator bool() const noexcept { return has_value(); }
128
129 constexpr bool has_value() const noexcept { return this->index() == 0; }
130
131 constexpr const T &value() const & {
132 ut_a(has_value());
133 return std::get<0>(*this);
134 }
135
136 constexpr T &value() & {
137 ut_a(has_value());
138 return std::get<0>(*this);
139 }
140
141 constexpr const T &&value() const && {
142 ut_a(has_value());
143 return std::move(std::get<0>(*this));
144 }
145
146 constexpr T &&value() && {
147 ut_a(has_value());
148 return std::move(std::get<0>(*this));
149 }
150
151 constexpr const E &error() const &noexcept {
152 ut_a(!has_value());
153 return std::get<1>(*this);
154 }
155
156 constexpr E &error() &noexcept {
157 ut_a(!has_value());
158 return std::get<1>(*this);
159 }
160
161 constexpr const E &&error() const &&noexcept {
162 ut_a(!has_value());
163 return std::move(std::get<1>(*this));
164 }
165
166 constexpr E &&error() &&noexcept {
167 ut_a(!has_value());
168 return std::move(std::get<1>(*this));
169 }
170};
171
172} /* namespace ut */
173
174#endif /* !ut0expected_h */
C++23 std::expected.
Definition: ut0expected.h:74
constexpr Expected & operator=(Expected &&)=default
constexpr const T * operator->() const noexcept
Definition: ut0expected.h:97
constexpr T & value() &
Definition: ut0expected.h:136
constexpr Expected(U &&u) noexcept
Definition: ut0expected.h:87
constexpr const E & error() const &noexcept
Definition: ut0expected.h:151
E error_type
Definition: ut0expected.h:77
constexpr const E && error() const &&noexcept
Definition: ut0expected.h:161
T value_type
Definition: ut0expected.h:76
constexpr T & operator*() &noexcept
Definition: ut0expected.h:112
constexpr T && operator*() &&noexcept
Definition: ut0expected.h:122
constexpr const T && operator*() const &&noexcept
Definition: ut0expected.h:117
constexpr Expected(const Expected &other)=default
constexpr T * operator->() noexcept
Definition: ut0expected.h:102
constexpr Expected(Expected &&other) noexcept
Definition: ut0expected.h:82
constexpr Expected(Unexpected< U > &&u)
Definition: ut0expected.h:91
constexpr E && error() &&noexcept
Definition: ut0expected.h:166
constexpr const T & operator*() const &noexcept
Definition: ut0expected.h:107
constexpr E & error() &noexcept
Definition: ut0expected.h:156
constexpr T && value() &&
Definition: ut0expected.h:146
constexpr Expected & operator=(const Expected &)=default
constexpr const T && value() const &&
Definition: ut0expected.h:141
constexpr const T & value() const &
Definition: ut0expected.h:131
constexpr bool has_value() const noexcept
Definition: ut0expected.h:129
C++23 std::unexpected.
Definition: ut0expected.h:48
constexpr Unexpected(Err &&e)
Definition: ut0expected.h:51
constexpr E && error() &&noexcept
Definition: ut0expected.h:59
constexpr E & error() &noexcept
Definition: ut0expected.h:55
E m_error
Definition: ut0expected.h:62
constexpr const E && error() const &&noexcept
Definition: ut0expected.h:57
constexpr const E & error() const &noexcept
Definition: ut0expected.h:53
#define U
Definition: ctype-tis620.cc:73
Global error codes for the database.
#define T
Definition: jit_executor_value.cc:373
bool index(const std::string &value, const String &search_for, uint32_t *idx)
Definition: contains.h:76
noexcept
The return type for any call_and_catch(f, args...) call where f(args...) returns Type.
Definition: call_and_catch.h:76
Define std::hash<Gtid>.
Definition: gtid.h:355
This file contains a set of libraries providing overloads for regular dynamic allocation routines whi...
Definition: aligned_alloc.h:48
Unexpected(E) -> Unexpected< E >
Definition: dtoa.cc:595
Debug utilities for Innobase.
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:97