feat add future

This commit is contained in:
tqcq 2024-04-16 22:33:37 +08:00
parent 440536676d
commit 5d07e41460
5 changed files with 38 additions and 39 deletions

View File

@ -2,7 +2,7 @@
#include "sled/futures/future.h"
namespace sled {
namespace detail {
namespace future_detail {
void
IncrementFuturesUsage()
{}
@ -11,5 +11,5 @@ void
DecrementFuturesUsage()
{}
}// namespace detail
}// namespace future_detail
}// namespace sled

View File

@ -12,11 +12,10 @@
#include "sled/task_queue/task_queue_base.h"
#include "sled/utility/forward_on_copy.h"
#include <atomic>
#include <future>
#include <list>
namespace sled {
namespace detail {
namespace future_detail {
template<typename F, typename... Args>
struct is_invocable : std::is_constructible<std::function<void(Args...)>,
std::reference_wrapper<typename std::remove_reference<F>::type>> {};
@ -55,7 +54,7 @@ struct FutureData {
std::list<std::function<void(const FailureT &)>> failure_callbacks;
sled::Mutex mutex_;
};
}// namespace detail
}// namespace future_detail
//
@ -66,7 +65,7 @@ class Future {
template<typename T2, typename FailureT2>
friend class Future;
friend class Promise<T, FailureT>;
friend struct detail::FutureData<T, FailureT>;
friend struct future_detail::FutureData<T, FailureT>;
public:
using Value = T;
@ -90,19 +89,19 @@ public:
{
SLED_ASSERT(data_ != nullptr, "Future is not valid");
int value = data_->state.load(std::memory_order_acquire);
return value == detail::kSuccessFuture || value == detail::kFailedFuture;
return value == future_detail::kSuccessFuture || value == future_detail::kFailedFuture;
}
bool IsFailed() const noexcept
{
SLED_ASSERT(data_ != nullptr, "Future is not valid");
return data_->state.load(std::memory_order_acquire) == detail::kFailedFuture;
return data_->state.load(std::memory_order_acquire) == future_detail::kFailedFuture;
}
bool IsSucceeded() const noexcept
{
SLED_ASSERT(data_ != nullptr, "Future is not valid");
return data_->state.load(std::memory_order_acquire) == detail::kSuccessFuture;
return data_->state.load(std::memory_order_acquire) == future_detail::kSuccessFuture;
}
bool IsValid() const noexcept { return static_cast<bool>(data_); }
@ -160,7 +159,7 @@ public:
return FailureT();
}
template<typename Func, typename = typename std::enable_if<detail::is_invocable<Func, T>::value>::type>
template<typename Func, typename = typename std::enable_if<future_detail::is_invocable<Func, T>::value>::type>
Future<T, FailureT> OnSuccess(Func &&f) const noexcept
{
SLED_ASSERT(data_ != nullptr, "Future is not valid");
@ -173,9 +172,9 @@ public:
try {
data_->success_callbacks.emplace_back(std::forward<Func>(f));
} catch (std::exception &e) {
return Future<T, FailureT>::Failed(detail::ExceptionFailure<FailureT>(e));
return Future<T, FailureT>::Failed(future_detail::ExceptionFailure<FailureT>(e));
} catch (...) {
return Future<T, FailureT>::Failed(detail::ExceptionFailure<FailureT>());
return Future<T, FailureT>::Failed(future_detail::ExceptionFailure<FailureT>());
}
}
}
@ -188,7 +187,7 @@ public:
return Future<T, FailureT>(data_);
}
template<typename Func, typename = detail::enable_if_t<detail::is_invocable<Func, FailureT>::value>>
template<typename Func, typename = future_detail::enable_if_t<future_detail::is_invocable<Func, FailureT>::value>>
Future<T, FailureT> OnFailure(Func &&f) const noexcept
{
SLED_ASSERT(data_ != nullptr, "Future is not valid");
@ -201,9 +200,9 @@ public:
try {
data_->failure_callbacks.emplace_back(std::forward<Func>(f));
} catch (std::exception &e) {
return Future<T, FailureT>::Failed(detail::ExceptionFailure<FailureT>(e));
return Future<T, FailureT>::Failed(future_detail::ExceptionFailure<FailureT>(e));
} catch (...) {
return Future<T, FailureT>::Failed(detail::ExceptionFailure<FailureT>());
return Future<T, FailureT>::Failed(future_detail::ExceptionFailure<FailureT>());
}
}
}
@ -216,7 +215,7 @@ public:
return Future<T, FailureT>(data_);
}
template<typename Func, typename = detail::enable_if_t<detail::is_invocable<Func>::value>>
template<typename Func, typename = future_detail::enable_if_t<future_detail::is_invocable<Func>::value>>
Future<T, FailureT> OnComplete(Func &&f) const noexcept
{
SLED_ASSERT(data_ != nullptr, "Future is not valid");
@ -225,7 +224,7 @@ public:
return Future<T, FailureT>(data_);
}
template<typename Func, typename = detail::enable_if_t<detail::is_invocable_r<bool, Func, T>::value>>
template<typename Func, typename = future_detail::enable_if_t<future_detail::is_invocable_r<bool, Func, T>::value>>
Future<T, FailureT>
Filter(Func &&f,
const FailureT &rejected = failure::FailureFromString<FailureT>("Result wasn't good enough")) const noexcept
@ -239,9 +238,9 @@ public:
result.FillFailure(rejected);
}
} catch (const std::exception &e) {
result.FillFailure(detail::ExceptionFailure<FailureT>(e));
result.FillFailure(future_detail::ExceptionFailure<FailureT>(e));
} catch (...) {
result.FillFailure(detail::ExceptionFailure<FailureT>());
result.FillFailure(future_detail::ExceptionFailure<FailureT>());
}
});
OnFailure([result](const FailureT &failure) noexcept { result.FillFailure(failure); });
@ -256,9 +255,9 @@ public:
try {
result.FillSuccess(f(v));
} catch (const std::exception &e) {
result.FillFailure(detail::ExceptionFailure<FailureT>(e));
result.FillFailure(future_detail::ExceptionFailure<FailureT>(e));
} catch (...) {
result.FillFailure(detail::ExceptionFailure<FailureT>());
result.FillFailure(future_detail::ExceptionFailure<FailureT>());
}
});
OnFailure([result](const FailureT &failure) mutable noexcept { result.FillFailure(failure); });
@ -274,9 +273,9 @@ public:
try {
result.FillFailure(f(failure));
} catch (const std::exception &e) {
result.FillFailure(detail::ExceptionFailure<OtherFailureT>(e));
result.FillFailure(future_detail::ExceptionFailure<OtherFailureT>(e));
} catch (...) {
result.FillFailure(detail::ExceptionFailure<OtherFailureT>());
result.FillFailure(future_detail::ExceptionFailure<OtherFailureT>());
}
});
return result;
@ -292,9 +291,9 @@ public:
f(v).OnSuccess([result](const U &v) mutable noexcept { result.FillSuccess(v); })
.OnFailure([result](const FailureT &failure) mutable noexcept { result.FillFailure(failure); });
} catch (const std::exception &e) {
result.FillFailure(detail::ExceptionFailure<FailureT>(e));
result.FillFailure(future_detail::ExceptionFailure<FailureT>(e));
} catch (...) {
result.FillFailure(detail::ExceptionFailure<FailureT>());
result.FillFailure(future_detail::ExceptionFailure<FailureT>());
}
});
OnFailure([result](const FailureT &failure) mutable noexcept { result.FillFailure(failure); });
@ -355,12 +354,12 @@ public:
}
private:
explicit Future(std::shared_ptr<detail::FutureData<T, FailureT>> other_data) { data_ = other_data; }
explicit Future(std::shared_ptr<future_detail::FutureData<T, FailureT>> other_data) { data_ = other_data; }
inline static Future<T, FailureT> Create()
{
Future<T, FailureT> result;
result.data_ = std::make_shared<detail::FutureData<T, FailureT>>();
result.data_ = std::make_shared<future_detail::FutureData<T, FailureT>>();
return result;
}
@ -373,9 +372,9 @@ private:
void FillSuccess(T &&value)
{
SLED_ASSERT(data_ != nullptr, "Future is not valid");
if (detail::HasLastFailure()) {
FailureT failure = detail::LastFailure<FailureT>();
detail::InvalidateLastFailure();
if (future_detail::HasLastFailure()) {
FailureT failure = future_detail::LastFailure<FailureT>();
future_detail::InvalidateLastFailure();
FillFailure(std::move(failure));
return;
}
@ -390,7 +389,7 @@ private:
// data_->value.template emplace<T>(std::move(value));
data_->value = std::move(value);
} catch (...) {}
data_->state.store(detail::kSuccessFuture, std::memory_order_release);
data_->state.store(future_detail::kSuccessFuture, std::memory_order_release);
callbacks = std::move(data_->success_callbacks);
data_->success_callbacks = std::list<std::function<void(const T &)>>();
data_->failure_callbacks.clear();
@ -422,7 +421,7 @@ private:
// data_->value = std::move(reason);
data_->value = std::move(reason);
} catch (...) {}
data_->state.store(detail::kFailedFuture, std::memory_order_release);
data_->state.store(future_detail::kFailedFuture, std::memory_order_release);
callbacks = std::move(data_->failure_callbacks);
data_->failure_callbacks = std::list<std::function<void(const FailureT &)>>();
data_->success_callbacks.clear();
@ -436,7 +435,7 @@ private:
}
}
std::shared_ptr<detail::FutureData<T, FailureT>> data_;
std::shared_ptr<future_detail::FutureData<T, FailureT>> data_;
};
}// namespace sled

