// Copyright 2018 The Fuchsia 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 LIB_FIT_PROMISE_H_
#define LIB_FIT_PROMISE_H_

#include <assert.h>

#include <tuple>
#include <type_traits>
#include <utility>

#include "function.h"
#include "promise_internal.h"
#include "result.h"
#include "variant.h"

namespace fit {

// A |fit::promise| is a building block for asynchronous control flow that
// wraps an asynchronous task in the form of a "continuation" that is
// repeatedly invoked by an executor until it produces a result.
//
// Additional asynchronous tasks can be chained onto the promise using
// a variety of combinators such as |then()|.
//
// Use |fit::make_promise()| to create a promise.
// Use |fit::future| to more conveniently hold a promise or its result.
// Use |fit::pending_task| to wrap a promise as a pending task for execution.
// Use |fit::executor| to execute a pending task.
// See examples below.
//
// Always look to the future; never look back.
//
// SYNOPSIS
//
// |V| is the type of value produced when the completes successfully.
// Defaults to |void|.
//
// |E| is the type of error produced when the completes with an error.
// Defaults to |void|.
//
// Class members are documented in |fit::promise_impl|.
//
// CHAINING PROMISES USING COMBINATORS
//
// Promises can be chained together using combinators such as |then()|
// which consume the original promise(s) and return a new combined promise.
//
// For example, the |then()| combinator returns a promise that has the effect
// of asynchronously awaiting completion of the prior promise (the instance
// upon which |then()| was called) then delivering its result to a handler
// function.
//
// Available combinators defined in this library:
//
//    |then()|: run a handler when prior promise completes
//    |and_then()|: run a handler when prior promise completes successfully
//    |or_else()|: run a handler when prior promise completes with an error
//    |inspect()|: examine result of prior promise
//    |discard_result()|: discard result and unconditionally return
//                        fit::result<> when prior promise completes
//    |wrap_with()|: applies a wrapper to the promise
//    |box()|: wraps the promise's continuation into a |fit::function|
//    |fit::join_promises()|: await multiple promises, once they all complete
//                            return a tuple of their results
//
// You can also create your own custom combinators by crafting new
// types of continuations.
//
// CONTINUATIONS AND HANDLERS
//
// Internally, |fit::promise| wraps a continuation (a kind of callable
// object) that holds the state of the asynchronous task and provides a
// means for making progress through repeated invocation.
//
// A promise's continuation is generated through the use of factories
// such as |make_promise()| and combinators such as |then()|.  Most of
// these functions accept a client-supplied "handler" (another kind
// of callable object, often a lambda expression) which performs the actual
// computations.
//
// Continuations have a very regular interface: they always accept a
// |fit::context&| argument and return a |fit::result|.  Conversely, handlers
// have a very flexible interface: clients can provide them in many forms
// all of which are documented by the individual functions which consume them.
// It's pretty easy to use: the library takes care of wrapping client-supplied
// handlers of all supported forms into the continuations it uses internally.
//
// THEORY OF OPERATION
//
// On its own, a promise is "inert"; it only makes progress in response to
// actions taken by its owner.  The state of the promise never changes
// spontaneously or concurrently.
//
// Typically, a promise is executed by wrapping it into a |fit::pending_task|
// and scheduling it for execution using |fit::executor::schedule_task()|.
// A promise's |operator(fit::context&)| can also be invoked directly by its owner
// from within the scope of another task (this is used to implement combinators
// and futures) though the principle is the same.
//
// |fit::executor| is an abstract class that encapsulates a strategy for
// executing tasks.  The executor is responsible for invoking each tasks's
// continuation until the task returns a non-pending result, indicating that
// the task has been completed.
//
// The method of execution and scheduling of each continuation call is left
// to the discretion of each executor implementation.  Typical executor
// implementations may dispatch tasks on an event-driven message loop or on
// a thread pool.  Developers are responsible for selecting appropriate
// executor implementations for their programs.
//
// During each invocation, the executor passes the continuation an execution
// context object represented by a subclass of |fit::context|.  The continuation
// attempts to make progress then returns a value of type |fit::result| to
// indicate whether it completed successfully (signaled by |fit::ok()|),
// failed with an error (signaled by |fit::error()|, or was unable to complete
// the task during that invocation (signaled by |fit::pending()|).
// For example, a continuation may be unable to complete the task if it must
// asynchronously await completion of an I/O or IPC operation before it
// can proceed any further.
//
// If the continuation was unable to complete the task during its invocation,
// it may to call |fit::context::suspend_task()| to acquire a
// |fit::suspended_task| object.  The continuation then arranges for the
// task to be resumed asynchronously (with |fit::suspended_task::resume_task()|)
// once it becomes possible for the promise to make forward progress again.
// Finally, the continuation returns returns |fit::pending()| to indicate to
// the executor that it was unable to complete the task during that invocation.
//
// When the executor receives a pending result from a task's continuation,
// it moves the task into a table of suspended tasks.  A suspended task
// is considered abandoned if has not been resume and all remaining
// |fit::suspended_task| handles representing it have been dropped.
// When a task is abandoned, the executor removes it from its table of
// suspended tasks and destroys the task because it is not possible for the task
// to be resumed or to make progress from that state.
//
// See also |fit::single_threaded_executor| for a simple executor implementation.
//
// BOXED AND UNBOXED PROMISES
//
// To make combination and execution as efficient as possible, the promises
// returned by |fit::make_promise| and by combinators are parameterized by
// complicated continuation types that are hard to describe, often consisting of
// nested templates and lambdas.  These are referred to as "unboxed"
// promises.  In contrast, "boxed" promises are parameterized by a
// a |fit::function| that hides (or "erases") the type of the continuation
// thereby yielding type that is easier to describe.
//
// You can recognize boxed and unboxed promises by their types.
// Here are two examples:
//
// - A boxed promise type: `fit::promise<void, void>` which is an alias for
//  `fit::promise_impl<void, void, std::function<fit::result<void, void>>`.
// - An unboxed promise type: `fit::promise_impl<void, void,
//   fit::internal::then_continuation<...something unintelligible...>>`
//
// Although boxed promises are easier to manipulate, they may cause the
// continuation to be allocated on the heap.  Chaining boxed promises can
// result in multiple allocations being produced.
//
// Conversely, unboxed promises have full type information.  Not only does
// this defer heap allocation but it also makes it easier for the C++
// compiler to fuse a chains of unboxed promises together into a single
// object that is easier to optimize.
//
// Unboxed promises can be boxed by assigning them to a boxed promise
// type (such as |fit::promise<>|) or using the |box()| combinator.
//
// As a rule of thumb, always defer boxing of promises until it is necessary
// to transport them using a simpler type.
//
// Do this: (chaining as a single expression performs at most one heap allocation)
//
//     fit::promise<> f = fit::make_promise([] { ... });
//         .then([](fit::result<> result) { ... });
//         .and_then([] { ... });
//
// Or this: (still only performs at most one heap allocation)
//
//     auto f = fit::make_promise([] { ... });
//     auto g = f.then([](fit::result<> result) { ... });
//     auto h = g.and_then([] { ... });
//     fit::promise<> boxed_h = h;
//
// But don't do this: (incurs up to three heap allocations due to eager boxing)
//
//     fit::promise<> f = fit::make_promise([] { ... });
//     fit::promise<> g = f.then([](fit::result<> result) { ... });
//     fit::promise<> h = g.and_then([] { ... });
//
// SINGLE OWNERSHIP MODEL
//
// Promises have single-ownership semantics.  This means that there
// can only be at most one reference to the task represented by its
// continuation along with any state held by that continuation.
//
// When a combinator is applied to a promise, ownership of its continuation
// is transferred to the combined promise, leaving the original promise
// in an "empty" state without a continuation.  Note that it is an error
// to attempt to invoke an empty promise (will assert at runtime).
//
// This model greatly simplifies reasoning about object lifetime.
// If a promise goes out of scope without completing its task, the task
// is considered "abandoned", causing all associated state to be destroyed.
//
// Note that a promise may capture references to other objects whose lifetime
// differs from that of the promise.  It is the responsibility of the promise
// to ensure reachability of the objects whose reference it captures such
// as by using reference counted pointers, weak pointers, or other appropriate
// mechanisms to ensure memory safety.
//
// THREADING MODEL
//
// Promise objects are not thread-safe themselves.  You cannot call their
// methods concurrently (or re-entrantly).  However, promises can safely
// be moved to other threads and executed there (unless their continuation
// requires thread affinity for some reason but that's beyond the scope
// of this document).
//
// This property of being thread-independent, combined with the single
// ownership model, greatly simplifies the implementation of thread pool
// based executors.
//
// RESULT RETENTION AND FIT::FUTURES
//
// A promise's continuation can only be executed to completion once.
// After it completes, it cannot be run again.
//
// This method of execution is very efficient; the promise's result is returned
// directly to its invoker; it is not copied or retained within the promise
// object itself.  It is entirely the caller's responsibility to decide how to
// consume or retain the result if need be.
//
// For example, the caller can move the promise into a |fit::future| to
// more conveniently hold either the promise or its result upon completion.
//
// CLARIFICATION OF NOMENCLATURE
//
// In this library, the words "promise" and "future" have the following
// definitions:
//
// - A *promise* holds the function that performs an asynchronous task.
//   It is the means to produce a value.
// - A *future* holds the value produced by an asynchronous task or a
//   promise to produce that value if the task has not yet completed.
//   It is a proxy for a value that is to be computed.
//
// Be aware that other libraries may use these terms slightly differently.
//
// For more information about the theory of futures and promises, see
// https://en.wikipedia.org/wiki/Futures_and_promises.
//
// COMPARISON WITH STD::FUTURE
//
// |std::future| provides a mechanism for running asynchronous tasks
// and awaiting their results on other threads.  Waiting can be performed
// either by blocking the waiting thread or by polling the future.
// The manner in which tasks are scheduled and executed is entirely
// controlled by the C++ standard library and offers limited control
// to developers.
//
// |fit::promise| and |fit::future| provide a mechanism for running asynchronous
// tasks, chaining additional tasks using combinators, and awaiting their
// results.  An executor is responsible for suspending tasks awaiting
// results of other tasks and is at liberty to run other tasks on the
// same thread rather than blocking.  In addition, developers can create custom
// executors to implement their own policies for running tasks.
//
// Decoupling awaiting from blocking makes |fit::promise| quite versatile.
// |fit::promise| can also interoperate with other task dispatching mechanisms
// (including |std::future|) using adapters such as |fit::bridge|.
//
// EXAMPLE
//
// - https://fuchsia.googlesource.com/zircon/+/master/system/utest/fit/examples/promise_example1.cpp
// - https://fuchsia.googlesource.com/zircon/+/master/system/utest/fit/examples/promise_example2.cpp
//
template <typename V = void, typename E = void>
using promise = promise_impl<function<result<V, E>(fit::context&)>>;

// Promise implementation details.
// See |fit::promise| documentation for more information.
template <typename Continuation>
class promise_impl final {
    static_assert(
        ::fit::internal::is_continuation<Continuation>::value,
        "Continuation type is invalid.  A continuation is a callable object "
        "with this signature: fit::result<V, E>(fit::context&).");

    using state_type = nullable<Continuation>;

public:
    // The type of callable object held by the promise.
    // Its signature is: result_type(fit::context&).
    using continuation_type = Continuation;

    // The promise's result type.
    // Equivalent to fit::result<value_type, error_type>.
    using result_type = typename ::fit::internal::continuation_traits<
        Continuation>::result_type;

    // The type of value produced when the promise completes successfully.
    // May be void.
    using value_type = typename result_type::value_type;

    // The type of value produced when the promise completes with an error.
    // May be void.
    using error_type = typename result_type::error_type;

    // Creates an empty promise without a continuation.
    // A continuation must be assigned before the promise can be used.
    promise_impl() = default;
    explicit promise_impl(decltype(nullptr)) {}

    // Creates a promise with a continuation.
    // If |continuation| equals nullptr then the promise is empty.
    explicit promise_impl(continuation_type continuation)
        : state_(std::move(continuation)) {}

    // Converts from a promise holding a continuation that is assignable to
    // to this promise's continuation type.
    //
    // This is typically used to create a promise with a boxed continuation
    // type (such as |fit::function|) from an unboxed promise produced by
    // |fit::make_promise| or by combinators.
    //
    // EXAMPLE
    //
    //     // f is a promise_impl with a complicated unboxed type
    //     auto f = fit::make_promise([] { ... });
    //
    //     // g wraps f's continuation
    //     fit::promise<> g = std::move(f);
    //
    template <typename OtherContinuation,
              typename = std::enable_if_t<
                  std::is_constructible<continuation_type,
                                        OtherContinuation&&>::value>>
    promise_impl(promise_impl<OtherContinuation> other)
        : state_(other.state_.has_value()
                     ? state_type(continuation_type(std::move(*other.state_)))
                     : state_type()) {}

    // Creates a promise by taking the continuation from another promise,
    // leaving the other promise empty.
    promise_impl(promise_impl&& other) = default;

    // Destroys the promise, releasing its continuation.
    ~promise_impl() = default;

