invoke_test.cc 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // Copyright 2017 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "absl/base/internal/invoke.h"
  15. #include <functional>
  16. #include <memory>
  17. #include <string>
  18. #include <utility>
  19. #include "gmock/gmock.h"
  20. #include "gtest/gtest.h"
  21. #include "absl/memory/memory.h"
  22. #include "absl/strings/str_cat.h"
  23. namespace absl {
  24. ABSL_NAMESPACE_BEGIN
  25. namespace base_internal {
  26. namespace {
  27. int Function(int a, int b) { return a - b; }
  28. int Sink(std::unique_ptr<int> p) {
  29. return *p;
  30. }
  31. std::unique_ptr<int> Factory(int n) {
  32. return make_unique<int>(n);
  33. }
  34. void NoOp() {}
  35. struct ConstFunctor {
  36. int operator()(int a, int b) const { return a - b; }
  37. };
  38. struct MutableFunctor {
  39. int operator()(int a, int b) { return a - b; }
  40. };
  41. struct EphemeralFunctor {
  42. int operator()(int a, int b) && { return a - b; }
  43. };
  44. struct OverloadedFunctor {
  45. template <typename... Args>
  46. std::string operator()(const Args&... args) & {
  47. return StrCat("&", args...);
  48. }
  49. template <typename... Args>
  50. std::string operator()(const Args&... args) const& {
  51. return StrCat("const&", args...);
  52. }
  53. template <typename... Args>
  54. std::string operator()(const Args&... args) && {
  55. return StrCat("&&", args...);
  56. }
  57. };
  58. struct Class {
  59. int Method(int a, int b) { return a - b; }
  60. int ConstMethod(int a, int b) const { return a - b; }
  61. int RefMethod(int a, int b) & { return a - b; }
  62. int RefRefMethod(int a, int b) && { return a - b; }
  63. int NoExceptMethod(int a, int b) noexcept { return a - b; }
  64. int VolatileMethod(int a, int b) volatile { return a - b; }
  65. int member;
  66. };
  67. struct FlipFlop {
  68. int ConstMethod() const { return member; }
  69. FlipFlop operator*() const { return {-member}; }
  70. int member;
  71. };
  72. // CallMaybeWithArg(f) resolves either to invoke(f) or invoke(f, 42), depending
  73. // on which one is valid.
  74. template <typename F>
  75. decltype(base_internal::invoke(std::declval<const F&>())) CallMaybeWithArg(
  76. const F& f) {
  77. return base_internal::invoke(f);
  78. }
  79. template <typename F>
  80. decltype(base_internal::invoke(std::declval<const F&>(), 42)) CallMaybeWithArg(
  81. const F& f) {
  82. return base_internal::invoke(f, 42);
  83. }
  84. TEST(InvokeTest, Function) {
  85. EXPECT_EQ(1, base_internal::invoke(Function, 3, 2));
  86. EXPECT_EQ(1, base_internal::invoke(&Function, 3, 2));
  87. }
  88. TEST(InvokeTest, NonCopyableArgument) {
  89. EXPECT_EQ(42, base_internal::invoke(Sink, make_unique<int>(42)));
  90. }
  91. TEST(InvokeTest, NonCopyableResult) {
  92. EXPECT_THAT(base_internal::invoke(Factory, 42), ::testing::Pointee(42));
  93. }
  94. TEST(InvokeTest, VoidResult) { base_internal::invoke(NoOp); }
  95. TEST(InvokeTest, ConstFunctor) {
  96. EXPECT_EQ(1, base_internal::invoke(ConstFunctor(), 3, 2));
  97. }
  98. TEST(InvokeTest, MutableFunctor) {
  99. MutableFunctor f;
  100. EXPECT_EQ(1, base_internal::invoke(f, 3, 2));
  101. EXPECT_EQ(1, base_internal::invoke(MutableFunctor(), 3, 2));
  102. }
  103. TEST(InvokeTest, EphemeralFunctor) {
  104. EphemeralFunctor f;
  105. EXPECT_EQ(1, base_internal::invoke(std::move(f), 3, 2));
  106. EXPECT_EQ(1, base_internal::invoke(EphemeralFunctor(), 3, 2));
  107. }
  108. TEST(InvokeTest, OverloadedFunctor) {
  109. OverloadedFunctor f;
  110. const OverloadedFunctor& cf = f;
  111. EXPECT_EQ("&", base_internal::invoke(f));
  112. EXPECT_EQ("& 42", base_internal::invoke(f, " 42"));
  113. EXPECT_EQ("const&", base_internal::invoke(cf));
  114. EXPECT_EQ("const& 42", base_internal::invoke(cf, " 42"));
  115. EXPECT_EQ("&&", base_internal::invoke(std::move(f)));
  116. OverloadedFunctor f2;
  117. EXPECT_EQ("&& 42", base_internal::invoke(std::move(f2), " 42"));
  118. }
  119. TEST(InvokeTest, ReferenceWrapper) {
  120. ConstFunctor cf;
  121. MutableFunctor mf;
  122. EXPECT_EQ(1, base_internal::invoke(std::cref(cf), 3, 2));
  123. EXPECT_EQ(1, base_internal::invoke(std::ref(cf), 3, 2));
  124. EXPECT_EQ(1, base_internal::invoke(std::ref(mf), 3, 2));
  125. }
  126. TEST(InvokeTest, MemberFunction) {
  127. std::unique_ptr<Class> p(new Class);
  128. std::unique_ptr<const Class> cp(new Class);
  129. std::unique_ptr<volatile Class> vp(new Class);
  130. EXPECT_EQ(1, base_internal::invoke(&Class::Method, p, 3, 2));
  131. EXPECT_EQ(1, base_internal::invoke(&Class::Method, p.get(), 3, 2));
  132. EXPECT_EQ(1, base_internal::invoke(&Class::Method, *p, 3, 2));
  133. EXPECT_EQ(1, base_internal::invoke(&Class::RefMethod, p, 3, 2));
  134. EXPECT_EQ(1, base_internal::invoke(&Class::RefMethod, p.get(), 3, 2));
  135. EXPECT_EQ(1, base_internal::invoke(&Class::RefMethod, *p, 3, 2));
  136. EXPECT_EQ(1, base_internal::invoke(&Class::RefRefMethod, std::move(*p), 3,
  137. 2)); // NOLINT
  138. EXPECT_EQ(1, base_internal::invoke(&Class::NoExceptMethod, p, 3, 2));
  139. EXPECT_EQ(1, base_internal::invoke(&Class::NoExceptMethod, p.get(), 3, 2));
  140. EXPECT_EQ(1, base_internal::invoke(&Class::NoExceptMethod, *p, 3, 2));
  141. EXPECT_EQ(1, base_internal::invoke(&Class::ConstMethod, p, 3, 2));
  142. EXPECT_EQ(1, base_internal::invoke(&Class::ConstMethod, p.get(), 3, 2));
  143. EXPECT_EQ(1, base_internal::invoke(&Class::ConstMethod, *p, 3, 2));
  144. EXPECT_EQ(1, base_internal::invoke(&Class::ConstMethod, cp, 3, 2));
  145. EXPECT_EQ(1, base_internal::invoke(&Class::ConstMethod, cp.get(), 3, 2));
  146. EXPECT_EQ(1, base_internal::invoke(&Class::ConstMethod, *cp, 3, 2));
  147. EXPECT_EQ(1, base_internal::invoke(&Class::VolatileMethod, p, 3, 2));
  148. EXPECT_EQ(1, base_internal::invoke(&Class::VolatileMethod, p.get(), 3, 2));
  149. EXPECT_EQ(1, base_internal::invoke(&Class::VolatileMethod, *p, 3, 2));
  150. EXPECT_EQ(1, base_internal::invoke(&Class::VolatileMethod, vp, 3, 2));
  151. EXPECT_EQ(1, base_internal::invoke(&Class::VolatileMethod, vp.get(), 3, 2));
  152. EXPECT_EQ(1, base_internal::invoke(&Class::VolatileMethod, *vp, 3, 2));
  153. EXPECT_EQ(1,
  154. base_internal::invoke(&Class::Method, make_unique<Class>(), 3, 2));
  155. EXPECT_EQ(1, base_internal::invoke(&Class::ConstMethod, make_unique<Class>(),
  156. 3, 2));
  157. EXPECT_EQ(1, base_internal::invoke(&Class::ConstMethod,
  158. make_unique<const Class>(), 3, 2));
  159. }
  160. TEST(InvokeTest, DataMember) {
  161. std::unique_ptr<Class> p(new Class{42});
  162. std::unique_ptr<const Class> cp(new Class{42});
  163. EXPECT_EQ(42, base_internal::invoke(&Class::member, p));
  164. EXPECT_EQ(42, base_internal::invoke(&Class::member, *p));
  165. EXPECT_EQ(42, base_internal::invoke(&Class::member, p.get()));
  166. base_internal::invoke(&Class::member, p) = 42;
  167. base_internal::invoke(&Class::member, p.get()) = 42;
  168. EXPECT_EQ(42, base_internal::invoke(&Class::member, cp));
  169. EXPECT_EQ(42, base_internal::invoke(&Class::member, *cp));
  170. EXPECT_EQ(42, base_internal::invoke(&Class::member, cp.get()));
  171. }
  172. TEST(InvokeTest, FlipFlop) {
  173. FlipFlop obj = {42};
  174. // This call could resolve to (obj.*&FlipFlop::ConstMethod)() or
  175. // ((*obj).*&FlipFlop::ConstMethod)(). We verify that it's the former.
  176. EXPECT_EQ(42, base_internal::invoke(&FlipFlop::ConstMethod, obj));
  177. EXPECT_EQ(42, base_internal::invoke(&FlipFlop::member, obj));
  178. }
  179. TEST(InvokeTest, SfinaeFriendly) {
  180. CallMaybeWithArg(NoOp);
  181. EXPECT_THAT(CallMaybeWithArg(Factory), ::testing::Pointee(42));
  182. }
  183. } // namespace
  184. } // namespace base_internal
  185. ABSL_NAMESPACE_END
  186. } // namespace absl