feat update
All checks were successful
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (push) Successful in 1m52s
linux-arm-gcc / linux-gcc-armhf (push) Successful in 2m6s
linux-x64-gcc / linux-gcc (Release) (push) Successful in 1m59s
linux-mips64-gcc / linux-gcc-mips64el (Debug) (push) Successful in 2m46s
linux-x64-gcc / linux-gcc (Debug) (push) Successful in 2m48s
linux-mips64-gcc / linux-gcc-mips64el (Release) (push) Successful in 2m51s
All checks were successful
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (push) Successful in 1m52s
linux-arm-gcc / linux-gcc-armhf (push) Successful in 2m6s
linux-x64-gcc / linux-gcc (Release) (push) Successful in 1m59s
linux-mips64-gcc / linux-gcc-mips64el (Debug) (push) Successful in 2m46s
linux-x64-gcc / linux-gcc (Debug) (push) Successful in 2m48s
linux-mips64-gcc / linux-gcc-mips64el (Release) (push) Successful in 2m51s
This commit is contained in:
parent
569d08139d
commit
440536676d
@ -10,8 +10,9 @@
|
||||
#include "sled/synchronization/event.h"
|
||||
#include "sled/synchronization/mutex.h"
|
||||
#include "sled/task_queue/task_queue_base.h"
|
||||
#include "sled/variant.h"
|
||||
#include "sled/utility/forward_on_copy.h"
|
||||
#include <atomic>
|
||||
#include <future>
|
||||
#include <list>
|
||||
|
||||
namespace sled {
|
||||
@ -48,7 +49,8 @@ struct FutureData {
|
||||
~FutureData() { DecrementFuturesUsage(); }
|
||||
|
||||
std::atomic_int state{kNotCompletedFuture};
|
||||
sled::variant<sled::monostate, T, FailureT> value;
|
||||
// sled::variant<sled::monostate, T, FailureT> value;
|
||||
sled::any value;
|
||||
std::list<std::function<void(const T &)>> success_callbacks;
|
||||
std::list<std::function<void(const FailureT &)>> failure_callbacks;
|
||||
sled::Mutex mutex_;
|
||||
@ -130,7 +132,8 @@ public:
|
||||
if (!IsCompleted()) Wait();
|
||||
if (IsSucceeded()) {
|
||||
try {
|
||||
return sled::get<T>(data_->value);
|
||||
// return sled::get<T>(data_->value);
|
||||
return sled::any_cast<T>(data_->value);
|
||||
} catch (...) {}
|
||||
}
|
||||
return T();
|
||||
@ -140,7 +143,8 @@ public:
|
||||
{
|
||||
SLED_ASSERT(data_ != nullptr, "Future is not valid");
|
||||
if (!IsCompleted()) { Wait(); }
|
||||
return sled::get<T>(data_->value);
|
||||
// return sled::get<T>(data_->value);
|
||||
return sled::any_cast<T>(data_->value);
|
||||
}
|
||||
|
||||
FailureT FailureReason() const
|
||||
@ -149,7 +153,8 @@ public:
|
||||
if (!IsCompleted()) { Wait(); }
|
||||
if (IsFailed()) {
|
||||
try {
|
||||
return sled::get<FailureT>(data_->value);
|
||||
// return sled::get<FailureT>(data_->value);
|
||||
return sled::any_cast<FailureT>(data_->value);
|
||||
} catch (...) {}
|
||||
}
|
||||
return FailureT();
|
||||
@ -176,7 +181,8 @@ public:
|
||||
}
|
||||
if (call_it) {
|
||||
try {
|
||||
f(sled::get<T>(data_->value));
|
||||
// f(sled::get<T>(data_->value));
|
||||
f(sled::any_cast<T>(data_->value));
|
||||
} catch (...) {}
|
||||
}
|
||||
return Future<T, FailureT>(data_);
|
||||
@ -203,7 +209,8 @@ public:
|
||||
}
|
||||
if (call_it) {
|
||||
try {
|
||||
f(sled::get<FailureT>(data_->value));
|
||||
// f(sled::get<FailureT>(data_->value));
|
||||
f(sled::any_cast<FailureT>(data_->value));
|
||||
} catch (...) {}
|
||||
}
|
||||
return Future<T, FailureT>(data_);
|
||||
@ -294,6 +301,20 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Func, typename U = decltype(std::declval<eggs::invoke_result_t<Func, T>().Result()>)>
|
||||
Future<U, FailureT> AndThen(Func &&f) const noexcept
|
||||
{
|
||||
return FlatMap([f](const T &) { return f(); });
|
||||
}
|
||||
|
||||
template<typename T2, typename U = typename std::decay<T2>::type>
|
||||
Future<U, FailureT> AndThenValue(T2 &&value) const noexcept
|
||||
{
|
||||
Future<U, FailureT> result = Future<U, FailureT>::Create();
|
||||
auto forward_on_copy = sled::MakeForwardOnCopy(std::forward<T2>(value));
|
||||
return Map([forward_on_copy](const T &) noexcept { return forward_on_copy.value(); });
|
||||
}
|
||||
|
||||
Future<T, FailureT> Via(TaskQueueBase *task_queue) const noexcept
|
||||
{
|
||||
SLED_ASSERT(task_queue != nullptr, "TaskQueue is not valid");
|
||||
@ -365,6 +386,7 @@ private:
|
||||
if (IsCompleted()) { return; }
|
||||
|
||||
try {
|
||||
// data_->value.template emplace<T>(std::move(value));
|
||||
// data_->value.template emplace<T>(std::move(value));
|
||||
data_->value = std::move(value);
|
||||
} catch (...) {}
|
||||
@ -376,7 +398,8 @@ private:
|
||||
|
||||
for (const auto &f : callbacks) {
|
||||
try {
|
||||
f(sled::get<T>(data_->value));
|
||||
// f(sled::get<T>(data_->value));
|
||||
f(sled::any_cast<T>(data_->value));
|
||||
} catch (...) {}
|
||||
}
|
||||
}
|
||||
@ -396,6 +419,7 @@ private:
|
||||
if (IsCompleted()) { return; }
|
||||
try {
|
||||
// data_->value.template emplace<FailureT>(std::move(reason));
|
||||
// data_->value = std::move(reason);
|
||||
data_->value = std::move(reason);
|
||||
} catch (...) {}
|
||||
data_->state.store(detail::kFailedFuture, std::memory_order_release);
|
||||
@ -406,7 +430,8 @@ private:
|
||||
|
||||
for (const auto &f : callbacks) {
|
||||
try {
|
||||
f(sled::get<FailureT>(data_->value));
|
||||
// f(sled::get<FailureT>(data_->value));
|
||||
f(sled::any_cast<FailureT>(data_->value));
|
||||
} catch (...) {}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
#include <sled/futures/future.h>
|
||||
#include <sled/system/thread.h>
|
||||
#include <type_traits>
|
||||
|
||||
TEST_SUITE("future")
|
||||
{
|
||||
TEST_CASE("base success")
|
||||
|
||||
{
|
||||
sled::Promise<int, std::string> p;
|
||||
auto f = p.GetFuture();
|
||||
@ -12,6 +14,7 @@ TEST_SUITE("future")
|
||||
CHECK(f.IsValid());
|
||||
CHECK_EQ(f.Result(), 42);
|
||||
}
|
||||
|
||||
TEST_CASE("base failed")
|
||||
{
|
||||
sled::Promise<int, std::string> p;
|
||||
@ -23,31 +26,65 @@ TEST_SUITE("future")
|
||||
CHECK(f.IsValid());
|
||||
CHECK_EQ(f.FailureReason(), "error");
|
||||
}
|
||||
TEST_CASE("thread success") {}
|
||||
|
||||
TEST_CASE("map")
|
||||
TEST_CASE("throw")
|
||||
{
|
||||
sled::Promise<int, std::string> p;
|
||||
auto f = p.GetFuture().Map([](int x) {
|
||||
throw std::runtime_error("test");
|
||||
return x;
|
||||
});
|
||||
|
||||
p.Success(42);
|
||||
REQUIRE(f.IsCompleted());
|
||||
REQUIRE(f.IsFailed());
|
||||
CHECK_EQ(f.FailureReason(), "test");
|
||||
}
|
||||
|
||||
TEST_CASE("base failed")
|
||||
{
|
||||
sled::Promise<int, std::string> p;
|
||||
auto f = p.GetFuture();
|
||||
auto f2 = f.Map([](int i) { return i + 1; });
|
||||
p.Failure("error");
|
||||
REQUIRE(p.IsFilled());
|
||||
REQUIRE(f.IsCompleted());
|
||||
CHECK(f.Wait(-1));
|
||||
CHECK(f.IsValid());
|
||||
CHECK_EQ(f.FailureReason(), "error");
|
||||
}
|
||||
|
||||
TEST_CASE("thread success") {}
|
||||
|
||||
TEST_CASE("Map")
|
||||
{
|
||||
sled::Promise<int, std::string> p;
|
||||
auto f = p.GetFuture();
|
||||
auto f2 = f.Map([](int i) { return i + 1; })
|
||||
.Map([](int i) { return std::to_string(i) + "00"; })
|
||||
.Map([](const std::string &str) {
|
||||
std::stringstream ss(str);
|
||||
int x;
|
||||
ss >> x;
|
||||
return x;
|
||||
});
|
||||
p.Success(42);
|
||||
CHECK(f2.Wait(-1));
|
||||
CHECK_EQ(f2.Result(), 43);
|
||||
CHECK_EQ(f2.Result(), 4300);
|
||||
}
|
||||
|
||||
TEST_CASE("FlatMap")
|
||||
{
|
||||
// sled::Promise<int, std::string> p;
|
||||
// auto f = p.GetFuture().FlatMap([](int i) {
|
||||
// auto str = std::to_string(i);
|
||||
// sled::Promise<std::string, std::string> p;
|
||||
// p.Success(str);
|
||||
//
|
||||
// return p.GetFuture();
|
||||
// });
|
||||
// p.Success(42);
|
||||
// CHECK(f.Wait(-1));
|
||||
// CHECK_EQ(f.Result(), "42");
|
||||
sled::Promise<int, std::string> p;
|
||||
auto f = p.GetFuture().FlatMap([](int i) {
|
||||
auto str = std::to_string(i);
|
||||
sled::Promise<std::string, std::string> p;
|
||||
p.Success(str);
|
||||
|
||||
return p.GetFuture();
|
||||
});
|
||||
p.Success(42);
|
||||
CHECK(f.IsCompleted());
|
||||
CHECK_EQ(f.Result(), "42");
|
||||
}
|
||||
|
||||
TEST_CASE("Via")
|
||||
|
76
src/sled/utility/forward_on_copy.h
Normal file
76
src/sled/utility/forward_on_copy.h
Normal file
@ -0,0 +1,76 @@
|
||||
#ifndef SLED_UTILITY_FORWARD_ON_COPY_H
|
||||
#define SLED_UTILITY_FORWARD_ON_COPY_H
|
||||
|
||||
#pragma once
|
||||
#include "sled/any.h"
|
||||
|
||||
namespace sled {
|
||||
namespace detail {
|
||||
|
||||
struct ForwardOnCopyTag {};
|
||||
|
||||
};// namespace detail
|
||||
|
||||
template<typename T>
|
||||
struct ForwardOnCopy {
|
||||
ForwardOnCopy(ForwardOnCopy &other)
|
||||
: is_moved_(other.is_moved_),
|
||||
value_(is_moved_ ? other.value_ : std::move(other.value_))
|
||||
{}
|
||||
|
||||
// ForwardOnCopy(ForwardOnCopy &&other) noexcept;
|
||||
ForwardOnCopy &operator=(ForwardOnCopy &other)
|
||||
{
|
||||
is_moved_ = other.is_moved_;
|
||||
value_ = is_moved_ ? other.value_ : std::move(other.value_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ForwardOnCopy &operator=(ForwardOnCopy &&other) noexcept;
|
||||
T value() const
|
||||
{
|
||||
if (is_moved_) {
|
||||
return std::move(sled::any_cast<T>(value_));
|
||||
} else {
|
||||
return sled::any_cast<T>(value_);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_moved_;
|
||||
sled::any value_;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
ForwardOnCopy<T>
|
||||
MakeForwardOnCopy(T value)
|
||||
{
|
||||
ForwardOnCopy<T> result;
|
||||
result.is_moved_ = false;
|
||||
result.value_ = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ForwardOnCopy<T>
|
||||
MakeForwardOnCopy(T &value)
|
||||
{
|
||||
ForwardOnCopy<T> result;
|
||||
result.is_moved_ = false;
|
||||
result.value_ = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ForwardOnCopy<T>
|
||||
MakeForwardOnCopy(T &&value)
|
||||
{
|
||||
ForwardOnCopy<T> result;
|
||||
result.is_moved_ = true;
|
||||
result.value_ = std::move(value);
|
||||
return result;
|
||||
}
|
||||
|
||||
}// namespace sled
|
||||
|
||||
#endif// SLED_UTILITY_FORWARD_ON_COPY_H
|
Loading…
Reference in New Issue
Block a user