1 /* Type sugar for success and failure
2 (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (25 commits)
3 File Created: July 2017
4
5
6 Boost Software License - Version 1.0 - August 17th, 2003
7
8 Permission is hereby granted, free of charge, to any person or organization
9 obtaining a copy of the software and accompanying documentation covered by
10 this license (the "Software") to use, reproduce, display, distribute,
11 execute, and transmit the Software, and to prepare derivative works of the
12 Software, and to permit third-parties to whom the Software is furnished to
13 do so, all subject to the following:
14
15 The copyright notices in the Software and this entire statement, including
16 the above license grant, this restriction and the following disclaimer,
17 must be included in all copies of the Software, in whole or in part, and
18 all derivative works of the Software, unless such copies or derivative
19 works are solely in the form of machine-executable object code generated by
20 a source language processor.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
25 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
26 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
27 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 DEALINGS IN THE SOFTWARE.
29 */
30
31 #ifndef BOOST_OUTCOME_SUCCESS_FAILURE_HPP
32 #define BOOST_OUTCOME_SUCCESS_FAILURE_HPP
33
34 #include "config.hpp"
35
36 BOOST_OUTCOME_V2_NAMESPACE_BEGIN
37
38 /*! AWAITING HUGO JSON CONVERSION TOOL
39 type definition template <class T> success_type. Potential doc page: `success_type<T>`
40 */
41 template <class T> struct BOOST_OUTCOME_NODISCARD success_type
42 {
43 using value_type = T;
44
45 private:
46 value_type _value;
47
48 public:
49 success_type() = default;
50 success_type(const success_type &) = default;
51 success_type(success_type &&) = default; // NOLINT
52 success_type &operator=(const success_type &) = default;
53 success_type &operator=(success_type &&) = default; // NOLINT
54 ~success_type() = default;
55 BOOST_OUTCOME_TEMPLATE(class U)
56 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_same<success_type, std::decay_t<U>>::value))
success_typesuccess_type57 constexpr explicit success_type(U &&v)
58 : _value(static_cast<U &&>(v)) // NOLINT
59 {
60 }
61
valuesuccess_type62 constexpr value_type &value() & { return _value; }
valuesuccess_type63 constexpr const value_type &value() const & { return _value; }
valuesuccess_type64 constexpr value_type &&value() && { return static_cast<value_type &&>(_value); }
valuesuccess_type65 constexpr const value_type &&value() const && { return static_cast<value_type &&>(_value); }
66 };
67 template <> struct BOOST_OUTCOME_NODISCARD success_type<void>
68 {
69 using value_type = void;
70 };
71 /*! Returns type sugar for implicitly constructing a `basic_result<T>` with a successful state,
72 default constructing `T` if necessary.
73 */
success()74 inline constexpr success_type<void> success() noexcept
75 {
76 return success_type<void>{};
77 }
78 /*! Returns type sugar for implicitly constructing a `basic_result<T>` with a successful state.
79 \effects Copies or moves the successful state supplied into the returned type sugar.
80 */
success(T && v)81 template <class T> inline constexpr success_type<std::decay_t<T>> success(T &&v)
82 {
83 return success_type<std::decay_t<T>>{static_cast<T &&>(v)};
84 }
85
86 /*! AWAITING HUGO JSON CONVERSION TOOL
87 type definition template <class EC, class E = void> failure_type. Potential doc page: `failure_type<EC, EP = void>`
88 */
89 template <class EC, class E = void> struct BOOST_OUTCOME_NODISCARD failure_type
90 {
91 using error_type = EC;
92 using exception_type = E;
93
94 private:
95 bool _have_error{}, _have_exception{};
96 error_type _error;
97 exception_type _exception;
98
99 struct error_init_tag
100 {
101 };
102 struct exception_init_tag
103 {
104 };
105
106 public:
107 failure_type() = default;
108 failure_type(const failure_type &) = default;
109 failure_type(failure_type &&) = default; // NOLINT
110 failure_type &operator=(const failure_type &) = default;
111 failure_type &operator=(failure_type &&) = default; // NOLINT
112 ~failure_type() = default;
113 template <class U, class V>
failure_typefailure_type114 constexpr explicit failure_type(U &&u, V &&v)
115 : _have_error(true)
116 , _have_exception(true)
117 , _error(static_cast<U &&>(u))
118 , _exception(static_cast<V &&>(v))
119 {
120 }
121 template <class U>
failure_typefailure_type122 constexpr explicit failure_type(in_place_type_t<error_type> /*unused*/, U &&u, error_init_tag /*unused*/ = error_init_tag())
123 : _have_error(true)
124 , _error(static_cast<U &&>(u))
125 , _exception()
126 {
127 }
128 template <class U>
failure_typefailure_type129 constexpr explicit failure_type(in_place_type_t<exception_type> /*unused*/, U &&u, exception_init_tag /*unused*/ = exception_init_tag())
130 : _have_exception(true)
131 , _error()
132 , _exception(static_cast<U &&>(u))
133 {
134 }
135
has_errorfailure_type136 constexpr bool has_error() const { return _have_error; }
has_exceptionfailure_type137 constexpr bool has_exception() const { return _have_exception; }
138
errorfailure_type139 constexpr error_type &error() & { return _error; }
errorfailure_type140 constexpr const error_type &error() const & { return _error; }
errorfailure_type141 constexpr error_type &&error() && { return static_cast<error_type &&>(_error); }
errorfailure_type142 constexpr const error_type &&error() const && { return static_cast<error_type &&>(_error); }
143
exceptionfailure_type144 constexpr exception_type &exception() & { return _exception; }
exceptionfailure_type145 constexpr const exception_type &exception() const & { return _exception; }
exceptionfailure_type146 constexpr exception_type &&exception() && { return static_cast<exception_type &&>(_exception); }
exceptionfailure_type147 constexpr const exception_type &&exception() const && { return static_cast<exception_type &&>(_exception); }
148 };
149 template <class EC> struct BOOST_OUTCOME_NODISCARD failure_type<EC, void>
150 {
151 using error_type = EC;
152 using exception_type = void;
153
154 private:
155 error_type _error;
156
157 public:
158 failure_type() = default;
159 failure_type(const failure_type &) = default;
160 failure_type(failure_type &&) = default; // NOLINT
161 failure_type &operator=(const failure_type &) = default;
162 failure_type &operator=(failure_type &&) = default; // NOLINT
163 ~failure_type() = default;
164 BOOST_OUTCOME_TEMPLATE(class U)
165 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_same<failure_type, std::decay_t<U>>::value))
failure_typefailure_type166 constexpr explicit failure_type(U &&u)
167 : _error(static_cast<U &&>(u)) // NOLINT
168 {
169 }
170
errorfailure_type171 constexpr error_type &error() & { return _error; }
errorfailure_type172 constexpr const error_type &error() const & { return _error; }
errorfailure_type173 constexpr error_type &&error() && { return static_cast<error_type &&>(_error); }
errorfailure_type174 constexpr const error_type &&error() const && { return static_cast<error_type &&>(_error); }
175 };
176 template <class E> struct BOOST_OUTCOME_NODISCARD failure_type<void, E>
177 {
178 using error_type = void;
179 using exception_type = E;
180
181 private:
182 exception_type _exception;
183
184 public:
185 failure_type() = default;
186 failure_type(const failure_type &) = default;
187 failure_type(failure_type &&) = default; // NOLINT
188 failure_type &operator=(const failure_type &) = default;
189 failure_type &operator=(failure_type &&) = default; // NOLINT
190 ~failure_type() = default;
191 BOOST_OUTCOME_TEMPLATE(class V)
192 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_same<failure_type, std::decay_t<V>>::value))
failure_typefailure_type193 constexpr explicit failure_type(V &&v)
194 : _exception(static_cast<V &&>(v)) // NOLINT
195 {
196 }
197
exceptionfailure_type198 constexpr exception_type &exception() & { return _exception; }
exceptionfailure_type199 constexpr const exception_type &exception() const & { return _exception; }
exceptionfailure_type200 constexpr exception_type &&exception() && { return static_cast<exception_type &&>(_exception); }
exceptionfailure_type201 constexpr const exception_type &&exception() const && { return static_cast<exception_type &&>(_exception); }
202 };
203 /*! AWAITING HUGO JSON CONVERSION TOOL
204 SIGNATURE NOT RECOGNISED
205 */
failure(EC && v)206 template <class EC> inline constexpr failure_type<std::decay_t<EC>> failure(EC &&v)
207 {
208 return failure_type<std::decay_t<EC>>{static_cast<EC &&>(v)};
209 }
210 /*! AWAITING HUGO JSON CONVERSION TOOL
211 SIGNATURE NOT RECOGNISED
212 */
failure(EC && v,E && w)213 template <class EC, class E> inline constexpr failure_type<std::decay_t<EC>, std::decay_t<E>> failure(EC &&v, E &&w)
214 {
215 return failure_type<std::decay_t<EC>, std::decay_t<E>>{static_cast<EC &&>(v), static_cast<E &&>(w)};
216 }
217
218 namespace detail
219 {
220 template <class T> struct is_success_type
221 {
222 static constexpr bool value = false;
223 };
224 template <class T> struct is_success_type<success_type<T>>
225 {
226 static constexpr bool value = true;
227 };
228 template <class T> struct is_failure_type
229 {
230 static constexpr bool value = false;
231 };
232 template <class EC, class E> struct is_failure_type<failure_type<EC, E>>
233 {
234 static constexpr bool value = true;
235 };
236 } // namespace detail
237
238 /*! AWAITING HUGO JSON CONVERSION TOOL
239 SIGNATURE NOT RECOGNISED
240 */
241 template <class T> static constexpr bool is_success_type = detail::is_success_type<std::decay_t<T>>::value;
242
243 /*! AWAITING HUGO JSON CONVERSION TOOL
244 SIGNATURE NOT RECOGNISED
245 */
246 template <class T> static constexpr bool is_failure_type = detail::is_failure_type<std::decay_t<T>>::value;
247
248 BOOST_OUTCOME_V2_NAMESPACE_END
249
250 #endif
251