/*
 * libjingle
 * Copyright 2012 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// 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). It captures any arguments to the method by value
// when Bind is called, producing 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 the method's 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 << talk_base::Bind(&Foo::Test1, &foo)() << endl;
//     cout << talk_base::Bind(&Foo::Test2, &foo)() << endl;
//     cout << talk_base::Bind(&Foo::Test3, &foo, 3)() << endl;
//     cout << talk_base::Bind(&Foo::Test4, &foo, 7, 8.5f)() << endl;
//   }

#ifndef TALK_BASE_BIND_H_
#define TALK_BASE_BIND_H_

#define NONAME

namespace talk_base {
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; };
}  // namespace detail

$var n = 5
$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_;
  ObjectT* object_;$for j [[

  P$j 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

]]

}  // namespace talk_base

#undef NONAME

#endif  // TALK_BASE_BIND_H_
