29 template <
class... Args>
35 template <
class... Args>
40 concept is_result = traits::is_result<std::decay_t<T>>::value;
53 [[nodiscard]]
decltype(
auto)
concat_result(R1 &&r1, Rs &&...rs);
56 template <
class E,
class T>
59 template <
class E,
class T>
69 template <
class E,
class T>
71 template <result_content RC>
73 using content_type =
typename std::conditional<RC == result_content::error, E, T>::type;
78 template <
class E,
class T>
79 class result<E, T> :
private any_of<result_content, result_impl<E, T>::template content_wrap, result_content::error> {
80 template <result_content RC>
91 static constexpr std::
size_t value_size = 1;
108 [[nodiscard]] inline T &operator*();
110 [[nodiscard]] inline T const &operator*() const;
112 [[nodiscard]] inline T *operator->();
114 [[nodiscard]] inline T const *operator->() const;
116 [[nodiscard]] T const &release() const &;
118 [[nodiscard]] T &release() &;
120 [[nodiscard]] T &&release() &&;
122 inline explicit operator
bool() const;
126 [[nodiscard]] inline E
error() const;
130 template <
class... Args>
132 using type = std::tuple<Args...>;
135 template <
class T1,
class T2>
137 using type = std::pair<T1, T2>;
147 template <
class... Ts>
150 template <
class E,
class... Ts>
155 using typename base::error_type;
156 using typename base::value_type;
157 static constexpr std::size_t value_size =
sizeof...(Ts);
172 using
base::operator=;
173 using
base::operator*;
175 using
base::operator->;
176 using
base::operator
bool;
183 using typename base::error_type;
184 using typename base::value_type;
185 static constexpr std::size_t value_size = 0;
188 template <
class T,
class =
typename std::enable_if<
189 not std::is_void<T>::value and not std::is_same<T, result_success_type>::value>::type>
199 using
base::operator=;
202 using
base::operator
bool;
209 using base::value_size;
210 using typename base::error_type;
211 using typename base::value_type;
221 using
base::operator=;
224 using
base::operator
bool;
228 [[nodiscard]] decltype(auto) get(R &&r);
231 [[nodiscard]] decltype(auto) get(R &&r);
234 [[nodiscard]] auto result_to_tuple(R &&r);
236 template <class E, class Tuple>
237 [[nodiscard]] auto result_from_tuple(Tuple &&tpl);
242 template <
class T, is_result R>
243 decltype(
auto)
get(R &&r) {
244 if constexpr (std::decay_t<R>::value_size == 1) {
245 if constexpr (std::is_rvalue_reference_v<R &&>) {
247 return std::move(*r);
252 return std::get<T>(*r);
256 template <std::
size_t I, is_result R>
257 decltype(
auto) get(R &&r) {
258 if constexpr (std::decay_t<R>::value_size == 1) {
259 static_assert(I == 0);
260 if constexpr (std::is_rvalue_reference_v<R &&>) {
262 return std::move(*r);
267 return std::get<I>(*r);
271 template <
class E,
class T>
277 template <
class E,
class T>
283 template <
class E,
class T>
288 template <
class E,
class T>
290 if (&other !=
this) {
291 switch (other.type()) {
293 base::template set<result_content::error>(content_wrap<result_content::error>{other.error()});
296 base::template set<result_content::data>(content_wrap<result_content::data>{*other});
303 template <
class E,
class T>
308 template <
class E,
class T>
313 template <
class E,
class T>
318 template <
class E,
class T>
323 template <
class E,
class T>
325 return std::move(**
this);
329 template <
class E,
class T>
334 template <
class E,
class T>
339 template <
class E,
class T>
344 template <
class E,
class T>
349 template <
class E,
class T>
352 template <
class E,
class T>
355 template <
class E,
class T>
358 template <
class E,
class T>
362 template <
class T,
class>
365 *
this = other.error();
371 template <
class E,
class... Ts>
374 template <
class E,
class... Ts>
378 template <std::size_t... Is, is_result R>
383 template <
class,
class>
386 template <
class E,
class... Args>
394 template <
class E,
class... Args>
399 template <
class E,
class T>
409 template <
class E, std::size_t... Is,
class Tuple>
412 if constexpr (result_t::value_size == 0) {
417 return result_t{tuple_t{std::get<Is>(tpl)...}};
421 static_assert(std::is_same_v<result<char>,
decltype(
result_from_tuple<char>(std::make_index_sequence<0>{}, std::tuple<>{}))>);
422 static_assert(std::is_same_v<result<char, int>,
decltype(
result_from_tuple<char>(std::make_index_sequence<1>{}, std::tuple<int>{}))>);
426 template <is_result R>
428 return impl::result_to_tuple(std::make_index_sequence<std::decay_t<R>::value_size>{}, std::forward<R>(r));
431 template <
class E,
class Tuple>
439 template <is_result R1, is_result... Rs>
441 if constexpr (
sizeof...(Rs) == 0) {
442 return std::forward<R1>(r1);
444 static_assert(std::conjunction_v<std::is_same<typename std::decay_t<R1>::error_type,
typename std::decay_t<Rs>::error_type>...>,
445 "All result types to concatenate must have the same error type.");
446 using error_t =
typename std::decay_t<R1>::error_type;
451 auto all_viable_recursive = [](
auto &self,
auto const &refr1,
auto const &...refrs) ->
result<error_t> {
453 return refr1.error();
455 if constexpr (
sizeof...(refrs) == 0) {
458 return self(self, refrs...);
463 if (
const auto all_viable = all_viable_recursive(all_viable_recursive, r1, rs...); not all_viable) {
464 return result_t{all_viable.error()};
473 static_assert(std::is_same_v<
decltype(
concat_result(std::declval<result<char>>(), std::declval<result<char>>())), result<char>>);
474 static_assert(std::is_same_v<
decltype(
concat_result(std::declval<result<char, int>>(), std::declval<result<char>>())), result<char, int>>);
475 static_assert(std::is_same_v<
decltype(
concat_result(std::declval<result<char>>(), std::declval<result<char, int>>())), result<char, int>>);
476 static_assert(std::is_same_v<
decltype(
concat_result(std::declval<result<char, int>>(), std::declval<result<char, float>>())), result<char, int, float>>);
477 static_assert(std::is_same_v<
decltype(
concat_result(std::declval<result<char, int, float>>(), std::declval<result<char, double>>())), result<char, int, float, double>>);
478 static_assert(std::is_same_v<
decltype(
concat_result(std::declval<result<char, int, float>>(), std::declval<result<char, double, unsigned>>())), result<char, int, float, double, unsigned>>);
479 static_assert(std::is_same_v<
decltype(
concat_result(std::declval<result<char, int, float, char>>(), std::declval<result<char, double, unsigned>>())), result<char, int, float, char, double, unsigned>>);
480 static_assert(std::is_same_v<
decltype(
concat_result(std::declval<result<char, int, float, char>>(), std::declval<result<char, double, unsigned, char>>())), result<char, int, float, char, double, unsigned, char>>);
481 static_assert(std::is_same_v<
decltype(
concat_result(std::declval<result<char, int, float, char>>(), std::declval<result<char, double>>(), std::declval<result<char, unsigned, char>>())), result<char, int, float, char, double, unsigned, char>>);
result & operator=(E error)
Definition result.hpp:272
typename result_impl< E, T >::template content_wrap< RC > content_wrap
Definition result.hpp:81
std::tuple< T > value_type_as_tuple
Definition result.hpp:92
E error_type
Definition result.hpp:89
result(result &&) noexcept=default
T value_type
Definition result.hpp:90
result(result &&) noexcept=default
std::tuple< Ts... > value_type_as_tuple
Definition result.hpp:158
Definition result.hpp:180
result(result &&) noexcept=default
std::tuple<> value_type_as_tuple
Definition result.hpp:186
result(result &&) noexcept=default
auto result_from_tuple(std::index_sequence< Is... >, Tuple &&tpl)
Definition result.hpp:410
auto result_to_tuple(std::index_sequence< Is... >, R &&r)
Definition result.hpp:379
auto result_to_tuple(R &&r)
Definition result.hpp:427
static constexpr result_success_type result_success
Definition result.hpp:63
decltype(auto) get(R &&r)
Definition result.hpp:243
decltype(auto) concat_result(R1 &&r1, Rs &&...rs)
Concatenates as many results as provided. The returned object will contain all result::value_type of ...
Definition result.hpp:440
auto result_from_tuple(Tuple &&tpl)
Definition result.hpp:432
typename impl::tuple_container_type< Ts... >::type tuple_container_t
Definition result.hpp:148
result_content
Definition result.hpp:15
tuple_container_t< Args... > type
Definition result.hpp:396
T type
Definition result.hpp:401
Definition result.hpp:392
std::pair< T1, T2 > type
Definition result.hpp:137
Definition result.hpp:131
std::tuple< Args... > type
Definition result.hpp:132
Definition result.hpp:384
content_type content
Definition result.hpp:74
typename std::conditional< RC==result_content::error, E, T >::type content_type
Definition result.hpp:73
bool operator==(result< E, T > const &res) const
Definition result.hpp:356
bool operator!=(result< E, T > const &res) const
Definition result.hpp:359