proxygen
IndestructibleTest.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 <folly/Indestructible.h>
18 
19 #include <functional>
20 #include <map>
21 #include <memory>
22 #include <string>
23 #include <tuple>
24 
25 #include <folly/Memory.h>
27 
28 using namespace std;
29 using namespace folly;
30 
31 namespace {
32 
33 struct Magic {
34  function<void()> dtor_;
35  function<void()> move_;
36  Magic(function<void()> ctor, function<void()> dtor, function<void()> move)
37  : dtor_(std::move(dtor)), move_(std::move(move)) {
38  ctor();
39  }
40  Magic(Magic&& other) /* may throw */ {
41  *this = std::move(other);
42  }
43  Magic& operator=(Magic&& other) {
44  dtor_ = std::move(other.dtor_);
45  move_ = std::move(other.move_);
46  move_();
47  return *this;
48  }
49  ~Magic() {
50  dtor_();
51  }
52 };
53 
54 class IndestructibleTest : public testing::Test {};
55 } // namespace
56 
57 TEST_F(IndestructibleTest, access) {
59  map<string, int>{{"key1", 17}, {"key2", 19}, {"key3", 23}}};
60 
61  auto& m = *data;
62  EXPECT_EQ(19, m.at("key2"));
63 }
64 
65 TEST_F(IndestructibleTest, no_destruction) {
66  int state = 0;
67  int value = 0;
68 
69  static Indestructible<Magic> sing(
70  [&] {
71  ++state;
72  value = 7;
73  },
74  [&] { state = -1; },
75  [] {});
76  EXPECT_EQ(1, state);
77  EXPECT_EQ(7, value);
78 
79  sing.~Indestructible();
80  EXPECT_EQ(1, state);
81 }
82 
83 TEST_F(IndestructibleTest, empty) {
85  auto& m = *data;
86  EXPECT_EQ(0, m.size());
87 }
88 
89 TEST_F(IndestructibleTest, move) {
90  int state = 0;
91  int value = 0;
92  int moves = 0;
93 
94  static Indestructible<Magic> sing( // move assignment
95  [&] {
96  ++state;
97  value = 7;
98  },
99  [&] { state = -1; },
100  [&] { ++moves; });
101 
102  EXPECT_EQ(1, state);
103  EXPECT_EQ(7, value);
104  EXPECT_EQ(0, moves);
105 
106  // move constructor
107  static Indestructible<Magic> move_ctor(std::move(sing));
108  EXPECT_EQ(1, state);
109  EXPECT_EQ(1, moves);
110 
111  // move assignment
112  static Indestructible<Magic> move_assign = std::move(move_ctor);
113  EXPECT_EQ(1, state);
114  EXPECT_EQ(2, moves);
115 }
116 
117 TEST_F(IndestructibleTest, disabled_default_ctor) {
118  EXPECT_TRUE((std::is_constructible<Indestructible<int>>::value)) << "sanity";
119 
120  struct Foo {
121  Foo(int) {}
122  };
123  EXPECT_FALSE((std::is_constructible<Indestructible<Foo>>::value));
124  EXPECT_FALSE((std::is_constructible<Indestructible<Foo>, Magic>::value));
125  EXPECT_TRUE((std::is_constructible<Indestructible<Foo>, int>::value));
126 }
127 
128 TEST_F(IndestructibleTest, list_initialization) {
130  EXPECT_EQ(map->at(1), 2);
131 }
132 
133 namespace {
134 class InitializerListConstructible {
135  public:
136  InitializerListConstructible(InitializerListConstructible&&) = default;
137  explicit InitializerListConstructible(std::initializer_list<int>) {}
138  InitializerListConstructible(std::initializer_list<double>, double) {}
139 };
140 } // namespace
141 
142 TEST_F(IndestructibleTest, initializer_list_in_place_initialization) {
143  using I = InitializerListConstructible;
144  std::ignore = Indestructible<I>{{1, 2, 3, 4}};
145  std::ignore = Indestructible<I>{{1.2}, 4.2};
146 }
147 
148 namespace {
149 class ExplicitlyMoveConstructible {
150  public:
151  ExplicitlyMoveConstructible() = default;
152  explicit ExplicitlyMoveConstructible(ExplicitlyMoveConstructible&&) = default;
153 };
154 } // namespace
155 
156 TEST_F(IndestructibleTest, list_initialization_explicit_implicit) {
157  using E = ExplicitlyMoveConstructible;
158  using I = std::map<int, int>;
159  EXPECT_TRUE((!std::is_convertible<E, Indestructible<E>>::value));
160  EXPECT_TRUE((std::is_convertible<I, Indestructible<I>>::value));
161 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
constexpr auto empty(C const &c) -> decltype(c.empty())
Definition: Access.h:55
static Map map(mapCap)
static map< string, int > m
static const char *const value
Definition: Conv.cpp:50
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST_F(IndestructibleTest, access)
static constexpr uint64_t data[1]
Definition: Fingerprint.cpp:43
state
Definition: http_parser.c:272