    // Returns true if the promise is non-empty (has a valid continuation).
    explicit operator bool() const { return state_.has_value(); }

    // Invokes the promise's continuation.
    //
    // This method should be called by an executor to evaluate the promise.
    // If the result's state is |result_state::pending| then the executor
    // is responsible for arranging to invoke the promise's continuation
    // again once it determines that it is possible to make progress
    // towards completion of the promise encapsulated within the promise.
    //
    // Once the continuation returns a result with status |result_state::ok|
    // or |result_state::error|, the promise is assigned an empty continuation.
    //
    // Asserts that the promise is non-empty.
    result_type operator()(context& context) {
        assert(state_.has_value());
        result_type result = (*state_)(context);
        if (!result.is_pending())
            state_.reset();
        return result;
    }

    // Takes the promise's continuation, leaving it in an empty state.
    // Asserts that the promise is non-empty.
    continuation_type take_continuation() {
        assert(state_.has_value());
        auto continuation = std::move(state_.value());
        state_.reset();
        return continuation;
    }

    // Assigns the promise by taking the continuation from another promise,
    // leaving the other promise empty.
    promise_impl& operator=(promise_impl&& other) = default;

    // Discards the promise's continuation, leaving it empty.
    promise_impl& operator=(decltype(nullptr)) {
        state_.reset();
        return *this;
    }

    // Assigns the promise's continuation.
    promise_impl& operator=(continuation_type continuation) {
        state_ = std::move(continuation);
        return *this;
    }

    // Swaps the promises' continuations.
    void swap(promise_impl& other) {
        using std::swap;
        swap(state_, other.state_);
    }

    // Returns an unboxed promise which invokes the specified handler
    // function after this promise completes (successfully or unsuccessfully),
    // passing its result.
    //
    // The received result's state is guaranteed to be either
    // |fit::result_state::ok| or |fit::result_state::error|, never
    // |fit::result_state::pending|.
    //
    // |handler| is a callable object (such as a lambda) which consumes the
    // result of this promise and returns a new result with any value type
    // and error type.  Must not be null.
    //
    // The handler must return one of the following types:
    // - void
    // - fit::result<new_value_type, new_error_type>
    // - fit::ok<new_value_type>
    // - fit::error<new_error_type>
    // - fit::pending
    // - fit::promise<new_value_type, new_error_type>
    // - any callable or unboxed promise with the following signature:
    //   fit::result<new_value_type, new_error_type>(fit::context&)
    //
    // The handler must accept one of the following argument lists:
    // - (result_type)
    // - (result_type&)
    // - (const result_type&)
    // - (fit::context&, result_type)
    // - (fit::context&, result_type&)
    // - (fit::context&, const result_type&)
    //
    // Asserts that the promise is non-empty.
    // This method consumes the promise's continuation, leaving it empty.
    //
    // EXAMPLE
    //
    //     auto f = fit::make_promise(...)
    //         .then([] (fit::result<int, std::string> result)
    //                   -> fit::result<std::string, void> {
    //             if (result.is_ok()) {
    //                 printf("received value: %d\n", result.value());
    //                 if (result.value() % 15 == 0)
    //                     return ::fit::ok("fizzbuzz");
    //                 if (result.value() % 3 == 0)
    //                     return ::fit::ok("fizz");
    //                 if (result.value() % 5 == 0)
    //                     return ::fit::ok("buzz");
    //                 return ::fit::ok(std::to_string(result.value()));
    //             } else {
    //                 printf("received error: %s\n", result.error().c_str());
    //                 return ::fit::error();
    //             }
    //         })
    //         .then(...);
    //
    template <typename ResultHandler>
    promise_impl<::fit::internal::then_continuation<promise_impl, ResultHandler>>
    then(ResultHandler handler) {
        static_assert(is_callable<ResultHandler>::value,
                      "ResultHandler must be a callable object.");

        assert(!is_null(handler));
        assert(state_.has_value());
        return make_promise_with_continuation(
            ::fit::internal::then_continuation<promise_impl, ResultHandler>(
                std::move(*this), std::move(handler)));
    }

    // Returns an unboxed promise which invokes the specified handler
    // function after this promise completes successfully, passing its
    // resulting value.
    //
    // |handler| is a callable object (such as a lambda) which consumes the
    // result of this promise and returns a new result with any value type
    // but the same error type.  Must not be null.
    //
    // The handler must return one of the following types:
    // - void
    // - fit::result<new_value_type, error_type>
    // - fit::ok<new_value_type>
    // - fit::error<error_type>
    // - fit::pending
    // - fit::promise<new_value_type, error_type>
    // - any callable or unboxed promise with the following signature:
    //   fit::result<new_value_type, error_type>(fit::context&)
    //
    // The handler must accept one of the following argument lists:
    // - (value_type)
    // - (value_type&)
    // - (const value_type&)
    // - (fit::context&, value_type)
    // - (fit::context&, value_type&)
    // - (fit::context&, const value_type&)
    //
    // Asserts that the promise is non-empty.
    // This method consumes the promise's continuation, leaving it empty.
    //
    // EXAMPLE
    //
    //     auto f = fit::make_promise(...)
    //         .and_then([] (int value) {
    //             printf("received value: %d\n", value);
    //             if (value % 15 == 0)
    //                 return ::fit::ok("fizzbuzz");
    //             if (value % 3 == 0)
    //                 return ::fit::ok("fizz");
    //             if (value % 5 == 0)
    //                 return ::fit::ok("buzz");
    //             return ::fit::ok(std::to_string(value));
    //         })
    //         .then(...);
    //
    template <typename ValueHandler>
    promise_impl<::fit::internal::and_then_continuation<promise_impl, ValueHandler>>
    and_then(ValueHandler handler) {
        static_assert(is_callable<ValueHandler>::value,
                      "ValueHandler must be a callable object.");

        assert(!is_null(handler));
        assert(state_.has_value());
        return make_promise_with_continuation(
            ::fit::internal::and_then_continuation<promise_impl, ValueHandler>(
                std::move(*this), std::move(handler)));
    }

