X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Ftest%2FMapUtilTest.cpp;h=32ffdba460e8f1bd907f3733bcf801d8e33712f1;hb=bba519bfb1b4c4d24fd210696e31fcf5e25d13e8;hp=7d73e9b67a677fbfd528ffe6043042916d4081c2;hpb=275ca94d04e44f28cfa411668eb1c1dd8db90b80;p=folly.git diff --git a/folly/test/MapUtilTest.cpp b/folly/test/MapUtilTest.cpp index 7d73e9b6..32ffdba4 100644 --- a/folly/test/MapUtilTest.cpp +++ b/folly/test/MapUtilTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2015 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,18 +17,232 @@ #include #include -#include +#include + +#include +#include using namespace folly; -TEST(MapUtil, Simple) { +TEST(MapUtil, get_default) { std::map m; m[1] = 2; EXPECT_EQ(2, get_default(m, 1, 42)); EXPECT_EQ(42, get_default(m, 2, 42)); EXPECT_EQ(0, get_default(m, 3)); +} + +TEST(MapUtil, get_default_function) { + std::map m; + m[1] = 2; + EXPECT_EQ(2, get_default(m, 1, [] { return 42; })); + EXPECT_EQ(42, get_default(m, 2, [] { return 42; })); + EXPECT_EQ(0, get_default(m, 3)); +} + +TEST(MapUtil, get_or_throw) { + std::map m; + m[1] = 2; + EXPECT_EQ(2, get_or_throw(m, 1)); + EXPECT_THROW(get_or_throw(m, 2), std::out_of_range); + EXPECT_EQ(&m[1], &get_or_throw(m, 1)); + get_or_throw(m, 1) = 3; + EXPECT_EQ(3, get_or_throw(m, 1)); + const auto& cm = m; + EXPECT_EQ(&m[1], &get_or_throw(cm, 1)); + EXPECT_EQ(3, get_or_throw(cm, 1)); + EXPECT_THROW(get_or_throw(cm, 2), std::out_of_range); +} + +TEST(MapUtil, get_or_throw_specified) { + std::map m; + m[1] = 2; + EXPECT_EQ(2, get_or_throw(m, 1)); + EXPECT_THROW(get_or_throw(m, 2), std::runtime_error); +} + +TEST(MapUtil, get_optional) { + std::map m; + m[1] = 2; + EXPECT_TRUE(get_optional(m, 1).hasValue()); + EXPECT_EQ(2, get_optional(m, 1).value()); + EXPECT_FALSE(get_optional(m, 2).hasValue()); +} + +TEST(MapUtil, get_ref_default) { + std::map m; + m[1] = 2; + const int i = 42; + EXPECT_EQ(2, get_ref_default(m, 1, i)); + EXPECT_EQ(42, get_ref_default(m, 2, i)); + EXPECT_EQ(std::addressof(i), std::addressof(get_ref_default(m, 2, i))); +} + +TEST(MapUtil, get_ref_default_function) { + std::map m; + m[1] = 2; + const int i = 42; + EXPECT_EQ(2, get_ref_default(m, 1, [&i]() -> const int& { return i; })); + EXPECT_EQ(42, get_ref_default(m, 2, [&i]() -> const int& { return i; })); + EXPECT_EQ( + std::addressof(i), + std::addressof( + get_ref_default(m, 2, [&i]() -> const int& { return i; }))); + // statically disallowed: + // get_ref_default(m, 2, [] { return 7; }); +} + +TEST(MapUtil, get_ptr) { + std::map m; + m[1] = 2; EXPECT_EQ(2, *get_ptr(m, 1)); EXPECT_TRUE(get_ptr(m, 2) == nullptr); *get_ptr(m, 1) = 4; EXPECT_EQ(4, m.at(1)); } + +TEST(MapUtil, get_ptr_path_simple) { + using std::map; + map>>> m{{1, {{2, {{3, {{4, 5}}}}}}}}; + EXPECT_EQ(5, *get_ptr(m, 1, 2, 3, 4)); + EXPECT_TRUE(get_ptr(m, 1, 2, 3, 4)); + EXPECT_FALSE(get_ptr(m, 1, 2, 3, 0)); + EXPECT_TRUE(get_ptr(m, 1, 2, 3)); + EXPECT_FALSE(get_ptr(m, 1, 2, 0)); + EXPECT_TRUE(get_ptr(m, 1, 2)); + EXPECT_FALSE(get_ptr(m, 1, 0)); + EXPECT_TRUE(get_ptr(m, 1)); + EXPECT_FALSE(get_ptr(m, 0)); + const auto& cm = m; + ++*get_ptr(m, 1, 2, 3, 4); + EXPECT_EQ(6, *get_ptr(cm, 1, 2, 3, 4)); + EXPECT_TRUE(get_ptr(cm, 1, 2, 3, 4)); + EXPECT_FALSE(get_ptr(cm, 1, 2, 3, 0)); +} + +TEST(MapUtil, get_ptr_path_mixed) { + using std::map; + using std::unordered_map; + using std::string; + unordered_map>> m{{"a", {{1, {{"b", 7}}}}}}; + EXPECT_EQ(7, *get_ptr(m, "a", 1, "b")); + EXPECT_TRUE(get_ptr(m, "a", 1, "b")); + EXPECT_FALSE(get_ptr(m, "b", 1, "b")); + EXPECT_FALSE(get_ptr(m, "a", 2, "b")); + EXPECT_FALSE(get_ptr(m, "a", 1, "c")); + EXPECT_TRUE(get_ptr(m, "a", 1, "b")); + EXPECT_TRUE(get_ptr(m, "a", 1)); + EXPECT_TRUE(get_ptr(m, "a")); + const auto& cm = m; + ++*get_ptr(m, "a", 1, "b"); + EXPECT_EQ(8, *get_ptr(cm, "a", 1, "b")); + EXPECT_TRUE(get_ptr(cm, "a", 1, "b")); + EXPECT_FALSE(get_ptr(cm, "b", 1, "b")); +} + +namespace { +template +struct element_type { + using type = typename std::decay::type; +}; + +template +struct element_type { + using type = T; +}; + +template +using element_type_t = typename element_type::type; + +template +struct Compiles : std::false_type {}; + +template +struct Compiles< + T, + void_t>>(), + std::declval(), + std::declval()))>> : std::true_type {}; +} + +TEST(MapUtil, get_default_temporary) { + EXPECT_TRUE(Compiles::value); + EXPECT_TRUE(Compiles::value); + EXPECT_FALSE(Compiles::value); + EXPECT_FALSE(Compiles::value); + + EXPECT_TRUE(Compiles::value); + EXPECT_TRUE(Compiles::value); + EXPECT_FALSE(Compiles::value); +} + +TEST(MapUtil, get_default_path) { + using std::map; + map> m; + m[4][2] = 42; + EXPECT_EQ(42, get_default(m, 4, 2, 42)); + EXPECT_EQ(42, get_default(m, 1, 3, 42)); +} + +TEST(MapUtil, get_default_path_mixed) { + using std::map; + using std::unordered_map; + using std::string; + map> m; + int key1 = 42; + const string key2 = "hello"; + constexpr StringPiece value = "world"; + constexpr StringPiece dflt = "default"; + m[key1][key2] = value; + EXPECT_EQ(value, get_default(m, 42, key2, dflt)); + EXPECT_EQ(value, get_default(m, key1, "hello", dflt)); + EXPECT_EQ(dflt, get_default(m, 0, key2, dflt)); + EXPECT_EQ(dflt, get_default(m, key1, "bad", "default")); +} + +TEST(MapUtil, get_ref_default_path) { + using std::map; + map> m; + m[4][2] = 42; + const int dflt = 13; + EXPECT_EQ(42, get_ref_default(m, 4, 2, dflt)); + EXPECT_EQ(dflt, get_ref_default(m, 1, 3, dflt)); +} + +TEST(MapUtil, get_ref_default_path_mixed) { + using std::map; + using std::unordered_map; + using std::string; + map> m; + int key1 = 42; + const string key2 = "hello"; + constexpr StringPiece value = "world"; + constexpr StringPiece dflt = "default"; + m[key1][key2] = value; + EXPECT_EQ(value, get_ref_default(m, 42, key2, dflt)); + EXPECT_EQ(value, get_ref_default(m, key1, "hello", dflt)); + EXPECT_EQ(dflt, get_ref_default(m, 0, key2, dflt)); + EXPECT_EQ(dflt, get_ref_default(m, key1, "bad", dflt)); +} + +namespace { +template +struct GetRefDefaultPathCompiles : std::false_type {}; + +template +struct GetRefDefaultPathCompiles< + T, + void_t>>>(), + std::declval(), + std::declval(), + std::declval()))>> : std::true_type {}; +} + +TEST(MapUtil, get_ref_default_path_temporary) { + EXPECT_TRUE(GetRefDefaultPathCompiles::value); + EXPECT_TRUE(GetRefDefaultPathCompiles::value); + EXPECT_FALSE(GetRefDefaultPathCompiles::value); + EXPECT_FALSE(GetRefDefaultPathCompiles::value); +}