Add MockFunction::AsStdFunction(). Also pull in gtest 688.


git-svn-id: http://googlemock.googlecode.com/svn/trunk@479 8415998a-534a-0410-bf83-d39667b30386
diff --git a/include/gmock/gmock-generated-function-mockers.h b/include/gmock/gmock-generated-function-mockers.h
index 1b01dc8..d14e1ad 100644
--- a/include/gmock/gmock-generated-function-mockers.h
+++ b/include/gmock/gmock-generated-function-mockers.h
@@ -854,6 +854,17 @@
 // point "2", and nothing should happen between the two check
 // points. The explicit check points make it easy to tell which
 // Bar("a") is called by which call to Foo().
+//
+// MockFunction<F> can also be used to exercise code that accepts
+// std::function<F> callbacks. To do so, use AsStdFunction() method
+// to create std::function proxy forwarding to original object's Call.
+// Example:
+//
+// TEST(FooTest, RunsCallbackWithBarArgument) {
+//   MockFunction<int(string)> callback;
+//   EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
+//   Foo(callback.AsStdFunction());
+// }
 template <typename F>
 class MockFunction;
 
@@ -864,6 +875,14 @@
 
   MOCK_METHOD0_T(Call, R());
 
+#if GTEST_LANG_CXX11
+  std::function<R()> AsStdFunction() {
+    return [this]() {
+      return this->Call();
+    };
+  }
+#endif  // GTEST_LANG_CXX11
+
  private:
   GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
 };
@@ -875,6 +894,14 @@
 
   MOCK_METHOD1_T(Call, R(A0));
 
+#if GTEST_LANG_CXX11
+  std::function<R(A0)> AsStdFunction() {
+    return [this](A0 a0) {
+      return this->Call(a0);
+    };
+  }
+#endif  // GTEST_LANG_CXX11
+
  private:
   GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
 };
@@ -886,6 +913,14 @@
 
   MOCK_METHOD2_T(Call, R(A0, A1));
 
+#if GTEST_LANG_CXX11
+  std::function<R(A0, A1)> AsStdFunction() {
+    return [this](A0 a0, A1 a1) {
+      return this->Call(a0, a1);
+    };
+  }
+#endif  // GTEST_LANG_CXX11
+
  private:
   GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
 };
@@ -897,6 +932,14 @@
 
   MOCK_METHOD3_T(Call, R(A0, A1, A2));
 
+#if GTEST_LANG_CXX11
+  std::function<R(A0, A1, A2)> AsStdFunction() {
+    return [this](A0 a0, A1 a1, A2 a2) {
+      return this->Call(a0, a1, a2);
+    };
+  }
+#endif  // GTEST_LANG_CXX11
+
  private:
   GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
 };
@@ -908,6 +951,14 @@
 
   MOCK_METHOD4_T(Call, R(A0, A1, A2, A3));
 
+#if GTEST_LANG_CXX11
+  std::function<R(A0, A1, A2, A3)> AsStdFunction() {
+    return [this](A0 a0, A1 a1, A2 a2, A3 a3) {
+      return this->Call(a0, a1, a2, a3);
+    };
+  }
+#endif  // GTEST_LANG_CXX11
+
  private:
   GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
 };
@@ -920,6 +971,14 @@
 
   MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4));
 
+#if GTEST_LANG_CXX11
+  std::function<R(A0, A1, A2, A3, A4)> AsStdFunction() {
+    return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
+      return this->Call(a0, a1, a2, a3, a4);
+    };
+  }
+#endif  // GTEST_LANG_CXX11
+
  private:
   GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
 };
@@ -932,6 +991,14 @@
 
   MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5));
 
+#if GTEST_LANG_CXX11
+  std::function<R(A0, A1, A2, A3, A4, A5)> AsStdFunction() {
+    return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
+      return this->Call(a0, a1, a2, a3, a4, a5);
+    };
+  }
+#endif  // GTEST_LANG_CXX11
+
  private:
   GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
 };
@@ -944,6 +1011,14 @@
 
   MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6));
 
+#if GTEST_LANG_CXX11
+  std::function<R(A0, A1, A2, A3, A4, A5, A6)> AsStdFunction() {
+    return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
+      return this->Call(a0, a1, a2, a3, a4, a5, a6);
+    };
+  }
+#endif  // GTEST_LANG_CXX11
+
  private:
   GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
 };