    // Returns an unboxed promise which invokes the specified handler
    // function after this promise completes with an error, passing its
    // resulting error.
    //
    // |handler| is a callable object (such as a lambda) which consumes the
    // result of this promise and returns a new result with any error type
    // but the same value type.  Must not be null.
    //
    // The handler must return one of the following types:
    // - void
    // - fit::result<value_type, new_error_type>
    // - fit::ok<value_type>
    // - fit::error<new_error_type>
    // - fit::pending
    // - fit::promise<value_type, new_error_type>
    // - any callable or unboxed promise with the following signature:
    //   fit::result<value_type, new_error_type>(fit::context&)
    //
    // The handler must accept one of the following argument lists:
    // - (error_type)
    // - (error_type&)
    // - (const error_type&)
    // - (fit::context&, error_type)
    // - (fit::context&, error_type&)
    // - (fit::context&, const error_type&)
    //
    // Asserts that the promise is non-empty.
    // This method consumes the promise's continuation, leaving it empty.
    //
    // EXAMPLE
    //
    //     auto f = fit::make_promise(...)
    //         .or_else([] (std::string error) {
    //             printf("received error: %s\n", error.c_str());
    //             return ::fit::error();
    //         })
    //         .then(...);
    //
    template <typename ErrorHandler>
    promise_impl<::fit::internal::or_else_continuation<promise_impl, ErrorHandler>>
    or_else(ErrorHandler handler) {
        static_assert(is_callable<ErrorHandler>::value,
                      "ErrorHandler must be a callable object.");

        assert(!is_null(handler));
        assert(state_.has_value());
        return make_promise_with_continuation(
            ::fit::internal::or_else_continuation<promise_impl, ErrorHandler>(
                std::move(*this), std::move(handler)));
    }

    // Returns an unboxed promise which invokes the specified handler
    // function after this promise completes (successfully or unsuccessfully),
    // passing it the promise's result then delivering the result onwards
    // to the next promise once the handler returns.
    //
    // The handler receive a copy, const reference, or non-const reference
    // depending on the signature of the handler's last argument.
    //
    // - Copies and const references are especially useful for inspecting a
    //   result mid-stream without modification, such as printing it for
    //   debugging.
    // - Non-const references are especially useful for synchronously
    //   modifying a result mid-stream, such as clamping its bounds or
    //   injecting a default value.
    //
    // |handler| is a callable object (such as a lambda) which can examine
    // or modify the incoming result.  Unlike |then()|, the handler does
    // not need to propagate the result onwards.  Must not be null.
    //
    // The handler must return one of the following types:
    // - void
    //
    // The handler must accept one of the following argument lists:
    // - (result_type)
    // - (result_type&)
    // - (const result_type&)
    // - (fit::context&, result_type)
    // - (fit::context&, result_type&)
    // - (fit::context&, const result_type&)
    //
    // Asserts that the promise is non-empty.
    // This method consumes the promise's continuation, leaving it empty.
    //
    // EXAMPLE
    //
    //     auto f = fit::make_promise(...)
    //         .inspect([] (const fit::result<int, std::string>& result) {
    //             if (result.is_ok())
    //                 printf("received value: %d\n", result.value());
    //             else
    //                 printf("received error: %s\n", result.error().c_str());
    //         })
    //         .then(...);
    //
    template <typename InspectHandler>
    promise_impl<::fit::internal::inspect_continuation<promise_impl, InspectHandler>>
    inspect(InspectHandler handler) {
        static_assert(is_callable<InspectHandler>::value,
                      "InspectHandler must be a callable object.");
        static_assert(std::is_void<typename callable_traits<
                          InspectHandler>::return_type>::value,
                      "InspectHandler must return void.");

        assert(!is_null(handler));
        assert(state_.has_value());
        return make_promise_with_continuation(
            ::fit::internal::inspect_continuation<promise_impl, InspectHandler>(
                std::move(*this), std::move(handler)));
    }

    // Returns an unboxed promise which discards the result of this promise
    // once it completes, thereby always producing a successful result of
    // type fit::result<void, void> regardless of whether this promise
    // succeeded or failed.
    //
    // Asserts that the promise is non-empty.
    // This method consumes the promise's continuation, leaving it empty.
    //
    // EXAMPLE
    //
    //     auto f = fit::make_promise(...)
    //         .discard_result()
    //         .then(...);
    //
    promise_impl<::fit::internal::discard_result_continuation<promise_impl>>
    discard_result() {
        assert(state_.has_value());
        return make_promise_with_continuation(
            ::fit::internal::discard_result_continuation<promise_impl>(
                std::move(*this)));
    }

    // Applies a |wrapper| to the promise.  Invokes the wrapper's |wrap()|
    // method, passes the promise to the wrapper by value followed by any
    // additional |args| passed to |wrap_with()|, then returns the wrapper's
    // result.
    //
    // |Wrapper| is a type that implements a method called |wrap()| which
    // accepts a promise as its argument and produces a wrapped result of
    // any type, such as another promise.
    //
    // Asserts that the promise is non-empty.
    // This method consumes the promise's continuation, leaving it empty.
    //
    // EXAMPLE
    //
    // In this example, |fit::sequencer| is a wrapper type that imposes
    // FIFO execution order onto a sequence of wrapped promises.
    //
    //     // This wrapper type is intended to be applied to
    //     // a sequence of promises so we store it in a variable.
    //     fit::sequencer seq;
    //
    //     // This task consists of some amount of work that must be
    //     // completed sequentially followed by other work that can
    //     // happen in any order.  We use |wrap_with()| to wrap the
    //     // sequential work with the sequencer.
    //     fit::promise<> perform_complex_task() {
    //         return fit::make_promise([] { /* do sequential work */ })
    //             .then([] (fit::result<> result) { /* this will also be wrapped */ })
    //             .wrap_with(seq)
    //             .then([] (fit::result<> result) { /* do more work */ });
    //     }
    //
    // This example can also be written without using |wrap_with()|.
    // The behavior is equivalent but the syntax may seem more awkward.
    //
    //     fit::sequencer seq;
    //
    //     promise<> perform_complex_task() {
    //         return seq.wrap(
    //                 fit::make_promise([] { /* sequential work */ })
    //             ).then([] (fit::result<> result) { /* more work */ });
    //     }
    //
    template <typename Wrapper, typename... Args>
    decltype(auto) wrap_with(Wrapper& wrapper, Args... args) {
        assert(state_.has_value());
        return wrapper.wrap(std::move(*this),
                            std::forward<Args>(args)...);
    }

    // Wraps the promise's continuation into a |fit::function|.
    //
    // A boxed promise is easier to store and pass around than the unboxed
    // promises produced by |fit::make_promise()| and combinators, though boxing
    // may incur a heap allocation.
    //
    // It is a good idea to defer boxing the promise until after all
    // desired combinators have been applied to prevent unnecessary heap
    // allocation during intermediate states of the promise's construction.
    //
    // Returns an empty promise if this promise is empty.
    // This method consumes the promise's continuation, leaving it empty.
    //
    // EXAMPLE
    //
    //     // f's is a fit::promise_impl<> whose continuation contains an
    //     // anonymous type (the lambda)
    //     auto f = fit::make_promise([] {});
    //
    //     // g's type will be fit::promise<> due to boxing
    //     auto boxed_f = f.box();
    //
    //     // alternately, we can get exactly the same effect by assigning
    //     // the unboxed promise to a variable of a named type instead of
    //     // calling box()
    //     fit::promise<> boxed_f = std::move(f);
    //
    promise_impl<function<result_type(context&)>> box() {
        return std::move(*this);
    }

