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

// To generate bind.h from bind.h.pump, execute:
// /home/build/google3/third_party/gtest/scripts/pump.py bind.h.pump

// 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.
//
// 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 WEBRTC_BASE_BIND_H_
#define WEBRTC_BASE_BIND_H_

#include "webrtc/base/scoped_ref_ptr.h"
#include "webrtc/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;
};

}  // namespace detail

$var n = 9
$range i 0..n
$for i [[
$range j 1..i

template <class ObjectT, class MethodT, class R$for j [[,
          class P$j]]>
class MethodFunctor$i {
 public:
  MethodFunctor$i(MethodT method, ObjectT* object$for j [[,
                 P$j p$j]])
      : method_(method), object_(object)$for j [[,
      p$(j)_(p$j)]] {}
  R operator()() const {
    return (object_->*method_)($for j , [[p$(j)_]]); }
 private:
  MethodT method_;
  typename detail::PointerType<ObjectT>::type object_;$for j [[

  typename rtc::remove_reference<P$j>::type p$(j)_;]]

};

template <class FunctorT, class R$for j [[,
          class P$j]]>
class Functor$i {
 public:
  $if i == 0 [[explicit ]]
Functor$i(const FunctorT& functor$for j [[, P$j p$j]])
      : functor_(functor)$for j [[,
      p$(j)_(p$j)]] {}
  R operator()() const {
    return functor_($for j , [[p$(j)_]]); }
 private:
  FunctorT functor_;$for j [[

  typename rtc::remove_reference<P$j>::type p$(j)_;]]

};


#define FP_T(x) R (ObjectT::*x)($for j , [[P$j]])

template <class ObjectT, class R$for j [[,
          class P$j]]>
MethodFunctor$i<ObjectT, FP_T(NONAME), R$for j [[, P$j]]>
Bind(FP_T(method), ObjectT* object$for j [[,
     typename detail::identity<P$j>::type p$j]]) {
  return MethodFunctor$i<ObjectT, FP_T(NONAME), R$for j [[, P$j]]>(
      method, object$for j [[, p$j]]);
}

#undef FP_T
#define FP_T(x) R (ObjectT::*x)($for j , [[P$j]]) const

template <class ObjectT, class R$for j [[,
          class P$j]]>
MethodFunctor$i<const ObjectT, FP_T(NONAME), R$for j [[, P$j]]>
Bind(FP_T(method), const ObjectT* object$for j [[,
     typename detail::identity<P$j>::type p$j]]) {
  return MethodFunctor$i<const ObjectT, FP_T(NONAME), R$for j [[, P$j]]>(
      method, object$for j [[, p$j]]);
}

#undef FP_T
#define FP_T(x) R (ObjectT::*x)($for j , [[P$j]])

template <class ObjectT, class R$for j [[,
          class P$j]]>
MethodFunctor$i<ObjectT, FP_T(NONAME), R$for j [[, P$j]]>
Bind(FP_T(method), const scoped_refptr<ObjectT>& object$for j [[,
     typename detail::identity<P$j>::type p$j]]) {
  return MethodFunctor$i<ObjectT, FP_T(NONAME), R$for j [[, P$j]]>(
      method, object.get()$for j [[, p$j]]);
}

#undef FP_T
#define FP_T(x) R (*x)($for j , [[P$j]])

template <class R$for j [[,
          class P$j]]>
Functor$i<FP_T(NONAME), R$for j [[, P$j]]>
Bind(FP_T(function)$for j [[,
     typename detail::identity<P$j>::type p$j]]) {
  return Functor$i<FP_T(NONAME), R$for j [[, P$j]]>(
      function$for j [[, p$j]]);
}

#undef FP_T

]]

}  // namespace rtc

#undef NONAME

#endif  // WEBRTC_BASE_BIND_H_
