/*
 *  Copyright 2020 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef RTC_BASE_FUNCTION_H_
#define RTC_BASE_FUNCTION_H_

#include <memory>
#include <type_traits>
#include <utility>

#include "rtc_base/system/assume.h"

namespace webrtc {
namespace webrtc_function_impl {

using FunVoid = void();

union VoidUnion {
  void* void_ptr;
  FunVoid* fun_ptr;
  typename std::aligned_storage<16>::type inline_storage;
};

template <typename T>
struct CallHelpers;
template <typename RetT, typename... ArgT>
struct CallHelpers<RetT(ArgT...)> {
  using return_type = RetT;
  template <typename F>
  static RetT CallVoidPtr(VoidUnion* vu, ArgT... args) {
    return (*static_cast<F*>(vu->void_ptr))(std::forward<ArgT>(args)...);
  }
  static RetT CallFunPtr(VoidUnion* vu, ArgT... args) {
    return (reinterpret_cast<RetT (*)(ArgT...)>(vu->fun_ptr))(
        std::forward<ArgT>(args)...);
  }
  template <typename F>
  static RetT CallInlineStorage(VoidUnion* vu, ArgT... args) {
    return (*reinterpret_cast<F*>(&vu->inline_storage))(
        std::forward<ArgT>(args)...);
  }
  static RetT DoCall(FunVoid* f, VoidUnion* vu, ArgT... args) {
    return reinterpret_cast<RetT (*)(VoidUnion*, ArgT...)>(f)(
        vu, std::forward<ArgT>(args)...);
  }
};

}  // namespace webrtc_function_impl

// A class that holds (and owns) any callable. The same function call signature
// must be provided when constructing and calling the object.
//
// The point of not having the call signature as a class template parameter is
// to have one single concrete type for all signatures; this reduces binary
// size.
class UntypedFunction final {
 public:
  // Create function for lambdas and other callables; it accepts every type of
  // argument except those noted in its enable_if call.
  template <
      typename Signature,
      typename F,
      typename std::enable_if<
          // Not for function pointers; we have another overload for that below.
          !std::is_function<typename std::remove_pointer<
              typename std::remove_reference<F>::type>::type>::value &&

          // Not for nullptr; we have another overload for that below.
          !std::is_same<std::nullptr_t,
                        typename std::remove_cv<F>::type>::value &&

          // Not for UntypedFunction objects; we have another overload for that.
          !std::is_same<UntypedFunction,
                        typename std::remove_cv<typename std::remove_reference<
                            F>::type>::type>::value>::type* = nullptr>
  static UntypedFunction Create(F&& f) {
    using F_deref = typename std::remove_reference<F>::type;
    // TODO(C++17): Use `constexpr if` here. The compiler appears to do the
    // right thing anyway w.r.t. resolving the branch statically and
    // eliminating dead code, but it would be good for readability.
    if (std::is_trivially_move_constructible<F_deref>::value &&
        std::is_trivially_destructible<F_deref>::value &&
        sizeof(F_deref) <=
            sizeof(webrtc_function_impl::VoidUnion::inline_storage)) {
      // The callable is trivial and small enough, so we just store its bytes
      // in the inline storage.
      webrtc_function_impl::VoidUnion vu;
      new (&vu.inline_storage) F_deref(std::forward<F>(f));
      return UntypedFunction(
          vu,
          reinterpret_cast<webrtc_function_impl::FunVoid*>(
              webrtc_function_impl::CallHelpers<
                  Signature>::template CallInlineStorage<F_deref>),
          nullptr);
    } else {
      // The callable is either nontrivial or too large, so we can't keep it
      // in the inline storage; use the heap instead.
      return UntypedFunction(
          webrtc_function_impl::VoidUnion{.void_ptr =
                                              new F_deref(std::forward<F>(f))},
          reinterpret_cast<webrtc_function_impl::FunVoid*>(
              webrtc_function_impl::CallHelpers<
                  Signature>::template CallVoidPtr<F_deref>),
          static_cast<void (*)(webrtc_function_impl::VoidUnion*)>(
              [](webrtc_function_impl::VoidUnion* vu) {
                // Assuming that this pointer isn't null allows the
                // compiler to eliminate a null check in the (inlined)
                // delete operation.
                RTC_ASSUME(vu->void_ptr != nullptr);
                delete reinterpret_cast<F_deref*>(vu->void_ptr);
              }));
    }
  }

  // Create function that accepts function pointers. If the argument is null,
  // the result is an empty UntypedFunction.
  template <typename Signature>
  static UntypedFunction Create(Signature* f) {
    return UntypedFunction(
        reinterpret_cast<webrtc_function_impl::FunVoid*>(f),
        f ? reinterpret_cast<webrtc_function_impl::FunVoid*>(
                webrtc_function_impl::CallHelpers<Signature>::CallFunPtr)
          : nullptr,
        nullptr);
  }

  // Default constructor. Creates an empty UntypedFunction.
  UntypedFunction() : call_(nullptr), delete_(nullptr) {}

  // Not copyable.
  UntypedFunction(const UntypedFunction&) = delete;
  UntypedFunction& operator=(const UntypedFunction&) = delete;

  // Move construction and assignment.
  UntypedFunction(UntypedFunction&& other)
      : f_(other.f_), call_(other.call_), delete_(other.delete_) {
    other.delete_ = nullptr;
  }
  UntypedFunction& operator=(UntypedFunction&& other) {
    f_ = other.f_;
    call_ = other.call_;
    delete_ = other.delete_;
    other.delete_ = nullptr;
    return *this;
  }

  ~UntypedFunction() {
    if (delete_) {
      delete_(&f_);
    }
  }

  friend void swap(UntypedFunction& a, UntypedFunction& b) {
    using std::swap;
    swap(a.f_, b.f_);
    swap(a.call_, b.call_);
    swap(a.delete_, b.delete_);
  }

  // Returns true if we have a function, false if we don't (i.e., we're null).
  explicit operator bool() const { return call_ != nullptr; }

  template <typename Signature, typename... ArgT>
  typename webrtc_function_impl::CallHelpers<Signature>::return_type Call(
      ArgT... args) {
    return webrtc_function_impl::CallHelpers<Signature>::DoCall(
        call_, &f_, std::forward<ArgT>(args)...);
  }

  // Returns true iff we don't need to call a destructor. This is guaranteed
  // to hold for a moved-from object.
  bool IsTriviallyDestructible() { return delete_ == nullptr; }

 private:
  UntypedFunction(webrtc_function_impl::VoidUnion f,
                  webrtc_function_impl::FunVoid* call,
                  void (*del)(webrtc_function_impl::VoidUnion*))
      : f_(f), call_(call), delete_(del) {}

  // The callable thing, or a pointer to it.
  webrtc_function_impl::VoidUnion f_;

  // Pointer to a dispatch function that knows the type of the callable thing
  // that's stored in f_, and how to call it. An UntypedFunction object is empty
  // (null) iff call_ is null.
  webrtc_function_impl::FunVoid* call_;

  // Pointer to a function that knows how to delete the callable thing that's
  // stored in f_. Null if `f_` is trivially deletable.
  void (*delete_)(webrtc_function_impl::VoidUnion*);
};

}  // namespace webrtc

#endif  // RTC_BASE_FUNCTION_H_
