proxygen
MapUtilTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2012-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/MapUtil.h>
18 
19 #include <cstddef>
20 #include <map>
21 #include <unordered_map>
22 
23 #include <folly/Traits.h>
25 
26 using namespace folly;
27 
28 TEST(MapUtil, get_default) {
29  std::map<int, int> m;
30  m[1] = 2;
31  EXPECT_EQ(2, get_default(m, 1, 42));
32  EXPECT_EQ(42, get_default(m, 2, 42));
33  EXPECT_EQ(0, get_default(m, 3));
34 }
35 
36 TEST(MapUtil, get_default_function) {
37  std::map<int, int> m;
38  m[1] = 2;
39  EXPECT_EQ(2, get_default(m, 1, [] { return 42; }));
40  EXPECT_EQ(42, get_default(m, 2, [] { return 42; }));
41  EXPECT_EQ(0, get_default(m, 3));
42 }
43 
44 TEST(MapUtil, get_or_throw) {
45  std::map<int, int> m;
46  m[1] = 2;
47  EXPECT_EQ(2, get_or_throw(m, 1));
48  EXPECT_THROW(get_or_throw(m, 2), std::out_of_range);
49  EXPECT_EQ(&m[1], &get_or_throw(m, 1));
50  get_or_throw(m, 1) = 3;
51  EXPECT_EQ(3, get_or_throw(m, 1));
52  const auto& cm = m;
53  EXPECT_EQ(&m[1], &get_or_throw(cm, 1));
54  EXPECT_EQ(3, get_or_throw(cm, 1));
55  EXPECT_THROW(get_or_throw(cm, 2), std::out_of_range);
56 }
57 
58 TEST(MapUtil, get_or_throw_specified) {
59  std::map<int, int> m;
60  m[1] = 2;
61  EXPECT_EQ(2, get_or_throw<std::runtime_error>(m, 1));
62  EXPECT_THROW(get_or_throw<std::runtime_error>(m, 2), std::runtime_error);
63 }
64 
65 TEST(MapUtil, get_optional) {
66  std::map<int, int> m;
67  m[1] = 2;
68  EXPECT_TRUE(get_optional(m, 1).hasValue());
69  EXPECT_EQ(2, get_optional(m, 1).value());
70  EXPECT_FALSE(get_optional(m, 2).hasValue());
71 }
72 
73 TEST(MapUtil, get_optional_path_simple) {
74  using std::map;
75  map<int, map<int, map<int, map<int, int>>>> m{{1, {{2, {{3, {{4, 5}}}}}}}};
76  EXPECT_EQ(folly::Optional<int>(5), get_optional(m, 1, 2, 3, 4));
77  EXPECT_TRUE(get_optional(m, 1, 2, 3, 4));
78  EXPECT_FALSE(get_optional(m, 1, 2, 3, 0));
79  EXPECT_TRUE(get_optional(m, 1, 2, 3));
80  EXPECT_FALSE(get_optional(m, 1, 2, 0));
81  EXPECT_TRUE(get_optional(m, 1, 2));
82  EXPECT_FALSE(get_optional(m, 1, 0));
85 }
86 
87 TEST(MapUtil, get_optional_path_mixed) {
88  using std::map;
89  using std::string;
90  using std::unordered_map;
91  unordered_map<string, map<int, map<string, int>>> m{{"a", {{1, {{"b", 2}}}}}};
92  EXPECT_EQ(folly::Optional<int>(2), get_optional(m, "a", 1, "b"));
93  EXPECT_TRUE(get_optional(m, "a", 1, "b"));
94  EXPECT_FALSE(get_optional(m, "b", 1, "b"));
95  EXPECT_FALSE(get_optional(m, "a", 2, "b"));
96  EXPECT_FALSE(get_optional(m, "a", 1, "c"));
97  EXPECT_TRUE(get_optional(m, "a", 1));
98  EXPECT_TRUE(get_optional(m, "a"));
99 }
100 
102  std::map<int, int> m;
103  m[1] = 2;
104  const int i = 42;
105  EXPECT_EQ(2, get_ref_default(m, 1, i));
106  EXPECT_EQ(42, get_ref_default(m, 2, i));
107  EXPECT_EQ(std::addressof(i), std::addressof(get_ref_default(m, 2, i)));
108 }
109 
110 TEST(MapUtil, get_ref_default_function) {
111  std::map<int, int> m;
112  m[1] = 2;
113  const int i = 42;
114  EXPECT_EQ(2, get_ref_default(m, 1, [&i]() -> const int& { return i; }));
115  EXPECT_EQ(42, get_ref_default(m, 2, [&i]() -> const int& { return i; }));
116  EXPECT_EQ(
117  std::addressof(i),
118  std::addressof(
119  get_ref_default(m, 2, [&i]() -> const int& { return i; })));
120  // statically disallowed:
121  // get_ref_default(m, 2, [] { return 7; });
122 }
123 
124 TEST(MapUtil, get_ptr) {
125  std::map<int, int> m;
126  m[1] = 2;
127  EXPECT_EQ(2, *get_ptr(m, 1));
128  EXPECT_TRUE(get_ptr(m, 2) == nullptr);
129  *get_ptr(m, 1) = 4;
130  EXPECT_EQ(4, m.at(1));
131 }
132 
133 TEST(MapUtil, get_ptr_path_simple) {
134  using std::map;
135  map<int, map<int, map<int, map<int, int>>>> m{{1, {{2, {{3, {{4, 5}}}}}}}};
136  EXPECT_EQ(5, *get_ptr(m, 1, 2, 3, 4));
137  EXPECT_TRUE(get_ptr(m, 1, 2, 3, 4));
138  EXPECT_FALSE(get_ptr(m, 1, 2, 3, 0));
139  EXPECT_TRUE(get_ptr(m, 1, 2, 3));
140  EXPECT_FALSE(get_ptr(m, 1, 2, 0));
141  EXPECT_TRUE(get_ptr(m, 1, 2));
142  EXPECT_FALSE(get_ptr(m, 1, 0));
143  EXPECT_TRUE(get_ptr(m, 1));
144  EXPECT_FALSE(get_ptr(m, 0));
145  const auto& cm = m;
146  ++*get_ptr(m, 1, 2, 3, 4);
147  EXPECT_EQ(6, *get_ptr(cm, 1, 2, 3, 4));
148  EXPECT_TRUE(get_ptr(cm, 1, 2, 3, 4));
149  EXPECT_FALSE(get_ptr(cm, 1, 2, 3, 0));
150 }
151 
152 TEST(MapUtil, get_ptr_path_mixed) {
153  using std::map;
154  using std::string;
155  using std::unordered_map;
156  unordered_map<string, map<int, map<string, int>>> m{{"a", {{1, {{"b", 7}}}}}};
157  EXPECT_EQ(7, *get_ptr(m, "a", 1, "b"));
158  EXPECT_TRUE(get_ptr(m, "a", 1, "b"));
159  EXPECT_FALSE(get_ptr(m, "b", 1, "b"));
160  EXPECT_FALSE(get_ptr(m, "a", 2, "b"));
161  EXPECT_FALSE(get_ptr(m, "a", 1, "c"));
162  EXPECT_TRUE(get_ptr(m, "a", 1));
163  EXPECT_TRUE(get_ptr(m, "a"));
164  const auto& cm = m;
165  ++*get_ptr(m, "a", 1, "b");
166  EXPECT_EQ(8, *get_ptr(cm, "a", 1, "b"));
167  EXPECT_TRUE(get_ptr(cm, "a", 1, "b"));
168  EXPECT_FALSE(get_ptr(cm, "b", 1, "b"));
169 }
170 
171 namespace {
172 template <typename T>
173 struct element_type {
174  using type = typename std::decay<T>::type;
175 };
176 
177 template <typename T>
178 struct element_type<T()> {
179  using type = T;
180 };
181 
182 template <typename T>
183 using element_type_t = typename element_type<T>::type;
184 
185 template <typename T, typename = void>
186 struct Compiles : std::false_type {};
187 
188 template <typename T>
189 struct Compiles<
190  T,
191  void_t<decltype(get_ref_default(
192  std::declval<std::map<int, element_type_t<T>>>(),
193  std::declval<int>(),
194  std::declval<T>()))>> : std::true_type {};
195 } // namespace
196 
197 TEST(MapUtil, get_default_temporary) {
202 
203  EXPECT_TRUE(Compiles<const int&()>::value);
204  EXPECT_TRUE(Compiles<int&()>::value);
205  EXPECT_FALSE(Compiles<int()>::value);
206 }
207 
208 TEST(MapUtil, get_default_path) {
209  using std::map;
211  m[4][2] = 42;
212  EXPECT_EQ(42, get_default(m, 4, 2, 42));
213  EXPECT_EQ(42, get_default(m, 1, 3, 42));
214 }
215 
216 TEST(MapUtil, get_default_path_mixed) {
217  using std::map;
218  using std::string;
219  using std::unordered_map;
221  int key1 = 42;
222  const string key2 = "hello";
223  constexpr StringPiece value = "world";
224  constexpr StringPiece dflt = "default";
225  m[key1][key2] = value;
226  EXPECT_EQ(value, get_default(m, 42, key2, dflt));
227  EXPECT_EQ(value, get_default(m, key1, "hello", dflt));
228  EXPECT_EQ(dflt, get_default(m, 0, key2, dflt));
229  EXPECT_EQ(dflt, get_default(m, key1, "bad", "default"));
230 }
231 
232 TEST(MapUtil, get_ref_default_path) {
233  using std::map;
235  m[4][2] = 42;
236  const int dflt = 13;
237  EXPECT_EQ(42, get_ref_default(m, 4, 2, dflt));
238  EXPECT_EQ(dflt, get_ref_default(m, 1, 3, dflt));
239 }
240 
241 TEST(MapUtil, get_ref_default_path_mixed) {
242  using std::map;
243  using std::string;
244  using std::unordered_map;
246  int key1 = 42;
247  const string key2 = "hello";
248  constexpr StringPiece value = "world";
249  constexpr StringPiece dflt = "default";
250  m[key1][key2] = value;
251  EXPECT_EQ(value, get_ref_default(m, 42, key2, dflt));
252  EXPECT_EQ(value, get_ref_default(m, key1, "hello", dflt));
253  EXPECT_EQ(dflt, get_ref_default(m, 0, key2, dflt));
254  EXPECT_EQ(dflt, get_ref_default(m, key1, "bad", dflt));
255 }
256 
257 namespace {
258 template <typename T, typename = void>
259 struct GetRefDefaultPathCompiles : std::false_type {};
260 
261 template <typename T>
262 struct GetRefDefaultPathCompiles<
263  T,
264  void_t<decltype(get_ref_default(
265  std::declval<std::map<int, std::map<int, element_type_t<T>>>>(),
266  std::declval<int>(),
267  std::declval<int>(),
268  std::declval<T>()))>> : std::true_type {};
269 } // namespace
270 
271 TEST(MapUtil, get_ref_default_path_temporary) {
276 }
277 
278 namespace {
279 
280 class TestConstruction {
281  public:
282  TestConstruction() {
283  EXPECT_TRUE(false);
284  }
285  TestConstruction(TestConstruction&&) {
286  EXPECT_TRUE(false);
287  }
288  TestConstruction(const TestConstruction&) {
289  EXPECT_TRUE(false);
290  }
291 
292  explicit TestConstruction(std::string&& string)
293  : string_{std::move(string)} {}
294  explicit TestConstruction(int&& integer) : integer_{integer} {}
295 
296  TestConstruction& operator=(const TestConstruction&) = delete;
297  TestConstruction& operator=(TestConstruction&&) = delete;
298 
299  int integer_{};
300  std::string string_{};
301 };
302 
303 } // namespace
304 
305 TEST(MapUtil, test_get_default_deferred_construction) {
306  auto map = std::unordered_map<int, TestConstruction>{};
307  map.emplace(
308  std::piecewise_construct,
309  std::forward_as_tuple(1),
310  std::forward_as_tuple(1));
311 
312  EXPECT_EQ(map.at(1).integer_, 1);
313 
314  {
315  auto val = get_default(map, 0, 1);
316  EXPECT_EQ(val.integer_, 1);
317  EXPECT_EQ(val.string_, "");
318  }
319 
320  {
321  auto val = get_default(map, 0, "something");
322  EXPECT_EQ(val.integer_, 0);
323  EXPECT_EQ(val.string_, "something");
324  }
325 }
const Map::mapped_type * get_ptr(const Map &map, const Key &key)
Definition: MapUtil.h:169
Map::mapped_type get_default(const Map &map, const Key &key)
Definition: MapUtil.h:31
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
PskType type
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
const Map::mapped_type & get_ref_default(const Map &map, const Key &key, const typename Map::mapped_type &dflt)
Definition: MapUtil.h:119
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
double val
Definition: String.cpp:273
Integer integer_
folly::std T
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
bool_constant< true > true_type
Definition: gtest-port.h:2210
static Map map(mapCap)
static map< string, int > m
folly::Optional< typename Map::mapped_type > get_optional(const Map &map, const Key &key)
Definition: MapUtil.h:102
Definition: Traits.h:594
static const char *const value
Definition: Conv.cpp:50
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
const char * string
Definition: Conv.cpp:212
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
bool_constant< false > false_type
Definition: gtest-port.h:2209
const Map::mapped_type & get_or_throw(const Map &map, const Key &key, const std::string &exceptionStrPrefix=std::string())
Definition: MapUtil.h:71
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST(SequencedExecutor, CPUThreadPoolExecutor)