//===--- Function.h - Utility callable wrappers  -----------------*- C++-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides an analogue to std::function that supports move semantics.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_FUNCTION_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_FUNCTION_H

#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Error.h"
#include <cassert>
#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>

namespace clang {
namespace clangd {

/// A move-only type-erasing function wrapper. Similar to `std::function`, but
/// allows to store move-only callables.
template <class> class UniqueFunction;
/// A Callback<T> is a void function that accepts Expected<T>.
/// This is accepted by ClangdServer functions that logically return T.
template <typename T> using Callback = UniqueFunction<void(llvm::Expected<T>)>;

template <class Ret, class... Args> class UniqueFunction<Ret(Args...)> {
public:
  UniqueFunction() = default;
  UniqueFunction(std::nullptr_t) : UniqueFunction(){};

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

  UniqueFunction(UniqueFunction &&) noexcept = default;
  UniqueFunction &operator=(UniqueFunction &&) noexcept = default;

  template <class Callable,
            /// A sfinae-check that Callable can be called with Args... and
            class = typename std::enable_if<std::is_convertible<
                decltype(std::declval<Callable>()(std::declval<Args>()...)),
                Ret>::value>::type>
  UniqueFunction(Callable &&Func)
      : CallablePtr(llvm::make_unique<
                    FunctionCallImpl<typename std::decay<Callable>::type>>(
            std::forward<Callable>(Func))) {}

  explicit operator bool() { return bool(CallablePtr); }

  Ret operator()(Args... As) {
    assert(CallablePtr);
    return CallablePtr->Call(std::forward<Args>(As)...);
  }

private:
  class FunctionCallBase {
  public:
    virtual ~FunctionCallBase() = default;
    virtual Ret Call(Args... As) = 0;
  };

  template <class Callable>
  class FunctionCallImpl final : public FunctionCallBase {
    static_assert(
        std::is_same<Callable, typename std::decay<Callable>::type>::value,
        "FunctionCallImpl must be instanstiated with std::decay'ed types");

  public:
    FunctionCallImpl(Callable Func) : Func(std::move(Func)) {}

    Ret Call(Args... As) override { return Func(std::forward<Args>(As)...); }

  private:
    Callable Func;
  };

  std::unique_ptr<FunctionCallBase> CallablePtr;
};

/// Stores a callable object (Func) and arguments (Args) and allows to call the
/// callable with provided arguments later using `operator ()`. The arguments
/// are std::forward'ed into the callable in the body of `operator()`. Therefore
/// `operator()` can only be called once, as some of the arguments could be
/// std::move'ed into the callable on first call.
template <class Func, class... Args> struct ForwardBinder {
  using Tuple = std::tuple<typename std::decay<Func>::type,
                           typename std::decay<Args>::type...>;
  Tuple FuncWithArguments;
#ifndef NDEBUG
  bool WasCalled = false;
#endif

public:
  ForwardBinder(Tuple FuncWithArguments)
      : FuncWithArguments(std::move(FuncWithArguments)) {}

private:
  template <std::size_t... Indexes, class... RestArgs>
  auto CallImpl(llvm::integer_sequence<std::size_t, Indexes...> Seq,
                RestArgs &&... Rest)
      -> decltype(std::get<0>(this->FuncWithArguments)(
          std::forward<Args>(std::get<Indexes + 1>(this->FuncWithArguments))...,
          std::forward<RestArgs>(Rest)...)) {
    return std::get<0>(this->FuncWithArguments)(
        std::forward<Args>(std::get<Indexes + 1>(this->FuncWithArguments))...,
        std::forward<RestArgs>(Rest)...);
  }

public:
  template <class... RestArgs>
  auto operator()(RestArgs &&... Rest)
      -> decltype(this->CallImpl(llvm::index_sequence_for<Args...>(),
                                 std::forward<RestArgs>(Rest)...)) {

#ifndef NDEBUG
    assert(!WasCalled && "Can only call result of Bind once.");
    WasCalled = true;
#endif
    return CallImpl(llvm::index_sequence_for<Args...>(),
                    std::forward<RestArgs>(Rest)...);
  }
};

/// Creates an object that stores a callable (\p F) and first arguments to the
/// callable (\p As) and allows to call \p F with \Args at a later point.
/// Similar to std::bind, but also works with move-only \p F and \p As.
///
/// The returned object must be called no more than once, as \p As are
/// std::forwarded'ed (therefore can be moved) into \p F during the call.
template <class Func, class... Args>
ForwardBinder<Func, Args...> Bind(Func F, Args &&... As) {
  return ForwardBinder<Func, Args...>(
      std::make_tuple(std::forward<Func>(F), std::forward<Args>(As)...));
}

} // namespace clangd
} // namespace clang

#endif
