Index: components/scheduler/promises/rejectable.h |
diff --git a/components/scheduler/promises/rejectable.h b/components/scheduler/promises/rejectable.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..24bfbaf67a106da86576a67a431789c7d136b977 |
--- /dev/null |
+++ b/components/scheduler/promises/rejectable.h |
@@ -0,0 +1,230 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef COMPONENTS_SCHEDULER_PROMISES_REJECTABLE_H_ |
+#define COMPONENTS_SCHEDULER_PROMISES_REJECTABLE_H_ |
+ |
+#include "components/scheduler/scheduler_export.h" |
+#include "components/scheduler/promises/template_helpers.h" |
+ |
+namespace promise { |
+namespace internal { |
+template <typename ResolveT> |
+class Resolve { |
+ public: |
+ explicit Resolve(const ResolveT& resolved) : resolved_(resolved) {} |
+ explicit Resolve(ResolveT&& resolved) : resolved_(std::move(resolved)) {} |
+ |
+ ResolveT resolved() const { return resolved_; } |
+ |
+ private: |
+ ResolveT resolved_; |
+}; |
+ |
+template <> |
+class Resolve<void> { |
+ public: |
+ Resolve() {} |
+}; |
+ |
+template <typename RejectT> |
+class Reject { |
+ public: |
+ explicit Reject(const RejectT& reject_reason) |
+ : reject_reason_(reject_reason) {} |
+ |
+ explicit Reject(RejectT&& reject_reason) |
+ : reject_reason_(std::move(reject_reason)) {} |
+ |
+ RejectT reject_reason() const { return reject_reason_; } |
+ |
+ private: |
+ RejectT reject_reason_; |
+}; |
+ |
+template <> |
+class Reject<void> { |
+ public: |
+ Reject() {} |
+}; |
+ |
+} // namespace internal |
+ |
+// Syntatic sugar for Reject() and Resolve() |
+template <typename ResolveT> |
+internal::Resolve<ResolveT> Resolve(ResolveT resolved) { |
+ return internal::Resolve<ResolveT>(std::move(resolved)); |
+} |
+ |
+inline internal::Resolve<void> Resolve() { |
+ return internal::Resolve<void>(); |
+} |
+ |
+template <typename RejectT> |
+internal::Reject<RejectT> Reject(RejectT reject_reason) { |
+ return internal::Reject<RejectT>(std::move(reject_reason)); |
+} |
+ |
+inline internal::Reject<void> Reject() { |
+ return internal::Reject<void>(); |
+} |
+ |
+class BaseRejectable { |
+ public: |
+ enum class State { UNRESOLVED, RESOLVED, REJECTED }; |
+ |
+ explicit BaseRejectable(State state) : state_(state) {} |
+ |
+ bool is_rejected() const { return state_ == State::REJECTED; } |
+ bool is_resolved() const { return state_ == State::RESOLVED; } |
+ bool is_unresolved() const { return state_ == State::UNRESOLVED; } |
+ |
+ protected: |
+ State state_; |
+}; |
+ |
+template <typename ResolveT, typename RejectT> |
+class Rejectable : public BaseRejectable { |
+ public: |
+ Rejectable() : BaseRejectable(State::UNRESOLVED) {} |
+ |
+ Rejectable(const internal::Resolve<ResolveT>& resolved) |
+ : BaseRejectable(State::RESOLVED), |
+ resolved_(std::move(resolved.resolved())) {} |
+ |
+ Rejectable(const internal::Reject<RejectT>& resolved) |
+ : BaseRejectable(State::REJECTED), |
+ reject_reason_(std::move(resolved.reject_reason())) {} |
+ |
+ ResolveT& resolved() { |
+ DCHECK(is_resolved()); |
+ return resolved_; |
+ } |
+ |
+ RejectT& reject_reason() { |
+ DCHECK(is_rejected()); |
+ return reject_reason_; |
+ } |
+ |
+ void Resolve(const ResolveT& resolved) { |
+ resolved_ = resolved; |
+ BaseRejectable::state_ = BaseRejectable::State::RESOLVED; |
+ } |
+ |
+ void Resolve(ResolveT&& resolved) { |
+ resolved_ = std::move(resolved); |
+ BaseRejectable::state_ = BaseRejectable::State::RESOLVED; |
+ } |
+ |
+ void Reject(const RejectT& reject_reason) { |
+ reject_reason_ = reject_reason; |
+ BaseRejectable::state_ = BaseRejectable::State::REJECTED; |
+ } |
+ |
+ void Reject(RejectT&& reject_reason) { |
+ reject_reason_ = std::move(reject_reason); |
+ BaseRejectable::state_ = BaseRejectable::State::REJECTED; |
+ } |
+ |
+ private: |
+ ResolveT resolved_; |
+ RejectT reject_reason_; |
+}; |
+ |
+template <typename ResolveT> |
+class Rejectable<ResolveT, void> : public BaseRejectable { |
+ public: |
+ Rejectable() : BaseRejectable(State::UNRESOLVED) {} |
+ |
+ Rejectable(const internal::Resolve<ResolveT>& resolved) |
+ : BaseRejectable(State::RESOLVED), |
+ resolved_(std::move(resolved.resolved())) {} |
+ |
+ Rejectable(const internal::Reject<void>& resolved) |
+ : BaseRejectable(State::REJECTED) {} |
+ |
+ ResolveT& resolved() { |
+ DCHECK(is_resolved()); |
+ return resolved_; |
+ } |
+ |
+ void Resolve(const ResolveT& resolved) { |
+ resolved_ = resolved; |
+ BaseRejectable::state_ = BaseRejectable::State::RESOLVED; |
+ } |
+ |
+ void Resolve(ResolveT&& resolved) { |
+ resolved_ = std::move(resolved); |
+ BaseRejectable::state_ = BaseRejectable::State::RESOLVED; |
+ } |
+ |
+ void Reject() { BaseRejectable::state_ = BaseRejectable::State::REJECTED; } |
+ |
+ private: |
+ ResolveT resolved_; |
+ bool is_rejected_; |
+}; |
+ |
+template <typename RejectT> |
+class Rejectable<void, RejectT> : public BaseRejectable { |
+ public: |
+ Rejectable() : BaseRejectable(State::UNRESOLVED) {} |
+ |
+ Rejectable(const internal::Resolve<void>& resolved) |
+ : BaseRejectable(State::RESOLVED) {} |
+ |
+ Rejectable(const internal::Reject<RejectT>& resolved) |
+ : BaseRejectable(State::REJECTED), |
+ reject_reason_(std::move(resolved.reject_reason())) {} |
+ |
+ RejectT& reject_reason() { |
+ DCHECK(is_rejected()); |
+ return reject_reason_; |
+ } |
+ |
+ void Resolve() { BaseRejectable::state_ = BaseRejectable::State::RESOLVED; } |
+ |
+ void Reject(const RejectT& reject_reason) { |
+ reject_reason_ = reject_reason; |
+ BaseRejectable::state_ = BaseRejectable::State::REJECTED; |
+ } |
+ |
+ void Reject(RejectT&& reject_reason) { |
+ reject_reason_ = std::move(reject_reason); |
+ BaseRejectable::state_ = BaseRejectable::State::REJECTED; |
+ } |
+ |
+ private: |
+ RejectT reject_reason_; |
+}; |
+ |
+template <> |
+class Rejectable<void, void> : public BaseRejectable { |
+ public: |
+ Rejectable() : BaseRejectable(State::UNRESOLVED) {} |
+ |
+ Rejectable(const internal::Resolve<void>& resolved) |
+ : BaseRejectable(State::RESOLVED) {} |
+ |
+ Rejectable(const internal::Reject<void>& resolved) |
+ : BaseRejectable(State::REJECTED) {} |
+ |
+ void Resolve() { BaseRejectable::state_ = BaseRejectable::State::RESOLVED; } |
+ |
+ void Reject() { BaseRejectable::state_ = BaseRejectable::State::REJECTED; } |
+}; |
+ |
+// Similar to std::enable_if but used to detect if a template parameter is a |
+// Rejectable<>. |
+template <typename R, class ResultT = void> |
+struct enable_if_rejectable {}; |
+ |
+template <typename ResolveT, typename RejectT, class ResultT> |
+struct enable_if_rejectable<Rejectable<ResolveT, RejectT>, ResultT> { |
+ typedef ResultT type; |
+}; |
+ |
+} // namespace promise |
+ |
+#endif // COMPONENTS_SCHEDULER_PROMISES_REJECTABLE_H_ |