18#include <yaclib_std/atomic>
34 if (!_done.load(std::memory_order_acquire) && !_done.exchange(
true, std::memory_order_acq_rel)) {
35 _core->Store(std::move(caller.Get()));
44template <
typename V,
typename E>
46 static bool DoneImpl(std::size_t
value)
noexcept {
47 return (
value & 1U) != 0;
56 : _state{2 * count},
_core{std::move(
core)} {
60 if (!DoneImpl(_state.load(std::memory_order_acquire))) {
61 auto&
result = caller.Get();
63 if (!DoneImpl(_state.exchange(1, std::memory_order_acq_rel))) {
68 }
else if (_state.fetch_sub(2, std::memory_order_acq_rel) == 2) {
79template <
typename V,
typename E>
81 static constexpr auto kDoneImpl = std::numeric_limits<std::uintptr_t>::max();
92 const auto state = _state.load(std::memory_order_relaxed);
106 auto state = _state.load(std::memory_order_acquire);
107 if (
state != kDoneImpl) {
108 auto&
result = caller.Get();
110 if (
state != 0 || !_state.compare_exchange_strong(
state,
reinterpret_cast<std::uintptr_t
>(&caller),
111 std::memory_order_acq_rel)) {
116 state = _state.exchange(kDoneImpl, std::memory_order_acq_rel);
117 if (
state != kDoneImpl) {
122 _core->Store(std::move(caller.Get()));
132template <
typename V,
typename E, FailPolicy P>
138 static auto Make(std::size_t count) {
148 input.CallInline(*
this);
152 template <
bool SymmetricTransfer>
162 [[
nodiscard]] InlineCore* Here(InlineCore& caller)
noexcept final {
165#if YACLIB_SYMMETRIC_TRANSFER != 0
166 [[
nodiscard]] yaclib_std::coroutine_handle<>
Next(InlineCore& caller)
noexcept final {
virtual void DecRef() noexcept
Decrements reference counter.
A intrusive pointer to objects with an embedded reference count.
bool Combine(ResultCore< V, E > &caller) noexcept
~AnyCombinatorBase() noexcept
ResultCorePtr< V, E > _core
AnyCombinatorBase(std::size_t, ResultCorePtr< V, E > &&core)
AnyCombinatorBase(std::size_t count, ResultCorePtr< V, E > &&core) noexcept
ResultCorePtr< V, E > _core
bool Combine(ResultCore< V, E > &caller) noexcept
bool Combine(ResultCore< V, E > &caller) noexcept
AnyCombinatorBase(std::size_t, ResultCorePtr< V, E > &&core) noexcept
ResultCorePtr< V, E > _core
void AddInput(ResultCore< V, E > &input) noexcept
static auto Make(std::size_t count)
void Store(Args &&... args) noexcept(std::is_nothrow_constructible_v< Result< V, E >, Args &&... >)
#define YACLIB_ASSERT(cond)
YACLIB_INLINE void Loop(InlineCore *prev, InlineCore *curr) noexcept
atomic< bool > atomic_bool
atomic< std::size_t > atomic_size_t
atomic< std::uintptr_t > atomic_uintptr_t
FailPolicy
This Policy describe how algorithm interpret if Future will be fulfilled by fail (exception or error)
constexpr auto * DownCast(From *from) noexcept
Contract< V, E > MakeContract()
Creates related future and promise.