+ ~FutureBase();
+
+ /// Returns a reference to the result, with a reference category and const-
+ /// qualification equivalent to the reference category and const-qualification
+ /// of the receiver.
+ ///
+ /// If moved-from, throws NoState.
+ ///
+ /// If !isReady(), throws FutureNotReady.
+ ///
+ /// If an exception has been captured, throws that exception.
+ T& value() &;
+ T const& value() const&;
+ T&& value() &&;
+ T const&& value() const&&;
+
+ /// Returns a reference to the try of the result. Throws as for value if
+ /// future is not valid.
+ Try<T>& result() &;
+ Try<T> const& result() const&;
+ Try<T>&& result() &&;
+ Try<T> const&& result() const&&;
+
+ /** True when the result (or exception) is ready. */
+ bool isReady() const;
+
+ /// sugar for getTry().hasValue()
+ bool hasValue();
+
+ /// sugar for getTry().hasException()
+ bool hasException();
+
+ /// If the promise has been fulfilled, return an Optional with the Try<T>.
+ /// Otherwise return an empty Optional.
+ /// Note that this moves the Try<T> out.
+ Optional<Try<T>> poll();
+
+ /// This is not the method you're looking for.
+ ///
+ /// This needs to be public because it's used by make* and when*, and it's
+ /// not worth listing all those and their fancy template signatures as
+ /// friends. But it's not for public consumption.
+ template <class F>
+ void setCallback_(F&& func);
+
+ bool isActive() {
+ return core_->isActive();
+ }
+
+ template <class E>
+ void raise(E&& exception) {
+ raise(make_exception_wrapper<typename std::remove_reference<E>::type>(
+ std::forward<E>(exception)));
+ }
+
+ /// Raise an interrupt. If the promise holder has an interrupt
+ /// handler it will be called and potentially stop asynchronous work from
+ /// being done. This is advisory only - a promise holder may not set an
+ /// interrupt handler, or may do anything including ignore. But, if you know
+ /// your future supports this the most likely result is stopping or
+ /// preventing the asynchronous operation (if in time), and the promise
+ /// holder setting an exception on the future. (That may happen
+ /// asynchronously, of course.)
+ void raise(exception_wrapper interrupt);
+
+ void cancel() {
+ raise(FutureCancellation());
+ }
+
+ protected:
+ friend class Promise<T>;
+ template <class>
+ friend class SemiFuture;
+ template <class>
+ friend class Future;
+
+ using corePtr = futures::detail::Core<T>*;
+
+ // shared core state object
+ corePtr core_;
+
+ explicit FutureBase(corePtr obj) : core_(obj) {}
+
+ explicit FutureBase(futures::detail::EmptyConstruct) noexcept;
+
+ void detach();
+
+ void throwIfInvalid() const;
+
+ template <class FutureType>
+ void assign(FutureType&) noexcept;
+
+ Executor* getExecutor() {
+ return core_->getExecutor();
+ }
+
+ void setExecutor(Executor* x, int8_t priority = Executor::MID_PRI) {
+ core_->setExecutor(x, priority);
+ }
+
+ // Variant: returns a value
+ // e.g. f.then([](Try<T> t){ return t.value(); });
+ template <typename F, typename R, bool isTry, typename... Args>
+ typename std::enable_if<!R::ReturnsFuture::value, typename R::Return>::type
+ thenImplementation(F&& func, futures::detail::argResult<isTry, F, Args...>);
+
+ // Variant: returns a Future
+ // e.g. f.then([](Try<T> t){ return makeFuture<T>(t); });
+ template <typename F, typename R, bool isTry, typename... Args>
+ typename std::enable_if<R::ReturnsFuture::value, typename R::Return>::type
+ thenImplementation(F&& func, futures::detail::argResult<isTry, F, Args...>);
+};
+} // namespace detail
+} // namespace futures
+
+template <class T>
+class SemiFuture : private futures::detail::FutureBase<T> {
+ private:
+ using Base = futures::detail::FutureBase<T>;
+ using DeferredExecutor = futures::detail::DeferredExecutor;
+
+ public:
+ static SemiFuture<T> makeEmpty(); // equivalent to moved-from
+
+ // Export public interface of FutureBase
+ // FutureBase is inherited privately to avoid subclasses being cast to
+ // a FutureBase pointer
+ using typename Base::value_type;