26template <
typename TValue,
typename TError>
29template <
typename TValue>
32template <
typename TError>
37namespace jsonv::detail
40template <
typename TResult1,
typename TResult2,
typename Enabler =
void>
41struct result_common_type
44template <
typename TValue1,
typename TError1,
typename TValue2,
typename TError2>
45struct result_common_type<jsonv::result<TValue1, TError1>,
47 std::void_t<std::common_type_t<TValue1, TValue2>, std::common_type_t<TError1, TError2>>
58template <
typename TValue1,
typename TError1,
typename TValue2,
typename TError2>
59struct common_type<jsonv::result<TValue1, TError1>,
jsonv::result<TValue2, TError2>> :
60 public jsonv::detail::result_common_type<jsonv::result<TValue1, TError1>, jsonv::result<TValue2, TError2>>
65namespace jsonv::detail
68template <
template <
typename...>
class TT,
typename Test>
69struct is_template_of :
public std::false_type
72template <
template <
typename...>
class TT,
typename... TArgs>
73struct is_template_of<TT, TT<TArgs...>> :
public std::true_type
76template <
template <
typename...>
class TT,
typename Test>
77inline constexpr bool is_template_of_v = is_template_of<TT, Test>::value;
79template <
typename TResult,
typename FUnary,
typename Enabler =
void>
80struct result_map_result
83template <
typename TInputValue,
typename TInputError,
typename FUnary>
84struct result_map_result<const result<TInputValue, TInputError>&,
86 std::void_t<std::invoke_result_t<FUnary, const TInputValue&>>
91 using function_result_type = std::invoke_result_t<FUnary, const TInputValue&>;
93 using type = result<function_result_type, TInputError>;
95 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary, const TInputValue&>
96 && std::is_nothrow_move_constructible_v<ok<function_result_type>>
97 && std::is_nothrow_copy_constructible_v<TInputError>;
101template <
typename TInputError,
typename FUnary>
102struct result_map_result<const result<void, TInputError>&, FUnary, std::void_t<std::invoke_result_t<FUnary>>>
106 using function_result_type = std::invoke_result_t<FUnary>;
108 using type = result<function_result_type, TInputError>;
110 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary>
111 && std::is_nothrow_move_constructible_v<ok<function_result_type>>
112 && std::is_nothrow_copy_constructible_v<TInputError>;
116template <
typename TInputValue,
typename TInputError,
typename FUnary>
117struct result_map_result<result<TInputValue, TInputError>&&,
119 std::void_t<std::invoke_result_t<FUnary, TInputValue&&>>
124 using function_result_type = std::invoke_result_t<FUnary, TInputValue&&>;
126 using type = result<function_result_type, TInputError>;
128 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary, TInputValue&&>
129 && std::is_nothrow_move_constructible_v<ok<function_result_type>>
130 && std::is_nothrow_copy_constructible_v<TInputError>;
134template <
typename TInputError,
typename FUnary>
135struct result_map_result<result<void, TInputError>&&, FUnary, std::void_t<std::invoke_result_t<FUnary>>>
139 using function_result_type = std::invoke_result_t<FUnary>;
141 using type = result<function_result_type, TInputError>;
143 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary>
144 && std::is_nothrow_move_constructible_v<ok<function_result_type>>
145 && std::is_nothrow_copy_constructible_v<TInputError>;
149template <
typename TResult,
typename FUnary>
150using result_map_result_info =
typename result_map_result<TResult, FUnary>::info;
152template <
typename TResult,
typename FUnary,
typename Enabler =
void>
153struct result_map_flat_result
156template <
typename TInputValue,
typename TInputError,
typename FUnary>
157struct result_map_flat_result<const result<TInputValue, TInputError>&,
159 std::void_t<std::invoke_result_t<FUnary, const TInputValue&>>
164 using function_result_type = std::invoke_result_t<FUnary, const TInputValue&>;
166 static_assert(is_template_of_v<result, function_result_type>,
167 "Function provided to `map_flat` must return a `jsonv::result`"
170 using error_type = std::common_type_t<TInputError, typename function_result_type::error_type>;
172 using type = result<typename function_result_type::value_type, error_type>;
174 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary, const TInputValue&>
175 && std::is_nothrow_constructible_v<type, const error<TInputError>&>
176 && std::is_nothrow_constructible_v<type, function_result_type&&>;
180template <
typename TInputError,
typename FUnary>
181struct result_map_flat_result<const result<void, TInputError>&,
183 std::void_t<std::invoke_result_t<FUnary>>
188 using function_result_type = std::invoke_result_t<FUnary>;
190 static_assert(is_template_of_v<result, function_result_type>,
191 "Function provided to `map_flat` must return a `jsonv::result`"
194 using error_type = std::common_type_t<TInputError, typename function_result_type::error_type>;
196 using type = result<typename function_result_type::value_type, error_type>;
198 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary>
199 && std::is_nothrow_constructible_v<type, const error<TInputError>&>
200 && std::is_nothrow_constructible_v<type, function_result_type&&>;
204template <
typename TInputValue,
typename TInputError,
typename FUnary>
205struct result_map_flat_result<result<TInputValue, TInputError>&&,
207 std::void_t<std::invoke_result_t<FUnary, TInputValue&&>>
212 using function_result_type = std::invoke_result_t<FUnary, TInputValue&&>;
214 static_assert(is_template_of_v<result, function_result_type>,
215 "Function provided to `map_flat` must return a `jsonv::result`"
218 using error_type = std::common_type_t<TInputError, typename function_result_type::error_type>;
220 using type = result<typename function_result_type::value_type, error_type>;
222 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary, TInputValue&&>
223 && std::is_nothrow_constructible_v<type, error<TInputError>&&>
224 && std::is_nothrow_constructible_v<type, function_result_type&&>;
228template <
typename TInputError,
typename FUnary>
229struct result_map_flat_result<result<void, TInputError>&&, FUnary, std::void_t<std::invoke_result_t<FUnary>>>
233 using function_result_type = std::invoke_result_t<FUnary>;
235 static_assert(is_template_of_v<result, function_result_type>,
236 "Function provided to `map_flat` must return a `jsonv::result`"
239 using error_type = std::common_type_t<TInputError, typename function_result_type::error_type>;
241 using type = result<typename function_result_type::value_type, error_type>;
243 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary>
244 && std::is_nothrow_constructible_v<type, error<TInputError>&&>
245 && std::is_nothrow_constructible_v<type, function_result_type&&>;
249template <
typename TResult,
typename FUnary>
250using result_map_flat_result_info =
typename result_map_flat_result<TResult, FUnary>::info;
252template <
typename TResult,
typename FUnary,
typename Enabler =
void>
253struct result_map_error_result
256template <
typename TInputValue,
typename TInputError,
typename FUnary>
257struct result_map_error_result<const result<TInputValue, TInputError>&,
259 std::void_t<std::invoke_result_t<FUnary, const TInputError&>>
264 using function_result_type = std::invoke_result_t<FUnary, const TInputError&>;
266 using type = result<TInputValue, function_result_type>;
268 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary, const TInputError&>
269 && std::is_nothrow_move_constructible_v<error<function_result_type>>
270 && std::is_nothrow_copy_constructible_v<TInputValue>;
274template <
typename TInputValue,
typename FUnary>
275struct result_map_error_result<const result<TInputValue, void>&,
277 std::void_t<std::invoke_result_t<FUnary>>
282 using function_result_type = std::invoke_result_t<FUnary>;
284 using type = result<TInputValue, function_result_type>;
286 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary>
287 && std::is_nothrow_move_constructible_v<error<function_result_type>>
288 && std::is_nothrow_copy_constructible_v<TInputValue>;
292template <
typename TInputValue,
typename TInputError,
typename FUnary>
293struct result_map_error_result<result<TInputValue, TInputError>&&,
295 std::void_t<std::invoke_result_t<FUnary, TInputError&&>>
300 using function_result_type = std::invoke_result_t<FUnary, TInputError&&>;
302 using type = result<TInputValue, function_result_type>;
304 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary, TInputError&&>
305 && std::is_nothrow_move_constructible_v<error<function_result_type>>
306 && std::is_nothrow_move_constructible_v<TInputValue>;
310template <
typename TInputValue,
typename FUnary>
311struct result_map_error_result<result<TInputValue, void>&&,
313 std::void_t<std::invoke_result_t<FUnary>>
318 using function_result_type = std::invoke_result_t<FUnary>;
320 using type = result<TInputValue, function_result_type>;
322 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary>
323 && std::is_nothrow_move_constructible_v<error<function_result_type>>
324 && std::is_nothrow_move_constructible_v<TInputValue>;
328template <
typename TResult,
typename FUnary>
329using result_map_error_result_info =
typename result_map_error_result<TResult, FUnary>::info;
331template <
typename TResult,
typename FUnary,
typename Enabler =
void>
332struct result_recover_result
335template <
typename TInputValue,
typename TInputError,
typename FUnary>
336struct result_recover_result<const result<TInputValue, TInputError>&,
338 std::void_t<std::invoke_result_t<FUnary, const TInputError&>>
343 using function_result_type = std::invoke_result_t<FUnary, const TInputError&>;
345 static_assert(is_template_of_v<std::optional, function_result_type>,
346 "Function provided to `recover` must return a `jsonv::optional`"
349 using function_result_value_type =
typename function_result_type::value_type;
351 using value_type = std::common_type_t<TInputValue, function_result_value_type>;
353 using type = result<value_type, TInputError>;
355 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary, const TInputError&>
356 && std::is_nothrow_constructible_v<value_type, function_result_value_type&&>
357 && std::is_nothrow_constructible_v<value_type, const TInputValue&>
358 && std::is_nothrow_copy_constructible_v<TInputError>;
362template <
typename TInputValue,
typename FUnary>
363struct result_recover_result<const result<TInputValue, void>&,
365 std::void_t<std::invoke_result_t<FUnary>>
370 using function_result_type = std::invoke_result_t<FUnary>;
372 static_assert(is_template_of_v<std::optional, function_result_type>,
373 "Function provided to `recover` must return a `jsonv::optional`"
376 using function_result_value_type =
typename function_result_type::value_type;
378 using value_type = std::common_type_t<TInputValue, function_result_value_type>;
380 using type = result<value_type, void>;
382 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary>
383 && std::is_nothrow_constructible_v<value_type, function_result_value_type&&>
384 && std::is_nothrow_constructible_v<value_type, const TInputValue&>;
388template <
typename TInputError,
typename FUnary>
389struct result_recover_result<const result<void, TInputError>&,
391 std::void_t<std::invoke_result_t<FUnary, const TInputError&>>
396 using function_result_type = std::invoke_result_t<FUnary, const TInputError&>;
398 static_assert(std::is_same_v<optional<ok<void>>, function_result_type>,
399 "Function provided to `recover` with `value_type` of `void` must return a "
400 "`jsonv::optional<jsonv::ok<void>>`"
403 using type = result<void, TInputError>;
405 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary, const TInputError&>
406 && std::is_nothrow_copy_constructible_v<TInputError>;
410template <
typename FUnary>
411struct result_recover_result<const result<void, void>&,
413 std::void_t<std::invoke_result_t<FUnary>>
418 using function_result_type = std::invoke_result_t<FUnary>;
420 static_assert(std::is_same_v<optional<ok<void>>, function_result_type>,
421 "Function provided to `recover` with `value_type` of `void` must return a "
422 "`jsonv::optional<jsonv::ok<void>>`"
425 using type = result<void, void>;
427 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary>;
431template <
typename TResult,
typename FUnary>
432using result_recover_result_info =
typename result_recover_result<TResult, FUnary>::info;
434template <
typename TResult,
typename FUnary,
typename Enabler =
void>
435struct result_recover_flat_result
438template <
typename TInputValue,
typename TInputError,
typename FUnary>
439struct result_recover_flat_result<const result<TInputValue, TInputError>&,
441 std::void_t<std::invoke_result_t<FUnary, const TInputError&>>
446 using source_type = result<TInputValue, TInputError>;
448 using function_result_type = std::invoke_result_t<FUnary, const TInputError&>;
450 static_assert(is_template_of_v<result, function_result_type>,
451 "Function provided to `recover_flat` must return a `jsonv::result`"
454 using value_type = std::common_type_t<TInputValue, typename function_result_type::value_type>;
456 using type = result<value_type, typename function_result_type::error_type>;
458 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary, const TInputError&>
459 && std::is_nothrow_constructible_v<type, function_result_type&&>;
463template <
typename TInputValue,
typename FUnary>
464struct result_recover_flat_result<const result<TInputValue, void>&,
466 std::void_t<std::invoke_result_t<FUnary>>
471 using source_type = result<TInputValue, void>;
473 using function_result_type = std::invoke_result_t<FUnary>;
475 static_assert(is_template_of_v<result, function_result_type>,
476 "Function provided to `recover_flat` must return a `jsonv::result`"
479 using value_type = std::common_type_t<TInputValue, typename function_result_type::value_type>;
481 using type = result<value_type, typename function_result_type::error_type>;
483 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary>
484 && std::is_nothrow_constructible_v<type, function_result_type&&>;
488template <
typename TInputValue,
typename TInputError,
typename FUnary>
489struct result_recover_flat_result<result<TInputValue, TInputError>&&,
491 std::void_t<std::invoke_result_t<FUnary, TInputError&&>>
496 using source_type = result<TInputValue, TInputError>;
498 using function_result_type = std::invoke_result_t<FUnary, TInputError&&>;
500 static_assert(is_template_of_v<result, function_result_type>,
501 "Function provided to `recover_flat` must return a `jsonv::result`"
504 using value_type = std::common_type_t<TInputValue, typename function_result_type::value_type>;
506 using type = result<value_type, typename function_result_type::error_type>;
508 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary, TInputError&&>
509 && std::is_nothrow_constructible_v<type, function_result_type&&>;
513template <
typename TInputValue,
typename FUnary>
514struct result_recover_flat_result<result<TInputValue, void>&&,
516 std::void_t<std::invoke_result_t<FUnary>>
521 using source_type = result<TInputValue, void>;
523 using function_result_type = std::invoke_result_t<FUnary>;
525 static_assert(is_template_of_v<result, function_result_type>,
526 "Function provided to `recover_flat` must return a `jsonv::result`"
529 using value_type = std::common_type_t<TInputValue, typename function_result_type::value_type>;
531 using type = result<value_type, typename function_result_type::error_type>;
533 static constexpr bool is_noexcept = std::is_nothrow_invocable_v<FUnary>
534 && std::is_nothrow_constructible_v<type, function_result_type&&>;
538template <
typename TResult,
typename FUnary>
539using result_recover_flat_result_info =
typename result_recover_flat_result<TResult, FUnary>::info;
554JSONV_PUBLIC std::ostream& operator<<(std::ostream&,
const result_state&);
567template <
typename TValue>
576 template <
typename...
TArgs>
606 explicit constexpr ok()
noexcept =
default;
609template <
typename TValue>
612template <
typename...
TArgs>
613ok(
TArgs...) ->
ok<std::enable_if_t<
sizeof...(TArgs) == 0,
void>>;
624template <
typename TError>
632 template <
typename...
TArgs>
639 error_type&& get() && {
return std::move(_error); }
660 explicit constexpr error()
noexcept =
default;
663template <
typename TError>
666template <
typename...
TArgs>
705 value_type&
value() & {
return get_raw(
"value"); }
706 value_type&& value() && {
return std::move(get_raw(
"value")); }
711 template <
typename UValue>
713 noexcept( std::is_nothrow_copy_constructible_v<value_type>
714 && std::is_nothrow_constructible_v<value_type, UValue>
721 template <
typename UValue>
723 noexcept( std::is_nothrow_move_constructible_v<value_type>
724 && std::is_nothrow_constructible_v<value_type, UValue>
727 auto&
self =
static_cast<self_type&
>(*this);
737 value_type& operator*() & {
return get_raw(
"operator*"); }
738 value_type&& operator*() && {
return std::move(get_raw(
"operator*")); }
746 value_type* operator->() {
return &get_raw(
"operator->"); }
750 inline constexpr const value_type& get_raw(
const char* op_name)
const
752 const auto& self =
static_cast<const self_type&
>(*this);
753 self.ensure_state(op_name, result_state::ok);
754 return std::get<self_type::ok_index>(self._storage).get();
757 inline constexpr value_type& get_raw(
const char* op_name)
759 auto& self =
static_cast<self_type&
>(*this);
760 self.ensure_state(op_name, result_state::ok);
761 return std::get<self_type::ok_index>(self._storage).get();
765template <
typename TSelf>
775 self.ensure_state(
"value", result_state::ok);
782template <
typename TSelf,
typename TError>
799 self.ensure_state(
"error", result_state::error);
800 return std::get<self_type::error_index>(
self._storage).get();
803 error_type&
error() &
805 auto&
self =
static_cast<self_type&
>(*this);
806 self.ensure_state(
"error", result_state::error);
807 return std::get<self_type::error_index>(
self._storage).get();
810 error_type&& error() &&
812 auto& self =
static_cast<self_type&
>(*this);
813 self.ensure_state(
"error", result_state::error);
814 return std::get<self_type::error_index>(std::move(self._storage)).get();
819template <
typename TSelf>
829 self.ensure_state(
"error", result_state::error);
1087template <
typename TValue,
typename TError = std::exception_ptr>
1094 template <
typename,
typename>
1097 template <
typename,
typename>
1100 template <
typename,
typename>
1117 template <
typename...
TArgs>
1125 template <
typename TOkValue>
1127 std::enable_if_t< detail::is_template_of_v<
ok, std::decay_t<TOkValue>>
1128 && std::is_convertible_v<typename TOkValue::value_type, value_type>
1136 template <
typename TOkValue>
1138 std::enable_if_t< std::is_same_v<
ok<void>, std::decay_t<TOkValue>>
1139 && std::is_void_v<value_type>
1148 template <
typename UValue>
1150 std::enable_if_t< std::is_convertible_v<UValue, value_type>
1151 && !std::is_same_v<value_type, error_type>
1159 template <
typename...
TArgs>
1167 template <
typename TErrorValue>
1169 std::enable_if_t< detail::is_template_of_v<jsonv::error, TErrorValue>
1170 && std::is_convertible_v<typename TErrorValue::error_type, error_type>
1178 template <
typename TErrorValue>
1181 && std::is_void_v<error_type>
1209 switch (
src.state())
1211 case result_state::ok:
1212 if constexpr (std::is_void_v<value_type>)
1221 case result_state::error:
1222 if constexpr (std::is_void_v<error_type>)
1231 case result_state::empty:
1238 template <
typename UValue,
1240 typename = std::enable_if_t< std::is_convertible_v<UValue, value_type>
1241 && std::is_convertible_v<UError, error_type>
1246 auto clear_src = detail::on_scope_exit([&] {
src.reset(); });
1247 switch (
src.state())
1249 case result_state::ok:
1250 if constexpr (std::is_void_v<value_type>)
1259 case result_state::error:
1260 if constexpr (std::is_void_v<error_type>)
1269 case result_state::empty:
1278 if (_storage.index() == ok_index)
1279 return result_state::ok;
1280 else if (_storage.index() == error_index)
1281 return result_state::error;
1283 return result_state::empty;
1289 return state() == result_state::ok;
1301 return state() == result_state::error;
1308 _storage = std::monostate{};
1347 template <
typename FUnary,
typename ResultInfo = detail::result_map_result_info<const self_type&, FUnary>>
1354 case result_state::ok:
1355 if constexpr (std::is_void_v<value_type>)
1357 if constexpr (std::is_void_v<typename return_type::value_type>)
1369 if constexpr (std::is_void_v<typename return_type::value_type>)
1371 std::forward<FUnary>(
transform)(std::get<ok_index>(_storage).get());
1377 std::forward<FUnary>(
transform)(std::get<ok_index>(_storage).get())
1381 case result_state::error:
1382 return return_type(in_place_error, std::get<error_index>(_storage));
1383 case result_state::empty:
1424 template <
typename FUnary,
typename ResultInfo = detail::result_map_result_info<self_type&&, FUnary>>
1429 auto clear_me = detail::on_scope_exit([&] { reset(); });
1433 case result_state::ok:
1434 if constexpr (std::is_void_v<value_type>)
1436 if constexpr (std::is_void_v<typename return_type::value_type>)
1448 if constexpr (std::is_void_v<typename return_type::value_type>)
1450 std::forward<FUnary>(
transform)(std::get<ok_index>(std::move(_storage)).get());
1456 std::forward<FUnary>(
transform)(std::get<ok_index>(std::move(_storage)).get())
1460 case result_state::error:
1461 return return_type(in_place_error, std::get<error_index>(std::move(_storage)));
1462 case result_state::empty:
1506 template <
typename FUnary,
typename ResultInfo = detail::result_map_flat_result_info<const self_type&, FUnary>>
1507 typename ResultInfo::type
1514 case result_state::ok:
1515 if constexpr (std::is_void_v<value_type>)
1517 return std::forward<FUnary>(
transform)();
1521 return std::forward<FUnary>(
transform)(std::get<ok_index>(_storage).get());
1523 case result_state::error:
1524 return return_type(in_place_error, std::get<error_index>(_storage));
1525 case result_state::empty:
1567 template <
typename FUnary,
typename ResultInfo = detail::result_map_flat_result_info<self_type&&, FUnary>>
1568 typename ResultInfo::type
1573 auto clear_me = detail::on_scope_exit([&] { reset(); });
1576 case result_state::ok:
1577 if constexpr (std::is_void_v<value_type>)
1579 return std::forward<FUnary>(
transform)();
1583 return std::forward<FUnary>(
transform)(std::get<ok_index>(std::move(_storage)).get());
1585 case result_state::error:
1586 return return_type(in_place_error, std::get<error_index>(std::move(_storage)));
1587 case result_state::empty:
1630 template <
typename FUnary,
typename ResultInfo = detail::result_map_error_result_info<const self_type&, FUnary>>
1631 typename ResultInfo::type
1638 case result_state::ok:
1639 return return_type(in_place_ok, std::get<ok_index>(_storage));
1640 case result_state::error:
1641 if constexpr (std::is_void_v<error_type>)
1643 if constexpr (std::is_void_v<typename return_type::error_type>)
1655 if constexpr (std::is_void_v<typename return_type::error_type>)
1657 std::forward<FUnary>(
transform)(std::get<error_index>(_storage).get());
1663 std::forward<FUnary>(
transform)(std::get<error_index>(_storage).get())
1667 case result_state::empty:
1708 template <
typename FUnary,
typename ResultInfo = detail::result_map_error_result_info<self_type&&, FUnary>>
1709 typename ResultInfo::type
1714 auto clear_me = detail::on_scope_exit([&] { reset(); });
1718 case result_state::ok:
1719 return return_type(in_place_ok, std::get<ok_index>(std::move(_storage)));
1720 case result_state::error:
1721 if constexpr (std::is_void_v<error_type>)
1723 if constexpr (std::is_void_v<typename return_type::error_type>)
1735 if constexpr (std::is_void_v<typename return_type::error_type>)
1737 std::forward<FUnary>(
transform)(std::get<error_index>(std::move(_storage)).get());
1743 std::forward<FUnary>(
transform)(std::get<error_index>(std::move(_storage)).get())
1747 case result_state::empty:
1803 template <
typename FUnary,
typename ResultInfo = detail::result_recover_result_info<const self_type&, FUnary>>
1804 typename ResultInfo::type
1811 case result_state::ok:
1812 if constexpr (std::is_void_v<value_type>)
1818 return return_type(in_place_ok, std::get<ok_index>(_storage).get());
1820 case result_state::error:
1822 using optional_type =
typename ResultInfo::function_result_type;
1827 if constexpr (std::is_void_v<error_type>)
1829 return std::forward<FUnary>(
recovery)();
1833 return std::forward<FUnary>(
recovery)(std::get<error_index>(_storage).get());
1843 return return_type(in_place_error, std::get<error_index>(_storage));
1846 case result_state::empty:
1890 template <
typename FUnary,
typename ResultInfo = detail::result_recover_flat_result_info<const self_type&, FUnary>>
1891 typename ResultInfo::type
1898 case result_state::ok:
1899 if constexpr (std::is_void_v<value_type>)
1905 return return_type(in_place_ok, std::get<ok_index>(_storage).get());
1907 case result_state::error:
1908 if constexpr (std::is_void_v<error_type>)
1910 return std::forward<FUnary>(
recovery)();
1914 return std::forward<FUnary>(
recovery)(std::get<error_index>(_storage).get());
1916 case result_state::empty:
1958 template <
typename FUnary,
typename ResultInfo = detail::result_recover_flat_result_info<self_type&&, FUnary>>
1959 typename ResultInfo::type
1964 auto clear_me = detail::on_scope_exit([&] { reset(); });
1967 case result_state::ok:
1968 if constexpr (std::is_void_v<value_type>)
1974 return return_type(in_place_ok, std::get<ok_index>(std::move(_storage)).get());
1976 case result_state::error:
1977 if constexpr (std::is_void_v<error_type>)
1979 return std::forward<FUnary>(
recovery)();
1983 return std::forward<FUnary>(
recovery)(std::get<error_index>(std::move(_storage)).get());
1985 case result_state::empty:
1995 static constexpr std::size_t empty_index = 0
U;
1996 static constexpr std::size_t ok_index = 1U;
1997 static constexpr std::size_t error_index = 2U;
2006 storage_type _storage;
2009template <
typename T>
2010result(ok<T>) -> result<T>;
Thrown when an attempt to access the contents of a result was illegal.
static bad_result_access must_be(string_view op_name, result_state expected, result_state actual)
Create an exception with a description noting the op_name must be performed in the expected state,...
static bad_result_access must_not_be(string_view op_name, result_state unexpected)
Create an exception with a description noting the op_name must not be performed in the unexpected sta...
bad_result_access(const std::string &description) noexcept
Create an exception with the given description.
An adapter for enumeration types.
A wrapper type for creating a result with result_state::error.
A wrapper type for creating a result with result_state::ok.
constexpr ok(TArgs &&... args) noexcept(std::is_nothrow_constructible_v< value_type, TArgs... >)
Create an instance from the given args.
const value_type & get() const &noexcept
The set of result operations which depend on the type of TError.
const error_type & error() const &
The set of result operations which depend on the type of TValue.
const value_type & value() const &
const value_type & operator*() const &
constexpr value_type value_or(UValue &&recovery_value) const &noexcept(std::is_nothrow_copy_constructible_v< value_type > &&std::is_nothrow_constructible_v< value_type, UValue >)
const value_type * operator->() const
A type that represents a value which might be a success (is_ok) or a failure (is_error).
ResultInfo::type map(FUnary &&transform) &&noexcept(ResultInfo::is_noexcept)
Apply transform to a result_state::ok value, returning the result of the transformation in another re...
ResultInfo::type map_error(FUnary &&transform) &&noexcept(ResultInfo::is_noexcept)
Apply transform to a result_state::error value, returning the result of the transformation in another...
constexpr result(UValue &&value, std::enable_if_t< std::is_convertible_v< UValue, value_type > &&!std::is_same_v< value_type, error_type > > *=nullptr) noexcept(std::is_nothrow_constructible_v< value_type, UValue >)
Construct a result with result_state::ok from the provided value.
constexpr bool is_error() const noexcept
Check that this result has state of result_state::error.
constexpr result(TOkValue &&value, std::enable_if_t< detail::is_template_of_v< ok, std::decay_t< TOkValue > > &&std::is_convertible_v< typename TOkValue::value_type, value_type > > *=nullptr)
Construct a result with result_state::ok from the contents of value.
constexpr result_state state() const noexcept
Get the state of this object.
constexpr result(result &&) noexcept=default
Result instances are move-constructible iff value_type and error_type are.
constexpr bool is_ok() const noexcept
Check that this result has state of result_state::ok.
constexpr result(in_place_error_t, TArgs &&... args) noexcept(std::is_nothrow_constructible_v< error_type, TArgs... >)
Construct a result with result_state::error from the provided args.
constexpr result(TOkValue &&value, std::enable_if_t< std::is_same_v< ok< void >, std::decay_t< TOkValue > > &&std::is_void_v< value_type > > *=nullptr) noexcept
Construct a result with result_state::ok from a ok<void>.
void reset() noexcept(std::is_nothrow_destructible_v< value_type > &&std::is_nothrow_destructible_v< error_type >)
Reset the contents of this instance to result_state::empty.
ResultInfo::type recover_flat(FUnary &&recovery) const &noexcept(ResultInfo::is_noexcept)
ResultInfo::type recover(FUnary &&recovery) const &noexcept(ResultInfo::is_noexcept)
ResultInfo::type map_flat(FUnary &&transform) const &noexcept(ResultInfo::is_noexcept)
ResultInfo::type map_error(FUnary &&transform) const &noexcept(ResultInfo::is_noexcept)
constexpr result() noexcept
Construct an empty result.
ResultInfo::type map_flat(FUnary &&transform) &&noexcept(ResultInfo::is_noexcept)
Apply transform to a result_state::ok value, returning the result of the transformation,...
constexpr result(TErrorValue &&, std::enable_if_t< std::is_same_v< jsonv::error< void >, std::decay_t< TErrorValue > > &&std::is_void_v< error_type > > *=nullptr) noexcept
Construct a result with result_state::error from an error<void>.
ResultInfo::type recover_flat(FUnary &&recovery) &&noexcept(ResultInfo::is_noexcept)
Apply recovery to a result_state::error value, returning the result of the transformation,...
constexpr result(TErrorValue &&error_value, std::enable_if_t< detail::is_template_of_v< jsonv::error, TErrorValue > &&std::is_convertible_v< typename TErrorValue::error_type, error_type > > *=nullptr)
Construct a result with result_state::error from the contents of error_value.
constexpr result(const result &)=default
Result instances are copy-constructible iff value_type and error_type are.
constexpr result(in_place_ok_t, TArgs &&... args) noexcept(std::is_nothrow_constructible_v< value_type, TArgs... >)
Construct a result with result_state::ok from the provided args.
ResultInfo::type map(FUnary &&transform) const &noexcept(ResultInfo::is_noexcept)
result(result< UValue, UError > &&src) noexcept
Converting constructor from a result with a convertible value_type and error_type.
Represents a single JSON value, which can be any one of a potential kind, each behaving slightly diff...
Copyright (c) 2014-2020 by Travis Gockel.
#define JSONV_PUBLIC
This function or class is part of the public API for JSON Voorhees.
Pulls in an implementation of optional.
result_state
Describes the state of a result instance.
Definition of the on_scope_exit utility.
Pulls in an implementation of string_view.
std::string_view string_view
A non-owning reference to a string.