OR-Tools  9.2
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
20
21namespace 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).
28template <class Collection>
29const 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.
43template <class Collection>
44const 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.
59template <class Collection>
60const 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.
73template <class Collection>
74typename 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.
88template <class Collection>
89const 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.
104template <class Collection, class Key, class Value>
105bool 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.
121template <class Collection>
122bool 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.
133template <class Collection, class Key, class Value>
134bool 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.
144template <class Collection>
145void 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.
153template <class Collection>
154void 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.
161template <class Collection>
162void 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.
172template <typename Collection>
173auto& 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.
184template <class Collection, class Key, class Value>
185bool 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.
199template <class Collection, class Key>
200bool ContainsKey(const Collection& collection, const Key& key) {
201 typename Collection::const_iterator it = collection.find(key);
202 return it != collection.end();
203}
204
205template <class Collection>
206const 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.
215template <class Collection>
216const 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.
225template <class Collection>
226typename 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.
236template <class Collection>
237typename 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:495
int64_t value
const Collection::value_type::second_type FindPtrOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:89
bool InsertOrUpdate(Collection *const collection, const Key &key, const Value &value)
Definition: map_util.h:105
void InsertOrDieNoPrint(Collection *const collection, const typename Collection::value_type &value)
Definition: map_util.h:145
bool InsertIfNotPresent(Collection *const collection, const typename Collection::value_type &value)
Definition: map_util.h:122
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
void InsertOrDie(Collection *const collection, const typename Collection::value_type &value)
Definition: map_util.h:154
bool FindCopy(const Collection &collection, const Key &key, Value *const value)
Definition: map_util.h:185
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 & FindOrDieNoPrint(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:216
const Collection::value_type::second_type * FindOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:60
bool ContainsKey(const Collection &collection, const Key &key)
Definition: map_util.h:200
auto & InsertKeyOrDie(Collection *const collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:173
std::function< int64_t(const Model &)> Value(IntegerVariable v)
Definition: integer.h:1673