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/event.h"
|
||||||
#include "sled/synchronization/mutex.h"
|
#include "sled/synchronization/mutex.h"
|
||||||
#include "sled/task_queue/task_queue_base.h"
|
#include "sled/task_queue/task_queue_base.h"
|
||||||
#include "sled/variant.h"
|
#include "sled/utility/forward_on_copy.h"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <future>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
namespace sled {
|
namespace sled {
|
||||||
@ -48,7 +49,8 @@ struct FutureData {
|
|||||||
~FutureData() { DecrementFuturesUsage(); }
|
~FutureData() { DecrementFuturesUsage(); }
|
||||||
|
|
||||||
std::atomic_int state{kNotCompletedFuture};
|
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 T &)>> success_callbacks;
|
||||||
std::list<std::function<void(const FailureT &)>> failure_callbacks;
|
std::list<std::function<void(const FailureT &)>> failure_callbacks;
|
||||||
sled::Mutex mutex_;
|
sled::Mutex mutex_;
|
||||||
@ -130,7 +132,8 @@ public:
|
|||||||
if (!IsCompleted()) Wait();
|
if (!IsCompleted()) Wait();
|
||||||
if (IsSucceeded()) {
|
if (IsSucceeded()) {
|
||||||
try {
|
try {
|
||||||
return sled::get<T>(data_->value);
|
// return sled::get<T>(data_->value);
|
||||||
|
return sled::any_cast<T>(data_->value);
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
}
|
}
|
||||||
return T();
|
return T();
|
||||||
@ -140,7 +143,8 @@ public:
|
|||||||
{
|
{
|
||||||
SLED_ASSERT(data_ != nullptr, "Future is not valid");
|
SLED_ASSERT(data_ != nullptr, "Future is not valid");
|
||||||
if (!IsCompleted()) { Wait(); }
|
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
|
FailureT FailureReason() const
|
||||||
@ -149,7 +153,8 @@ public:
|
|||||||
if (!IsCompleted()) { Wait(); }
|
if (!IsCompleted()) { Wait(); }
|
||||||
if (IsFailed()) {
|
if (IsFailed()) {
|
||||||
try {
|
try {
|
||||||
return sled::get<FailureT>(data_->value);
|
// return sled::get<FailureT>(data_->value);
|
||||||
|
return sled::any_cast<FailureT>(data_->value);
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
}
|
}
|
||||||
return FailureT();
|
return FailureT();
|
||||||
@ -176,7 +181,8 @@ public:
|
|||||||
}
|
}
|
||||||
if (call_it) {
|
if (call_it) {
|
||||||
try {
|
try {
|
||||||
f(sled::get<T>(data_->value));
|
// f(sled::get<T>(data_->value));
|
||||||
|
f(sled::any_cast<T>(data_->value));
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
}
|
}
|
||||||
return Future<T, FailureT>(data_);
|
return Future<T, FailureT>(data_);
|
||||||
@ -203,7 +209,8 @@ public:
|
|||||||
}
|
}
|
||||||
if (call_it) {
|
if (call_it) {
|
||||||
try {
|
try {
|
||||||
f(sled::get<FailureT>(data_->value));
|
// f(sled::get<FailureT>(data_->value));
|
||||||
|
f(sled::any_cast<FailureT>(data_->value));
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
}
|
}
|
||||||
return Future<T, FailureT>(data_);
|
return Future<T, FailureT>(data_);
|
||||||
@ -294,6 +301,20 @@ public:
|
|||||||
return result;
|
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
|
Future<T, FailureT> Via(TaskQueueBase *task_queue) const noexcept
|
||||||
{
|
{
|
||||||
SLED_ASSERT(task_queue != nullptr, "TaskQueue is not valid");
|
SLED_ASSERT(task_queue != nullptr, "TaskQueue is not valid");
|
||||||
@ -365,6 +386,7 @@ private:
|
|||||||
if (IsCompleted()) { return; }
|
if (IsCompleted()) { return; }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// data_->value.template emplace<T>(std::move(value));
|
||||||
// data_->value.template emplace<T>(std::move(value));
|
// data_->value.template emplace<T>(std::move(value));
|
||||||
data_->value = std::move(value);
|
data_->value = std::move(value);
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
@ -376,7 +398,8 @@ private:
|
|||||||
|
|
||||||
for (const auto &f : callbacks) {
|
for (const auto &f : callbacks) {
|
||||||
try {
|
try {
|
||||||
f(sled::get<T>(data_->value));
|
// f(sled::get<T>(data_->value));
|
||||||
|
f(sled::any_cast<T>(data_->value));
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,6 +419,7 @@ private:
|
|||||||
if (IsCompleted()) { return; }
|
if (IsCompleted()) { return; }
|
||||||
try {
|
try {
|
||||||
// data_->value.template emplace<FailureT>(std::move(reason));
|
// data_->value.template emplace<FailureT>(std::move(reason));
|
||||||
|
// data_->value = std::move(reason);
|
||||||
data_->value = std::move(reason);
|
data_->value = std::move(reason);
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
data_->state.store(detail::kFailedFuture, std::memory_order_release);
|
data_->state.store(detail::kFailedFuture, std::memory_order_release);
|
||||||
@ -406,7 +430,8 @@ private:
|
|||||||
|
|
||||||
for (const auto &f : callbacks) {
|
for (const auto &f : callbacks) {
|
||||||
try {
|
try {
|
||||||
f(sled::get<FailureT>(data_->value));
|
// f(sled::get<FailureT>(data_->value));
|
||||||
|
f(sled::any_cast<FailureT>(data_->value));
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
#include <sled/futures/future.h>
|
#include <sled/futures/future.h>
|
||||||
#include <sled/system/thread.h>
|
#include <sled/system/thread.h>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
TEST_SUITE("future")
|
TEST_SUITE("future")
|
||||||
{
|
{
|
||||||
TEST_CASE("base success")
|
TEST_CASE("base success")
|
||||||
|
|
||||||
{
|
{
|
||||||
sled::Promise<int, std::string> p;
|
sled::Promise<int, std::string> p;
|
||||||
auto f = p.GetFuture();
|
auto f = p.GetFuture();
|
||||||
@ -12,6 +14,7 @@ TEST_SUITE("future")
|
|||||||
CHECK(f.IsValid());
|
CHECK(f.IsValid());
|
||||||
CHECK_EQ(f.Result(), 42);
|
CHECK_EQ(f.Result(), 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("base failed")
|
TEST_CASE("base failed")
|
||||||
{
|
{
|
||||||
sled::Promise<int, std::string> p;
|
sled::Promise<int, std::string> p;
|
||||||
@ -23,31 +26,65 @@ TEST_SUITE("future")
|
|||||||
CHECK(f.IsValid());
|
CHECK(f.IsValid());
|
||||||
CHECK_EQ(f.FailureReason(), "error");
|
CHECK_EQ(f.FailureReason(), "error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
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("thread success") {}
|
||||||
|
|
||||||
TEST_CASE("map")
|
TEST_CASE("Map")
|
||||||
{
|
{
|
||||||
sled::Promise<int, std::string> p;
|
sled::Promise<int, std::string> p;
|
||||||
auto f = p.GetFuture();
|
auto f = p.GetFuture();
|
||||||
auto f2 = f.Map([](int i) { return i + 1; });
|
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);
|
p.Success(42);
|
||||||
CHECK(f2.Wait(-1));
|
CHECK(f2.Wait(-1));
|
||||||
CHECK_EQ(f2.Result(), 43);
|
CHECK_EQ(f2.Result(), 4300);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("FlatMap")
|
TEST_CASE("FlatMap")
|
||||||
{
|
{
|
||||||
// sled::Promise<int, std::string> p;
|
sled::Promise<int, std::string> p;
|
||||||
// auto f = p.GetFuture().FlatMap([](int i) {
|
auto f = p.GetFuture().FlatMap([](int i) {
|
||||||
// auto str = std::to_string(i);
|
auto str = std::to_string(i);
|
||||||
// sled::Promise<std::string, std::string> p;
|
sled::Promise<std::string, std::string> p;
|
||||||
// p.Success(str);
|
p.Success(str);
|
||||||
//
|
|
||||||
// return p.GetFuture();
|
return p.GetFuture();
|
||||||
// });
|
});
|
||||||
// p.Success(42);
|
p.Success(42);
|
||||||
// CHECK(f.Wait(-1));
|
CHECK(f.IsCompleted());
|
||||||
// CHECK_EQ(f.Result(), "42");
|
CHECK_EQ(f.Result(), "42");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Via")
|
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