// Copyright 2017 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_FUNCTION_H_
#define LIB_FIT_FUNCTION_H_

#include "function_internal.h"

namespace fit {

template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
class function_impl;

template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
class callback_impl;

// The default size allowance for storing a target inline within a function
// object, in bytes.  This default allows for inline storage of targets
// as big as two pointers, such as an object pointer and a pointer to a member
// function.
constexpr size_t default_inline_target_size = sizeof(void*) * 2;

// A |fit::function| is a move-only polymorphic function wrapper.
//
// If you need a class with similar characteristics that also ensures
// "run-once" semantics (such as callbacks shared with timeouts, or for
// service requests with redundant, failover, or fallback service providers),
// see |fit::callback|.
//
// |fit::function<T>| behaves like |std::function<T>| except that it is
// move-only instead of copyable, so it can hold targets that cannot be copied,
// such as mutable lambdas, and immutable lambdas that capture move-only
// objects.
//
// Targets of up to |inline_target_size| bytes in size (rounded up for memory
// alignment) are stored inline within the function object without incurring
// any heap allocation.  Larger callable objects will be moved to the heap as
// required.
//
// See also |fit::inline_function<T, size>| for more control over allocation
// behavior.
//
// SYNOPSIS
//
// |T| is the function's signature.  e.g. void(int, std::string).
//
// |inline_target_size| is the minimum size of target that is guaranteed to
// fit within a function without requiring heap allocation.
// Defaults to |default_inline_target_size|.
//
// Class members are documented in |fit::function_impl|, below.
//
// EXAMPLES
//
// - https://fuchsia.googlesource.com/fuchsia/+/master/zircon/system/utest/fit/examples/function_example1.cpp
// - https://fuchsia.googlesource.com/fuchsia/+/master/zircon/system/utest/fit/examples/function_example2.cpp
//
template <typename T,
          size_t inline_target_size = default_inline_target_size>
using function = function_impl<inline_target_size,
                               /*require_inline=*/false, T>;

// A move-only callable object wrapper that forces callables to be stored inline
// and never performs heap allocation.
//
// Behaves just like |fit::function<T, inline_target_size>| except that
// attempting to store a target larger than |inline_target_size| will fail to
// compile.
template <typename T, size_t inline_target_size = default_inline_target_size>
using inline_function = function_impl<inline_target_size,
                                      /*require_inline=*/true, T>;

// Synonym for a function which takes no arguments and produces no result.
using closure = function<void()>;

// A |fit::callback| is a move-only polymorphic function wrapper that also
// ensures "run-once" semantics (such as callbacks shared with timeouts, or for
// service requests with redundant, failover, or fallback service providers).
// A |fit::callback| releases it's resources after the first call, and can be
// inspected before calling, so a potential caller can know if it should call
// the function, or skip the call because the target was already called.
//
// If you need a move-only function class with typical function characteristics,
// that permits multiple invocations of the same function, see |fit::function|.
//
// |fit::callback<T>| behaves like |std::function<T>| except:
//
//   1. It is move-only instead of copyable, so it can hold targets that cannot
//      be copied, such as mutable lambdas, and immutable lambdas that capture
//      move-only objects.
//   2. On the first call to invoke a |fit::callback|, the target function held
//      by the |fit::callback| cannot be called again.
//
// When a |fit::callback| is invoked for the first time, the target function is
// released and destructed, along with any resources owned by that function
// (typically the objects captured by a lambda).
//
// A |fit::callback| in the "already called" state has the same state as a
// |fit::callback| that has been assigned to |nullptr|. It can be compared to
// |nullptr| (via "==" or "!=", and its "operator bool()" returns false, which
// provides a convenient way to gate whether or not the |fit::callback| should
// be called. (Note that invoking an empty |fit::callback| or |fit::function|
// will cause a program abort!)
//
// As an example, sharing |fit::callback| between both a service and a timeout
// might look something like this:
//
//  void service_with_timeout(fit::callback<void(bool)> cb, uint timeout_ms) {
//    service_request([cb = cb.share()]() mutable { if (cb) cb(false); });
//    timeout(timeout_ms, [cb = std::move(cb)]() mutable { if (cb) cb(true); });
//  }
//
// Since |fit::callback| objects are move-only, and not copyable, duplicate
// references to the same |fit::callback| can be obtained via share(), as shown
// in the example above. This method converts the |fit::callback| into a
// reference-counted version of the |fit::callback| and returns a copy of the
// reference as another |fit::callback| with the same target function.
//
// What is notable about |fit::callback<T>.share()| is that invoking any shared
// copy will "nullify" all shared copies, as shown in the example.
//
// Note that |fit::callback| is NOT thread-safe by default. If multi-threaded
// support is required, you would need to implement your own mutex, or similar
// guard, before checking and calling a |fit::callback|.
//
// Targets of up to |inline_target_size| bytes in size (rounded up for memory
// alignment) are stored inline within the callback object without incurring
// any heap allocation.  Larger callable objects will be moved to the heap as
// required.
//
// See also |fit::inline_callback<T, size>| for more control over allocation
// behavior.
//
// SYNOPSIS
//
// |T| is the callback's signature.  e.g. void(int, std::string).
//
// |inline_target_size| is the minimum size of target that is guaranteed to
// fit within a callback without requiring heap allocation.
// Defaults to |default_inline_target_size|.
//
// Class members are documented in |fit::callback_impl|, below.
//
template <typename T,
          size_t inline_target_size = default_inline_target_size>
using callback = callback_impl<inline_target_size, /*require_inline=*/false, T>;

// A move-only, run-once, callable object wrapper that forces callables to be
// stored inline and never performs heap allocation.
//
// Behaves just like |fit::callback<T, inline_target_size>| except that
// attempting to store a target larger than |inline_target_size| will fail to
// compile.
template <typename T,
          size_t inline_target_size = default_inline_target_size>
using inline_callback = callback_impl<inline_target_size,
                                      /*require_inline=*/true, T>;

template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
class function_impl<inline_target_size, require_inline, Result(Args...)>
    final : private ::fit::internal::function_base<inline_target_size,
                                                   require_inline,
                                                   Result(Args...)> {

    using base = ::fit::internal::function_base<inline_target_size,
                                                require_inline,
                                                Result(Args...)>;

    // function_base requires private access during share()
    friend class ::fit::internal::function_base<inline_target_size,
                                                require_inline,
                                                Result(Args...)>;

    // supports target() for shared functions
    friend const void* ::fit::internal::get_target_type_id<>(
        const function_impl<inline_target_size, require_inline,
                            Result(Args...)>&);

public:
    // The function's result type.
    using typename base::result_type;

    // Initializes an empty (null) function. Attempting to call an empty
    // function will abort the program.
    function_impl() = default;

    // Creates a function with an empty target (same outcome as the default
    // constructor).
    function_impl(decltype(nullptr))
        : base(nullptr) {}

    // Creates a function bound to the specified function pointer.
    // If target == nullptr, assigns an empty target.
    function_impl(Result (*target)(Args...))
        : base(target) {}

    // Creates a function bound to the specified callable object.
    // If target == nullptr, assigns an empty target.
    //
    // For functors, we need to capture the raw type but also restrict on the
    // existence of an appropriate operator () to resolve overloads and implicit
    // casts properly.
    //
    // Note that specializations of this template method that take fit::callback
    // objects as the target Callable are deleted (see below).
    template <typename Callable,
              typename = std::enable_if_t<
                  std::is_convertible<
                      decltype(std::declval<Callable&>()(
                          std::declval<Args>()...)),
                      result_type>::value>>
    function_impl(Callable target)
        : base(std::move(target)) {}

    // Deletes the specializations of function_impl(Callable) that would allow
    // a |fit::function| to be constructed from a |fit::callback|. This prevents
    // unexpected behavior of a |fit::function| that would otherwise fail after
    // one call. To explicitly allow this, simply wrap the |fit::callback| in a
    // pass-through lambda before passing it to the |fit::function|.
    template <size_t other_inline_target_size, bool other_require_inline>
    function_impl(::fit::callback_impl<other_inline_target_size,
                                       other_require_inline,
                                       Result(Args...)>) = delete;

    // Creates a function with a target moved from another function,
    // leaving the other function with an empty target.
    function_impl(function_impl&& other)
        : base(static_cast<base&&>(other)) {}

    // Destroys the function, releasing its target.
    ~function_impl() = default;

    // Assigns the function to an empty target. Attempting to invoke the
    // function will abort the program.
    function_impl& operator=(decltype(nullptr)) {
        base::assign(nullptr);
        return *this;
    }

    // Assigns the function to the specified callable object. If target ==
    // nullptr, assigns an empty target.
    //
    // For functors, we need to capture the raw type but also restrict on the
    // existence of an appropriate operator () to resolve overloads and implicit
    // casts properly.
    //
    // Note that specializations of this template method that take fit::callback
    // objects as the target Callable are deleted (see below).
    template <typename Callable,
              typename = std::enable_if_t<
                  std::is_convertible<
                      decltype(std::declval<Callable&>()(
                          std::declval<Args>()...)),
                      result_type>::value>>
    function_impl& operator=(Callable target) {
        base::assign(std::move(target));
        return *this;
    }

    // Deletes the specializations of operator=(Callable) that would allow
    // a |fit::function| to be assigned from a |fit::callback|. This
    // prevents unexpected behavior of a |fit::function| that would otherwise
    // fail after one call. To explicitly allow this, simply wrap the
    // |fit::callback| in a pass-through lambda before assigning it to the
    // |fit::function|.
    template <size_t other_inline_target_size, bool other_require_inline>
    function_impl& operator=(::fit::callback_impl<other_inline_target_size,
                                                  other_require_inline,
                                                  Result(Args...)>) = delete;

    // Move assignment
    function_impl& operator=(function_impl&& other) {
        if (&other == this)
            return *this;
        base::assign(static_cast<base&&>(other));
        return *this;
    }

    // Swaps the functions' targets.
    void swap(function_impl& other) {
        base::swap(other);
    }

    // Returns a pointer to the function's target.
    using base::target;

    // Returns true if the function has a non-empty target.
    using base::operator bool;

    // Invokes the function's target.
    // Aborts if the function's target is empty.
    Result operator()(Args... args) const {
        return base::invoke(std::forward<Args>(args)...);
    }

    // Returns a new function object that invokes the same target.
    // The target itself is not copied; it is moved to the heap and its
    // lifetime is extended until all references have been released.
    //
    // Note: This method is not supported on |fit::inline_function<>|
    //       because it may incur a heap allocation which is contrary to
    //       the stated purpose of |fit::inline_function<>|.
    function_impl share() {
        function_impl copy;
        base::template share_with<function_impl>(copy);
        return copy;
    }
};

template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
void swap(function_impl<inline_target_size, require_inline,
                        Result, Args...>& a,
          function_impl<inline_target_size, require_inline,
                        Result, Args...>& b) {
    a.swap(b);
}

template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
bool operator==(
    const function_impl<inline_target_size, require_inline,
                        Result, Args...>& f,
    decltype(nullptr)) {
    return !f;
}
template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
bool operator==(
    decltype(nullptr),
    const function_impl<inline_target_size, require_inline,
                        Result, Args...>& f) {
    return !f;
}
template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
bool operator!=(
    const function_impl<inline_target_size, require_inline,
                        Result, Args...>& f,
    decltype(nullptr)) {
    return !!f;
}
template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
bool operator!=(
    decltype(nullptr),
    const function_impl<inline_target_size, require_inline,
                        Result, Args...>& f) {
    return !!f;
}

template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
class callback_impl<inline_target_size, require_inline,
                    Result(Args...)>
    final : private ::fit::internal::function_base<inline_target_size,
                                                   require_inline,
                                                   Result(Args...)> {

    using base = ::fit::internal::function_base<inline_target_size,
                                                require_inline,
                                                Result(Args...)>;

    // function_base requires private access during share()
    friend class ::fit::internal::function_base<inline_target_size,
                                                require_inline,
                                                Result(Args...)>;

    // supports target() for shared functions
    friend const void* ::fit::internal::get_target_type_id<>(
        const callback_impl<inline_target_size, require_inline,
                            Result(Args...)>&);

public:
    // The callback function's result type.
    using typename base::result_type;

    // Initializes an empty (null) callback. Attempting to call an empty
    // callback will abort the program.
    callback_impl() = default;

    // Creates a callback with an empty target (same outcome as the default
    // constructor).
    callback_impl(decltype(nullptr))
        : base(nullptr) {}

    // Creates a callback bound to the specified function pointer.
    // If target == nullptr, assigns an empty target.
    callback_impl(Result (*target)(Args...))
        : base(target) {}

    // Creates a callback bound to the specified callable object.
    // If target == nullptr, assigns an empty target.
    //
    // For functors, we need to capture the raw type but also restrict on the
    // existence of an appropriate operator () to resolve overloads and implicit
    // casts properly.
    template <typename Callable,
              typename = std::enable_if_t<
                  std::is_convertible<
                      decltype(std::declval<Callable&>()(
                          std::declval<Args>()...)),
                      result_type>::value>>
    callback_impl(Callable target)
        : base(std::move(target)) {}

    // Creates a callback with a target moved from another callback,
    // leaving the other callback with an empty target.
    callback_impl(callback_impl&& other)
        : base(static_cast<base&&>(other)) {}

    // Destroys the callback, releasing its target.
    ~callback_impl() = default;

    // Assigns the callback to an empty target. Attempting to invoke the
    // callback will abort the program.
    callback_impl& operator=(decltype(nullptr)) {
        base::assign(nullptr);
        return *this;
    }

    // Assigns the callback to the specified callable object. If target ==
    // nullptr, assigns an empty target.
    //
    // For functors, we need to capture the raw type but also restrict on the
    // existence of an appropriate operator () to resolve overloads and implicit
    // casts properly.
    template <typename Callable,
              typename = std::enable_if_t<
                  std::is_convertible<
                      decltype(std::declval<Callable&>()(
                          std::declval<Args>()...)),
                      result_type>::value>>
    callback_impl& operator=(Callable target) {
        base::assign(std::move(target));
        return *this;
    }

    // Move assignment
    callback_impl& operator=(callback_impl&& other) {
        if (&other == this)
            return *this;
        base::assign(static_cast<base&&>(other));
        return *this;
    }

    // Swaps the callbacks' targets.
    void swap(callback_impl& other) {
        base::swap(other);
    }

    // Returns a pointer to the callback's target.
    using base::target;

    // Returns true if the callback has a non-empty target.
    using base::operator bool;

    // Invokes the callback's target.
    // Aborts if the callback's target is empty.
    // |fit::callback| must be non-const to invoke. Before the target function
    // is actually called, the fit::callback will be set to the default empty
    // state (== nullptr, and operator bool() will subsequently return |false|).
    // The target function will then be released after the function is called.
    // If the callback was shared, any remaining copies will also be cleared.
    Result operator()(Args... args) {
        auto temp = std::move(*this);
        return temp.invoke(std::forward<Args>(args)...);
    }

    // Returns a new callback object that invokes the same target.
    // The target itself is not copied; it is moved to the heap and its
    // lifetime is extended until all references have been released.
    // For |fit::callback| (unlike fit::function), the first invocation of the
    // callback will release all references to the target. All callbacks
    // derived from the same original callback (via share()) will be cleared,
    // as if set to |nullptr|, and "operator bool()" will return false.
    //
    // Note: This method is not supported on |fit::inline_function<>|
    //       because it may incur a heap allocation which is contrary to
    //       the stated purpose of |fit::inline_function<>|.
    callback_impl share() {
        callback_impl copy;
        base::template share_with<callback_impl>(copy);
        return copy;
    }
};

template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
void swap(callback_impl<inline_target_size, require_inline,
                        Result, Args...>& a,
          callback_impl<inline_target_size, require_inline,
                        Result, Args...>& b) {
    a.swap(b);
}

template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
bool operator==(
    const callback_impl<inline_target_size, require_inline,
                        Result, Args...>& f,
    decltype(nullptr)) {
    return !f;
}
template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
bool operator==(
    decltype(nullptr),
    const callback_impl<inline_target_size, require_inline,
                        Result, Args...>& f) {
    return !f;
}
template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
bool operator!=(
    const callback_impl<inline_target_size, require_inline,
                        Result, Args...>& f,
    decltype(nullptr)) {
    return !!f;
}
template <size_t inline_target_size, bool require_inline,
          typename Result, typename... Args>
bool operator!=(
    decltype(nullptr),
    const callback_impl<inline_target_size, require_inline,
                        Result, Args...>& f) {
    return !!f;
}

// Returns a Callable object that invokes a member function of an object.
template <typename R, typename T, typename... Args>
auto bind_member(T* instance, R (T::*fn)(Args...)) {
    return [instance, fn](Args... args) {
        return (instance->*fn)(std::forward<Args>(args)...);
    };
}

} // namespace fit

#endif // LIB_FIT_FUNCTION_H_
