Commit 6cc710c4 authored by Irene Liu's avatar Irene Liu Committed by Facebook Github Bot

Add variadic template for get_optional to support nested map (#932)

Summary:
Pull Request resolved: https://github.com/facebook/folly/pull/932

As title.

Reviewed By: yfeldblum

Differential Revision: D9817328

fbshipit-source-id: 261c68f21316e91f3ed752c4aeab9e9c95dfe16d
parent f81f9a88
...@@ -216,6 +216,23 @@ auto extract_default(const KeysDefault&... keysDefault) -> ...@@ -216,6 +216,23 @@ auto extract_default(const KeysDefault&... keysDefault) ->
} }
} // namespace detail } // namespace detail
/**
* Given a map of maps and a path of keys, return a Optional<V> if the nested
* key exists and None if the nested keys does not exist in the map.
*/
template <class Map, class Key1, class Key2, class... Keys>
auto get_optional(
const Map& map,
const Key1& key1,
const Key2& key2,
const Keys&... keys)
-> folly::Optional<
typename detail::NestedMapType<Map, 2 + sizeof...(Keys)>::type> {
auto pos = map.find(key1);
return pos != map.end() ? get_optional(pos->second, key2, keys...)
: folly::none;
}
/** /**
* Given a map of maps and a path of keys, return a pointer to the nested value, * Given a map of maps and a path of keys, return a pointer to the nested value,
* or nullptr if the key doesn't exist in the map. * or nullptr if the key doesn't exist in the map.
......
...@@ -70,6 +70,34 @@ TEST(MapUtil, get_optional) { ...@@ -70,6 +70,34 @@ TEST(MapUtil, get_optional) {
EXPECT_FALSE(get_optional(m, 2).hasValue()); EXPECT_FALSE(get_optional(m, 2).hasValue());
} }
TEST(MapUtil, get_optional_path_simple) {
using std::map;
map<int, map<int, map<int, map<int, int>>>> m{{1, {{2, {{3, {{4, 5}}}}}}}};
EXPECT_EQ(folly::Optional<int>(5), get_optional(m, 1, 2, 3, 4));
EXPECT_TRUE(get_optional(m, 1, 2, 3, 4));
EXPECT_FALSE(get_optional(m, 1, 2, 3, 0));
EXPECT_TRUE(get_optional(m, 1, 2, 3));
EXPECT_FALSE(get_optional(m, 1, 2, 0));
EXPECT_TRUE(get_optional(m, 1, 2));
EXPECT_FALSE(get_optional(m, 1, 0));
EXPECT_TRUE(get_optional(m, 1));
EXPECT_FALSE(get_optional(m, 0));
}
TEST(MapUtil, get_optional_path_mixed) {
using std::map;
using std::string;
using std::unordered_map;
unordered_map<string, map<int, map<string, int>>> m{{"a", {{1, {{"b", 2}}}}}};
EXPECT_EQ(folly::Optional<int>(2), get_optional(m, "a", 1, "b"));
EXPECT_TRUE(get_optional(m, "a", 1, "b"));
EXPECT_FALSE(get_optional(m, "b", 1, "b"));
EXPECT_FALSE(get_optional(m, "a", 2, "b"));
EXPECT_FALSE(get_optional(m, "a", 1, "c"));
EXPECT_TRUE(get_optional(m, "a", 1));
EXPECT_TRUE(get_optional(m, "a"));
}
TEST(MapUtil, get_ref_default) { TEST(MapUtil, get_ref_default) {
std::map<int, int> m; std::map<int, int> m;
m[1] = 2; m[1] = 2;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment