2 * Copyright 2017-present Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <folly/lang/PropagateConst.h>
21 #include <folly/portability/GTest.h>
23 using namespace folly;
25 class PropagateConstTest : public testing::Test {};
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>>;
33 static bool is_const(T&&) {
34 return std::is_const<_t<std::remove_reference<T>>>::value;
38 using pc = propagate_const<T>;
40 TEST_F(PropagateConstTest, construct_assign) {
48 /* implicit */ Implicit(Source) {}
53 explicit Explicit(Source) {}
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));
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));
71 TEST_F(PropagateConstTest, op_assign_move) {
72 auto ptr = pc<std::unique_ptr<int>>{std::make_unique<int>(1)};
75 ptr = std::make_unique<int>(2);
79 TEST_F(PropagateConstTest, get) {
82 auto pc_a = pc<int*>(a);
84 EXPECT_EQ(a, pc_a.get());
85 EXPECT_EQ(a, as_const(pc_a).get());
86 EXPECT_FALSE(is_const(*pc_a.get()));
87 EXPECT_TRUE(is_const(*as_const(pc_a).get()));
90 TEST_F(PropagateConstTest, op_indirect) {
93 auto pc_a = pc<int*>(a);
96 EXPECT_EQ(a, &*as_const(pc_a));
97 EXPECT_FALSE(is_const(*pc_a));
98 EXPECT_TRUE(is_const(*as_const(pc_a)));
101 TEST_F(PropagateConstTest, op_element_type_ptr) {
104 auto pc_a = pc<int*>(a);
106 EXPECT_EQ(a, static_cast<int*>(pc_a));
107 EXPECT_EQ(a, static_cast<int const*>(as_const(pc_a)));
110 TEST_F(PropagateConstTest, op_bool) {
113 auto pc_a = pc<int*>(a);
114 auto pc_0 = pc<int*>(nullptr);
120 TEST_F(PropagateConstTest, get_underlying) {
123 auto pc_a = pc<int*>(a);
125 EXPECT_EQ(a, get_underlying(pc_a));
126 EXPECT_EQ(a, get_underlying(as_const(pc_a)));
127 EXPECT_FALSE(is_const(get_underlying(pc_a)));
128 EXPECT_TRUE(is_const(get_underlying(as_const(pc_a))));
129 EXPECT_TRUE(&get_underlying(pc_a) == &get_underlying(as_const(pc_a)));
132 TEST_F(PropagateConstTest, swap) {
133 int data[2] = {3, 4};
136 auto pc_a = pc<int*>(a);
137 auto pc_b = pc<int*>(b);
148 TEST_F(PropagateConstTest, op_equal_to) {
149 int data[2] = {3, 4};
152 auto pc_a = pc<int*>(a);
153 auto pc_b = pc<int*>(b);
155 auto _ = [](auto&& x, auto&& y) { return x == y; };
156 EXPECT_TRUE(_(pc_a, pc_a));
157 EXPECT_FALSE(_(pc_a, pc_b));
158 EXPECT_FALSE(_(pc_a, nullptr));
159 EXPECT_TRUE(_(pc_a, a));
160 EXPECT_FALSE(_(pc_a, b));
161 EXPECT_TRUE(_(a, pc_a));
162 EXPECT_FALSE(_(b, pc_a));
165 TEST_F(PropagateConstTest, op_not_equal_to) {
166 int data[2] = {3, 4};
169 auto pc_a = pc<int*>(a);
170 auto pc_b = pc<int*>(b);
172 auto _ = [](auto&& x, auto&& y) { return x != y; };
173 EXPECT_FALSE(_(pc_a, pc_a));
174 EXPECT_TRUE(_(pc_a, pc_b));
175 EXPECT_TRUE(_(pc_a, nullptr));
176 EXPECT_FALSE(_(pc_a, a));
177 EXPECT_TRUE(_(pc_a, b));
178 EXPECT_FALSE(_(a, pc_a));
179 EXPECT_TRUE(_(b, pc_a));
182 TEST_F(PropagateConstTest, op_less) {
183 int data[2] = {3, 4};
186 auto pc_a = pc<int*>(a);
187 auto pc_b = pc<int*>(b);
189 auto _ = [](auto&& x, auto&& y) { return x < y; };
190 EXPECT_FALSE(_(pc_a, pc_a));
191 EXPECT_FALSE(_(pc_a, a));
192 EXPECT_FALSE(_(a, pc_a));
193 EXPECT_TRUE(_(pc_a, pc_b));
194 EXPECT_TRUE(_(pc_a, b));
195 EXPECT_TRUE(_(a, pc_b));
196 EXPECT_FALSE(_(pc_b, pc_a));
197 EXPECT_FALSE(_(pc_b, a));
198 EXPECT_FALSE(_(b, pc_a));
199 EXPECT_FALSE(_(pc_b, pc_b));
200 EXPECT_FALSE(_(pc_b, b));
201 EXPECT_FALSE(_(b, pc_b));
204 TEST_F(PropagateConstTest, op_greater) {
205 int data[2] = {3, 4};
208 auto pc_a = pc<int*>(a);
209 auto pc_b = pc<int*>(b);
211 auto _ = [](auto&& x, auto&& y) { return x > y; };
212 EXPECT_FALSE(_(pc_a, pc_a));
213 EXPECT_FALSE(_(pc_a, a));
214 EXPECT_FALSE(_(a, pc_a));
215 EXPECT_FALSE(_(pc_a, pc_b));
216 EXPECT_FALSE(_(pc_a, b));
217 EXPECT_FALSE(_(a, pc_b));
218 EXPECT_TRUE(_(pc_b, pc_a));
219 EXPECT_TRUE(_(pc_b, a));
220 EXPECT_TRUE(_(b, pc_a));
221 EXPECT_FALSE(_(pc_b, pc_b));
222 EXPECT_FALSE(_(pc_b, b));
223 EXPECT_FALSE(_(b, pc_b));
226 TEST_F(PropagateConstTest, op_less_equal) {
227 int data[2] = {3, 4};
230 auto pc_a = pc<int*>(a);
231 auto pc_b = pc<int*>(b);
233 auto _ = [](auto&& x, auto&& y) { return x <= y; };
234 EXPECT_TRUE(_(pc_a, pc_a));
235 EXPECT_TRUE(_(pc_a, a));
236 EXPECT_TRUE(_(a, pc_a));
237 EXPECT_TRUE(_(pc_a, pc_b));
238 EXPECT_TRUE(_(pc_a, b));
239 EXPECT_TRUE(_(a, pc_b));
240 EXPECT_FALSE(_(pc_b, pc_a));
241 EXPECT_FALSE(_(pc_b, a));
242 EXPECT_FALSE(_(b, pc_a));
243 EXPECT_TRUE(_(pc_b, pc_b));
244 EXPECT_TRUE(_(pc_b, b));
245 EXPECT_TRUE(_(b, pc_b));
248 TEST_F(PropagateConstTest, op_greater_equal) {
249 int data[2] = {3, 4};
252 auto pc_a = pc<int*>(a);
253 auto pc_b = pc<int*>(b);
255 auto _ = [](auto&& x, auto&& y) { return x >= y; };
256 EXPECT_TRUE(_(pc_a, pc_a));
257 EXPECT_TRUE(_(pc_a, a));
258 EXPECT_TRUE(_(a, pc_a));
259 EXPECT_FALSE(_(pc_a, pc_b));
260 EXPECT_FALSE(_(pc_a, b));
261 EXPECT_FALSE(_(a, pc_b));
262 EXPECT_TRUE(_(pc_b, pc_a));
263 EXPECT_TRUE(_(pc_b, a));
264 EXPECT_TRUE(_(b, pc_a));
265 EXPECT_TRUE(_(pc_b, pc_b));
266 EXPECT_TRUE(_(pc_b, b));
267 EXPECT_TRUE(_(b, pc_b));
270 TEST_F(PropagateConstTest, hash) {
273 auto pc_a = pc<int*>(a);
275 EXPECT_EQ(std::hash<int*>()(a), std::hash<pc<int*>>()(pc_a));
278 TEST_F(PropagateConstTest, equal_to) {
279 int data[2] = {3, 4};
282 auto pc_a = pc<int*>(a);
283 auto pc_b = pc<int*>(b);
285 auto _ = std::equal_to<pc<int*>>{};
286 EXPECT_TRUE(_(pc_a, pc_a));
287 EXPECT_FALSE(_(pc_a, pc_b));
290 TEST_F(PropagateConstTest, not_equal_to) {
291 int data[2] = {3, 4};
294 auto pc_a = pc<int*>(a);
295 auto pc_b = pc<int*>(b);
297 auto _ = std::not_equal_to<pc<int*>>{};
298 EXPECT_FALSE(_(pc_a, pc_a));
299 EXPECT_TRUE(_(pc_a, pc_b));
302 TEST_F(PropagateConstTest, less) {
303 int data[2] = {3, 4};
306 auto pc_a = pc<int*>(a);
307 auto pc_b = pc<int*>(b);
309 auto _ = std::less<pc<int*>>{};
310 EXPECT_FALSE(_(pc_a, pc_a));
311 EXPECT_TRUE(_(pc_a, pc_b));
312 EXPECT_FALSE(_(pc_b, pc_a));
313 EXPECT_FALSE(_(pc_b, pc_b));
316 TEST_F(PropagateConstTest, greater) {
317 int data[2] = {3, 4};
320 auto pc_a = pc<int*>(a);
321 auto pc_b = pc<int*>(b);
323 auto _ = std::greater<pc<int*>>{};
324 EXPECT_FALSE(_(pc_a, pc_a));
325 EXPECT_FALSE(_(pc_a, pc_b));
326 EXPECT_TRUE(_(pc_b, pc_a));
327 EXPECT_FALSE(_(pc_b, pc_b));
330 TEST_F(PropagateConstTest, less_equal) {
331 int data[2] = {3, 4};
334 auto pc_a = pc<int*>(a);
335 auto pc_b = pc<int*>(b);
337 auto _ = std::less_equal<pc<int*>>{};
338 EXPECT_TRUE(_(pc_a, pc_a));
339 EXPECT_TRUE(_(pc_a, pc_b));
340 EXPECT_FALSE(_(pc_b, pc_a));
341 EXPECT_TRUE(_(pc_b, pc_b));
344 TEST_F(PropagateConstTest, greater_equal) {
345 int data[2] = {3, 4};
348 auto pc_a = pc<int*>(a);
349 auto pc_b = pc<int*>(b);
351 auto _ = std::greater_equal<pc<int*>>{};
352 EXPECT_TRUE(_(pc_a, pc_a));
353 EXPECT_FALSE(_(pc_a, pc_b));
354 EXPECT_TRUE(_(pc_b, pc_a));
355 EXPECT_TRUE(_(pc_b, pc_b));