OR-Tools  9.1
map_util.h
Go to the documentation of this file.
1 // Copyright 2010-2021 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #ifndef OR_TOOLS_BASE_MAP_UTIL_H_
15 #define OR_TOOLS_BASE_MAP_UTIL_H_
16 
17 #include <utility>
18 
19 #include "ortools/base/logging.h"
20 
21 namespace gtl {
22 // Perform a lookup in a std::map or std::unordered_map.
23 // If the key is present in the map then the value associated with that
24 // key is returned, otherwise the value passed as a default is returned.
25 //
26 // Prefer the two-argument form unless you need to specify a custom default
27 // value (i.e., one that is not equal to a value-initialized instance).
28 template <class Collection>
29 const typename Collection::value_type::second_type& FindWithDefault(
30  const Collection& collection,
31  const typename Collection::value_type::first_type& key,
32  const typename Collection::value_type::second_type& value) {
33  typename Collection::const_iterator it = collection.find(key);
34  if (it == collection.end()) {
35  return value;
36  }
37  return it->second;
38 }
39 
40 // Returns a const reference to the value associated with the given key if it
41 // exists, otherwise returns a const reference to a value-initialized object
42 // that is never destroyed.
43 template <class Collection>
44 const typename Collection::value_type::second_type& FindWithDefault(
45  const Collection& collection,
46  const typename Collection::value_type::first_type& key) {
47  static const typename Collection::value_type::second_type* const
48  default_value = new typename Collection::value_type::second_type{};
49  typename Collection::const_iterator it = collection.find(key);
50  if (it == collection.end()) {
51  return *default_value;
52  }
53  return it->second;
54 }
55 
56 // Perform a lookup in a std::map or std::unordered_map.
57 // If the key is present a const pointer to the associated value is returned,
58 // otherwise a NULL pointer is returned.
59 template <class Collection>
60 const typename Collection::value_type::second_type* FindOrNull(
61  const Collection& collection,
62  const typename Collection::value_type::first_type& key) {
63  typename Collection::const_iterator it = collection.find(key);
64  if (it == collection.end()) {
65  return 0;
66  }
67  return &it->second;
68 }
69 
70 // Perform a lookup in a std::map or std::unordered_map.
71 // Same as above but the returned pointer is not const and can be used to change
72 // the stored value.
73 template <class Collection>
74 typename Collection::value_type::second_type* FindOrNull(
75  Collection& collection, // NOLINT
76  const typename Collection::value_type::first_type& key) {
77  typename Collection::iterator it = collection.find(key);
78  if (it == collection.end()) {
79  return 0;
80  }
81  return &it->second;
82 }
83 
84 // Perform a lookup in a std::map or std::unordered_map whose values are
85 // pointers. If the key is present a const pointer to the associated value is
86 // returned, otherwise a NULL pointer is returned. This function does not
87 // distinguish between a missing key and a key mapped to a NULL value.
88 template <class Collection>
89 const typename Collection::value_type::second_type FindPtrOrNull(
90  const Collection& collection,
91  const typename Collection::value_type::first_type& key) {
92  typename Collection::const_iterator it = collection.find(key);
93  if (it == collection.end()) {
94  return 0;
95  }
96  return it->second;
97 }
98 
99 // Change the value associated with a particular key in a std::map or
100 // std::unordered_map. If the key is not present in the map the key and value
101 // are inserted, otherwise the value is updated to be a copy of the value
102 // provided. True indicates that an insert took place, false indicates an
103 // update.
104 template <class Collection, class Key, class Value>
105 bool InsertOrUpdate(Collection* const collection, const Key& key,
106  const Value& value) {
107  std::pair<typename Collection::iterator, bool> ret =
108  collection->insert(typename Collection::value_type(key, value));
109  if (!ret.second) {
110  // update
111  ret.first->second = value;
112  return false;
113  }
114  return true;
115 }
116 
117 // Insert a new key into a set.
118 // If the key is not present in the set the key is
119 // inserted, otherwise nothing happens. True indicates that an insert
120 // took place, false indicates the key was already present.
121 template <class Collection>
122 bool InsertIfNotPresent(Collection* const collection,
123  const typename Collection::value_type& value) {
124  std::pair<typename Collection::iterator, bool> ret =
125  collection->insert(value);
126  return ret.second;
127 }
128 
129 // Insert a new key and value into a std::map or std::unordered_map.
130 // If the key is not present in the map the key and value are
131 // inserted, otherwise nothing happens. True indicates that an insert
132 // took place, false indicates the key was already present.
133 template <class Collection, class Key, class Value>
134 bool InsertIfNotPresent(Collection* const collection, const Key& key,
135  const Value& value) {
136  std::pair<typename Collection::iterator, bool> ret =
137  collection->insert(typename Collection::value_type(key, value));
138  return ret.second;
139 }
140 
141 // Inserts a new std::pair<key,value> into a std::map or std::unordered_map.
142 // Insert a new key into a std::set or std::unordered_set.
143 // Dies if the key is already present.
144 template <class Collection>
145 void InsertOrDieNoPrint(Collection* const collection,
146  const typename Collection::value_type& value) {
147  CHECK(collection->insert(value).second);
148 }
149 
150 // Inserts a new std::pair<key,value> into a std::map or std::unordered_map.
151 // Insert a new key into a std::set or std::unordered_set.
152 // Dies if the key is already present.
153 template <class Collection>
154 void InsertOrDie(Collection* const collection,
155  const typename Collection::value_type& value) {
156  CHECK(collection->insert(value).second) << "duplicate value: " << value;
157 }
158 
159 // Inserts a new key/value into a std::map or std::unordered_map.
160 // Dies if the key is already present.
161 template <class Collection>
162 void InsertOrDie(Collection* const collection,
163  const typename Collection::value_type::first_type& key,
164  const typename Collection::value_type::second_type& data) {
165  typedef typename Collection::value_type value_type;
166  CHECK(collection->insert(value_type(key, data)).second)
167  << "duplicate key: " << key;
168 }
169 
170 // Inserts a key into a map with the default value or dies. Returns a reference
171 // to the inserted element.
172 template <typename Collection>
173 auto& InsertKeyOrDie(Collection* const collection,
174  const typename Collection::value_type::first_type& key) {
175  auto [it, did_insert] = collection->insert(typename Collection::value_type(
176  key, typename Collection::value_type::second_type()));
177  CHECK(did_insert) << "duplicate key " << key;
178  return it->second;
179 }
180 
181 // Perform a lookup in std::map or std::unordered_map.
182 // If the key is present and value is non-NULL then a copy of the value
183 // associated with the key is made into *value. Returns whether key was present.
184 template <class Collection, class Key, class Value>
185 bool FindCopy(const Collection& collection, const Key& key,
186  Value* const value) {
187  typename Collection::const_iterator it = collection.find(key);
188  if (it == collection.end()) {
189  return false;
190  }
191  if (value) {
192  *value = it->second;
193  }
194  return true;
195 }
196 
197 // Test to see if a std::set, std::map, std::unordered_set or std::unordered_map
198 // contains a particular key. Returns true if the key is in the collection.
199 template <class Collection, class Key>
200 bool ContainsKey(const Collection& collection, const Key& key) {
201  typename Collection::const_iterator it = collection.find(key);
202  return it != collection.end();
203 }
204 
205 template <class Collection>
206 const typename Collection::value_type::second_type& FindOrDie(
207  const Collection& collection,
208  const typename Collection::value_type::first_type& key) {
209  typename Collection::const_iterator it = collection.find(key);
210  CHECK(it != collection.end()) << "Map key not found: " << key;
211  return it->second;
212 }
213 
214 // Same as FindOrDie above, but doesn't log the key on failure.
215 template <class Collection>
216 const typename Collection::value_type::second_type& FindOrDieNoPrint(
217  const Collection& collection,
218  const typename Collection::value_type::first_type& key) {
219  typename Collection::const_iterator it = collection.find(key);
220  CHECK(it != collection.end()) << "Map key not found";
221  return it->second;
222 }
223 
224 // Same as above, but returns a non-const reference.
225 template <class Collection>
226 typename Collection::value_type::second_type& FindOrDieNoPrint(
227  Collection& collection, // NOLINT
228  const typename Collection::value_type::first_type& key) {
229  typename Collection::iterator it = collection.find(key);
230  CHECK(it != collection.end()) << "Map key not found";
231  return it->second;
232 }
233 
234 // Lookup a key in a std::map or std::unordered_map, insert it if it is not
235 // present. Returns a reference to the value associated with the key.
236 template <class Collection>
237 typename Collection::value_type::second_type& LookupOrInsert(
238  Collection* const collection,
239  const typename Collection::value_type::first_type& key,
240  const typename Collection::value_type::second_type& value) {
241  std::pair<typename Collection::iterator, bool> ret =
242  collection->insert(typename Collection::value_type(key, value));
243  return ret.first->second;
244 }
245 } // namespace gtl
246 #endif // OR_TOOLS_BASE_MAP_UTIL_H_
#define CHECK(condition)
Definition: base/logging.h:491
const Collection::value_type::second_type & FindOrDieNoPrint(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:216
bool InsertIfNotPresent(Collection *const collection, const typename Collection::value_type &value)
Definition: map_util.h:122
bool FindCopy(const Collection &collection, const Key &key, Value *const value)
Definition: map_util.h:185
void InsertOrDie(Collection *const collection, const typename Collection::value_type &value)
Definition: map_util.h:154
auto & InsertKeyOrDie(Collection *const collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:173
const Collection::value_type::second_type FindPtrOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:89
std::function< int64_t(const Model &)> Value(IntegerVariable v)
Definition: integer.h:1544
void InsertOrDieNoPrint(Collection *const collection, const typename Collection::value_type &value)
Definition: map_util.h:145
bool ContainsKey(const Collection &collection, const Key &key)
Definition: map_util.h:200
const Collection::value_type::second_type & FindOrDie(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:206
const Collection::value_type::second_type & FindWithDefault(const Collection &collection, const typename Collection::value_type::first_type &key, const typename Collection::value_type::second_type &value)
Definition: map_util.h:29
const Collection::value_type::second_type * FindOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:60
Collection::value_type::second_type & LookupOrInsert(Collection *const collection, const typename Collection::value_type::first_type &key, const typename Collection::value_type::second_type &value)
Definition: map_util.h:237
bool InsertOrUpdate(Collection *const collection, const Key &key, const Value &value)
Definition: map_util.h:105
int64_t value