Use the GTest portability headers
[folly.git] / folly / test / IndestructibleTest.cpp
1 /*
2  * Copyright 2016 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/Indestructible.h>
18
19 #include <functional>
20 #include <map>
21 #include <memory>
22 #include <string>
23
24 #include <folly/Memory.h>
25 #include <folly/portability/GTest.h>
26
27 using namespace std;
28 using namespace folly;
29
30 namespace {
31
32 struct Magic {
33   function<void()> dtor_;
34   function<void()> move_;
35   Magic(function<void()> ctor, function<void()> dtor, function<void()> move)
36       : dtor_(std::move(dtor)), move_(std::move(move)) {
37     ctor();
38   }
39   Magic(Magic&& other) /* may throw */ { *this = std::move(other); }
40   Magic& operator=(Magic&& other) {
41     dtor_ = std::move(other.dtor_);
42     move_ = std::move(other.move_);
43     move_();
44     return *this;
45   }
46   ~Magic() { dtor_(); }
47 };
48
49 class IndestructibleTest : public testing::Test {};
50 }
51
52 TEST_F(IndestructibleTest, access) {
53   static const Indestructible<map<string, int>> data{
54       map<string, int>{{"key1", 17}, {"key2", 19}, {"key3", 23}}};
55
56   auto& m = *data;
57   EXPECT_EQ(19, m.at("key2"));
58 }
59
60 TEST_F(IndestructibleTest, no_destruction) {
61   int state = 0;
62   int value = 0;
63
64   static Indestructible<Magic> sing(
65       [&] {
66         ++state;
67         value = 7;
68       },
69       [&] { state = -1; },
70       [] {});
71   EXPECT_EQ(1, state);
72   EXPECT_EQ(7, value);
73
74   sing.~Indestructible();
75   EXPECT_EQ(1, state);
76 }
77
78 TEST_F(IndestructibleTest, move) {
79   int state = 0;
80   int value = 0;
81   int moves = 0;
82
83   static Indestructible<Magic> sing( // move assignment
84       [&] {
85         ++state;
86         value = 7;
87       },
88       [&] { state = -1; },
89       [&] { ++moves; });
90
91   EXPECT_EQ(1, state);
92   EXPECT_EQ(7, value);
93   EXPECT_EQ(0, moves);
94
95   // move constructor
96   static Indestructible<Magic> move_ctor(std::move(sing));
97   EXPECT_EQ(1, state);
98   EXPECT_EQ(1, moves);
99
100   // move assignment
101   static Indestructible<Magic> move_assign = std::move(move_ctor);
102   EXPECT_EQ(1, state);
103   EXPECT_EQ(2, moves);
104 }