    promise_impl(const promise_impl&) = delete;
    promise_impl& operator=(const promise_impl&) = delete;

private:
    template <typename>
    friend class promise_impl;

    state_type state_;
};

template <typename Continuation>
void swap(promise_impl<Continuation>& a,
          promise_impl<Continuation>& b) {
    a.swap(b);
}

template <typename Continuation>
bool operator==(const promise_impl<Continuation>& f,
                decltype(nullptr)) {
    return !f;
}
template <typename Continuation>
bool operator==(decltype(nullptr),
                const promise_impl<Continuation>& f) {
    return !f;
}
template <typename Continuation>
bool operator!=(const promise_impl<Continuation>& f,
                decltype(nullptr)) {
    return !!f;
}
template <typename Continuation>
bool operator!=(decltype(nullptr),
                const promise_impl<Continuation>& f) {
    return !!f;
}

// Makes a promise containing the specified continuation.
//
// This function is used for making a promises given a callable object
// that represents a valid continuation type.  In contrast,
// |fit::make_promise()| supports a wider range of types and should be
// preferred in most situations.
//
// |Continuation| is a callable object with the signature
// fit::result<V, E>(fit::context&).
template <typename Continuation>
inline promise_impl<Continuation> make_promise_with_continuation(
    Continuation continuation) {
    return promise_impl<Continuation>(std::move(continuation));
}

// Returns an unboxed promise that wraps the specified handler.
// The type of the promise's result is inferred from the handler's result.
//
// |handler| is a callable object (such as a lambda.  Must not be null.
//
// The handler must return one of the following types:
// - void
// - fit::result<value_type, error_type>
// - fit::ok<value_type>
// - fit::error<error_type>
// - fit::pending
// - fit::promise<value_type, error_type>
// - any callable or unboxed promise with the following signature:
//   fit::result<value_type, error_type>(fit::context&)
//
// The handler must accept one of the following argument lists:
// - ()
// - (fit::context&)
//
// See documentation of |fit::promise| for more information.
//
// SYNOPSIS
//
// |Handler| is the handler function type.  It is typically inferred by the
// compiler from the |handler| argument.
//
// EXAMPLE
//
//     enum class weather_type { sunny, glorious, cloudy, eerie, ... };
//
//     weather_type look_outside() { ... }
//     void wait_for_tomorrow(fit::suspended_task task) {
//         ... arrange to call task.resume_task() tomorrow ...
//     }
//
//     fit::promise<weather_type, std::string> wait_for_good_weather(int max_days) {
//         return fit::make_promise([days_left = max_days] (fit::context context&) mutable
//                             -> fit::result<int, std::string> {
//             weather_type weather = look_outside();
//             if (weather == weather_type::sunny || weather == weather_type::glorious)
//                 return fit::ok(weather);
//             if (days_left > 0) {
//                 wait_for_tomorrow(context.suspend_task());
//                 return fit::pending();
//             }
//             days_left--;
//             return fit::error("nothing but grey skies");
//         });
//     }
//
//     auto f = wait_for_good_weather(7)
//         .and_then([] (weather_type weather) { ... })
//         .or_else([] (std::string error) { ... });
//
template <typename PromiseHandler>
inline promise_impl<::fit::internal::context_handler_invoker<PromiseHandler>>
make_promise(PromiseHandler handler) {
    static_assert(is_callable<PromiseHandler>::value,
                  "PromiseHandler must be a callable object.");

    assert(!is_null(handler));
    return make_promise_with_continuation(
        ::fit::internal::promise_continuation<PromiseHandler>(
            std::move(handler)));
}

// Jointly evaluates zero or more promises.
// Returns a promise that produces a std::tuple<> containing the result
// of each promise once they all complete.
//
// EXAMPLE
//
//     auto get_random_number() {
//         return fit::make_promise([] { return rand() % 10 });
//     }
//
//     auto get_random_product() {
//         auto f = get_random_number();
//         auto g = get_random_number();
//         return fit::join_promises(std::move(f), std::move(g))
//             .and_then([] (std::tuple<fit::result<int>, fit::result<int>> results) {
//                 return fit::ok(results.get<0>.value() + results.get<1>.value());
//             });
//     }
//
template <typename... Promises>
inline promise_impl<::fit::internal::join_continuation<Promises...>>
join_promises(Promises... promises) {
    return make_promise_with_continuation(
        ::fit::internal::join_continuation<Promises...>(std::move(promises)...));
}

// Jointly evaluates zero or more homogenous promises (same result and error
// type).  Returns a promise that produces a std::vector<> containing the
// result of each promise once they all complete.
//
// EXAMPLE
//
//     auto get_random_number() {
//         return fit::make_promise([] { return rand() % 10 });
//     }
//
//     auto get_random_product() {
//         std::vector<fit::promise<int>> promises;
//         promises.push_back(get_random_number());
//         promises.push_back(get_random_number());
//         return fit::join_promise_vector(std::move(promises))
//             .and_then([] (std::vector<fit::result<int>> results) {
//                 return fit::ok(results[0].value() + results[1].value());
//             });
//     }
//
template <typename V, typename E>
inline promise<std::vector<::fit::result<V, E>>>
join_promise_vector(std::vector<::fit::promise<V, E>> promises) {
    std::vector<fit::result<V, E>> results(promises.size());
    return ::fit::make_promise(
        [promises = std::move(promises),
         results = std::move(results)](fit::context& context) mutable
        -> fit::result<std::vector<fit::result<V, E>>> {
            bool all_done{true};
            for (size_t i = 0; i < promises.size(); ++i) {
                if (!results[i]) {
                    results[i] = promises[i](context);
                    all_done &= !!results[i];
                }
            }
            if (all_done) {
                return fit::ok(std::move(results));
            }
            return fit::pending();
        });
}

// Describes the status of a future.
enum class future_state {
    // The future neither holds a result nor a promise that could produce a result.
    // An empty future cannot make progress until a promise or result is assigned to it.
    empty,
    // The future holds a promise that may eventually produce a result but
    // it currently doesn't have a result.  The future's promise must be
    // invoked in order to make progress from this state.
    pending,
    // The future holds a successful result.
    ok,
    // The future holds an error result.
    error
};

// A |fit::future| holds onto a |fit::promise| until it has completed then
// provides access to its |fit::result|.
//
// SYNOPSIS
//
// |V| is the type of value produced when the completes successfully.
// Defaults to |void|.
//
// |E| is the type of error produced when the completes with an error.
// Defaults to |void|.
//
// THEORY OF OPERATION
//
// A future has a single owner who is responsible for setting its promise
// or result and driving its execution.  Unlike |fit::promise|, a future retains
// the result produced by completion of its asynchronous task.  Result retention
// eases the implementation of combined tasks that need to await the results
// of other tasks before proceeding.
//
// See the example for details.
//
// A future can be in one of four states, depending on whether it holds...
// - a successful result: |fit::future_state::ok|
// - an error result: |fit::future_state::error|
// - a promise that may eventually produce a result: |fit::future_state::pending|
// - neither: |fit::future_state_empty|
//
// On its own, a future is "inert"; it only makes progress in response to
// actions taken by its owner.  The state of the future never changes
// spontaneously or concurrently.
//
// When the future's state is |fit::future_state::empty|, its owner is
// responsible for setting the future's promise or result thereby moving the
// future into the pending or ready state.
//
// When the future's state is |fit::future_state::pending|, its owner is
// responsible for calling the future's |operator()| to invoke the promise.
// If the promise completes and returns a result, the future will transition
// to the ok or error state according to the result.  The promise itself will
// then be destroyed since it has fulfilled its purpose.
//
// When the future's state is |fit::future_state::ok|, its owner is responsible
// for consuming the stored value using |value()|, |take_value()|,
// |result()|, |take_result()|, or |take_ok_result()|.
//
// When the future's state is |fit::future_state::error|, its owner is
// responsible for consuming the stored error using |error()|, |take_error()|,
// |result()|, |take_result()|, or |take_error_result()|.
//
// See also |fit::promise| for more information about promises and their
// execution.
//
// EXAMPLE
//
// - https://fuchsia.googlesource.com/zircon/+/master/system/utest/fit/examples/promise_example2.cpp
template <typename V = void, typename E = void>
using future = future_impl<promise<V, E>>;

// Future implementation details.
// See |fit::future| documentation for more information.
template <typename Promise>
class future_impl final {
public:
    // The type of promise held by the future.
    using promise_type = Promise;

