17#include <yaclib_std/atomic>
30template <
typename V,
typename E>
53template <
typename V,
typename E>
84 static std::pair<ResultPtr, AllCombinator*>
Make(std::size_t count) {
86 return {
nullptr,
nullptr};
97 input.CallInline(*
this);
102 if (std::is_same_v<R, V> && !_core) {
105 if constexpr (std::is_void_v<R>) {
106 _core->Store(std::in_place);
108 _core->Store(std::move(this->_results));
116 if constexpr (!std::is_void_v<R>) {
122 template <
bool SymmetricTransfer>
125 if constexpr (std::is_same_v<R, V>) {
126 if (!this->
_done.load(std::memory_order_acquire) && CombineValue(std::move(
core.Get()))) {
132 const auto ticket = this->_ticket.fetch_add(1, std::memory_order_acq_rel);
133 this->_results[
ticket].~R();
134 new (&this->_results[
ticket])
R{std::move(
core.Get())};
139 [[
nodiscard]] InlineCore* Here(InlineCore& caller)
noexcept final {
142#if YACLIB_SYMMETRIC_TRANSFER != 0
143 [[
nodiscard]] yaclib_std::coroutine_handle<>
Next(InlineCore& caller)
noexcept final {
148 bool CombineValue(Result<V, E>&&
result)
noexcept {
151 if constexpr (!std::is_void_v<V>) {
152 const auto ticket = this->_ticket.fetch_add(1, std::memory_order_acq_rel);
155 }
else if (!this->
_done.exchange(
true, std::memory_order_acq_rel)) {
175template <
typename R,
typename E>
182 static std::pair<ResultPtr, AllCombinator*>
Make(std::size_t count) {
184 return {
nullptr,
nullptr};
195 _callers.push_back(&
input);
196 input.CallInline(*
this);
201 for (
auto* caller : _callers) {
208 if (std::is_same_v<R, V> && !_core) {
212 if constexpr (std::is_void_v<R>) {
214 _core->Store(std::in_place);
217 results.reserve(_callers.size());
218 for (
auto* caller : _callers) {
219 if constexpr (std::is_same_v<R, V>) {
222 results.push_back(std::move(caller->Get()));
227 _core->Store(std::move(
results));
234 _callers.reserve(count);
238 template <
bool SymmetricTransfer>
241 if constexpr (std::is_same_v<R, V>) {
242 if (!this->
_done.load(std::memory_order_acquire) && CombineValue(std::move(
core.Get()))) {
251 [[
nodiscard]] InlineCore* Here(InlineCore& caller)
noexcept final {
254#if YACLIB_SYMMETRIC_TRANSFER != 0
255 [[
nodiscard]] yaclib_std::coroutine_handle<>
Next(InlineCore& caller)
noexcept final {
260 bool CombineValue(Result<V, E>&&
result)
noexcept {
274 std::vector<ResultCore<V, E>*> _callers;
virtual void DecRef() noexcept
Decrements reference counter.
A intrusive pointer to objects with an embedded reference count.
Encapsulated return value from caller.
AllCombinator(ResultPtr &&core, std::size_t count)
~AllCombinator() noexcept override
void AddInput(ResultCore< V, E > &input) noexcept
static std::pair< ResultPtr, AllCombinator * > Make(std::size_t count)
~AllCombinator() noexcept override
static std::pair< ResultPtr, AllCombinator * > Make(std::size_t count)
void AddInput(ResultCore< V, E > &input) noexcept
AllCombinator(ResultPtr &&core, std::size_t count) noexcept(std::is_void_v< R >)
#define YACLIB_ASSERT(cond)
YACLIB_INLINE void Loop(InlineCore *prev, InlineCore *curr) noexcept
atomic< bool > atomic_bool
atomic< std::size_t > atomic_size_t
Contract< V, E > MakeContract()
Creates related future and promise.
OrderPolicy
This Policy describe how algorithm produce result.
typename detail::InstantiationTypes< Result, T >::Value result_value_t
std::vector< Result< V, E > > FutureValue
std::vector< V > FutureValue
std::vector< unsigned char > FutureValue
std::vector< Result< V, E > > FutureValue
std::vector< V > FutureValue
yaclib_std::atomic_bool _done