@@ -956,6 +1031,14 @@
 
   MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7));
 
+#if GTEST_LANG_CXX11
+  std::function<R(A0, A1, A2, A3, A4, A5, A6, A7)> AsStdFunction() {
+    return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
+      return this->Call(a0, a1, a2, a3, a4, a5, a6, a7);
+    };
+  }
+#endif  // GTEST_LANG_CXX11
+
  private:
   GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
 };
@@ -968,6 +1051,15 @@
 
   MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8));
 
+#if GTEST_LANG_CXX11
+  std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> AsStdFunction() {
+    return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7,
+        A8 a8) {
+      return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+    };
+  }
+#endif  // GTEST_LANG_CXX11
+
  private:
   GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
 };
@@ -981,6 +1073,15 @@
 
   MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9));
 
+#if GTEST_LANG_CXX11
+  std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> AsStdFunction() {
+    return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7,
+        A8 a8, A9 a9) {
+      return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+    };
+  }
+#endif  // GTEST_LANG_CXX11
+
  private:
   GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
 };
diff --git a/include/gmock/gmock-generated-function-mockers.h.pump b/include/gmock/gmock-generated-function-mockers.h.pump
index be81996..5e83962 100644
--- a/include/gmock/gmock-generated-function-mockers.h.pump
+++ b/include/gmock/gmock-generated-function-mockers.h.pump
@@ -241,18 +241,40 @@
 // point "2", and nothing should happen between the two check
 // points. The explicit check points make it easy to tell which
 // Bar("a") is called by which call to Foo().
+//
+// MockFunction<F> can also be used to exercise code that accepts
+// std::function<F> callbacks. To do so, use AsStdFunction() method
+// to create std::function proxy forwarding to original object's Call.
+// Example:
+//
+// TEST(FooTest, RunsCallbackWithBarArgument) {
+//   MockFunction<int(string)> callback;
+//   EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
+//   Foo(callback.AsStdFunction());
+// }
 template <typename F>
 class MockFunction;
 
 
 $for i [[
 $range j 0..i-1
+$var ArgTypes = [[$for j, [[A$j]]]]
+$var ArgNames = [[$for j, [[a$j]]]]
+$var ArgDecls = [[$for j, [[A$j a$j]]]]
 template <typename R$for j [[, typename A$j]]>
-class MockFunction<R($for j, [[A$j]])> {
+class MockFunction<R($ArgTypes)> {
  public:
   MockFunction() {}
 
-  MOCK_METHOD$i[[]]_T(Call, R($for j, [[A$j]]));
+  MOCK_METHOD$i[[]]_T(Call, R($ArgTypes));
+
+#if GTEST_LANG_CXX11
+  std::function<R($ArgTypes)> AsStdFunction() {
+    return [this]($ArgDecls) {
+      return this->Call($ArgNames);
+    };
+  }
+#endif  // GTEST_LANG_CXX11
 
  private:
   GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
diff --git a/test/gmock-generated-function-mockers_test.cc b/test/gmock-generated-function-mockers_test.cc
index 169ed5a..14dded8 100644
--- a/test/gmock-generated-function-mockers_test.cc
+++ b/test/gmock-generated-function-mockers_test.cc
@@ -595,5 +595,18 @@
   EXPECT_EQ(2, foo.Call(true, 'a', 0, 0, 0, 0, 0, 'b', 1, false));
 }
 
+#if GTEST_LANG_CXX11
+TEST(MockFunctionTest, AsStdFunction) {
+  MockFunction<int(int)> foo;
+  auto call = [](const std::function<int(int)> &f, int i) {
+    return f(i);
+  };
+  EXPECT_CALL(foo, Call(1)).WillOnce(Return(-1));
+  EXPECT_CALL(foo, Call(2)).WillOnce(Return(-2));
+  EXPECT_EQ(-1, call(foo.AsStdFunction(), 1));
+  EXPECT_EQ(-2, call(foo.AsStdFunction(), 2));
+}
+#endif  // GTEST_LANG_CXX11
+
 }  // namespace gmock_generated_function_mockers_test
 }  // namespace testing