    // The promise's result type.
    // Equivalent to fit::result<value_type, error_type>.
    using result_type = typename Promise::result_type;

    // The type of value produced when the promise completes successfully.
    // May be void.
    using value_type = typename Promise::value_type;

    // The type of value produced when the promise completes with an error.
    // May be void.
    using error_type = typename Promise::error_type;

    // Creates a future in the empty state.
    future_impl() = default;
    future_impl(decltype(nullptr)) {}

    // Creates a future and assigns a promise to compute its result.
    // If the promise is empty, the future enters the empty state.
    // Otherwise the future enters the pending state.
    explicit future_impl(promise_type promise) {
        if (promise) {
            state_.template emplace<1>(std::move(promise));
        }
    }

    // Creates a future and assigns its result.
    // If the result is pending, the future enters the empty state.
    // Otherwise the future enters the ok or error state.
    explicit future_impl(result_type result) {
        if (result) {
            state_.template emplace<2>(std::move(result));
        }
    }

    // Moves from another future, leaving the other one in an empty state.
    future_impl(future_impl&& other)
        : state_(std::move(other.state_)) {
        other.state_.template emplace<0>();
    }

    // Destroys the promise, releasing its promise and result (if any).
    ~future_impl() = default;

    // Returns the state of the future: empty, pending, ok, or error.
    future_state state() const {
        switch (state_.index()) {
        case 0:
            return future_state::empty;
        case 1:
            return future_state::pending;
        case 2:
            return state_.template get<2>().is_ok()
                       ? future_state::ok
                       : future_state::error;
        }
        __builtin_unreachable();
    }

    // Returns true if the future's state is not |fit::future_state::empty|:
    // it either holds a result or holds a promise that can be invoked to make
    // progress towards obtaining a result.
    explicit operator bool() const { return !is_empty(); }

    // Returns true if the future's state is |fit::future_state::empty|:
    // it does not hold a result or a promise so it cannot make progress.
    bool is_empty() const { return state() == fit::future_state::empty; }

    // Returns true if the future's state is |fit::future_state::pending|:
    // it does not hold a result yet but it does hold a promise that can be invoked
    // to make progress towards obtaining a result.
    bool is_pending() const { return state() == fit::future_state::pending; }

    // Returns true if the future's state is |fit::future_state::ok|:
    // it holds a value that can be retrieved using |value()|, |take_value()|,
    // |result()|, |take_result()|, or |take_ok_result()|.
    bool is_ok() const { return state() == fit::future_state::ok; }

    // Returns true if the future's state is |fit::future_state::error|:
    // it holds an error that can be retrieved using |error()|, |take_error()|,
    // |result()|, |take_result()|, or |take_error_result()|.
    bool is_error() const { return state() == fit::future_state::error; }

    // Returns true if the future's state is either |fit::future_state::ok| or
    // |fit::future_state::error|.
    bool is_ready() const { return state_.index() == 2; }

    // Evaluates the future and returns true if its result is ready.
    // Asserts that the future is not empty.
    //
    // If the promise completes and returns a result, the future will transition
    // to the ok or error state according to the result.  The promise itself will
    // then be destroyed since it has fulfilled its purpose.
    bool operator()(fit::context& context) {
        switch (state_.index()) {
        case 0:
            return false;
        case 1: {
            result_type result = state_.template get<1>()(context);
            if (!result)
                return false;
            state_.template emplace<2>(std::move(result));
            return true;
        }
        case 2:
            return true;
        }
        __builtin_unreachable();
    }

    // Gets a reference to the future's promise.
    // Asserts that the future's state is |fit::future_state::pending|.
    const promise_type& promise() const {
        assert(is_pending());
        return state_.template get<1>();
    }

    // Takes the future's promise, leaving it in an empty state.
    // Asserts that the future's state is |fit::future_state::pending|.
    promise_type take_promise() {
        assert(is_pending());
        auto promise = std::move(state_.template get<1>());
        state_.template emplace<0>();
        return promise;
    }

    // Gets a reference to the future's result.
    // Asserts that the future's state is |fit::future_state::ok| or
    // |fit::future_state::error|.
    result_type& result() {
        assert(is_ready());
        return state_.template get<2>();
    }
    const result_type& result() const {
        assert(is_ready());
        return state_.template get<2>();
    }

    // Takes the future's result, leaving it in an empty state.
    // Asserts that the future's state is |fit::future_state::ok| or
    // |fit::future_state::error|.
    result_type take_result() {
        assert(is_ready());
        auto result = std::move(state_.template get<2>());
        state_.template emplace<0>();
        return result;
    }

