MySQL 9.6.0
Source Code Documentation
return_status.h
Go to the documentation of this file.
1// Copyright (c) 2023, 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_UTILS_RETURN_STATUS_H
25#define MYSQL_UTILS_RETURN_STATUS_H
26
27/// @file
28/// Experimental API header
29
30/// @addtogroup GroupLibsMysqlUtils
31/// @{
32
33#include <concepts> // invocable
34#include <utility> // forward
35
36namespace mysql::utils {
37
38/// @brief Simple, strongly-typed enumeration to indicate internal status:
39/// ok, error
40enum class Return_status {
41 ok, ///< operation succeeded
42 error, ///< operation failed
43};
44
45// A default-constructed return status should be 'ok'.
46static_assert(Return_status{} == Return_status::ok);
47
48/// Helper that calls the given function and returns its result, or returns
49/// `Return_status::ok` if the function returns `void`.
50///
51/// Use case: Suppose a function `f` has two overloads: one that can fail and
52/// one that cannot fail. Then the overload that can fail should return
53/// `Return_status` and have the `[[nodiscard]]` attribute and the overload that
54/// cannot fail should return void, as follows:
55///
56/// @code
57/// void f(/*args...*/) { this overload cannot fail }
58/// [[nodiscard]] Return_status f(/*args...*/) { this overload can fail }
59/// @code
60///
61/// Then, a function template `w1` that invokes `f` and forwards the
62/// return status (`w1` is a "wrapper"), can be defined like:
63///
64/// @code
65/// [[nodiscard]] auto w1(/*args...*/) {
66/// ...
67/// return w1(/*args...*/);
68/// }
69/// @endcode
70///
71/// This makes `w1` inherit both the return type and the `[[nodiscard]]`
72/// attribute from the overload of `f` that it invokes, since `[[nodiscard]]` is
73/// automatically dropped when the return type is deduced to `void`.
74///
75/// (If the non-failing overload of `f` would return `Return_status::ok` always,
76/// `w1` would return `Return_status::ok` always, and have the `[[nodiscard]]`
77/// attribute always, which could force callers to check the return value even
78/// in cases it is known to always be `ok`).
79///
80/// Now, `void_to_ok` is usable in cases where a function template `w2` needs to
81/// invoke `f` and forward the return status, *and* must always return
82/// `Return_status`, perhaps because `w2` has error cases that do not depend on
83/// errors in the invocation of `f`. For example:
84///
85/// @code
86/// [[nodiscard]] Return_status w2(/*args...*/) {
87/// ...
88/// if (/*condition1*/) return Return_status::ok;
89/// ...
90/// if (/*condition2*/) return Return_status::error;
91/// ...
92/// if (/*condition3*/) return void_to_ok([&] { return f(/*args...*/); });
93/// ...
94/// }
95/// @endcode
96///
97/// @tparam Return_t The return type of this function. If Func_t returns
98/// non-void, Func_t's return type must be convertible to Return_t. The default
99/// is Return_status.
100///
101/// @tparam Func_t The type of the function to call.
102///
103/// @tparam Args_t Types of the arguments.
104///
105/// @param func Function to call.
106///
107/// @param args Arguments that will be forwarded to the function.
108///
109/// @return Return_t: if `func` returns non-void, casts the result to `Return_t`
110/// and returns it; otherwise returns a default-constructed `Return_t` value.
111template <class Return_t = Return_status, class Func_t, class... Args_t>
112 requires std::invocable<Func_t, Args_t...>
113[[nodiscard]] Return_t void_to_ok(const Func_t &func, Args_t &&...args) {
114 if constexpr (std::same_as<std::invoke_result_t<Func_t, Args_t...>, void>) {
115 func(std::forward<Args_t>(args)...);
116 return Return_t{};
117 } else {
118 static_assert(
119 std::convertible_to<std::invoke_result_t<Func_t, Args_t...>, Return_t>);
120 return func(std::forward<Args_t>(args)...);
121 }
122}
123
124} // namespace mysql::utils
125
126/// @}
127
128#endif // MYSQL_UTILS_RETURN_STATUS_H
Definition: gtid_format.h:47
decltype(call_function()) Return_t
Definition: call_and_catch.h:80
Return_status
Simple, strongly-typed enumeration to indicate internal status: ok, error.
Definition: return_status.h:40
@ ok
operation succeeded
@ error
operation failed
Return_t void_to_ok(const Func_t &func, Args_t &&...args)
Helper that calls the given function and returns its result, or returns Return_status::ok if the func...
Definition: return_status.h:113