proxygen
PartialTest.cpp
Go to the documentation of this file.
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 
17 #include <memory>
18 
19 #include <folly/Function.h>
21 
23 
24 using folly::partial;
25 
26 int add3(int x, int y, int z) {
27  return 100 * x + 10 * y + z;
28 }
29 
30 TEST(Partial, Simple) {
31  auto p0 = partial(&add3);
32  EXPECT_EQ(123, p0(1, 2, 3));
33 
34  auto p1 = partial(&add3, 2);
35  EXPECT_EQ(234, p1(3, 4));
36 
37  auto p2 = partial(&add3, 3, 4);
38  EXPECT_EQ(345, p2(5));
39 
40  auto p3 = partial(&add3, 4, 5, 6);
41  EXPECT_EQ(456, p3());
42 }
43 
44 struct Foo {
45  int method(int& x, int& y, int& z) {
46  return 1000 + 100 * x + 10 * y + z;
47  }
48  int constMethod(int const& x, int const& y, int const& z) const {
49  return 2000 + 100 * x + 10 * y + z;
50  }
51  int tempMethod(int&& x, int&& y, int&& z) {
52  return 3000 + 100 * x + 10 * y + z;
53  }
54 };
55 
56 TEST(Partial, ReferenceArguments) {
57  auto p0 = partial(&Foo::method, Foo{}, 2, 3);
58  int four = 4;
59  EXPECT_EQ(1234, p0(four));
60 
61  auto const p1 = partial(&Foo::constMethod, Foo{}, 3, 4);
62  EXPECT_EQ(2345, p1(5));
63 
64  auto p2 = partial(&Foo::tempMethod, Foo{}, 4, 5);
65  EXPECT_EQ(3456, std::move(p2)(6));
66 }
67 
68 struct RefQualifiers {
69  int operator()(int x, int y, int z) & {
70  return 1000 + 100 * x + 10 * y + z;
71  }
72  int operator()(int x, int y, int z) const& {
73  return 2000 + 100 * x + 10 * y + z;
74  }
75  int operator()(int x, int y, int z) && {
76  return 3000 + 100 * x + 10 * y + z;
77  }
78 };
79 
80 TEST(Partial, RefQualifiers) {
81  auto p = partial(RefQualifiers{});
82  auto const& pconst = p;
83 
84  EXPECT_EQ(1234, p(2, 3, 4));
85  EXPECT_EQ(2345, pconst(3, 4, 5));
86  EXPECT_EQ(3456, std::move(p)(4, 5, 6));
87 }
88 
90  int operator()(int& x, int const& y, int z) & {
91  return 1000 + 100 * x + 10 * y + z;
92  }
93  int operator()(int const& x, int y, int z) const& {
94  return 2000 + 100 * x + 10 * y + z;
95  }
96  int operator()(int&& x, int const& y, int z) && {
97  return 3000 + 100 * x + 10 * y + z;
98  }
99 };
100 
101 TEST(Partial, RefQualifiers2) {
102  auto p = partial(RefQualifiers2{}, 9, 8);
103  auto const& pconst = p;
104 
105  EXPECT_EQ(1984, p(4));
106  EXPECT_EQ(2985, pconst(5));
107  EXPECT_EQ(3986, std::move(p)(6));
108 }
109 
110 std::unique_ptr<int> calc_uptr(std::unique_ptr<int> x, std::unique_ptr<int> y) {
111  *x = 100 * *x + 10 * *y;
112  return x;
113 }
114 
115 TEST(Partial, MoveOnly) {
116  auto five = std::make_unique<int>(5);
117  auto six = std::make_unique<int>(6);
118 
119  // create a partial object which holds a pointer to the `calc_uptr` function
120  // and a `unique_ptr<int>` for the first argument
121  auto p = partial(&calc_uptr, std::move(five));
122 
123  // `five` should be moved out of
124  EXPECT_FALSE(five);
125 
126  // call to the partial object as rvalue, which allows the call to consume
127  // captured data (here: the `unique_ptr<int>` storing 5), and pass it
128  // the other `unique_ptr`
129  auto result = std::move(p)(std::move(six));
130 
131  // ...which now should be moved out of
132  EXPECT_FALSE(six);
133 
134  EXPECT_EQ(560, *result);
135 }
136 
137 TEST(Partial, WrapInStdFunction) {
138  auto p1 = partial(&add3, 2);
139  std::function<int(int, int)> func = p1;
140  EXPECT_EQ(234, func(3, 4));
141 }
142 
143 TEST(Partial, WrapInFollyFunction) {
144  auto p1 = partial(&add3, 2);
146  EXPECT_EQ(234, func(3, 4));
147 }
Definition: InvokeTest.cpp:58
int operator()(int const &x, int y, int z) const &
Definition: PartialTest.cpp:93
int operator()(int x, int y, int z)&
Definition: PartialTest.cpp:69
int operator()(int x, int y, int z) const &
Definition: PartialTest.cpp:72
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
int add3(int x, int y, int z)
Definition: PartialTest.cpp:26
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
const int x
int method(int &x, int &y, int &z)
Definition: PartialTest.cpp:45
TEST(Partial, Simple)
Definition: PartialTest.cpp:30
int operator()(int x, int y, int z)&&
Definition: PartialTest.cpp:75
auto partial(F &&f, Args &&...args) -> detail::partial::Partial< typename std::decay< F >::type, std::tuple< typename std::decay< Args >::type... >>
Definition: Partial.h:119
int operator()(int &&x, int const &y, int z)&&
Definition: PartialTest.cpp:96
int constMethod(int const &x, int const &y, int const &z) const
Definition: PartialTest.cpp:48
std::unique_ptr< int > calc_uptr(std::unique_ptr< int > x, std::unique_ptr< int > y)
Definition: InvokeTest.cpp:72
moveonly_::MoveOnly MoveOnly
Definition: Utility.h:386
Definition: InvokeTest.cpp:65
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
int tempMethod(int &&x, int &&y, int &&z)
Definition: PartialTest.cpp:51
int operator()(int &x, int const &y, int z)&
Definition: PartialTest.cpp:90