From 5480083584caaf6942ce289e1a66d32219b854b9 Mon Sep 17 00:00:00 2001 From: Yedidya Feldblum Date: Mon, 5 Jun 2017 14:35:46 -0700 Subject: [PATCH] Let map-related functions be templated over key types Summary: [Folly] Let map-related functions be templated over key types. This supports the case where map members like `find` may be overloaded or templated on types other than the map's `key_type const&`. In C++14, standard library map types gain template overloads for `find` and for other members, permitting lookups without constructing `key_type` instances. This is useful primarily when `key_type` is expensive but another object type comparable with `key_type` is inexpensive. As a common example, a `key_type` of `std::string` is expensive in the general case because it allocates storage on the heap but `std::string_view` (C++17), when constructed with non-allocated `char const*, std::size_t`, would be inexpensive. Reviewed By: terrelln Differential Revision: D5145879 fbshipit-source-id: 979b75bfe55661aab11d5302da1bcd7830abd5af --- folly/MapUtil.h | 60 +++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/folly/MapUtil.h b/folly/MapUtil.h index d6be5711..e38446b3 100644 --- a/folly/MapUtil.h +++ b/folly/MapUtil.h @@ -26,11 +26,11 @@ namespace folly { * Given a map and a key, return the value corresponding to the key in the map, * or a given default value if the key doesn't exist in the map. */ -template +template typename Map::mapped_type get_default( - const Map& map, const typename Map::key_type& key, - const typename Map::mapped_type& dflt = - typename Map::mapped_type()) { + const Map& map, + const Key& key, + const typename Map::mapped_type& dflt = typename Map::mapped_type()) { auto pos = map.find(key); return (pos != map.end() ? pos->second : dflt); } @@ -41,12 +41,13 @@ typename Map::mapped_type get_default( */ template < class Map, + typename Key = typename Map::key_type, typename Func, typename = typename std::enable_if::type, typename Map::mapped_type>::value>::type> typename Map::mapped_type -get_default(const Map& map, const typename Map::key_type& key, Func&& dflt) { +get_default(const Map& map, const Key& key, Func&& dflt) { auto pos = map.find(key); return pos != map.end() ? pos->second : dflt(); } @@ -55,10 +56,13 @@ get_default(const Map& map, const typename Map::key_type& key, Func&& dflt) { * Given a map and a key, return the value corresponding to the key in the map, * or throw an exception of the specified type. */ -template +template < + class E = std::out_of_range, + class Map, + typename Key = typename Map::key_type> const typename Map::mapped_type& get_or_throw( const Map& map, - const typename Map::key_type& key, + const Key& key, const std::string& exceptionStrPrefix = std::string()) { auto pos = map.find(key); if (pos != map.end()) { @@ -67,10 +71,13 @@ const typename Map::mapped_type& get_or_throw( throw E(folly::to(exceptionStrPrefix, key)); } -template +template < + class E = std::out_of_range, + class Map, + typename Key = typename Map::key_type> typename Map::mapped_type& get_or_throw( Map& map, - const typename Map::key_type& key, + const Key& key, const std::string& exceptionStrPrefix = std::string()) { auto pos = map.find(key); if (pos != map.end()) { @@ -83,9 +90,10 @@ typename Map::mapped_type& get_or_throw( * Given a map and a key, return a Optional if the key exists and None if the * key does not exist in the map. */ -template +template folly::Optional get_optional( - const Map& map, const typename Map::key_type& key) { + const Map& map, + const Key& key) { auto pos = map.find(key); if (pos != map.end()) { return folly::Optional(pos->second); @@ -99,9 +107,10 @@ folly::Optional get_optional( * key in the map, or the given default reference if the key doesn't exist in * the map. */ -template +template const typename Map::mapped_type& get_ref_default( - const Map& map, const typename Map::key_type& key, + const Map& map, + const Key& key, const typename Map::mapped_type& dflt) { auto pos = map.find(key); return (pos != map.end() ? pos->second : dflt); @@ -113,16 +122,16 @@ const typename Map::mapped_type& get_ref_default( * The caller must ensure that the default value outlives the reference returned * by get_ref_default(). */ -template +template const typename Map::mapped_type& get_ref_default( const Map& map, - const typename Map::key_type& key, + const Key& key, typename Map::mapped_type&& dflt) = delete; -template +template const typename Map::mapped_type& get_ref_default( const Map& map, - const typename Map::key_type& key, + const Key& key, const typename Map::mapped_type&& dflt) = delete; /** @@ -132,16 +141,15 @@ const typename Map::mapped_type& get_ref_default( */ template < class Map, + typename Key = typename Map::key_type, typename Func, typename = typename std::enable_if::type, const typename Map::mapped_type&>::value>::type, typename = typename std::enable_if< std::is_reference::type>::value>::type> -const typename Map::mapped_type& get_ref_default( - const Map& map, - const typename Map::key_type& key, - Func&& dflt) { +const typename Map::mapped_type& +get_ref_default(const Map& map, const Key& key, Func&& dflt) { auto pos = map.find(key); return (pos != map.end() ? pos->second : dflt()); } @@ -150,9 +158,8 @@ const typename Map::mapped_type& get_ref_default( * Given a map and a key, return a pointer to the value corresponding to the * key in the map, or nullptr if the key doesn't exist in the map. */ -template -const typename Map::mapped_type* get_ptr( - const Map& map, const typename Map::key_type& key) { +template +const typename Map::mapped_type* get_ptr(const Map& map, const Key& key) { auto pos = map.find(key); return (pos != map.end() ? &pos->second : nullptr); } @@ -160,9 +167,8 @@ const typename Map::mapped_type* get_ptr( /** * Non-const overload of the above. */ -template -typename Map::mapped_type* get_ptr( - Map& map, const typename Map::key_type& key) { +template +typename Map::mapped_type* get_ptr(Map& map, const Key& key) { auto pos = map.find(key); return (pos != map.end() ? &pos->second : nullptr); } -- 2.34.1