1a62f48d79c5bec191d72f7a890fd162a9867875
[folly.git] / folly / lang / test / PropagateConstTest.cpp
1 /*
2  * Copyright 2017-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 <folly/lang/PropagateConst.h>
18
19 #include <memory>
20
21 #include <folly/portability/GTest.h>
22
23 using namespace folly;
24
25 class PropagateConstTest : public testing::Test {};
26
27 //  force complete template instantiations
28 template class folly::propagate_const<int*>;
29 template class folly::propagate_const<std::unique_ptr<int>>;
30 template class folly::propagate_const<std::shared_ptr<int>>;
31
32 template <typename T>
33 static bool is_const(T&&) {
34   return std::is_const<_t<std::remove_reference<T>>>::value;
35 }
36
37 template <typename T>
38 using pc = propagate_const<T>;
39
40 TEST_F(PropagateConstTest, construct_assign) {
41   struct Source {
42     int& operator*();
43     int* get();
44   };
45   struct Implicit {
46     int& operator*();
47     int* get();
48     /* implicit */ Implicit(Source) {}
49   };
50   struct Explicit {
51     int& operator*();
52     int* get();
53     explicit Explicit(Source) {}
54   };
55
56   EXPECT_TRUE((std::is_constructible<pc<Implicit>, Source>::value));
57   EXPECT_TRUE((std::is_constructible<pc<Explicit>, Source>::value));
58   EXPECT_TRUE((std::is_convertible<Source, pc<Implicit>>::value));
59   EXPECT_FALSE((std::is_convertible<Source, pc<Explicit>>::value));
60   EXPECT_TRUE((std::is_assignable<pc<Implicit>, Source>::value));
61   EXPECT_FALSE((std::is_assignable<pc<Explicit>, Source>::value));
62
63   EXPECT_TRUE((std::is_constructible<pc<Implicit>, pc<Source>>::value));
64   EXPECT_TRUE((std::is_constructible<pc<Explicit>, pc<Source>>::value));
65   EXPECT_TRUE((std::is_convertible<pc<Source>, pc<Implicit>>::value));
66   EXPECT_FALSE((std::is_convertible<pc<Source>, pc<Explicit>>::value));
67   EXPECT_TRUE((std::is_assignable<pc<Implicit>, pc<Source>>::value));
68   EXPECT_FALSE((std::is_assignable<pc<Explicit>, pc<Source>>::value));
69 }
70
71 TEST_F(PropagateConstTest, op_assign_move) {
72   auto ptr = pc<std::unique_ptr<int>>{std::make_unique<int>(1)};
73   EXPECT_EQ(*ptr, 1);
74
75   ptr = std::make_unique<int>(2);
76   EXPECT_EQ(*ptr, 2);
77 }
78
79 TEST_F(PropagateConstTest, get) {
80   int a = 3;
81   auto pc_a = pc<int*>(&a);
82
83   EXPECT_EQ(&a, pc_a.get());
84   EXPECT_EQ(&a, as_const(pc_a).get());
85   EXPECT_FALSE(is_const(*pc_a.get()));
86   EXPECT_TRUE(is_const(*as_const(pc_a).get()));
87 }
88
89 TEST_F(PropagateConstTest, op_indirect) {
90   int a = 3;
91   auto pc_a = pc<int*>(&a);
92
93   EXPECT_EQ(&a, &*pc_a);
94   EXPECT_EQ(&a, &*as_const(pc_a));
95   EXPECT_FALSE(is_const(*pc_a));
96   EXPECT_TRUE(is_const(*as_const(pc_a)));
97 }
98
99 TEST_F(PropagateConstTest, op_element_type_ptr) {
100   int a = 3;
101   auto pc_a = pc<int*>(&a);
102
103   EXPECT_EQ(&a, static_cast<int*>(pc_a));
104   EXPECT_EQ(&a, static_cast<int const*>(as_const(pc_a)));
105 }
106
107 TEST_F(PropagateConstTest, op_bool) {
108   int a = 3;
109   auto pc_a = pc<int*>(&a);
110   auto pc_0 = pc<int*>(nullptr);
111
112   EXPECT_TRUE(pc_a);
113   EXPECT_FALSE(pc_0);
114 }
115
116 TEST_F(PropagateConstTest, get_underlying) {
117   int a = 3;
118   auto pc_a = pc<int*>(&a);
119
120   EXPECT_EQ(&a, get_underlying(pc_a));
121   EXPECT_EQ(&a, get_underlying(as_const(pc_a)));
122   EXPECT_FALSE(is_const(get_underlying(pc_a)));
123   EXPECT_TRUE(is_const(get_underlying(as_const(pc_a))));
124   EXPECT_TRUE(&get_underlying(pc_a) == &get_underlying(as_const(pc_a)));
125 }
126
127 TEST_F(PropagateConstTest, swap) {
128   int a = 3;
129   int b = 4;
130   auto pc_a = pc<int*>(&a);
131   auto pc_b = pc<int*>(&b);
132
133   swap(pc_a, pc_b);
134   EXPECT_EQ(3, *pc_b);
135   EXPECT_EQ(4, *pc_a);
136
137   swap(pc_a, pc_b);
138   EXPECT_EQ(3, *pc_a);
139   EXPECT_EQ(4, *pc_b);
140 }
141
142 TEST_F(PropagateConstTest, op_equal_to) {
143   int a = 3;
144   int b = 4;
145   auto pc_a = pc<int*>(&a);
146   auto pc_b = pc<int*>(&b);
147
148   auto _ = [](auto&& x, auto&& y) { return x == y; };
149   EXPECT_TRUE(_(pc_a, pc_a));
150   EXPECT_FALSE(_(pc_a, pc_b));
151   EXPECT_FALSE(_(pc_a, nullptr));
152   EXPECT_TRUE(_(pc_a, &a));
153   EXPECT_FALSE(_(pc_a, &b));
154   EXPECT_TRUE(_(&a, pc_a));
155   EXPECT_FALSE(_(&b, pc_a));
156 }
157
158 TEST_F(PropagateConstTest, op_not_equal_to) {
159   int a = 3;
160   int b = 4;
161   auto pc_a = pc<int*>(&a);
162   auto pc_b = pc<int*>(&b);
163
164   auto _ = [](auto&& x, auto&& y) { return x != y; };
165   EXPECT_FALSE(_(pc_a, pc_a));
166   EXPECT_TRUE(_(pc_a, pc_b));
167   EXPECT_TRUE(_(pc_a, nullptr));
168   EXPECT_FALSE(_(pc_a, &a));
169   EXPECT_TRUE(_(pc_a, &b));
170   EXPECT_FALSE(_(&a, pc_a));
171   EXPECT_TRUE(_(&b, pc_a));
172 }
173
174 TEST_F(PropagateConstTest, op_less) {
175   int a = 3;
176   int b = 4;
177   auto pc_a = pc<int*>(&a);
178   auto pc_b = pc<int*>(&b);
179
180   auto _ = [](auto&& x, auto&& y) { return x < y; };
181   EXPECT_FALSE(_(pc_a, pc_a));
182   EXPECT_FALSE(_(pc_a, &a));
183   EXPECT_FALSE(_(&a, pc_a));
184   EXPECT_TRUE(_(pc_a, pc_b));
185   EXPECT_TRUE(_(pc_a, &b));
186   EXPECT_TRUE(_(&a, pc_b));
187   EXPECT_FALSE(_(pc_b, pc_a));
188   EXPECT_FALSE(_(pc_b, &a));
189   EXPECT_FALSE(_(&b, pc_a));
190   EXPECT_FALSE(_(pc_b, pc_b));
191   EXPECT_FALSE(_(pc_b, &b));
192   EXPECT_FALSE(_(&b, pc_b));
193 }
194
195 TEST_F(PropagateConstTest, op_greater) {
196   int a = 3;
197   int b = 4;
198   auto pc_a = pc<int*>(&a);
199   auto pc_b = pc<int*>(&b);
200
201   auto _ = [](auto&& x, auto&& y) { return x > y; };
202   EXPECT_FALSE(_(pc_a, pc_a));
203   EXPECT_FALSE(_(pc_a, &a));
204   EXPECT_FALSE(_(&a, pc_a));
205   EXPECT_FALSE(_(pc_a, pc_b));
206   EXPECT_FALSE(_(pc_a, &b));
207   EXPECT_FALSE(_(&a, pc_b));
208   EXPECT_TRUE(_(pc_b, pc_a));
209   EXPECT_TRUE(_(pc_b, &a));
210   EXPECT_TRUE(_(&b, pc_a));
211   EXPECT_FALSE(_(pc_b, pc_b));
212   EXPECT_FALSE(_(pc_b, &b));
213   EXPECT_FALSE(_(&b, pc_b));
214 }
215
216 TEST_F(PropagateConstTest, op_less_equal) {
217   int a = 3;
218   int b = 4;
219   auto pc_a = pc<int*>(&a);
220   auto pc_b = pc<int*>(&b);
221
222   auto _ = [](auto&& x, auto&& y) { return x <= y; };
223   EXPECT_TRUE(_(pc_a, pc_a));
224   EXPECT_TRUE(_(pc_a, &a));
225   EXPECT_TRUE(_(&a, pc_a));
226   EXPECT_TRUE(_(pc_a, pc_b));
227   EXPECT_TRUE(_(pc_a, &b));
228   EXPECT_TRUE(_(&a, pc_b));
229   EXPECT_FALSE(_(pc_b, pc_a));
230   EXPECT_FALSE(_(pc_b, &a));
231   EXPECT_FALSE(_(&b, pc_a));
232   EXPECT_TRUE(_(pc_b, pc_b));
233   EXPECT_TRUE(_(pc_b, &b));
234   EXPECT_TRUE(_(&b, pc_b));
235 }
236
237 TEST_F(PropagateConstTest, op_greater_equal) {
238   int a = 3;
239   int b = 4;
240   auto pc_a = pc<int*>(&a);
241   auto pc_b = pc<int*>(&b);
242
243   auto _ = [](auto&& x, auto&& y) { return x >= y; };
244   EXPECT_TRUE(_(pc_a, pc_a));
245   EXPECT_TRUE(_(pc_a, &a));
246   EXPECT_TRUE(_(&a, pc_a));
247   EXPECT_FALSE(_(pc_a, pc_b));
248   EXPECT_FALSE(_(pc_a, &b));
249   EXPECT_FALSE(_(&a, pc_b));
250   EXPECT_TRUE(_(pc_b, pc_a));
251   EXPECT_TRUE(_(pc_b, &a));
252   EXPECT_TRUE(_(&b, pc_a));
253   EXPECT_TRUE(_(pc_b, pc_b));
254   EXPECT_TRUE(_(pc_b, &b));
255   EXPECT_TRUE(_(&b, pc_b));
256 }
257
258 TEST_F(PropagateConstTest, hash) {
259   int a = 3;
260   auto pc_a = pc<int*>(&a);
261
262   EXPECT_EQ(std::hash<int*>()(&a), std::hash<pc<int*>>()(pc_a));
263 }
264
265 TEST_F(PropagateConstTest, equal_to) {
266   int a = 3;
267   int b = 4;
268   auto pc_a = pc<int*>(&a);
269   auto pc_b = pc<int*>(&b);
270
271   auto _ = std::equal_to<pc<int*>>{};
272   EXPECT_TRUE(_(pc_a, pc_a));
273   EXPECT_FALSE(_(pc_a, pc_b));
274 }
275
276 TEST_F(PropagateConstTest, not_equal_to) {
277   int a = 3;
278   int b = 4;
279   auto pc_a = pc<int*>(&a);
280   auto pc_b = pc<int*>(&b);
281
282   auto _ = std::not_equal_to<pc<int*>>{};
283   EXPECT_FALSE(_(pc_a, pc_a));
284   EXPECT_TRUE(_(pc_a, pc_b));
285 }
286
287 TEST_F(PropagateConstTest, less) {
288   int a = 3;
289   int b = 4;
290   auto pc_a = pc<int*>(&a);
291   auto pc_b = pc<int*>(&b);
292
293   auto _ = std::less<pc<int*>>{};
294   EXPECT_FALSE(_(pc_a, pc_a));
295   EXPECT_TRUE(_(pc_a, pc_b));
296   EXPECT_FALSE(_(pc_b, pc_a));
297   EXPECT_FALSE(_(pc_b, pc_b));
298 }
299
300 TEST_F(PropagateConstTest, greater) {
301   int a = 3;
302   int b = 4;
303   auto pc_a = pc<int*>(&a);
304   auto pc_b = pc<int*>(&b);
305
306   auto _ = std::greater<pc<int*>>{};
307   EXPECT_FALSE(_(pc_a, pc_a));
308   EXPECT_FALSE(_(pc_a, pc_b));
309   EXPECT_TRUE(_(pc_b, pc_a));
310   EXPECT_FALSE(_(pc_b, pc_b));
311 }
312
313 TEST_F(PropagateConstTest, less_equal) {
314   int a = 3;
315   int b = 4;
316   auto pc_a = pc<int*>(&a);
317   auto pc_b = pc<int*>(&b);
318
319   auto _ = std::less_equal<pc<int*>>{};
320   EXPECT_TRUE(_(pc_a, pc_a));
321   EXPECT_TRUE(_(pc_a, pc_b));
322   EXPECT_FALSE(_(pc_b, pc_a));
323   EXPECT_TRUE(_(pc_b, pc_b));
324 }
325
326 TEST_F(PropagateConstTest, greater_equal) {
327   int a = 3;
328   int b = 4;
329   auto pc_a = pc<int*>(&a);
330   auto pc_b = pc<int*>(&b);
331
332   auto _ = std::greater_equal<pc<int*>>{};
333   EXPECT_TRUE(_(pc_a, pc_a));
334   EXPECT_FALSE(_(pc_a, pc_b));
335   EXPECT_TRUE(_(pc_b, pc_a));
336   EXPECT_TRUE(_(pc_b, pc_b));
337 }