YACLib
C++ library for concurrent tasks execution
Loading...
Searching...
No Matches
expected.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <yaclib/fwd.hpp>
5
6#include <exception>
7#include <expected>
8#include <type_traits>
9#include <utility>
10
11namespace yaclib_ext {
12
13/**
14 * Result trait that plugs std::expected<V, E> into yaclib, \see yaclib::ResultTrait for the contract
15 *
16 * Requirements for E:
17 * - E(yaclib::StopTag) constructs the cancellation error
18 * - E(std::exception_ptr) converts an exception thrown by user callback
19 * - operator== to recognize cancellation, \see IsStop
20 */
21template <typename E>
23 static_assert(std::is_constructible_v<E, yaclib::StopTag>, "E should be constructible from yaclib::StopTag");
24 static_assert(std::is_constructible_v<E, std::exception_ptr>, "E should be constructible from std::exception_ptr");
25
26 template <typename V>
27 using Result = std::expected<V, E>;
28
29 using Error = E;
30
31 template <typename R>
33
34 template <typename V, typename... Args>
35 static Result<V> MakeResult(Args&&... args) {
36 static_assert(sizeof...(Args) > 0);
37 using Head = std::decay_t<yaclib::head_t<Args&&...>>;
38 if constexpr (sizeof...(Args) == 1 && std::is_same_v<Head, yaclib::Unit>) {
39 return Result<V>{std::in_place};
40 } else if constexpr (sizeof...(Args) == 1 &&
41 (std::is_same_v<Head, yaclib::StopTag> || std::is_same_v<Head, std::exception_ptr> ||
42 std::is_same_v<Head, E>)) {
43 return Result<V>{std::unexpect, E{std::forward<Args>(args)...}};
44 } else if constexpr (std::is_same_v<Head, std::in_place_t> ||
45 (sizeof...(Args) == 1 && std::is_same_v<Head, Result<V>>)) {
46 return Result<V>{std::forward<Args>(args)...};
47 } else {
48 return Result<V>{std::in_place, std::forward<Args>(args)...};
49 }
50 }
51
52 template <typename V>
53 static bool Ok(const Result<V>& r) noexcept {
54 return r.has_value();
55 }
56
57 template <typename R>
58 static decltype(auto) GetValue(R&& r) noexcept {
59 if constexpr (std::is_void_v<typename std::remove_reference_t<R>::value_type>) {
60 return yaclib::Unit{};
61 } else {
62 return *std::forward<R>(r);
63 }
64 }
65
66 template <typename R>
67 static decltype(auto) GetError(R&& r) noexcept {
68 return std::forward<R>(r).error();
69 }
70
71 template <typename R>
72 static decltype(auto) Get(R&& r) {
73 return std::forward<R>(r).value();
74 }
75
76 static bool IsStop(const E& error) noexcept {
77 return error == E{yaclib::StopTag{}};
78 }
79};
80
81} // namespace yaclib_ext
Contract< V, T > MakeContract()
Creates related future and promise.
Definition contract.hpp:25
typename detail::Head< Args... >::Type head_t
Result trait that plugs std::expected<V, E> into yaclib,.
Definition expected.hpp:22
static decltype(auto) GetValue(R &&r) noexcept
Definition expected.hpp:58
static bool IsStop(const E &error) noexcept
Definition expected.hpp:76
typename yaclib::detail::InstantiationTypes< std::expected, R >::Value Value
Definition expected.hpp:32
static Result< V > MakeResult(Args &&... args)
Definition expected.hpp:35
static bool Ok(const Result< V > &r) noexcept
Definition expected.hpp:53
std::expected< V, E > Result
Definition expected.hpp:27
static decltype(auto) GetError(R &&r) noexcept
Definition expected.hpp:67
static decltype(auto) Get(R &&r)
Definition expected.hpp:72