// 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::make_ok_promise()| to create a promise that immediately returns a value.
// Use |fit::make_error_promise()| to create a promise that immediately returns an error.
// Use |fit::make_result_promise()| to create a promise that immediately returns a result.
// 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 in an argument list,
//                            once they all complete return a tuple of
//                            their results
//    |fit::join_promise_vector()|: await multiple promises in a vector,
//                                  once they all complete return a vector
//                                  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/fuchsia/+/master/zircon/system/utest/fit/examples/promise_example1.cpp
// -
// https://fuchsia.googlesource.com/fuchsia/+/master/zircon/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)) {}

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

  // Constructs the promise by taking the continuation from another promise,
  // leaving the other promise empty.
  promise_impl(promise_impl&& other) : state_{std::move(other.state_)} { other.state_.reset(); }

  // Assigns the promise by taking the continuation from another promise,
  // leaving the other promise empty.
  promise_impl& operator=(promise_impl&& other) {
    if (this != &other) {
      state_ = std::move(other.state_);
      other.state_.reset();
    }
    return *this;
  }

  // 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,
      std::enable_if_t<!std::is_same<continuation_type, OtherContinuation>::value &&
                           std::is_constructible<continuation_type, OtherContinuation&&>::value,
                       bool> = true>
  promise_impl(promise_impl<OtherContinuation> other)
      : state_(other.state_.has_value() ? state_type(continuation_type(std::move(*other.state_)))
                                        : state_type()) {}

  // 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) {
    result_type result = (state_.value())(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() {
    auto continuation = std::move(state_.value());
    state_.reset();
    return continuation;
  }

  // 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&)
  // - (const 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&)
  // - (const 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([] (const 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&)
  // - (const 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([] (const 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 receives a const reference, or non-const reference
  // depending on the signature of the handler's last argument.
  //
  // - 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&)
  // - (const 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); }

 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([] (const weather_type& weather) { ... })
//         .or_else([] (const 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)));
}

// Returns an unboxed promise that immediately returns the specified result when invoked.
//
// This function is especially useful for returning promises from functions
// that have multiple branches some of which complete synchronously.
//
// |result| is the result for the promise to return.
//
// See documentation of |fit::promise| for more information.
template <typename V = void, typename E = void>
inline promise_impl<::fit::internal::result_continuation<V, E>> make_result_promise(
    fit::result<V, E> result) {
  return make_promise_with_continuation(
      ::fit::internal::result_continuation<V, E>(std::move(result)));
}
template <typename V = void, typename E = void>
inline promise_impl<::fit::internal::result_continuation<V, E>> make_result_promise(
    fit::ok_result<V> result) {
  return make_promise_with_continuation(
      ::fit::internal::result_continuation<V, E>(std::move(result)));
}
template <typename V = void, typename E = void>
inline promise_impl<::fit::internal::result_continuation<V, E>> make_result_promise(
    fit::error_result<E> result) {
  return make_promise_with_continuation(
      ::fit::internal::result_continuation<V, E>(std::move(result)));
}
template <typename V = void, typename E = void>
inline promise_impl<::fit::internal::result_continuation<V, E>> make_result_promise(
    fit::pending_result result) {
  return make_promise_with_continuation(
      ::fit::internal::result_continuation<V, E>(std::move(result)));
}

// Returns an unboxed promise that immediately returns the specified value when invoked.
//
// This function is especially useful for returning promises from functions
// that have multiple branches some of which complete synchronously.
//
// |value| is the value for the promise to return.
//
// See documentation of |fit::promise| for more information.
template <typename V>
inline promise_impl<::fit::internal::result_continuation<V, void>> make_ok_promise(V value) {
  return make_result_promise(fit::ok(std::move(value)));
}

// Overload of |make_ok_promise()| used when the value type is void.
inline promise_impl<::fit::internal::result_continuation<void, void>> make_ok_promise() {
  return make_result_promise(fit::ok());
}

// Returns an unboxed promise that immediately returns the specified error when invoked.
//
// This function is especially useful for returning promises from functions
// that have multiple branches some of which complete synchronously.
//
// |error| is the error for the promise to return.
//
// See documentation of |fit::promise| for more information.
template <typename E>
inline promise_impl<::fit::internal::result_continuation<void, E>> make_error_promise(E error) {
  return make_result_promise(fit::error(std::move(error)));
}

// Overload of |make_error_promise()| used when the error type is void.
inline promise_impl<::fit::internal::result_continuation<void, void>> make_error_promise() {
  return make_result_promise(fit::error());
}

// 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_impl<::fit::internal::join_vector_continuation<fit::promise<V, E>>>
join_promise_vector(std::vector<fit::promise<V, E>> promises) {
  return make_promise_with_continuation(
      ::fit::internal::join_vector_continuation<fit::promise<V, E>>(std::move(promises)));
}

// 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/fuchsia/+/master/zircon/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:
  variant<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_
