mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
Improve cti::split and make it workable with plain callbacks
This commit is contained in:
parent
daa2fdd686
commit
bc4d69735c
@ -36,10 +36,27 @@
|
|||||||
#include <continuable/continuable-base.hpp>
|
#include <continuable/continuable-base.hpp>
|
||||||
#include <continuable/continuable-traverse.hpp>
|
#include <continuable/continuable-traverse.hpp>
|
||||||
#include <continuable/continuable-types.hpp>
|
#include <continuable/continuable-types.hpp>
|
||||||
|
#include <continuable/detail/utility/traits.hpp>
|
||||||
|
|
||||||
namespace cti {
|
namespace cti {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
namespace operations {
|
namespace operations {
|
||||||
|
template <typename T, bool Else, typename = void>
|
||||||
|
struct operator_bool_or {
|
||||||
|
template <typename O>
|
||||||
|
static bool get(O&& /*obj*/) noexcept {
|
||||||
|
return Else;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <typename T, bool Else>
|
||||||
|
struct operator_bool_or<T, Else,
|
||||||
|
traits::void_t<decltype(bool(std::declval<T&>()))>> {
|
||||||
|
template <typename O>
|
||||||
|
static bool get(O&& obj) noexcept {
|
||||||
|
return bool(obj);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename First, typename... Promises>
|
template <typename First, typename... Promises>
|
||||||
class split_promise {
|
class split_promise {
|
||||||
First first_;
|
First first_;
|
||||||
@ -51,34 +68,22 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void operator()(Args... args) && {
|
void operator()(Args&&... args) && {
|
||||||
traverse_pack(
|
traverse_pack(
|
||||||
[&](auto&& promise) mutable -> void {
|
[&](auto&& promise) mutable -> void {
|
||||||
if (promise) {
|
using accessor =
|
||||||
|
operator_bool_or<traits::unrefcv_t<decltype(promise)>, true>;
|
||||||
|
if (accessor::get(promise)) {
|
||||||
std::forward<decltype(promise)>(promise)(args...);
|
std::forward<decltype(promise)>(promise)(args...);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
std::move(promises_));
|
std::move(promises_));
|
||||||
|
|
||||||
if (first_) {
|
if (operator_bool_or<First, true>::get(first_)) {
|
||||||
std::move(first_)(std::forward<Args>(args)...);
|
std::move(first_)(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(exception_arg_t tag, exception_t exception) && {
|
|
||||||
traverse_pack(
|
|
||||||
[&](auto&& promise) mutable -> void {
|
|
||||||
if (promise) {
|
|
||||||
std::forward<decltype(promise)>(promise)(tag, exception);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
std::move(promises_));
|
|
||||||
|
|
||||||
if (first_) {
|
|
||||||
std::move(first_)(tag, std::move(exception));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void set_value(Args... args) {
|
void set_value(Args... args) {
|
||||||
std::move (*this)(std::move(args)...);
|
std::move (*this)(std::move(args)...);
|
||||||
@ -89,10 +94,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
explicit operator bool() const noexcept {
|
explicit operator bool() const noexcept {
|
||||||
bool is_valid = bool(first_);
|
bool is_valid = operator_bool_or<First, true>::get(first_);
|
||||||
traverse_pack(
|
traverse_pack(
|
||||||
[&](auto&& promise) mutable -> void {
|
[&](auto&& promise) mutable -> void {
|
||||||
if (!is_valid && bool(promise)) {
|
using accessor =
|
||||||
|
operator_bool_or<traits::unrefcv_t<decltype(promise)>, true>;
|
||||||
|
if (!is_valid && accessor::get(promise)) {
|
||||||
is_valid = true;
|
is_valid = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -46,3 +46,17 @@ TYPED_TEST(single_dimension_tests, operations_split) {
|
|||||||
all.set_value();
|
all.set_value();
|
||||||
ASSERT_TRUE(resolved);
|
ASSERT_TRUE(resolved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(single_dimension_tests, operations_split_plain_callback) {
|
||||||
|
promise<> all;
|
||||||
|
bool resolved = false;
|
||||||
|
|
||||||
|
all = split(std::move(all), [&](auto&&...) {
|
||||||
|
EXPECT_FALSE(resolved);
|
||||||
|
resolved = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_FALSE(resolved);
|
||||||
|
all.set_value();
|
||||||
|
ASSERT_TRUE(resolved);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user