YACLib
C++ library for concurrent tasks execution
Loading...
Searching...
No Matches
status_or.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <yaclib/fwd.hpp>
6
7#include <exception>
8#include <type_traits>
9#include <utility>
10
11#include <absl/status/status.h>
12#include <absl/status/statusor.h>
13
14namespace yaclib_ext {
15
16/**
17 * Result trait that plugs absl::StatusOr<V> into yaclib, \see yaclib::ResultTrait for the contract
18 *
19 * Result<void> is absl::Status. Cancellation is absl::StatusCode::kCancelled.
20 * Exceptions thrown by user callbacks are converted to absl::StatusCode::kUnknown.
21 */
23 template <typename V>
24 using Result = std::conditional_t<std::is_void_v<V>, absl::Status, absl::StatusOr<V>>;
25
26 using Error = absl::Status;
27
28 template <typename R>
29 using Value = std::conditional_t<std::is_same_v<R, absl::Status>, void,
31
32 static absl::Status FromException(std::exception_ptr e) noexcept {
33 try {
34 std::rethrow_exception(std::move(e));
35 } catch (const yaclib::StopException&) {
36 return absl::CancelledError("yaclib::StopException");
37 } catch (const std::exception& exception) {
38 return absl::UnknownError(exception.what());
39 } catch (...) {
40 return absl::UnknownError("unknown exception");
41 }
42 }
43
44 template <typename V, typename... Args>
45 static Result<V> MakeResult(Args&&... args) {
46 static_assert(sizeof...(Args) > 0);
47 using Head = std::decay_t<yaclib::head_t<Args&&...>>;
48 if constexpr (sizeof...(Args) == 1 && std::is_same_v<Head, yaclib::Unit>) {
49 if constexpr (std::is_void_v<V>) {
50 return absl::OkStatus();
51 } else {
52 return Result<V>{std::in_place};
53 }
54 } else if constexpr (sizeof...(Args) == 1 && std::is_same_v<Head, yaclib::StopTag>) {
55 return Result<V>{absl::CancelledError("yaclib::StopTag")};
56 } else if constexpr (sizeof...(Args) == 1 && std::is_same_v<Head, std::exception_ptr>) {
57 return Result<V>{FromException(std::forward<Args>(args)...)};
58 } else if constexpr (std::is_same_v<Head, std::in_place_t> ||
59 (sizeof...(Args) == 1 &&
60 (std::is_same_v<Head, absl::Status> || std::is_same_v<Head, Result<V>>))) {
61 if constexpr (std::is_void_v<V> && std::is_same_v<Head, std::in_place_t>) {
62 return absl::OkStatus();
63 } else {
64 return Result<V>{std::forward<Args>(args)...};
65 }
66 } else {
67 return Result<V>{std::in_place, std::forward<Args>(args)...};
68 }
69 }
70
71 // Two deducible overloads: Result<V> is a conditional_t alias, so V would be non-deduced
72 static bool Ok(const absl::Status& r) noexcept {
73 return r.ok();
74 }
75 template <typename U>
76 static bool Ok(const absl::StatusOr<U>& r) noexcept {
77 return r.ok();
78 }
79
80 template <typename R>
81 static decltype(auto) GetValue(R&& r) noexcept {
82 if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<R>>, absl::Status>) {
83 return yaclib::Unit{};
84 } else {
85 return *std::forward<R>(r);
86 }
87 }
88
89 template <typename R>
90 static decltype(auto) GetError(R&& r) noexcept {
91 if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<R>>, absl::Status>) {
92 return std::forward<R>(r);
93 } else {
94 return std::forward<R>(r).status();
95 }
96 }
97
98 template <typename R>
99 static decltype(auto) Get(R&& r) {
100 if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<R>>, absl::Status>) {
101 if (!r.ok()) {
102 throw absl::BadStatusOrAccess{std::forward<R>(r)};
103 }
104 } else {
105 return std::forward<R>(r).value();
106 }
107 }
108
109 static bool IsStop(const absl::Status& error) noexcept {
110 return error.code() == absl::StatusCode::kCancelled;
111 }
112};
113
114} // namespace yaclib_ext
Contract< V, T > MakeContract()
Creates related future and promise.
Definition contract.hpp:25
typename detail::Head< Args... >::Type head_t
Exception that represents cancellation of an async operation,.
Definition result.hpp:27
Result trait that plugs absl::StatusOr<V> into yaclib,.
Definition status_or.hpp:22
static bool IsStop(const absl::Status &error) noexcept
static decltype(auto) Get(R &&r)
Definition status_or.hpp:99
static Result< V > MakeResult(Args &&... args)
Definition status_or.hpp:45
std::conditional_t< std::is_same_v< R, absl::Status >, void, typename yaclib::detail::InstantiationType< absl::StatusOr, R >::Value > Value
Definition status_or.hpp:30
static decltype(auto) GetValue(R &&r) noexcept
Definition status_or.hpp:81
static decltype(auto) GetError(R &&r) noexcept
Definition status_or.hpp:90
static bool Ok(const absl::StatusOr< U > &r) noexcept
Definition status_or.hpp:76
static bool Ok(const absl::Status &r) noexcept
Definition status_or.hpp:72
std::conditional_t< std::is_void_v< V >, absl::Status, absl::StatusOr< V > > Result
Definition status_or.hpp:24
static absl::Status FromException(std::exception_ptr e) noexcept
Definition status_or.hpp:32