    // Gets a reference to the future's value.
    // Asserts that the future's state is |fit::future_state::ok|.
    template <typename R = value_type,
              typename = std::enable_if_t<!std::is_void<R>::value>>
    R& value() {
        assert(is_ok());
        return state_.template get<2>().value();
    }
    template <typename R = value_type,
              typename = std::enable_if_t<!std::is_void<R>::value>>
    const R& value() const {
        assert(is_ok());
        return state_.template get<2>().value();
    }

    // Takes the future's value, leaving it in an empty state.
    // Asserts that the future's state is |fit::future_state::ok|.
    template <typename R = value_type,
              typename = std::enable_if_t<!std::is_void<R>::value>>
    R take_value() {
        assert(is_ok());
        auto value = state_.template get<2>().take_value();
        state_.template emplace<0>();
        return value;
    }
    ok_result<value_type> take_ok_result() {
        assert(is_ok());
        auto result = state_.template get<2>().take_ok_result();
        state_.template emplace<0>();
        return result;
    }

    // Gets a reference to the future's error.
    // Asserts that the future's state is |fit::future_state::error|.
    template <typename R = error_type,
              typename = std::enable_if_t<!std::is_void<R>::value>>
    R& error() {
        assert(is_error());
        return state_.template get<2>().error();
    }
    template <typename R = error_type,
              typename = std::enable_if_t<!std::is_void<R>::value>>
    const R& error() const {
        assert(is_error());
        return state_.template get<2>().error();
    }

    // Takes the future's error, leaving it in an empty state.
    // Asserts that the future's state is |fit::future_state::error|.
    template <typename R = error_type,
              typename = std::enable_if_t<!std::is_void<R>::value>>
    R take_error() {
        assert(is_error());
        auto error = state_.template get<2>().take_error();
        state_.template emplace<0>();
        return error;
    }
    error_result<error_type> take_error_result() {
        assert(is_error());
        auto result = state_.template get<2>().take_error_result();
        state_.template emplace<0>();
        return result;
    }

    // Move assigns from another future, leaving the other one in an empty state.
    future_impl& operator=(future_impl&& other) = default;

    // Discards the future's promise and result, leaving it empty.
    future_impl& operator=(decltype(nullptr)) {
        state_.template emplace<0>();
        return *this;
    }

    // Assigns a promise to compute the future's result.
    // If the promise is empty, the future enters the empty state.
    // Otherwise the future enters the pending state.
    future_impl& operator=(promise_type promise) {
        if (promise) {
            state_.template emplace<1>(std::move(promise));
        } else {
            state_.template emplace<0>();
        }
        return *this;
    }

    // Assigns the future's result.
    // If the result is pending, the future enters the empty state.
    // Otherwise the future enters the ok or error state.
    future_impl& operator=(result_type result) {
        if (result) {
            state_.template emplace<2>(std::move(result));
        } else {
            state_.template emplace<0>();
        }
        return *this;
    }

    // Swaps the futures' contents.
    void swap(future_impl& other) {
        using std::swap;
        swap(state_, other.state_);
    }

    future_impl(const future_impl&) = delete;
    future_impl& operator=(const future_impl&) = delete;

private:
    ::fit::internal::variant<::fit::internal::monostate,
                             promise_type, result_type>
        state_;
};

template <typename Promise>
void swap(future_impl<Promise>& a, future_impl<Promise>& b) {
    a.swap(b);
}

template <typename Promise>
bool operator==(const future_impl<Promise>& f, decltype(nullptr)) {
    return !f;
}
template <typename Promise>
bool operator==(decltype(nullptr), const future_impl<Promise>& f) {
    return !f;
}
template <typename Promise>
bool operator!=(const future_impl<Promise>& f, decltype(nullptr)) {
    return !!f;
}
template <typename Promise>
bool operator!=(decltype(nullptr), const future_impl<Promise>& f) {
    return !!f;
}

// Makes a future containing the specified promise.
template <typename Promise>
future_impl<Promise> make_future(Promise promise) {
    return future_impl<Promise>(std::move(promise));
}

// A pending task holds a |fit::promise| that can be scheduled to run on
// a |fit::executor| using |fit::executor::schedule_task()|.
//
// An executor repeatedly invokes a pending task until it returns true,
// indicating completion.  Note that the promise's resulting value or error
// is discarded since it is not meaningful to the executor.  If you need
// to consume the result, use a combinator such as |fit::pending::then()|
// to capture it prior to wrapping the promise into a pending task.
//
// See documentation of |fit::promise| for more information.
class pending_task final {
public:
    // The type of promise held by this task.
    using promise_type = promise<void, void>;

    // Creates an empty pending task without a promise.
    pending_task() = default;

    // Creates a pending task that wraps an already boxed promise that returns
    // |fit::result<void, void>|.
    pending_task(promise_type promise)
        : promise_(std::move(promise)) {}

    // Creates a pending task that wraps any kind of promise, boxed or unboxed,
    // regardless of its result type and with any context that is assignable
    // from this task's context type.
    template <typename Continuation>
    pending_task(promise_impl<Continuation> promise)
        : promise_(promise ? promise.discard_result().box() : promise_type()) {}

    pending_task(pending_task&&) = default;
    pending_task& operator=(pending_task&&) = default;

    // Destroys the pending task, releasing its promise.
    ~pending_task() = default;

    // Returns true if the pending task is non-empty (has a valid promise).
    explicit operator bool() const { return !!promise_; }

    // Evaluates the pending task.
    // If the task completes (returns a non-pending result), the task reverts
    // to an empty state (because the promise it holds has reverted to an empty
    // state) and returns true.
    // It is an error to invoke this method if the pending task is empty.
    bool operator()(fit::context& context) {
        return !promise_(context).is_pending();
    }

    // Extracts the pending task's promise.
    promise_type take_promise() {
        return std::move(promise_);
    }

    pending_task(const pending_task&) = delete;
    pending_task& operator=(const pending_task&) = delete;

private:
    promise_type promise_;
};

// Execution context for an asynchronous task, such as a |fit::promise|,
// |fit::future|, or |fit::pending_task|.
//
// When a |fit::executor| executes a task, it provides the task with an
// execution context which enables the task to communicate with the
// executor and manage its own lifecycle.  Specialized executors may subclass
// |fit::context| and offer additional methods beyond those which are
// defined here, such as to provide access to platform-specific features
// supported by the executor.
//
// The context provided to a task is only valid within the scope of a single
// invocation; the task must not retain a reference to the context across
// invocations.
//
// See documentation of |fit::promise| for more information.
class context {
public:
    // Gets the executor that is running the task, never null.
    virtual class executor* executor() const = 0;

