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 T>
17class ResultCore : public BaseCore {
18 public:
19 using Value = V;
20 using Trait = T;
21 using Result = typename T::template Result<V>;
22
25
26 template <typename... Args>
27 explicit ResultCore(std::in_place_t, Args&&... args) : BaseCore{kResult} {
28 if constexpr (sizeof...(Args) == 0) {
29 Store(Unit{});
30 } else {
31 Store(std::forward<Args>(args)...);
32 }
33 }
34
35 ~ResultCore() noexcept override {
36 YACLIB_ASSERT(_callback.load(std::memory_order_relaxed) == kResult);
37 _result.~Result();
38 }
39
40 template <typename... Args>
41 void Store(Args&&... args) {
42 ::new (&_result) Result{T::template MakeResult<V>(std::forward<Args>(args)...)};
43 }
44
46 return _result;
47 }
48
49 template <bool Condition>
50 decltype(auto) MoveOrConst() {
51 if constexpr (Condition) {
52 return std::move(Get());
53 } else {
54 return std::as_const(Get());
55 }
56 }
57
58 virtual Result Retire() = 0;
59
60 union {
63 };
64
65 protected:
66 template <bool SymmetricTransfer, bool Shared>
67 [[nodiscard]] YACLIB_INLINE auto Impl(InlineCore& caller) noexcept {
68 if constexpr (std::is_copy_constructible_v<wrap_void_t<V>>) {
69 // Copy values can come from both Unique and Shared cores
70 const auto ref = caller.GetRef();
71 if (ref >= 3) {
72 // This is a Shared core and Shared futures exist and/or not
73 // the last callback in the list, the value may not be moved
75 return BaseCore::SetResultImpl<SymmetricTransfer, Shared>();
76 }
77 // ref == 1: This is a Unique core, move the value and destroy the core
78 // ref == 2: This is a Shared core, no more SharedFutures exist and the
79 // last callback in the list, move the value but do not destroy the core
81 if (ref == 1) {
82 caller.DecRef();
83 }
84 return BaseCore::SetResultImpl<SymmetricTransfer, Shared>();
85 } else if constexpr (std::is_move_constructible_v<wrap_void_t<V>>) {
86 // Move-only values are from Unique cores only
88 caller.DecRef();
89 return BaseCore::SetResultImpl<SymmetricTransfer, Shared>();
90 } else {
91 // Unreachable, cannot set callbacks on immovable cores
94 }
95 }
96};
97
98} // namespace yaclib::detail
Reference counting interface.
Definition ref.hpp:12
yaclib_std::atomic_uintptr_t _callback
Definition base_core.hpp:68
void Store(Args &&... args)
YACLIB_INLINE auto Impl(InlineCore &caller) noexcept
Result & Get() noexcept
ResultCore(std::in_place_t, Args &&... args)
typename T::template Result< V > Result
decltype(auto) MoveOrConst()
~ResultCore() noexcept override
virtual Result Retire()=0
#define YACLIB_ASSERT(cond)
Definition log.hpp:85
#define YACLIB_PURE_VIRTUAL()
Definition log.hpp:86
Contract< V, T > MakeContract()
Creates related future and promise.
Definition contract.hpp:25
constexpr auto * DownCast(From *from) noexcept
Definition cast.hpp:26