View File

@ -1,7 +1,7 @@
#include "sled/futures/internal/failure_handling.h"
namespace sled {
namespace detail {
namespace future_detail {
static thread_local sled::any last_failure;
bool
@ -28,5 +28,5 @@ SetLastFailure(const sled::any &failure) noexcept
last_failure = failure;
}
}// namespace detail
}// namespace future_detail
}// namespace sled

View File

@ -31,7 +31,7 @@ FailureFromString<std::string>(std::string &&str)
}// namespace failure
namespace detail {
namespace future_detail {
bool HasLastFailure() noexcept;
void InvalidateLastFailure() noexcept;
const sled::any &LastFailureAny() noexcept;
@ -69,7 +69,7 @@ ExceptionFailure()
{
return failure::FailureFromString<FailureT>("Exception");
}
}// namespace detail
}// namespace future_detail
template<typename T, typename FailureT>
class Future;
@ -87,7 +87,7 @@ struct WithFuture {
template<typename T>
operator T() const noexcept
{
detail::SetLastFailure(std::move(failure_));
future_detail::SetLastFailure(std::move(failure_));
return T();
}

View File

@ -26,7 +26,7 @@
#include "sled/filesystem/temporary_file.h"
// futures
// #include "sled/futures/promise.h"
#include "sled/futures/future.h"
#include "sled/ioc/ioc.h"
// lang