blob: f55aee37689383ac80a725ff5d34814f6b84ebd8 [file] [log] [blame]
Keir Mierle8ebb0732012-04-30 23:09:08 -07001// Ceres Solver - A fast non-linear least squares minimizer
Keir Mierle7492b0d2015-03-17 22:30:16 -07002// Copyright 2015 Google Inc. All rights reserved.
3// http://ceres-solver.org/
Keir Mierle8ebb0732012-04-30 23:09:08 -07004//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7//
8// * Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13// * Neither the name of Google Inc. nor the names of its contributors may be
14// used to endorse or promote products derived from this software without
15// specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27// POSSIBILITY OF SUCH DAMAGE.
28//
29// Author: keir@google.com (Keir Mierle)
30//
31// Originally by Anton Carver
32
33#ifndef CERES_INTERNAL_MAP_UTIL_H_
34#define CERES_INTERNAL_MAP_UTIL_H_
35
36#include <utility>
37#include "ceres/internal/port.h"
Sameer Agarwal509f68c2013-02-20 01:39:03 -080038#include "glog/logging.h"
Keir Mierle8ebb0732012-04-30 23:09:08 -070039
40namespace ceres {
41
42// Perform a lookup in a map or hash_map, assuming that the key exists.
43// Crash if it does not.
44//
45// This is intended as a replacement for operator[] as an rvalue (for reading)
46// when the key is guaranteed to exist.
47//
48// operator[] is discouraged for several reasons:
49// * It has a side-effect of inserting missing keys
50// * It is not thread-safe (even when it is not inserting, it can still
51// choose to resize the underlying storage)
52// * It invalidates iterators (when it chooses to resize)
53// * It default constructs a value object even if it doesn't need to
54//
55// This version assumes the key is printable, and includes it in the fatal log
56// message.
57template <class Collection>
58const typename Collection::value_type::second_type&
59FindOrDie(const Collection& collection,
60 const typename Collection::value_type::first_type& key) {
61 typename Collection::const_iterator it = collection.find(key);
62 CHECK(it != collection.end()) << "Map key not found: " << key;
63 return it->second;
64}
65
66// Perform a lookup in a map or hash_map.
67// If the key is present in the map then the value associated with that
68// key is returned, otherwise the value passed as a default is returned.
69template <class Collection>
Sameer Agarwal2fd39fc2016-09-01 16:05:06 -070070const typename Collection::value_type::second_type
Keir Mierle8ebb0732012-04-30 23:09:08 -070071FindWithDefault(const Collection& collection,
72 const typename Collection::value_type::first_type& key,
73 const typename Collection::value_type::second_type& value) {
74 typename Collection::const_iterator it = collection.find(key);
75 if (it == collection.end()) {
76 return value;
77 }
78 return it->second;
79}
80
81// Insert a new key and value into a map or hash_map.
82// If the key is not present in the map the key and value are
83// inserted, otherwise nothing happens. True indicates that an insert
84// took place, false indicates the key was already present.
85template <class Collection>
86bool InsertIfNotPresent(
87 Collection * const collection,
88 const typename Collection::value_type::first_type& key,
89 const typename Collection::value_type::second_type& value) {
Sameer Agarwalbcc865f2014-12-17 07:35:09 -080090 std::pair<typename Collection::iterator, bool> ret =
91 collection->insert(typename Collection::value_type(key, value));
Keir Mierle8ebb0732012-04-30 23:09:08 -070092 return ret.second;
93}
94
95// Perform a lookup in a map or hash_map.
96// Same as above but the returned pointer is not const and can be used to change
97// the stored value.
98template <class Collection>
99typename Collection::value_type::second_type*
100FindOrNull(Collection& collection, // NOLINT
101 const typename Collection::value_type::first_type& key) {
102 typename Collection::iterator it = collection.find(key);
103 if (it == collection.end()) {
104 return 0;
105 }
106 return &it->second;
107}
108
109// Test to see if a set, map, hash_set or hash_map contains a particular key.
110// Returns true if the key is in the collection.
111template <class Collection, class Key>
112bool ContainsKey(const Collection& collection, const Key& key) {
113 typename Collection::const_iterator it = collection.find(key);
114 return it != collection.end();
115}
116
117// Inserts a new key/value into a map or hash_map.
118// Dies if the key is already present.
119template<class Collection>
120void InsertOrDie(Collection* const collection,
121 const typename Collection::value_type::first_type& key,
122 const typename Collection::value_type::second_type& data) {
123 typedef typename Collection::value_type value_type;
124 CHECK(collection->insert(value_type(key, data)).second)
125 << "duplicate key: " << key;
126}
127
128} // namespace ceres
129
130#endif // CERES_INTERNAL_MAP_UTIL_H_