FunctionRefTest.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. * Copyright 2016-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <list>
  17. #include <folly/Function.h>
  18. #include <folly/portability/GTest.h>
  19. using folly::Function;
  20. using folly::FunctionRef;
  21. TEST(FunctionRef, Traits) {
  22. static_assert(std::is_literal_type<FunctionRef<int(int)>>::value, "");
  23. // Some earlier versions of libstdc++ lack these traits. Frustrating that
  24. // the value of __GLIBCXX__ doesn't increase with version, but rather reflects
  25. // release date, so some larger values of __GLIBCXX__ lack the traits while
  26. // some smaller values have them. Can't figure out how to reliably test for the
  27. // presence or absence of the traits. :-(
  28. #if !defined(__GLIBCXX__) || __GNUC__ >= 5
  29. static_assert(
  30. std::is_trivially_copy_constructible<FunctionRef<int(int)>>::value, "");
  31. static_assert(
  32. std::is_trivially_move_constructible<FunctionRef<int(int)>>::value, "");
  33. static_assert(
  34. std::is_trivially_constructible<
  35. FunctionRef<int(int)>,
  36. FunctionRef<int(int)>&>::value,
  37. "");
  38. static_assert(
  39. std::is_trivially_copy_assignable<FunctionRef<int(int)>>::value, "");
  40. static_assert(
  41. std::is_trivially_move_assignable<FunctionRef<int(int)>>::value, "");
  42. static_assert(
  43. std::is_trivially_assignable<
  44. FunctionRef<int(int)>,
  45. FunctionRef<int(int)>&>::value,
  46. "");
  47. #endif
  48. static_assert(
  49. std::is_nothrow_copy_constructible<FunctionRef<int(int)>>::value, "");
  50. static_assert(
  51. std::is_nothrow_move_constructible<FunctionRef<int(int)>>::value, "");
  52. static_assert(
  53. std::is_nothrow_constructible<
  54. FunctionRef<int(int)>,
  55. FunctionRef<int(int)>&>::value,
  56. "");
  57. static_assert(
  58. std::is_nothrow_copy_assignable<FunctionRef<int(int)>>::value, "");
  59. static_assert(
  60. std::is_nothrow_move_assignable<FunctionRef<int(int)>>::value, "");
  61. static_assert(
  62. std::is_nothrow_assignable<
  63. FunctionRef<int(int)>,
  64. FunctionRef<int(int)>&>::value,
  65. "");
  66. }
  67. TEST(FunctionRef, Simple) {
  68. int x = 1000;
  69. auto lambda = [&x](int v) { return x += v; };
  70. FunctionRef<int(int)> fref = lambda;
  71. EXPECT_EQ(1005, fref(5));
  72. EXPECT_EQ(1011, fref(6));
  73. EXPECT_EQ(1018, fref(7));
  74. FunctionRef<int(int)> const cfref = lambda;
  75. EXPECT_EQ(1023, cfref(5));
  76. EXPECT_EQ(1029, cfref(6));
  77. EXPECT_EQ(1036, cfref(7));
  78. auto const& clambda = lambda;
  79. FunctionRef<int(int)> fcref = clambda;
  80. EXPECT_EQ(1041, fcref(5));
  81. EXPECT_EQ(1047, fcref(6));
  82. EXPECT_EQ(1054, fcref(7));
  83. FunctionRef<int(int)> const cfcref = clambda;
  84. EXPECT_EQ(1059, cfcref(5));
  85. EXPECT_EQ(1065, cfcref(6));
  86. EXPECT_EQ(1072, cfcref(7));
  87. }
  88. TEST(FunctionRef, FunctionPtr) {
  89. int (*funcptr)(int) = [](int v) { return v * v; };
  90. FunctionRef<int(int)> fref = funcptr;
  91. EXPECT_EQ(100, fref(10));
  92. EXPECT_EQ(121, fref(11));
  93. FunctionRef<int(int)> const cfref = funcptr;
  94. EXPECT_EQ(100, cfref(10));
  95. EXPECT_EQ(121, cfref(11));
  96. }
  97. TEST(FunctionRef, OverloadedFunctor) {
  98. struct OverloadedFunctor {
  99. // variant 1
  100. int operator()(int x) {
  101. return 100 + 1 * x;
  102. }
  103. // variant 2 (const-overload of v1)
  104. int operator()(int x) const {
  105. return 100 + 2 * x;
  106. }
  107. // variant 3
  108. int operator()(int x, int) {
  109. return 100 + 3 * x;
  110. }
  111. // variant 4 (const-overload of v3)
  112. int operator()(int x, int) const {
  113. return 100 + 4 * x;
  114. }
  115. // variant 5 (non-const, has no const-overload)
  116. int operator()(int x, char const*) {
  117. return 100 + 5 * x;
  118. }
  119. // variant 6 (const only)
  120. int operator()(int x, std::vector<int> const&) const {
  121. return 100 + 6 * x;
  122. }
  123. };
  124. OverloadedFunctor of;
  125. auto const& cof = of;
  126. FunctionRef<int(int)> variant1 = of;
  127. EXPECT_EQ(100 + 1 * 15, variant1(15));
  128. FunctionRef<int(int)> const cvariant1 = of;
  129. EXPECT_EQ(100 + 1 * 15, cvariant1(15));
  130. FunctionRef<int(int)> variant2 = cof;
  131. EXPECT_EQ(100 + 2 * 16, variant2(16));
  132. FunctionRef<int(int)> const cvariant2 = cof;
  133. EXPECT_EQ(100 + 2 * 16, cvariant2(16));
  134. FunctionRef<int(int, int)> variant3 = of;
  135. EXPECT_EQ(100 + 3 * 17, variant3(17, 0));
  136. FunctionRef<int(int, int)> const cvariant3 = of;
  137. EXPECT_EQ(100 + 3 * 17, cvariant3(17, 0));
  138. FunctionRef<int(int, int)> variant4 = cof;
  139. EXPECT_EQ(100 + 4 * 18, variant4(18, 0));
  140. FunctionRef<int(int, int)> const cvariant4 = cof;
  141. EXPECT_EQ(100 + 4 * 18, cvariant4(18, 0));
  142. FunctionRef<int(int, char const*)> variant5 = of;
  143. EXPECT_EQ(100 + 5 * 19, variant5(19, "foo"));
  144. FunctionRef<int(int, char const*)> const cvariant5 = of;
  145. EXPECT_EQ(100 + 5 * 19, cvariant5(19, "foo"));
  146. FunctionRef<int(int, std::vector<int> const&)> variant6 = of;
  147. EXPECT_EQ(100 + 6 * 20, variant6(20, {}));
  148. EXPECT_EQ(100 + 6 * 20, variant6(20, {1, 2, 3}));
  149. FunctionRef<int(int, std::vector<int> const&)> const cvariant6 = of;
  150. EXPECT_EQ(100 + 6 * 20, cvariant6(20, {}));
  151. EXPECT_EQ(100 + 6 * 20, cvariant6(20, {1, 2, 3}));
  152. FunctionRef<int(int, std::vector<int> const&)> variant6const = cof;
  153. EXPECT_EQ(100 + 6 * 21, variant6const(21, {}));
  154. FunctionRef<int(int, std::vector<int> const&)> const cvariant6const = cof;
  155. EXPECT_EQ(100 + 6 * 21, cvariant6const(21, {}));
  156. }
  157. TEST(FunctionRef, DefaultConstructAndAssign) {
  158. FunctionRef<int(int, int)> fref;
  159. EXPECT_FALSE(fref);
  160. EXPECT_THROW(fref(1, 2), std::bad_function_call);
  161. int (*func)(int, int) = [](int x, int y) { return 10 * x + y; };
  162. fref = func;
  163. EXPECT_TRUE(fref);
  164. EXPECT_EQ(42, fref(4, 2));
  165. }
  166. template <typename ValueType>
  167. class ForEach {
  168. public:
  169. template <typename InputIterator>
  170. ForEach(InputIterator begin, InputIterator end)
  171. : func_([begin, end](FunctionRef<void(ValueType)> f) {
  172. for (auto it = begin; it != end; ++it) {
  173. f(*it);
  174. }
  175. }) {}
  176. void operator()(FunctionRef<void(ValueType)> f) const {
  177. func_(f);
  178. }
  179. private:
  180. Function<void(FunctionRef<void(ValueType)>) const> const func_;
  181. };
  182. TEST(FunctionRef, ForEach) {
  183. std::list<int> s{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  184. int sum = 0;
  185. ForEach<int> fe{s.begin(), s.end()};
  186. fe([&](int x) { sum += x; });
  187. EXPECT_EQ(55, sum);
  188. }