Loading src/sled/futures/future.cc +2 −2 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ #include "sled/futures/future.h" namespace sled { namespace detail { namespace future_detail { void IncrementFuturesUsage() {} Loading @@ -11,5 +11,5 @@ void DecrementFuturesUsage() {} }// namespace detail }// namespace future_detail }// namespace sled src/sled/futures/future.h +30 −31 Original line number Diff line number Diff line Loading @@ -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>> {}; Loading Loading @@ -55,7 +54,7 @@ struct FutureData { std::list<std::function<void(const FailureT &)>> failure_callbacks; sled::Mutex mutex_; }; }// namespace detail }// namespace future_detail // Loading @@ -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; Loading @@ -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_); } Loading Loading @@ -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"); Loading @@ -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>()); } } } Loading @@ -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"); Loading @@ -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>()); } } } Loading @@ -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"); Loading @@ -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 Loading @@ -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); }); Loading @@ -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); }); Loading @@ -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; Loading @@ -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); }); Loading Loading @@ -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; } Loading @@ -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; } Loading @@ -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(); Loading Loading @@ -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(); Loading @@ -436,7 +435,7 @@ private: } } std::shared_ptr<detail::FutureData<T, FailureT>> data_; std::shared_ptr<future_detail::FutureData<T, FailureT>> data_; }; }// namespace sled Loading src/sled/futures/internal/failure_handling.cc +2 −2 Original line number Diff line number Diff line #include "sled/futures/internal/failure_handling.h" namespace sled { namespace detail { namespace future_detail { static thread_local sled::any last_failure; bool Loading @@ -28,5 +28,5 @@ SetLastFailure(const sled::any &failure) noexcept last_failure = failure; } }// namespace detail }// namespace future_detail }// namespace sled src/sled/futures/internal/failure_handling.h +3 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -69,7 +69,7 @@ ExceptionFailure() { return failure::FailureFromString<FailureT>("Exception"); } }// namespace detail }// namespace future_detail template<typename T, typename FailureT> class Future; Loading @@ -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(); } Loading src/sled/sled.h +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
src/sled/futures/future.cc +2 −2 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ #include "sled/futures/future.h" namespace sled { namespace detail { namespace future_detail { void IncrementFuturesUsage() {} Loading @@ -11,5 +11,5 @@ void DecrementFuturesUsage() {} }// namespace detail }// namespace future_detail }// namespace sled
src/sled/futures/future.h +30 −31 Original line number Diff line number Diff line Loading @@ -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>> {}; Loading Loading @@ -55,7 +54,7 @@ struct FutureData { std::list<std::function<void(const FailureT &)>> failure_callbacks; sled::Mutex mutex_; }; }// namespace detail }// namespace future_detail // Loading @@ -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; Loading @@ -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_); } Loading Loading @@ -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"); Loading @@ -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>()); } } } Loading @@ -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"); Loading @@ -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>()); } } } Loading @@ -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"); Loading @@ -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 Loading @@ -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); }); Loading @@ -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); }); Loading @@ -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; Loading @@ -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); }); Loading Loading @@ -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; } Loading @@ -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; } Loading @@ -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(); Loading Loading @@ -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(); Loading @@ -436,7 +435,7 @@ private: } } std::shared_ptr<detail::FutureData<T, FailureT>> data_; std::shared_ptr<future_detail::FutureData<T, FailureT>> data_; }; }// namespace sled Loading
src/sled/futures/internal/failure_handling.cc +2 −2 Original line number Diff line number Diff line #include "sled/futures/internal/failure_handling.h" namespace sled { namespace detail { namespace future_detail { static thread_local sled::any last_failure; bool Loading @@ -28,5 +28,5 @@ SetLastFailure(const sled::any &failure) noexcept last_failure = failure; } }// namespace detail }// namespace future_detail }// namespace sled
src/sled/futures/internal/failure_handling.h +3 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -69,7 +69,7 @@ ExceptionFailure() { return failure::FailureFromString<FailureT>("Exception"); } }// namespace detail }// namespace future_detail template<typename T, typename FailureT> class Future; Loading @@ -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(); } Loading
src/sled/sled.h +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading