/*
 *  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::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_
