1 // This file was GENERATED by command:
3 // DO NOT EDIT BY HAND!!!
7 * Copyright 2012 Google Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
12 * 1. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
23 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 // To generate bind.h from bind.h.pump, execute:
33 // /home/build/google3/third_party/gtest/scripts/pump.py bind.h.pump
35 // Bind() is an overloaded function that converts method calls into function
36 // objects (aka functors). It captures any arguments to the method by value
37 // when Bind is called, producing a stateful, nullary function object. Care
38 // should be taken about the lifetime of objects captured by Bind(); the
39 // returned functor knows nothing about the lifetime of the method's object or
40 // any arguments passed by pointer, and calling the functor with a destroyed
41 // object will surely do bad things.
45 // int Test1() { return 42; }
46 // int Test2() const { return 52; }
47 // int Test3(int x) { return x*x; }
48 // float Test4(int x, float y) { return x + y; }
53 // cout << talk_base::Bind(&Foo::Test1, &foo)() << endl;
54 // cout << talk_base::Bind(&Foo::Test2, &foo)() << endl;
55 // cout << talk_base::Bind(&Foo::Test3, &foo, 3)() << endl;
56 // cout << talk_base::Bind(&Foo::Test4, &foo, 7, 8.5f)() << endl;
59 #ifndef TALK_BASE_BIND_H_
60 #define TALK_BASE_BIND_H_
66 // This is needed because the template parameters in Bind can't be resolved
67 // if they're used both as parameters of the function pointer type and as
68 // parameters to Bind itself: the function pointer parameters are exact
69 // matches to the function prototype, but the parameters to bind have
70 // references stripped. This trick allows the compiler to dictate the Bind
71 // parameter types rather than deduce them.
72 template <class T> struct identity { typedef T type; };
75 template <class ObjectT, class MethodT, class R>
76 class MethodFunctor0 {
78 MethodFunctor0(MethodT method, ObjectT* object)
79 : method_(method), object_(object) {}
80 R operator()() const {
81 return (object_->*method_)(); }
87 #define FP_T(x) R (ObjectT::*x)()
89 template <class ObjectT, class R>
90 MethodFunctor0<ObjectT, FP_T(NONAME), R>
91 Bind(FP_T(method), ObjectT* object) {
92 return MethodFunctor0<ObjectT, FP_T(NONAME), R>(
97 #define FP_T(x) R (ObjectT::*x)() const
99 template <class ObjectT, class R>
100 MethodFunctor0<const ObjectT, FP_T(NONAME), R>
101 Bind(FP_T(method), const ObjectT* object) {
102 return MethodFunctor0<const ObjectT, FP_T(NONAME), R>(
108 template <class ObjectT, class MethodT, class R,
110 class MethodFunctor1 {
112 MethodFunctor1(MethodT method, ObjectT* object,
114 : method_(method), object_(object),
116 R operator()() const {
117 return (object_->*method_)(p1_); }
124 #define FP_T(x) R (ObjectT::*x)(P1)
126 template <class ObjectT, class R,
128 MethodFunctor1<ObjectT, FP_T(NONAME), R, P1>
129 Bind(FP_T(method), ObjectT* object,
130 typename detail::identity<P1>::type p1) {
131 return MethodFunctor1<ObjectT, FP_T(NONAME), R, P1>(
136 #define FP_T(x) R (ObjectT::*x)(P1) const
138 template <class ObjectT, class R,
140 MethodFunctor1<const ObjectT, FP_T(NONAME), R, P1>
141 Bind(FP_T(method), const ObjectT* object,
142 typename detail::identity<P1>::type p1) {
143 return MethodFunctor1<const ObjectT, FP_T(NONAME), R, P1>(
149 template <class ObjectT, class MethodT, class R,
152 class MethodFunctor2 {
154 MethodFunctor2(MethodT method, ObjectT* object,
157 : method_(method), object_(object),
160 R operator()() const {
161 return (object_->*method_)(p1_, p2_); }
169 #define FP_T(x) R (ObjectT::*x)(P1, P2)
171 template <class ObjectT, class R,
174 MethodFunctor2<ObjectT, FP_T(NONAME), R, P1, P2>
175 Bind(FP_T(method), ObjectT* object,
176 typename detail::identity<P1>::type p1,
177 typename detail::identity<P2>::type p2) {
178 return MethodFunctor2<ObjectT, FP_T(NONAME), R, P1, P2>(
179 method, object, p1, p2);
183 #define FP_T(x) R (ObjectT::*x)(P1, P2) const
185 template <class ObjectT, class R,
188 MethodFunctor2<const ObjectT, FP_T(NONAME), R, P1, P2>
189 Bind(FP_T(method), const ObjectT* object,
190 typename detail::identity<P1>::type p1,
191 typename detail::identity<P2>::type p2) {
192 return MethodFunctor2<const ObjectT, FP_T(NONAME), R, P1, P2>(
193 method, object, p1, p2);
198 template <class ObjectT, class MethodT, class R,
202 class MethodFunctor3 {
204 MethodFunctor3(MethodT method, ObjectT* object,
208 : method_(method), object_(object),
212 R operator()() const {
213 return (object_->*method_)(p1_, p2_, p3_); }
222 #define FP_T(x) R (ObjectT::*x)(P1, P2, P3)
224 template <class ObjectT, class R,
228 MethodFunctor3<ObjectT, FP_T(NONAME), R, P1, P2, P3>
229 Bind(FP_T(method), ObjectT* object,
230 typename detail::identity<P1>::type p1,
231 typename detail::identity<P2>::type p2,
232 typename detail::identity<P3>::type p3) {
233 return MethodFunctor3<ObjectT, FP_T(NONAME), R, P1, P2, P3>(
234 method, object, p1, p2, p3);
238 #define FP_T(x) R (ObjectT::*x)(P1, P2, P3) const
240 template <class ObjectT, class R,
244 MethodFunctor3<const ObjectT, FP_T(NONAME), R, P1, P2, P3>
245 Bind(FP_T(method), const ObjectT* object,
246 typename detail::identity<P1>::type p1,
247 typename detail::identity<P2>::type p2,
248 typename detail::identity<P3>::type p3) {
249 return MethodFunctor3<const ObjectT, FP_T(NONAME), R, P1, P2, P3>(
250 method, object, p1, p2, p3);
255 template <class ObjectT, class MethodT, class R,
260 class MethodFunctor4 {
262 MethodFunctor4(MethodT method, ObjectT* object,
267 : method_(method), object_(object),
272 R operator()() const {
273 return (object_->*method_)(p1_, p2_, p3_, p4_); }
283 #define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4)
285 template <class ObjectT, class R,
290 MethodFunctor4<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4>
291 Bind(FP_T(method), ObjectT* object,
292 typename detail::identity<P1>::type p1,
293 typename detail::identity<P2>::type p2,
294 typename detail::identity<P3>::type p3,
295 typename detail::identity<P4>::type p4) {
296 return MethodFunctor4<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4>(
297 method, object, p1, p2, p3, p4);
301 #define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4) const
303 template <class ObjectT, class R,
308 MethodFunctor4<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4>
309 Bind(FP_T(method), const ObjectT* object,
310 typename detail::identity<P1>::type p1,
311 typename detail::identity<P2>::type p2,
312 typename detail::identity<P3>::type p3,
313 typename detail::identity<P4>::type p4) {
314 return MethodFunctor4<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4>(
315 method, object, p1, p2, p3, p4);
320 template <class ObjectT, class MethodT, class R,
326 class MethodFunctor5 {
328 MethodFunctor5(MethodT method, ObjectT* object,
334 : method_(method), object_(object),
340 R operator()() const {
341 return (object_->*method_)(p1_, p2_, p3_, p4_, p5_); }
352 #define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5)
354 template <class ObjectT, class R,
360 MethodFunctor5<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5>
361 Bind(FP_T(method), ObjectT* object,
362 typename detail::identity<P1>::type p1,
363 typename detail::identity<P2>::type p2,
364 typename detail::identity<P3>::type p3,
365 typename detail::identity<P4>::type p4,
366 typename detail::identity<P5>::type p5) {
367 return MethodFunctor5<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5>(
368 method, object, p1, p2, p3, p4, p5);
372 #define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5) const
374 template <class ObjectT, class R,
380 MethodFunctor5<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5>
381 Bind(FP_T(method), const ObjectT* object,
382 typename detail::identity<P1>::type p1,
383 typename detail::identity<P2>::type p2,
384 typename detail::identity<P3>::type p3,
385 typename detail::identity<P4>::type p4,
386 typename detail::identity<P5>::type p5) {
387 return MethodFunctor5<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5>(
388 method, object, p1, p2, p3, p4, p5);
393 } // namespace talk_base
397 #endif // TALK_BASE_BIND_H_