/*
 *  Copyright 2012 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.
 */

// Bind() is an overloaded function that converts method calls into function
// objects (aka functors). The method object is captured as a scoped_refptr<> if
// possible, and as a raw pointer otherwise. Any arguments to the method are
// captured by value. The return value of Bind is a stateful, nullary function
// object. Care should be taken about the lifetime of objects captured by
// Bind(); the returned functor knows nothing about the lifetime of a non
// ref-counted method object or any arguments passed by pointer, and calling the
// functor with a destroyed object will surely do bad things.
//
// To prevent the method object from being captured as a scoped_refptr<>, you
// can use Unretained. But this should only be done when absolutely necessary,
// and when the caller knows the extra reference isn't needed.
//
// Example usage:
//   struct Foo {
//     int Test1() { return 42; }
//     int Test2() const { return 52; }
//     int Test3(int x) { return x*x; }
//     float Test4(int x, float y) { return x + y; }
//   };
//
//   int main() {
//     Foo foo;
//     cout << rtc::Bind(&Foo::Test1, &foo)() << endl;
//     cout << rtc::Bind(&Foo::Test2, &foo)() << endl;
//     cout << rtc::Bind(&Foo::Test3, &foo, 3)() << endl;
//     cout << rtc::Bind(&Foo::Test4, &foo, 7, 8.5f)() << endl;
//   }
//
// Example usage of ref counted objects:
//   struct Bar {
//     int AddRef();
//     int Release();
//
//     void Test() {}
//     void BindThis() {
//       // The functor passed to AsyncInvoke() will keep this object alive.
//       invoker.AsyncInvoke(RTC_FROM_HERE,rtc::Bind(&Bar::Test, this));
//     }
//   };
//
//   int main() {
//     rtc::scoped_refptr<Bar> bar = new rtc::RefCountedObject<Bar>();
//     auto functor = rtc::Bind(&Bar::Test, bar);
//     bar = nullptr;
//     // The functor stores an internal scoped_refptr<Bar>, so this is safe.
//     functor();
//   }
//

#ifndef RTC_BASE_BIND_H_
#define RTC_BASE_BIND_H_

#include <tuple>
#include <type_traits>

#include "rtc_base/scoped_ref_ptr.h"
#include "rtc_base/template_util.h"

#define NONAME

namespace rtc {
namespace detail {
// This is needed because the template parameters in Bind can't be resolved
// if they're used both as parameters of the function pointer type and as
// parameters to Bind itself: the function pointer parameters are exact
// matches to the function prototype, but the parameters to bind have
// references stripped. This trick allows the compiler to dictate the Bind
// parameter types rather than deduce them.
template <class T> struct identity { typedef T type; };

// IsRefCounted<T>::value will be true for types that can be used in
// rtc::scoped_refptr<T>, i.e. types that implements nullary functions AddRef()
// and Release(), regardless of their return types. AddRef() and Release() can
// be defined in T or any superclass of T.
template <typename T>
class IsRefCounted {
  // This is a complex implementation detail done with SFINAE.

  // Define types such that sizeof(Yes) != sizeof(No).
  struct Yes { char dummy[1]; };
  struct No { char dummy[2]; };
  // Define two overloaded template functions with return types of different
  // size. This way, we can use sizeof() on the return type to determine which
  // function the compiler would have chosen. One function will be preferred
  // over the other if it is possible to create it without compiler errors,
  // otherwise the compiler will simply remove it, and default to the less
  // preferred function.
  template <typename R>
  static Yes test(R* r, decltype(r->AddRef(), r->Release(), 42));
  template <typename C> static No test(...);

public:
  // Trick the compiler to tell if it's possible to call AddRef() and Release().
  static const bool value = sizeof(test<T>((T*)nullptr, 42)) == sizeof(Yes);
};

// TernaryTypeOperator is a helper class to select a type based on a static bool
// value.
template <bool condition, typename IfTrueT, typename IfFalseT>
struct TernaryTypeOperator {};

template <typename IfTrueT, typename IfFalseT>
struct TernaryTypeOperator<true, IfTrueT, IfFalseT> {
  typedef IfTrueT type;
};

template <typename IfTrueT, typename IfFalseT>
struct TernaryTypeOperator<false, IfTrueT, IfFalseT> {
  typedef IfFalseT type;
};

// PointerType<T>::type will be scoped_refptr<T> for ref counted types, and T*
// otherwise.
template <class T>
struct PointerType {
  typedef typename TernaryTypeOperator<IsRefCounted<T>::value,
                                       scoped_refptr<T>,
                                       T*>::type type;
};

template <typename T>
class UnretainedWrapper {
 public:
  explicit UnretainedWrapper(T* o) : ptr_(o) {}
  T* get() const { return ptr_; }

 private:
  T* ptr_;
};

}  // namespace detail

template <typename T>
static inline detail::UnretainedWrapper<T> Unretained(T* o) {
  return detail::UnretainedWrapper<T>(o);
}

template <class ObjectT, class MethodT, class R, typename... Args>
class MethodFunctor {
 public:
  MethodFunctor(MethodT method, ObjectT* object, Args... args)
      : method_(method), object_(object), args_(args...) {}
  R operator()() const {
    return CallMethod(typename sequence_generator<sizeof...(Args)>::type());
  }

 private:
  // Use sequence_generator (see template_util.h) to expand a MethodFunctor
  // with 2 arguments to (std::get<0>(args_), std::get<1>(args_)), for
  // instance.
  template <int... S>
  R CallMethod(sequence<S...>) const {
    return (object_->*method_)(std::get<S>(args_)...);
  }

  MethodT method_;
  typename detail::PointerType<ObjectT>::type object_;
  typename std::tuple<typename std::remove_reference<Args>::type...> args_;
};

template <class ObjectT, class MethodT, class R, typename... Args>
class UnretainedMethodFunctor {
 public:
  UnretainedMethodFunctor(MethodT method,
                          detail::UnretainedWrapper<ObjectT> object,
                          Args... args)
      : method_(method), object_(object.get()), args_(args...) {}
  R operator()() const {
    return CallMethod(typename sequence_generator<sizeof...(Args)>::type());
  }

 private:
  // Use sequence_generator (see template_util.h) to expand an
  // UnretainedMethodFunctor with 2 arguments to (std::get<0>(args_),
  // std::get<1>(args_)), for instance.
  template <int... S>
  R CallMethod(sequence<S...>) const {
    return (object_->*method_)(std::get<S>(args_)...);
  }

  MethodT method_;
  ObjectT* object_;
  typename std::tuple<typename std::remove_reference<Args>::type...> args_;
};

template <class FunctorT, class R, typename... Args>
class Functor {
 public:
  Functor(const FunctorT& functor, Args... args)
      : functor_(functor), args_(args...) {}
  R operator()() const {
    return CallFunction(typename sequence_generator<sizeof...(Args)>::type());
  }

 private:
  // Use sequence_generator (see template_util.h) to expand a Functor
  // with 2 arguments to (std::get<0>(args_), std::get<1>(args_)), for
  // instance.
  template <int... S>
  R CallFunction(sequence<S...>) const {
    return functor_(std::get<S>(args_)...);
  }

  FunctorT functor_;
  typename std::tuple<typename std::remove_reference<Args>::type...> args_;
};

#define FP_T(x) R (ObjectT::*x)(Args...)

template <class ObjectT, class R, typename... Args>
MethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
    FP_T(method),
    ObjectT* object,
    typename detail::identity<Args>::type... args) {
  return MethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(method, object,
                                                          args...);
}

template <class ObjectT, class R, typename... Args>
MethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
    FP_T(method),
    const scoped_refptr<ObjectT>& object,
    typename detail::identity<Args>::type... args) {
  return MethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(method, object.get(),
                                                          args...);
}

template <class ObjectT, class R, typename... Args>
UnretainedMethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
    FP_T(method),
    detail::UnretainedWrapper<ObjectT> object,
    typename detail::identity<Args>::type... args) {
  return UnretainedMethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(
      method, object, args...);
}

#undef FP_T
#define FP_T(x) R (ObjectT::*x)(Args...) const

template <class ObjectT, class R, typename... Args>
MethodFunctor<const ObjectT, FP_T(NONAME), R, Args...> Bind(
    FP_T(method),
    const ObjectT* object,
    typename detail::identity<Args>::type... args) {
  return MethodFunctor<const ObjectT, FP_T(NONAME), R, Args...>(method, object,
                                                                args...);
}
template <class ObjectT, class R, typename... Args>
UnretainedMethodFunctor<const ObjectT, FP_T(NONAME), R, Args...> Bind(
    FP_T(method),
    detail::UnretainedWrapper<const ObjectT> object,
    typename detail::identity<Args>::type... args) {
  return UnretainedMethodFunctor<const ObjectT, FP_T(NONAME), R, Args...>(
      method, object, args...);
}

#undef FP_T
#define FP_T(x) R (*x)(Args...)

template <class R, typename... Args>
Functor<FP_T(NONAME), R, Args...> Bind(
    FP_T(function),
    typename detail::identity<Args>::type... args) {
  return Functor<FP_T(NONAME), R, Args...>(function, args...);
}

#undef FP_T

}  // namespace rtc

#undef NONAME

#endif  // RTC_BASE_BIND_H_
