get_or_throw(map, key) returns references
[folly.git] / folly / MapUtil.h
1 /*
2  * Copyright 2016 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 #pragma once
18
19 #include <folly/Conv.h>
20 #include <folly/Optional.h>
21
22 namespace folly {
23
24 /**
25  * Given a map and a key, return the value corresponding to the key in the map,
26  * or a given default value if the key doesn't exist in the map.
27  */
28 template <class Map>
29 typename Map::mapped_type get_default(
30     const Map& map, const typename Map::key_type& key,
31     const typename Map::mapped_type& dflt =
32     typename Map::mapped_type()) {
33   auto pos = map.find(key);
34   return (pos != map.end() ? pos->second : dflt);
35 }
36
37 /**
38  * Give a map and a key, return the value corresponding to the key in the map,
39  * or a given default value if the key doesn't exist in the map.
40  */
41 template <
42     class Map,
43     typename Func,
44     typename = typename std::enable_if<std::is_convertible<
45         typename std::result_of<Func()>::type,
46         typename Map::mapped_type>::value>::type>
47 typename Map::mapped_type
48 get_default(const Map& map, const typename Map::key_type& key, Func&& dflt) {
49   auto pos = map.find(key);
50   return pos != map.end() ? pos->second : dflt();
51 }
52
53 /**
54  * Given a map and a key, return the value corresponding to the key in the map,
55  * or throw an exception of the specified type.
56  */
57 template <class E = std::out_of_range, class Map>
58 const typename Map::mapped_type& get_or_throw(
59     const Map& map,
60     const typename Map::key_type& key,
61     const std::string& exceptionStrPrefix = std::string()) {
62   auto pos = map.find(key);
63   if (pos != map.end()) {
64     return pos->second;
65   }
66   throw E(folly::to<std::string>(exceptionStrPrefix, key));
67 }
68
69 template <class E = std::out_of_range, class Map>
70 typename Map::mapped_type& get_or_throw(
71     Map& map,
72     const typename Map::key_type& key,
73     const std::string& exceptionStrPrefix = std::string()) {
74   auto pos = map.find(key);
75   if (pos != map.end()) {
76     return pos->second;
77   }
78   throw E(folly::to<std::string>(exceptionStrPrefix, key));
79 }
80
81 /**
82  * Given a map and a key, return a Optional<V> if the key exists and None if the
83  * key does not exist in the map.
84  */
85 template <class Map>
86 folly::Optional<typename Map::mapped_type> get_optional(
87     const Map& map, const typename Map::key_type& key) {
88   auto pos = map.find(key);
89   if (pos != map.end()) {
90     return folly::Optional<typename Map::mapped_type>(pos->second);
91   } else {
92     return folly::none;
93   }
94 }
95
96 /**
97  * Given a map and a key, return a reference to the value corresponding to the
98  * key in the map, or the given default reference if the key doesn't exist in
99  * the map.
100  */
101 template <class Map>
102 const typename Map::mapped_type& get_ref_default(
103     const Map& map, const typename Map::key_type& key,
104     const typename Map::mapped_type& dflt) {
105   auto pos = map.find(key);
106   return (pos != map.end() ? pos->second : dflt);
107 }
108
109 /**
110  * Given a map and a key, return a reference to the value corresponding to the
111  * key in the map, or the given default reference if the key doesn't exist in
112  * the map.
113  */
114 template <
115     class Map,
116     typename Func,
117     typename = typename std::enable_if<std::is_convertible<
118         typename std::result_of<Func()>::type,
119         const typename Map::mapped_type&>::value>::type>
120 const typename Map::mapped_type& get_ref_default(
121     const Map& map,
122     const typename Map::key_type& key,
123     Func&& dflt) {
124   auto pos = map.find(key);
125   return (pos != map.end() ? pos->second : dflt());
126 }
127
128 /**
129  * Given a map and a key, return a pointer to the value corresponding to the
130  * key in the map, or nullptr if the key doesn't exist in the map.
131  */
132 template <class Map>
133 const typename Map::mapped_type* get_ptr(
134     const Map& map, const typename Map::key_type& key) {
135   auto pos = map.find(key);
136   return (pos != map.end() ? &pos->second : nullptr);
137 }
138
139 /**
140  * Non-const overload of the above.
141  */
142 template <class Map>
143 typename Map::mapped_type* get_ptr(
144     Map& map, const typename Map::key_type& key) {
145   auto pos = map.find(key);
146   return (pos != map.end() ? &pos->second : nullptr);
147 }
148
149 }  // namespace folly