    // Obtains a handle that can be used to resume the task after it has been
    // suspended.
    //
    // Clients should call this method before returning |fit::pending()| from
    // the task.  See documentation on |fit::executor|.
    virtual suspended_task suspend_task() = 0;

    // Converts this context to a derived context type.
    template <typename Context,
              typename = std::enable_if_t<std::is_base_of<context, Context>::value>>
    Context& as() & {
        // TODO(CP-163): We should perform a run-time type check here rather
        // than blindly casting.  That's why this method exists.
        return static_cast<Context&>(*this);
    }

protected:
    virtual ~context() = default;
};

// An abstract interface for executing asynchronous tasks, such as promises,
// represented by |fit::pending_task|.
//
// EXECUTING TASKS
//
// An executor evaluates its tasks incrementally.  During each iteration
// of the executor's main loop, it invokes the next task from its ready queue.
//
// If the task returns true, then the task is deemed to have completed.
// The executor removes the tasks from its queue and destroys it since there
// it nothing left to do.
//
// If the task returns false, then the task is deemed to have voluntarily
// suspended itself pending some event that it is awaiting.  Prior to
// returning, the task should acquire at least one |fit::suspended_task|
// handle from its execution context using |fit::context::suspend_task()|
// to provide a means for the task to be resumed once it can make forward
// progress again.
//
// Once the suspended task is resumed with |fit::suspended_task::resume()|, it
// is moved back to the ready queue and it will be invoked again during a later
// iteration of the executor's loop.
//
// If all |fit::suspended_task| handles for a given task are destroyed without
// the task ever being resumed then the task is also destroyed since there
// would be no way for the task to be resumed from suspension.  We say that
// such a task has been "abandoned".
//
// The executor retains single-ownership of all active and suspended tasks.
// When the executor is destroyed, all of its remaining tasks are also
// destroyed.
//
// Please read |fit::promise| for a more detailed explanation of the
// responsibilities of tasks and executors.
//
// NOTES FOR IMPLEMENTORS
//
// This interface is designed to support a variety of different executor
// implementations.  For example, one implementation might run its tasks on
// a single thread whereas another might dispatch them on an event-driven
// message loop or use a thread pool.
//
// See also |fit::single_threaded_executor| for a concrete implementation.
class executor {
public:
    // Destroys the executor along with all of its remaining scheduled tasks
    // that have yet to complete.
    virtual ~executor() = default;

    // Schedules a task for eventual execution by the executor.
    //
    // This method is thread-safe.
    virtual void schedule_task(pending_task task) = 0;
};

// Represents a task that is awaiting resumption.
//
// This object has RAII semantics.  If the task is not resumed by at least
// one holder of its |suspended_task| handles, then it will be destroyed
// by the executor since it is no longer possible for the task to make
// progress.  The task is said have been "abandoned".
//
// See documentation of |fit::executor| for more information.
class suspended_task final {
public:
    // A handle that grants the capability to resume a suspended task.
    // Each issued ticket must be individually resolved.
    using ticket = uint64_t;

    // The resolver mechanism implements a lightweight form of reference
    // counting for tasks that have been suspended.
    //
    // When a suspended task is created in a non-empty state, it receives
    // a pointer to a resolver interface and a ticket.  The ticket is
    // a one-time-use handle that represents the task that was suspended
    // and provides a means to resume it.  The |suspended_task| class ensures
    // that every ticket is precisely accounted for.
    //
    // When |suspended_task::resume_task()| is called on an instance with
    // a valid ticket, the resolver's |resolve_ticket()| method is invoked
    // passing the ticket's value along with *true* to resume the task.  This
    // operation consumes the ticket so the |suspended_task| transitions to
    // an empty state.  The ticket and resolver cannot be used again by
    // this |suspended_task| instance.
    //
    // Similarly, when |suspended_task::reset()| is called on an instance with
    // a valid ticket or when the task goes out of scope on such an instance,
    // the resolver's |resolve_ticket()| method is invoked but this time passes
    // *false* to not resume the task.  As before, the ticket is consumed.
    //
    // Finally, when the |suspended_task| is copied, its ticket is duplicated
    // using |duplicate_ticket()| resulting in two tickets, both of which
    // must be individually resolved.
    //
    // Resuming a task that has already been resumed has no effect.
    // Conversely, a task is considered "abandoned" if all of its tickets
    // have been resolved without it ever being resumed.  See documentation
    // of |fit::promise| for more information.
    //
    // The methods of this class are safe to call from any thread, including
    // threads that may not be managed by the task's executor.
    class resolver {
    public:
        // Duplicates the provided ticket, returning a new ticket.
        // Note: The new ticket may have the same numeric value as the
        //       original ticket but should be considered a distinct instance
        //       that must be separately resolved.
        virtual ticket duplicate_ticket(ticket ticket) = 0;

        // Consumes the provided ticket, optionally resuming its associated task.
        // The provided ticket must not be used again.
        virtual void resolve_ticket(ticket ticket, bool resume_task) = 0;

    protected:
        virtual ~resolver() = default;
    };

    suspended_task()
        : resolver_(nullptr), ticket_(0) {}

    suspended_task(resolver* resolver, ticket ticket)
        : resolver_(resolver), ticket_(ticket) {}

    suspended_task(const suspended_task& other);
    suspended_task(suspended_task&& other);

    // Releases the task without resumption.
    //
    // Does nothing if this object does not hold a ticket.
    ~suspended_task();

    // Returns true if this object holds a ticket for a suspended task.
    explicit operator bool() const { return resolver_ != nullptr; }

    // Asks the task's executor to resume execution of the suspended task
    // if it has not already been resumed or completed.  Also releases
    // the task's ticket as a side-effect.
    //
    // Clients should call this method when it is possible for the task to
    // make progress; for example, because some event the task was
    // awaiting has occurred.  See documentation on |fit::executor|.
    //
    // Does nothing if this object does not hold a ticket.
    void resume_task() { resolve(true); }

    // Releases the suspended task without resumption.
    //
    // Does nothing if this object does not hold a ticket.
    void reset() { resolve(false); }

    // Swaps suspended tasks.
    void swap(suspended_task& other);

    suspended_task& operator=(const suspended_task& other);
    suspended_task& operator=(suspended_task&& other);

private:
    void resolve(bool resume_task);

    resolver* resolver_;
    ticket ticket_;
};

inline void swap(suspended_task& a, suspended_task& b) {
    a.swap(b);
}

} // namespace fit

#endif // LIB_FIT_PROMISE_H_
