YACLib
C++ library for concurrent tasks execution
Loading...
Searching...
No Matches
result_core.hpp
Go to the documentation of this file.
1#pragma once
2
6
7#include <utility>
8
9namespace yaclib::detail {
10
11struct Callback {
12 IRef* caller = nullptr;
13 char unwrapping = 0;
14};
15
16template <typename V, typename E>
17class ResultCore : public BaseCore {
18 public:
19 using Value = V;
20 using Error = E;
21
24
25 template <typename... Args>
26 explicit ResultCore(Args&&... args) noexcept(std::is_nothrow_constructible_v<Result<V, E>, Args&&...>)
27 : BaseCore{kResult}, _result{std::forward<Args>(args)...} {
28 }
29
30 ~ResultCore() noexcept override {
31 YACLIB_ASSERT(_callback.load(std::memory_order_relaxed) == kResult);
32 _result.~Result<V, E>();
33 }
34
35 template <typename... Args>
36 void Store(Args&&... args) noexcept(std::is_nothrow_constructible_v<Result<V, E>, Args&&...>) {
37 new (&_result) Result<V, E>{std::forward<Args>(args)...};
38 }
39
41 return _result;
42 }
43
44 template <bool Condition>
45 decltype(auto) MoveOrConst() {
46 if constexpr (Condition) {
47 return std::move(Get());
48 } else {
49 return std::as_const(Get());
50 }
51 }
52
53 union {
56 };
57
58 protected:
59 template <bool SymmetricTransfer, bool Shared>
60 [[nodiscard]] YACLIB_INLINE auto Impl(InlineCore& caller) noexcept {
61 if constexpr (std::is_copy_constructible_v<Result<V, E>>) {
62 // Copy values can come from both Unique and Shared cores
63 const auto ref = caller.GetRef();
64 if (ref >= 3) {
65 // This is a Shared core and Shared futures exist and/or not
66 // the last callback in the list, the value may not be moved
68 return BaseCore::SetResultImpl<SymmetricTransfer, Shared>();
69 }
70 // ref == 1: This is a Unique core, move the value and destroy the core
71 // ref == 2: This is a Shared core, no more SharedFutures exist and the
72 // last callback in the list, move the value but do not destroy the core
74 if (ref == 1) {
75 caller.DecRef();
76 }
77 return BaseCore::SetResultImpl<SymmetricTransfer, Shared>();
78 } else if constexpr (std::is_move_constructible_v<Result<V, E>>) {
79 // Move-only values are from Unique cores only
81 caller.DecRef();
82 return BaseCore::SetResultImpl<SymmetricTransfer, Shared>();
83 } else {
84 // Unreachable, cannot set callbacks on immovable cores
87 }
88 }
89};
90
91} // namespace yaclib::detail
Reference counting interface.
Definition ref.hpp:12
Encapsulated return value from caller.
Definition result.hpp:90
yaclib_std::atomic_uintptr_t _callback
Definition base_core.hpp:68
~ResultCore() noexcept override
ResultCore(Args &&... args) noexcept(std::is_nothrow_constructible_v< Result< V, E >, Args &&... >)
Result< V, E > & Get() noexcept
decltype(auto) MoveOrConst()
YACLIB_INLINE auto Impl(InlineCore &caller) noexcept
void Store(Args &&... args) noexcept(std::is_nothrow_constructible_v< Result< V, E >, Args &&... >)
#define YACLIB_ASSERT(cond)
Definition log.hpp:85
#define YACLIB_PURE_VIRTUAL()
Definition log.hpp:86
constexpr auto * DownCast(From *from) noexcept
Definition cast.hpp:26
Contract< V, E > MakeContract()
Creates related future and promise.
Definition contract.hpp:25