PartialTest.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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 <memory>
  17. #include <folly/Function.h>
  18. #include <folly/functional/Partial.h>
  19. #include <folly/portability/GTest.h>
  20. using folly::partial;
  21. int add3(int x, int y, int z) {
  22. return 100 * x + 10 * y + z;
  23. }
  24. TEST(Partial, Simple) {
  25. auto p0 = partial(&add3);
  26. EXPECT_EQ(123, p0(1, 2, 3));
  27. auto p1 = partial(&add3, 2);
  28. EXPECT_EQ(234, p1(3, 4));
  29. auto p2 = partial(&add3, 3, 4);
  30. EXPECT_EQ(345, p2(5));
  31. auto p3 = partial(&add3, 4, 5, 6);
  32. EXPECT_EQ(456, p3());
  33. }
  34. struct Foo {
  35. int method(int& x, int& y, int& z) {
  36. return 1000 + 100 * x + 10 * y + z;
  37. }
  38. int constMethod(int const& x, int const& y, int const& z) const {
  39. return 2000 + 100 * x + 10 * y + z;
  40. }
  41. int tempMethod(int&& x, int&& y, int&& z) {
  42. return 3000 + 100 * x + 10 * y + z;
  43. }
  44. };
  45. TEST(Partial, ReferenceArguments) {
  46. auto p0 = partial(&Foo::method, Foo{}, 2, 3);
  47. int four = 4;
  48. EXPECT_EQ(1234, p0(four));
  49. auto const p1 = partial(&Foo::constMethod, Foo{}, 3, 4);
  50. EXPECT_EQ(2345, p1(5));
  51. auto p2 = partial(&Foo::tempMethod, Foo{}, 4, 5);
  52. EXPECT_EQ(3456, std::move(p2)(6));
  53. }
  54. struct RefQualifiers {
  55. int operator()(int x, int y, int z) & {
  56. return 1000 + 100 * x + 10 * y + z;
  57. }
  58. int operator()(int x, int y, int z) const& {
  59. return 2000 + 100 * x + 10 * y + z;
  60. }
  61. int operator()(int x, int y, int z) && {
  62. return 3000 + 100 * x + 10 * y + z;
  63. }
  64. };
  65. TEST(Partial, RefQualifiers) {
  66. auto p = partial(RefQualifiers{});
  67. auto const& pconst = p;
  68. EXPECT_EQ(1234, p(2, 3, 4));
  69. EXPECT_EQ(2345, pconst(3, 4, 5));
  70. EXPECT_EQ(3456, std::move(p)(4, 5, 6));
  71. }
  72. struct RefQualifiers2 {
  73. int operator()(int& x, int const& y, int z) & {
  74. return 1000 + 100 * x + 10 * y + z;
  75. }
  76. int operator()(int const& x, int y, int z) const& {
  77. return 2000 + 100 * x + 10 * y + z;
  78. }
  79. int operator()(int&& x, int const& y, int z) && {
  80. return 3000 + 100 * x + 10 * y + z;
  81. }
  82. };
  83. TEST(Partial, RefQualifiers2) {
  84. auto p = partial(RefQualifiers2{}, 9, 8);
  85. auto const& pconst = p;
  86. EXPECT_EQ(1984, p(4));
  87. EXPECT_EQ(2985, pconst(5));
  88. EXPECT_EQ(3986, std::move(p)(6));
  89. }
  90. std::unique_ptr<int> calc_uptr(std::unique_ptr<int> x, std::unique_ptr<int> y) {
  91. *x = 100 * *x + 10 * *y;
  92. return x;
  93. }
  94. TEST(Partial, MoveOnly) {
  95. auto five = std::make_unique<int>(5);
  96. auto six = std::make_unique<int>(6);
  97. // create a partial object which holds a pointer to the `calc_uptr` function
  98. // and a `unique_ptr<int>` for the first argument
  99. auto p = partial(&calc_uptr, std::move(five));
  100. // `five` should be moved out of
  101. EXPECT_FALSE(five);
  102. // call to the partial object as rvalue, which allows the call to consume
  103. // captured data (here: the `unique_ptr<int>` storing 5), and pass it
  104. // the other `unique_ptr`
  105. auto result = std::move(p)(std::move(six));
  106. // ...which now should be moved out of
  107. EXPECT_FALSE(six);
  108. EXPECT_EQ(560, *result);
  109. }
  110. TEST(Partial, WrapInStdFunction) {
  111. auto p1 = partial(&add3, 2);
  112. std::function<int(int, int)> func = p1;
  113. EXPECT_EQ(234, func(3, 4));
  114. }
  115. TEST(Partial, WrapInFollyFunction) {
  116. auto p1 = partial(&add3, 2);
  117. folly::Function<int(int, int)> func = p1;
  118. EXPECT_EQ(234, func(3, 4));
  119. }