blob: 8f345d4d70ac7b8f375eb029c65b5babafc64862 [file] [log] [blame]
Keir Mierle8ebb0732012-04-30 23:09:08 -07001// Ceres Solver - A fast non-linear least squares minimizer
2// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
3// http://code.google.com/p/ceres-solver/
4//
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// Portable HashMap and HashSet, and a specialized overload for hashing pairs.
32
33#ifndef CERES_INTERNAL_COLLECTIONS_PORT_H_
34#define CERES_INTERNAL_COLLECTIONS_PORT_H_
35
Sameer Agarwalf6b67df2013-10-25 06:24:19 -070036#if defined(CERES_NO_UNORDERED_MAP)
Keir Mierled2164902012-08-15 19:04:50 -070037# include <map>
38# include <set>
Keir Mierleefe7ac62012-06-24 22:25:28 -070039#endif
Sameer Agarwalf6b67df2013-10-25 06:24:19 -070040
41#if defined(CERES_TR1_UNORDERED_MAP)
42# include <tr1/unordered_map>
43# include <tr1/unordered_set>
Sameer Agarwal602096c2013-10-27 05:09:38 -070044# define CERES_HASH_NAMESPACE_START namespace std { namespace tr1 {
45# define CERES_HASH_NAMESPACE_END } }
Sameer Agarwalf6b67df2013-10-25 06:24:19 -070046#endif
47
48#if defined(CERES_STD_UNORDERED_MAP)
49# include <unordered_map>
50# include <unordered_set>
Sameer Agarwal602096c2013-10-27 05:09:38 -070051# define CERES_HASH_NAMESPACE_START namespace std {
52# define CERES_HASH_NAMESPACE_END }
Sameer Agarwalf6b67df2013-10-25 06:24:19 -070053#endif
54
Sameer Agarwal602096c2013-10-27 05:09:38 -070055#if !defined(CERES_NO_UNORDERED_MAP) && !defined(CERES_TR1_UNORDERED_MAP) && !defined(CERES_STD_UNORDERED_MAP)
56#error One of: CERES_NO_UNORDERED_MAP, CERES_TR1_UNORDERED_MAP, CERES_STD_UNORDERED_MAP must be defined!
57#endif
Sameer Agarwalf6b67df2013-10-25 06:24:19 -070058
Keir Mierle8ebb0732012-04-30 23:09:08 -070059#include <utility>
60#include "ceres/integral_types.h"
61#include "ceres/internal/port.h"
62
Sameer Agarwalf6b67df2013-10-25 06:24:19 -070063// Some systems don't have access to unordered_map/unordered_set. In
64// that case, substitute the hash map/set with normal map/set. The
Sameer Agarwal602096c2013-10-27 05:09:38 -070065// price to pay is slower speed for some operations.
Sameer Agarwalf6b67df2013-10-25 06:24:19 -070066#if defined(CERES_NO_UNORDERED_MAP)
Keir Mierled2164902012-08-15 19:04:50 -070067
68namespace ceres {
69namespace internal {
70
71template<typename K, typename V>
72struct HashMap : map<K, V> {};
73
74template<typename K>
75struct HashSet : set<K> {};
76
77} // namespace internal
78} // namespace ceres
79
80#else
81
Keir Mierle8ebb0732012-04-30 23:09:08 -070082namespace ceres {
83namespace internal {
84
Sameer Agarwalf6b67df2013-10-25 06:24:19 -070085#if defined(CERES_TR1_UNORDERED_MAP)
Keir Mierle8ebb0732012-04-30 23:09:08 -070086template<typename K, typename V>
Keir Mierleaff5a452012-08-10 16:58:56 -070087struct HashMap : std::tr1::unordered_map<K, V> {};
Keir Mierle8ebb0732012-04-30 23:09:08 -070088template<typename K>
Keir Mierleaff5a452012-08-10 16:58:56 -070089struct HashSet : std::tr1::unordered_set<K> {};
Sameer Agarwalf6b67df2013-10-25 06:24:19 -070090#endif
91
92#if defined(CERES_STD_UNORDERED_MAP)
93template<typename K, typename V>
94struct HashMap : std::unordered_map<K, V> {};
95template<typename K>
96struct HashSet : std::unordered_set<K> {};
97#endif
Keir Mierle8ebb0732012-04-30 23:09:08 -070098
Sergey Sharybin267ccc42013-02-25 01:04:16 +060099#if defined(_WIN32) && !defined(__MINGW64__) && !defined(__MINGW32__)
Keir Mierle8ebb0732012-04-30 23:09:08 -0700100#define GG_LONGLONG(x) x##I64
101#define GG_ULONGLONG(x) x##UI64
102#else
103#define GG_LONGLONG(x) x##LL
104#define GG_ULONGLONG(x) x##ULL
105#endif
106
107// The hash function is due to Bob Jenkins (see
108// http://burtleburtle.net/bob/hash/index.html). Each mix takes 36 instructions,
109// in 18 cycles if you're lucky. On x86 architectures, this requires 45
110// instructions in 27 cycles, if you're lucky.
111//
112// 32bit version
113inline void hash_mix(uint32& a, uint32& b, uint32& c) {
114 a -= b; a -= c; a ^= (c>>13);
115 b -= c; b -= a; b ^= (a<<8);
116 c -= a; c -= b; c ^= (b>>13);
117 a -= b; a -= c; a ^= (c>>12);
118 b -= c; b -= a; b ^= (a<<16);
119 c -= a; c -= b; c ^= (b>>5);
120 a -= b; a -= c; a ^= (c>>3);
121 b -= c; b -= a; b ^= (a<<10);
122 c -= a; c -= b; c ^= (b>>15);
123}
124
125// 64bit version
126inline void hash_mix(uint64& a, uint64& b, uint64& c) {
127 a -= b; a -= c; a ^= (c>>43);
128 b -= c; b -= a; b ^= (a<<9);
129 c -= a; c -= b; c ^= (b>>8);
130 a -= b; a -= c; a ^= (c>>38);
131 b -= c; b -= a; b ^= (a<<23);
132 c -= a; c -= b; c ^= (b>>5);
133 a -= b; a -= c; a ^= (c>>35);
134 b -= c; b -= a; b ^= (a<<49);
135 c -= a; c -= b; c ^= (b>>11);
136}
137
138inline uint32 Hash32NumWithSeed(uint32 num, uint32 c) {
139 // The golden ratio; an arbitrary value.
140 uint32 b = 0x9e3779b9UL;
141 hash_mix(num, b, c);
142 return c;
143}
144
145inline uint64 Hash64NumWithSeed(uint64 num, uint64 c) {
146 // More of the golden ratio.
147 uint64 b = GG_ULONGLONG(0xe08c1d668b756f82);
148 hash_mix(num, b, c);
149 return c;
150}
151
152} // namespace internal
153} // namespace ceres
154
155// Since on some platforms this is a doubly-nested namespace (std::tr1) and
156// others it is not, the entire namespace line must be in a macro.
157CERES_HASH_NAMESPACE_START
158
159// The outrageously annoying specializations below are for portability reasons.
160// In short, it's not possible to have two overloads of hash<pair<T1, T2>
161
162// Hasher for STL pairs. Requires hashers for both members to be defined.
163template<typename T>
164struct hash<pair<T, T> > {
165 size_t operator()(const pair<T, T>& p) const {
166 size_t h1 = hash<T>()(p.first);
167 size_t h2 = hash<T>()(p.second);
168 // The decision below is at compile time
169 return (sizeof(h1) <= sizeof(ceres::internal::uint32)) ?
170 ceres::internal::Hash32NumWithSeed(h1, h2) :
171 ceres::internal::Hash64NumWithSeed(h1, h2);
172 }
173 // Less than operator for MSVC.
174 bool operator()(const pair<T, T>& a,
175 const pair<T, T>& b) const {
176 return a < b;
177 }
178 static const size_t bucket_size = 4; // These are required by MSVC
179 static const size_t min_buckets = 8; // 4 and 8 are defaults.
180};
181
182CERES_HASH_NAMESPACE_END
183
Sameer Agarwalf6b67df2013-10-25 06:24:19 -0700184#endif // CERES_NO_UNORDERED_MAP
Keir Mierle8ebb0732012-04-30 23:09:08 -0700185#endif // CERES_INTERNAL_COLLECTIONS_PORT_H_