f8a81f1bd74d8263e74b665922e0070b77fe2b90
[folly.git] / folly / test / FunctionalTest.cpp
1 /*
2  * Copyright 2017 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 <utility>
18
19 #include <folly/Functional.h>
20 #include <folly/portability/GTest.h>
21
22 TEST(RvalueReferenceWrapper, MoveAndConvert) {
23   using folly::rvalue_reference_wrapper;
24
25   // Destructive moves.
26   int i1 = 0;
27   rvalue_reference_wrapper<int> rref1(std::move(i1));
28   ASSERT_TRUE(rref1.valid());
29   rvalue_reference_wrapper<int> rref0(std::move(rref1));
30   ASSERT_TRUE(rref0.valid());
31   ASSERT_FALSE(rref1.valid());
32   rref1 = std::move(rref0);
33   ASSERT_FALSE(rref0.valid());
34   ASSERT_TRUE(rref1.valid());
35   const int& r1 = std::move(rref1);
36   ASSERT_FALSE(rref1.valid());
37   ASSERT_EQ(&r1, &i1);
38
39   // Destructive unwrap to T&&.
40   int i2 = 0;
41   rvalue_reference_wrapper<int> rref2(std::move(i2));
42   int&& r2 = std::move(rref2);
43   ASSERT_EQ(&r2, &i2);
44
45   // Destructive unwrap to const T&.
46   const int i3 = 0;
47   rvalue_reference_wrapper<const int> rref3(std::move(i3));
48   const int& r3 = std::move(rref3);
49   ASSERT_EQ(&r3, &i3);
50
51   // Destructive unwrap to const T&&.
52   const int i4 = 0;
53   rvalue_reference_wrapper<const int> rref4(std::move(i4));
54   const int&& r4 = std::move(rref4);
55   ASSERT_EQ(&r4, &i4);
56
57   /*
58    * Things that intentionally do not compile. Copy construction, copy
59    * assignment, unwrap of lvalue reference to wrapper, const violations.
60    *
61   int i5;
62   const int i6 = 0;
63   rvalue_reference_wrapper<int> rref5(i5);
64   rvalue_reference_wrapper<const int> rref6(i6);
65   rref1 = rref5;
66   int& r5 = rref5;
67   const int& r6 = rref6;
68   int i7;
69   const rvalue_reference_wrapper<int> rref7(std::move(i7));
70   int& r7 = std::move(rref7);
71   */
72 }
73
74 TEST(RvalueReferenceWrapper, Call) {
75   int a = 4711, b, c;
76   auto callMe = [&](int x, const int& y, int&& z) -> int {
77     EXPECT_EQ(a, x);
78     EXPECT_EQ(&b, &y);
79     EXPECT_EQ(&c, &z);
80     return a;
81   };
82   int result = folly::rref(std::move(callMe))(a, b, std::move(c));
83   EXPECT_EQ(a, result);
84 }