isotree 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -1
  3. data/LICENSE.txt +2 -2
  4. data/README.md +32 -14
  5. data/ext/isotree/ext.cpp +144 -31
  6. data/ext/isotree/extconf.rb +7 -7
  7. data/lib/isotree/isolation_forest.rb +110 -30
  8. data/lib/isotree/version.rb +1 -1
  9. data/vendor/isotree/LICENSE +1 -1
  10. data/vendor/isotree/README.md +165 -27
  11. data/vendor/isotree/include/isotree.hpp +2111 -0
  12. data/vendor/isotree/include/isotree_oop.hpp +394 -0
  13. data/vendor/isotree/inst/COPYRIGHTS +62 -0
  14. data/vendor/isotree/src/RcppExports.cpp +525 -52
  15. data/vendor/isotree/src/Rwrapper.cpp +1931 -268
  16. data/vendor/isotree/src/c_interface.cpp +953 -0
  17. data/vendor/isotree/src/crit.hpp +4232 -0
  18. data/vendor/isotree/src/dist.hpp +1886 -0
  19. data/vendor/isotree/src/exp_depth_table.hpp +134 -0
  20. data/vendor/isotree/src/extended.hpp +1444 -0
  21. data/vendor/isotree/src/external_facing_generic.hpp +399 -0
  22. data/vendor/isotree/src/fit_model.hpp +2401 -0
  23. data/vendor/isotree/src/{dealloc.cpp → headers_joined.hpp} +38 -22
  24. data/vendor/isotree/src/helpers_iforest.hpp +813 -0
  25. data/vendor/isotree/src/{impute.cpp → impute.hpp} +353 -122
  26. data/vendor/isotree/src/indexer.cpp +515 -0
  27. data/vendor/isotree/src/instantiate_template_headers.cpp +118 -0
  28. data/vendor/isotree/src/instantiate_template_headers.hpp +240 -0
  29. data/vendor/isotree/src/isoforest.hpp +1659 -0
  30. data/vendor/isotree/src/isotree.hpp +1804 -392
  31. data/vendor/isotree/src/isotree_exportable.hpp +99 -0
  32. data/vendor/isotree/src/merge_models.cpp +159 -16
  33. data/vendor/isotree/src/mult.hpp +1321 -0
  34. data/vendor/isotree/src/oop_interface.cpp +842 -0
  35. data/vendor/isotree/src/oop_interface.hpp +278 -0
  36. data/vendor/isotree/src/other_helpers.hpp +219 -0
  37. data/vendor/isotree/src/predict.hpp +1932 -0
  38. data/vendor/isotree/src/python_helpers.hpp +134 -0
  39. data/vendor/isotree/src/ref_indexer.hpp +154 -0
  40. data/vendor/isotree/src/robinmap/LICENSE +21 -0
  41. data/vendor/isotree/src/robinmap/README.md +483 -0
  42. data/vendor/isotree/src/robinmap/include/tsl/robin_growth_policy.h +406 -0
  43. data/vendor/isotree/src/robinmap/include/tsl/robin_hash.h +1620 -0
  44. data/vendor/isotree/src/robinmap/include/tsl/robin_map.h +807 -0
  45. data/vendor/isotree/src/robinmap/include/tsl/robin_set.h +660 -0
  46. data/vendor/isotree/src/serialize.cpp +4300 -139
  47. data/vendor/isotree/src/sql.cpp +141 -59
  48. data/vendor/isotree/src/subset_models.cpp +174 -0
  49. data/vendor/isotree/src/utils.hpp +3808 -0
  50. data/vendor/isotree/src/xoshiro.hpp +467 -0
  51. data/vendor/isotree/src/ziggurat.hpp +405 -0
  52. metadata +38 -104
  53. data/vendor/cereal/LICENSE +0 -24
  54. data/vendor/cereal/README.md +0 -85
  55. data/vendor/cereal/include/cereal/access.hpp +0 -351
  56. data/vendor/cereal/include/cereal/archives/adapters.hpp +0 -163
  57. data/vendor/cereal/include/cereal/archives/binary.hpp +0 -169
  58. data/vendor/cereal/include/cereal/archives/json.hpp +0 -1019
  59. data/vendor/cereal/include/cereal/archives/portable_binary.hpp +0 -334
  60. data/vendor/cereal/include/cereal/archives/xml.hpp +0 -956
  61. data/vendor/cereal/include/cereal/cereal.hpp +0 -1089
  62. data/vendor/cereal/include/cereal/details/helpers.hpp +0 -422
  63. data/vendor/cereal/include/cereal/details/polymorphic_impl.hpp +0 -796
  64. data/vendor/cereal/include/cereal/details/polymorphic_impl_fwd.hpp +0 -65
  65. data/vendor/cereal/include/cereal/details/static_object.hpp +0 -127
  66. data/vendor/cereal/include/cereal/details/traits.hpp +0 -1411
  67. data/vendor/cereal/include/cereal/details/util.hpp +0 -84
  68. data/vendor/cereal/include/cereal/external/base64.hpp +0 -134
  69. data/vendor/cereal/include/cereal/external/rapidjson/allocators.h +0 -284
  70. data/vendor/cereal/include/cereal/external/rapidjson/cursorstreamwrapper.h +0 -78
  71. data/vendor/cereal/include/cereal/external/rapidjson/document.h +0 -2652
  72. data/vendor/cereal/include/cereal/external/rapidjson/encodedstream.h +0 -299
  73. data/vendor/cereal/include/cereal/external/rapidjson/encodings.h +0 -716
  74. data/vendor/cereal/include/cereal/external/rapidjson/error/en.h +0 -74
  75. data/vendor/cereal/include/cereal/external/rapidjson/error/error.h +0 -161
  76. data/vendor/cereal/include/cereal/external/rapidjson/filereadstream.h +0 -99
  77. data/vendor/cereal/include/cereal/external/rapidjson/filewritestream.h +0 -104
  78. data/vendor/cereal/include/cereal/external/rapidjson/fwd.h +0 -151
  79. data/vendor/cereal/include/cereal/external/rapidjson/internal/biginteger.h +0 -290
  80. data/vendor/cereal/include/cereal/external/rapidjson/internal/diyfp.h +0 -271
  81. data/vendor/cereal/include/cereal/external/rapidjson/internal/dtoa.h +0 -245
  82. data/vendor/cereal/include/cereal/external/rapidjson/internal/ieee754.h +0 -78
  83. data/vendor/cereal/include/cereal/external/rapidjson/internal/itoa.h +0 -308
  84. data/vendor/cereal/include/cereal/external/rapidjson/internal/meta.h +0 -186
  85. data/vendor/cereal/include/cereal/external/rapidjson/internal/pow10.h +0 -55
  86. data/vendor/cereal/include/cereal/external/rapidjson/internal/regex.h +0 -740
  87. data/vendor/cereal/include/cereal/external/rapidjson/internal/stack.h +0 -232
  88. data/vendor/cereal/include/cereal/external/rapidjson/internal/strfunc.h +0 -69
  89. data/vendor/cereal/include/cereal/external/rapidjson/internal/strtod.h +0 -290
  90. data/vendor/cereal/include/cereal/external/rapidjson/internal/swap.h +0 -46
  91. data/vendor/cereal/include/cereal/external/rapidjson/istreamwrapper.h +0 -128
  92. data/vendor/cereal/include/cereal/external/rapidjson/memorybuffer.h +0 -70
  93. data/vendor/cereal/include/cereal/external/rapidjson/memorystream.h +0 -71
  94. data/vendor/cereal/include/cereal/external/rapidjson/msinttypes/inttypes.h +0 -316
  95. data/vendor/cereal/include/cereal/external/rapidjson/msinttypes/stdint.h +0 -300
  96. data/vendor/cereal/include/cereal/external/rapidjson/ostreamwrapper.h +0 -81
  97. data/vendor/cereal/include/cereal/external/rapidjson/pointer.h +0 -1414
  98. data/vendor/cereal/include/cereal/external/rapidjson/prettywriter.h +0 -277
  99. data/vendor/cereal/include/cereal/external/rapidjson/rapidjson.h +0 -656
  100. data/vendor/cereal/include/cereal/external/rapidjson/reader.h +0 -2230
  101. data/vendor/cereal/include/cereal/external/rapidjson/schema.h +0 -2497
  102. data/vendor/cereal/include/cereal/external/rapidjson/stream.h +0 -223
  103. data/vendor/cereal/include/cereal/external/rapidjson/stringbuffer.h +0 -121
  104. data/vendor/cereal/include/cereal/external/rapidjson/writer.h +0 -709
  105. data/vendor/cereal/include/cereal/external/rapidxml/license.txt +0 -52
  106. data/vendor/cereal/include/cereal/external/rapidxml/manual.html +0 -406
  107. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml.hpp +0 -2624
  108. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_iterators.hpp +0 -175
  109. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_print.hpp +0 -428
  110. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_utils.hpp +0 -123
  111. data/vendor/cereal/include/cereal/macros.hpp +0 -154
  112. data/vendor/cereal/include/cereal/specialize.hpp +0 -139
  113. data/vendor/cereal/include/cereal/types/array.hpp +0 -79
  114. data/vendor/cereal/include/cereal/types/atomic.hpp +0 -55
  115. data/vendor/cereal/include/cereal/types/base_class.hpp +0 -203
  116. data/vendor/cereal/include/cereal/types/bitset.hpp +0 -176
  117. data/vendor/cereal/include/cereal/types/boost_variant.hpp +0 -164
  118. data/vendor/cereal/include/cereal/types/chrono.hpp +0 -72
  119. data/vendor/cereal/include/cereal/types/common.hpp +0 -129
  120. data/vendor/cereal/include/cereal/types/complex.hpp +0 -56
  121. data/vendor/cereal/include/cereal/types/concepts/pair_associative_container.hpp +0 -73
  122. data/vendor/cereal/include/cereal/types/deque.hpp +0 -62
  123. data/vendor/cereal/include/cereal/types/forward_list.hpp +0 -68
  124. data/vendor/cereal/include/cereal/types/functional.hpp +0 -43
  125. data/vendor/cereal/include/cereal/types/list.hpp +0 -62
  126. data/vendor/cereal/include/cereal/types/map.hpp +0 -36
  127. data/vendor/cereal/include/cereal/types/memory.hpp +0 -425
  128. data/vendor/cereal/include/cereal/types/optional.hpp +0 -66
  129. data/vendor/cereal/include/cereal/types/polymorphic.hpp +0 -483
  130. data/vendor/cereal/include/cereal/types/queue.hpp +0 -132
  131. data/vendor/cereal/include/cereal/types/set.hpp +0 -103
  132. data/vendor/cereal/include/cereal/types/stack.hpp +0 -76
  133. data/vendor/cereal/include/cereal/types/string.hpp +0 -61
  134. data/vendor/cereal/include/cereal/types/tuple.hpp +0 -123
  135. data/vendor/cereal/include/cereal/types/unordered_map.hpp +0 -36
  136. data/vendor/cereal/include/cereal/types/unordered_set.hpp +0 -99
  137. data/vendor/cereal/include/cereal/types/utility.hpp +0 -47
  138. data/vendor/cereal/include/cereal/types/valarray.hpp +0 -89
  139. data/vendor/cereal/include/cereal/types/variant.hpp +0 -109
  140. data/vendor/cereal/include/cereal/types/vector.hpp +0 -112
  141. data/vendor/cereal/include/cereal/version.hpp +0 -52
  142. data/vendor/isotree/src/Makevars +0 -4
  143. data/vendor/isotree/src/crit.cpp +0 -912
  144. data/vendor/isotree/src/dist.cpp +0 -749
  145. data/vendor/isotree/src/extended.cpp +0 -790
  146. data/vendor/isotree/src/fit_model.cpp +0 -1090
  147. data/vendor/isotree/src/helpers_iforest.cpp +0 -324
  148. data/vendor/isotree/src/isoforest.cpp +0 -771
  149. data/vendor/isotree/src/mult.cpp +0 -607
  150. data/vendor/isotree/src/predict.cpp +0 -853
  151. data/vendor/isotree/src/utils.cpp +0 -1566
@@ -0,0 +1,807 @@
1
+ /**
2
+ * MIT License
3
+ *
4
+ * Copyright (c) 2017 Thibaut Goetghebuer-Planchon <tessil@gmx.com>
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+ #ifndef TSL_ROBIN_MAP_H
25
+ #define TSL_ROBIN_MAP_H
26
+
27
+ #include <cstddef>
28
+ #include <functional>
29
+ #include <initializer_list>
30
+ #include <memory>
31
+ #include <type_traits>
32
+ #include <utility>
33
+
34
+ #include "robin_hash.h"
35
+
36
+ namespace tsl {
37
+
38
+ /**
39
+ * Implementation of a hash map using open-addressing and the robin hood hashing
40
+ * algorithm with backward shift deletion.
41
+ *
42
+ * For operations modifying the hash map (insert, erase, rehash, ...), the
43
+ * strong exception guarantee is only guaranteed when the expression
44
+ * `std::is_nothrow_swappable<std::pair<Key, T>>::value &&
45
+ * std::is_nothrow_move_constructible<std::pair<Key, T>>::value` is true,
46
+ * otherwise if an exception is thrown during the swap or the move, the hash map
47
+ * may end up in a undefined state. Per the standard a `Key` or `T` with a
48
+ * noexcept copy constructor and no move constructor also satisfies the
49
+ * `std::is_nothrow_move_constructible<std::pair<Key, T>>::value` criterion (and
50
+ * will thus guarantee the strong exception for the map).
51
+ *
52
+ * When `StoreHash` is true, 32 bits of the hash are stored alongside the
53
+ * values. It can improve the performance during lookups if the `KeyEqual`
54
+ * function takes time (if it engenders a cache-miss for example) as we then
55
+ * compare the stored hashes before comparing the keys. When
56
+ * `tsl::rh::power_of_two_growth_policy` is used as `GrowthPolicy`, it may also
57
+ * speed-up the rehash process as we can avoid to recalculate the hash. When it
58
+ * is detected that storing the hash will not incur any memory penalty due to
59
+ * alignment (i.e. `sizeof(tsl::detail_robin_hash::bucket_entry<ValueType,
60
+ * true>) == sizeof(tsl::detail_robin_hash::bucket_entry<ValueType, false>)`)
61
+ * and `tsl::rh::power_of_two_growth_policy` is used, the hash will be stored
62
+ * even if `StoreHash` is false so that we can speed-up the rehash (but it will
63
+ * not be used on lookups unless `StoreHash` is true).
64
+ *
65
+ * `GrowthPolicy` defines how the map grows and consequently how a hash value is
66
+ * mapped to a bucket. By default the map uses
67
+ * `tsl::rh::power_of_two_growth_policy`. This policy keeps the number of
68
+ * buckets to a power of two and uses a mask to map the hash to a bucket instead
69
+ * of the slow modulo. Other growth policies are available and you may define
70
+ * your own growth policy, check `tsl::rh::power_of_two_growth_policy` for the
71
+ * interface.
72
+ *
73
+ * `std::pair<Key, T>` must be swappable.
74
+ *
75
+ * `Key` and `T` must be copy and/or move constructible.
76
+ *
77
+ * If the destructor of `Key` or `T` throws an exception, the behaviour of the
78
+ * class is undefined.
79
+ *
80
+ * Iterators invalidation:
81
+ * - clear, operator=, reserve, rehash: always invalidate the iterators.
82
+ * - insert, emplace, emplace_hint, operator[]: if there is an effective
83
+ * insert, invalidate the iterators.
84
+ * - erase: always invalidate the iterators.
85
+ */
86
+ template <class Key, class T, class Hash = std::hash<Key>,
87
+ class KeyEqual = std::equal_to<Key>,
88
+ class Allocator = std::allocator<std::pair<Key, T>>,
89
+ bool StoreHash = false,
90
+ class GrowthPolicy = tsl::rh::power_of_two_growth_policy<2>>
91
+ class robin_map {
92
+ private:
93
+ template <typename U>
94
+ using has_is_transparent = tsl::detail_robin_hash::has_is_transparent<U>;
95
+
96
+ class KeySelect {
97
+ public:
98
+ using key_type = Key;
99
+
100
+ const key_type& operator()(
101
+ const std::pair<Key, T>& key_value) const noexcept {
102
+ return key_value.first;
103
+ }
104
+
105
+ key_type& operator()(std::pair<Key, T>& key_value) noexcept {
106
+ return key_value.first;
107
+ }
108
+ };
109
+
110
+ class ValueSelect {
111
+ public:
112
+ using value_type = T;
113
+
114
+ const value_type& operator()(
115
+ const std::pair<Key, T>& key_value) const noexcept {
116
+ return key_value.second;
117
+ }
118
+
119
+ value_type& operator()(std::pair<Key, T>& key_value) noexcept {
120
+ return key_value.second;
121
+ }
122
+ };
123
+
124
+ using ht = detail_robin_hash::robin_hash<std::pair<Key, T>, KeySelect,
125
+ ValueSelect, Hash, KeyEqual,
126
+ Allocator, StoreHash, GrowthPolicy>;
127
+
128
+ public:
129
+ using key_type = typename ht::key_type;
130
+ using mapped_type = T;
131
+ using value_type = typename ht::value_type;
132
+ using size_type = typename ht::size_type;
133
+ using difference_type = typename ht::difference_type;
134
+ using hasher = typename ht::hasher;
135
+ using key_equal = typename ht::key_equal;
136
+ using allocator_type = typename ht::allocator_type;
137
+ using reference = typename ht::reference;
138
+ using const_reference = typename ht::const_reference;
139
+ using pointer = typename ht::pointer;
140
+ using const_pointer = typename ht::const_pointer;
141
+ using iterator = typename ht::iterator;
142
+ using const_iterator = typename ht::const_iterator;
143
+
144
+ public:
145
+ /*
146
+ * Constructors
147
+ */
148
+ robin_map() : robin_map(ht::DEFAULT_INIT_BUCKETS_SIZE) {}
149
+
150
+ explicit robin_map(size_type bucket_count, const Hash& hash = Hash(),
151
+ const KeyEqual& equal = KeyEqual(),
152
+ const Allocator& alloc = Allocator())
153
+ : m_ht(bucket_count, hash, equal, alloc) {}
154
+
155
+ robin_map(size_type bucket_count, const Allocator& alloc)
156
+ : robin_map(bucket_count, Hash(), KeyEqual(), alloc) {}
157
+
158
+ robin_map(size_type bucket_count, const Hash& hash, const Allocator& alloc)
159
+ : robin_map(bucket_count, hash, KeyEqual(), alloc) {}
160
+
161
+ explicit robin_map(const Allocator& alloc)
162
+ : robin_map(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) {}
163
+
164
+ template <class InputIt>
165
+ robin_map(InputIt first, InputIt last,
166
+ size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE,
167
+ const Hash& hash = Hash(), const KeyEqual& equal = KeyEqual(),
168
+ const Allocator& alloc = Allocator())
169
+ : robin_map(bucket_count, hash, equal, alloc) {
170
+ insert(first, last);
171
+ }
172
+
173
+ template <class InputIt>
174
+ robin_map(InputIt first, InputIt last, size_type bucket_count,
175
+ const Allocator& alloc)
176
+ : robin_map(first, last, bucket_count, Hash(), KeyEqual(), alloc) {}
177
+
178
+ template <class InputIt>
179
+ robin_map(InputIt first, InputIt last, size_type bucket_count,
180
+ const Hash& hash, const Allocator& alloc)
181
+ : robin_map(first, last, bucket_count, hash, KeyEqual(), alloc) {}
182
+
183
+ robin_map(std::initializer_list<value_type> init,
184
+ size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE,
185
+ const Hash& hash = Hash(), const KeyEqual& equal = KeyEqual(),
186
+ const Allocator& alloc = Allocator())
187
+ : robin_map(init.begin(), init.end(), bucket_count, hash, equal, alloc) {}
188
+
189
+ robin_map(std::initializer_list<value_type> init, size_type bucket_count,
190
+ const Allocator& alloc)
191
+ : robin_map(init.begin(), init.end(), bucket_count, Hash(), KeyEqual(),
192
+ alloc) {}
193
+
194
+ robin_map(std::initializer_list<value_type> init, size_type bucket_count,
195
+ const Hash& hash, const Allocator& alloc)
196
+ : robin_map(init.begin(), init.end(), bucket_count, hash, KeyEqual(),
197
+ alloc) {}
198
+
199
+ robin_map& operator=(std::initializer_list<value_type> ilist) {
200
+ m_ht.clear();
201
+
202
+ m_ht.reserve(ilist.size());
203
+ m_ht.insert(ilist.begin(), ilist.end());
204
+
205
+ return *this;
206
+ }
207
+
208
+ allocator_type get_allocator() const { return m_ht.get_allocator(); }
209
+
210
+ /*
211
+ * Iterators
212
+ */
213
+ iterator begin() noexcept { return m_ht.begin(); }
214
+ const_iterator begin() const noexcept { return m_ht.begin(); }
215
+ const_iterator cbegin() const noexcept { return m_ht.cbegin(); }
216
+
217
+ iterator end() noexcept { return m_ht.end(); }
218
+ const_iterator end() const noexcept { return m_ht.end(); }
219
+ const_iterator cend() const noexcept { return m_ht.cend(); }
220
+
221
+ /*
222
+ * Capacity
223
+ */
224
+ bool empty() const noexcept { return m_ht.empty(); }
225
+ size_type size() const noexcept { return m_ht.size(); }
226
+ size_type max_size() const noexcept { return m_ht.max_size(); }
227
+
228
+ /*
229
+ * Modifiers
230
+ */
231
+ void clear() noexcept { m_ht.clear(); }
232
+
233
+ std::pair<iterator, bool> insert(const value_type& value) {
234
+ return m_ht.insert(value);
235
+ }
236
+
237
+ template <class P, typename std::enable_if<std::is_constructible<
238
+ value_type, P&&>::value>::type* = nullptr>
239
+ std::pair<iterator, bool> insert(P&& value) {
240
+ return m_ht.emplace(std::forward<P>(value));
241
+ }
242
+
243
+ std::pair<iterator, bool> insert(value_type&& value) {
244
+ return m_ht.insert(std::move(value));
245
+ }
246
+
247
+ iterator insert(const_iterator hint, const value_type& value) {
248
+ return m_ht.insert_hint(hint, value);
249
+ }
250
+
251
+ template <class P, typename std::enable_if<std::is_constructible<
252
+ value_type, P&&>::value>::type* = nullptr>
253
+ iterator insert(const_iterator hint, P&& value) {
254
+ return m_ht.emplace_hint(hint, std::forward<P>(value));
255
+ }
256
+
257
+ iterator insert(const_iterator hint, value_type&& value) {
258
+ return m_ht.insert_hint(hint, std::move(value));
259
+ }
260
+
261
+ template <class InputIt>
262
+ void insert(InputIt first, InputIt last) {
263
+ m_ht.insert(first, last);
264
+ }
265
+
266
+ void insert(std::initializer_list<value_type> ilist) {
267
+ m_ht.insert(ilist.begin(), ilist.end());
268
+ }
269
+
270
+ template <class M>
271
+ std::pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj) {
272
+ return m_ht.insert_or_assign(k, std::forward<M>(obj));
273
+ }
274
+
275
+ template <class M>
276
+ std::pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj) {
277
+ return m_ht.insert_or_assign(std::move(k), std::forward<M>(obj));
278
+ }
279
+
280
+ template <class M>
281
+ iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj) {
282
+ return m_ht.insert_or_assign(hint, k, std::forward<M>(obj));
283
+ }
284
+
285
+ template <class M>
286
+ iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj) {
287
+ return m_ht.insert_or_assign(hint, std::move(k), std::forward<M>(obj));
288
+ }
289
+
290
+ /**
291
+ * Due to the way elements are stored, emplace will need to move or copy the
292
+ * key-value once. The method is equivalent to
293
+ * insert(value_type(std::forward<Args>(args)...));
294
+ *
295
+ * Mainly here for compatibility with the std::unordered_map interface.
296
+ */
297
+ template <class... Args>
298
+ std::pair<iterator, bool> emplace(Args&&... args) {
299
+ return m_ht.emplace(std::forward<Args>(args)...);
300
+ }
301
+
302
+ /**
303
+ * Due to the way elements are stored, emplace_hint will need to move or copy
304
+ * the key-value once. The method is equivalent to insert(hint,
305
+ * value_type(std::forward<Args>(args)...));
306
+ *
307
+ * Mainly here for compatibility with the std::unordered_map interface.
308
+ */
309
+ template <class... Args>
310
+ iterator emplace_hint(const_iterator hint, Args&&... args) {
311
+ return m_ht.emplace_hint(hint, std::forward<Args>(args)...);
312
+ }
313
+
314
+ template <class... Args>
315
+ std::pair<iterator, bool> try_emplace(const key_type& k, Args&&... args) {
316
+ return m_ht.try_emplace(k, std::forward<Args>(args)...);
317
+ }
318
+
319
+ template <class... Args>
320
+ std::pair<iterator, bool> try_emplace(key_type&& k, Args&&... args) {
321
+ return m_ht.try_emplace(std::move(k), std::forward<Args>(args)...);
322
+ }
323
+
324
+ template <class... Args>
325
+ iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args) {
326
+ return m_ht.try_emplace_hint(hint, k, std::forward<Args>(args)...);
327
+ }
328
+
329
+ template <class... Args>
330
+ iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args) {
331
+ return m_ht.try_emplace_hint(hint, std::move(k),
332
+ std::forward<Args>(args)...);
333
+ }
334
+
335
+ iterator erase(iterator pos) { return m_ht.erase(pos); }
336
+ iterator erase(const_iterator pos) { return m_ht.erase(pos); }
337
+ iterator erase(const_iterator first, const_iterator last) {
338
+ return m_ht.erase(first, last);
339
+ }
340
+ size_type erase(const key_type& key) { return m_ht.erase(key); }
341
+
342
+ /**
343
+ * Use the hash value 'precalculated_hash' instead of hashing the key. The
344
+ * hash value should be the same as hash_function()(key). Useful to speed-up
345
+ * the lookup to the value if you already have the hash.
346
+ */
347
+ size_type erase(const key_type& key, std::size_t precalculated_hash) {
348
+ return m_ht.erase(key, precalculated_hash);
349
+ }
350
+
351
+ /**
352
+ * This overload only participates in the overload resolution if the typedef
353
+ * KeyEqual::is_transparent exists. If so, K must be hashable and comparable
354
+ * to Key.
355
+ */
356
+ template <
357
+ class K, class KE = KeyEqual,
358
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
359
+ size_type erase(const K& key) {
360
+ return m_ht.erase(key);
361
+ }
362
+
363
+ /**
364
+ * @copydoc erase(const K& key)
365
+ *
366
+ * Use the hash value 'precalculated_hash' instead of hashing the key. The
367
+ * hash value should be the same as hash_function()(key). Useful to speed-up
368
+ * the lookup to the value if you already have the hash.
369
+ */
370
+ template <
371
+ class K, class KE = KeyEqual,
372
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
373
+ size_type erase(const K& key, std::size_t precalculated_hash) {
374
+ return m_ht.erase(key, precalculated_hash);
375
+ }
376
+
377
+ void swap(robin_map& other) { other.m_ht.swap(m_ht); }
378
+
379
+ /*
380
+ * Lookup
381
+ */
382
+ T& at(const Key& key) { return m_ht.at(key); }
383
+
384
+ /**
385
+ * Use the hash value 'precalculated_hash' instead of hashing the key. The
386
+ * hash value should be the same as hash_function()(key). Useful to speed-up
387
+ * the lookup if you already have the hash.
388
+ */
389
+ T& at(const Key& key, std::size_t precalculated_hash) {
390
+ return m_ht.at(key, precalculated_hash);
391
+ }
392
+
393
+ const T& at(const Key& key) const { return m_ht.at(key); }
394
+
395
+ /**
396
+ * @copydoc at(const Key& key, std::size_t precalculated_hash)
397
+ */
398
+ const T& at(const Key& key, std::size_t precalculated_hash) const {
399
+ return m_ht.at(key, precalculated_hash);
400
+ }
401
+
402
+ /**
403
+ * This overload only participates in the overload resolution if the typedef
404
+ * KeyEqual::is_transparent exists. If so, K must be hashable and comparable
405
+ * to Key.
406
+ */
407
+ template <
408
+ class K, class KE = KeyEqual,
409
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
410
+ T& at(const K& key) {
411
+ return m_ht.at(key);
412
+ }
413
+
414
+ /**
415
+ * @copydoc at(const K& key)
416
+ *
417
+ * Use the hash value 'precalculated_hash' instead of hashing the key. The
418
+ * hash value should be the same as hash_function()(key). Useful to speed-up
419
+ * the lookup if you already have the hash.
420
+ */
421
+ template <
422
+ class K, class KE = KeyEqual,
423
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
424
+ T& at(const K& key, std::size_t precalculated_hash) {
425
+ return m_ht.at(key, precalculated_hash);
426
+ }
427
+
428
+ /**
429
+ * @copydoc at(const K& key)
430
+ */
431
+ template <
432
+ class K, class KE = KeyEqual,
433
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
434
+ const T& at(const K& key) const {
435
+ return m_ht.at(key);
436
+ }
437
+
438
+ /**
439
+ * @copydoc at(const K& key, std::size_t precalculated_hash)
440
+ */
441
+ template <
442
+ class K, class KE = KeyEqual,
443
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
444
+ const T& at(const K& key, std::size_t precalculated_hash) const {
445
+ return m_ht.at(key, precalculated_hash);
446
+ }
447
+
448
+ T& operator[](const Key& key) { return m_ht[key]; }
449
+ T& operator[](Key&& key) { return m_ht[std::move(key)]; }
450
+
451
+ size_type count(const Key& key) const { return m_ht.count(key); }
452
+
453
+ /**
454
+ * Use the hash value 'precalculated_hash' instead of hashing the key. The
455
+ * hash value should be the same as hash_function()(key). Useful to speed-up
456
+ * the lookup if you already have the hash.
457
+ */
458
+ size_type count(const Key& key, std::size_t precalculated_hash) const {
459
+ return m_ht.count(key, precalculated_hash);
460
+ }
461
+
462
+ /**
463
+ * This overload only participates in the overload resolution if the typedef
464
+ * KeyEqual::is_transparent exists. If so, K must be hashable and comparable
465
+ * to Key.
466
+ */
467
+ template <
468
+ class K, class KE = KeyEqual,
469
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
470
+ size_type count(const K& key) const {
471
+ return m_ht.count(key);
472
+ }
473
+
474
+ /**
475
+ * @copydoc count(const K& key) const
476
+ *
477
+ * Use the hash value 'precalculated_hash' instead of hashing the key. The
478
+ * hash value should be the same as hash_function()(key). Useful to speed-up
479
+ * the lookup if you already have the hash.
480
+ */
481
+ template <
482
+ class K, class KE = KeyEqual,
483
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
484
+ size_type count(const K& key, std::size_t precalculated_hash) const {
485
+ return m_ht.count(key, precalculated_hash);
486
+ }
487
+
488
+ iterator find(const Key& key) { return m_ht.find(key); }
489
+
490
+ /**
491
+ * Use the hash value 'precalculated_hash' instead of hashing the key. The
492
+ * hash value should be the same as hash_function()(key). Useful to speed-up
493
+ * the lookup if you already have the hash.
494
+ */
495
+ iterator find(const Key& key, std::size_t precalculated_hash) {
496
+ return m_ht.find(key, precalculated_hash);
497
+ }
498
+
499
+ const_iterator find(const Key& key) const { return m_ht.find(key); }
500
+
501
+ /**
502
+ * @copydoc find(const Key& key, std::size_t precalculated_hash)
503
+ */
504
+ const_iterator find(const Key& key, std::size_t precalculated_hash) const {
505
+ return m_ht.find(key, precalculated_hash);
506
+ }
507
+
508
+ /**
509
+ * This overload only participates in the overload resolution if the typedef
510
+ * KeyEqual::is_transparent exists. If so, K must be hashable and comparable
511
+ * to Key.
512
+ */
513
+ template <
514
+ class K, class KE = KeyEqual,
515
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
516
+ iterator find(const K& key) {
517
+ return m_ht.find(key);
518
+ }
519
+
520
+ /**
521
+ * @copydoc find(const K& key)
522
+ *
523
+ * Use the hash value 'precalculated_hash' instead of hashing the key. The
524
+ * hash value should be the same as hash_function()(key). Useful to speed-up
525
+ * the lookup if you already have the hash.
526
+ */
527
+ template <
528
+ class K, class KE = KeyEqual,
529
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
530
+ iterator find(const K& key, std::size_t precalculated_hash) {
531
+ return m_ht.find(key, precalculated_hash);
532
+ }
533
+
534
+ /**
535
+ * @copydoc find(const K& key)
536
+ */
537
+ template <
538
+ class K, class KE = KeyEqual,
539
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
540
+ const_iterator find(const K& key) const {
541
+ return m_ht.find(key);
542
+ }
543
+
544
+ /**
545
+ * @copydoc find(const K& key)
546
+ *
547
+ * Use the hash value 'precalculated_hash' instead of hashing the key. The
548
+ * hash value should be the same as hash_function()(key). Useful to speed-up
549
+ * the lookup if you already have the hash.
550
+ */
551
+ template <
552
+ class K, class KE = KeyEqual,
553
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
554
+ const_iterator find(const K& key, std::size_t precalculated_hash) const {
555
+ return m_ht.find(key, precalculated_hash);
556
+ }
557
+
558
+ bool contains(const Key& key) const { return m_ht.contains(key); }
559
+
560
+ /**
561
+ * Use the hash value 'precalculated_hash' instead of hashing the key. The
562
+ * hash value should be the same as hash_function()(key). Useful to speed-up
563
+ * the lookup if you already have the hash.
564
+ */
565
+ bool contains(const Key& key, std::size_t precalculated_hash) const {
566
+ return m_ht.contains(key, precalculated_hash);
567
+ }
568
+
569
+ /**
570
+ * This overload only participates in the overload resolution if the typedef
571
+ * KeyEqual::is_transparent exists. If so, K must be hashable and comparable
572
+ * to Key.
573
+ */
574
+ template <
575
+ class K, class KE = KeyEqual,
576
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
577
+ bool contains(const K& key) const {
578
+ return m_ht.contains(key);
579
+ }
580
+
581
+ /**
582
+ * @copydoc contains(const K& key) const
583
+ *
584
+ * Use the hash value 'precalculated_hash' instead of hashing the key. The
585
+ * hash value should be the same as hash_function()(key). Useful to speed-up
586
+ * the lookup if you already have the hash.
587
+ */
588
+ template <
589
+ class K, class KE = KeyEqual,
590
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
591
+ bool contains(const K& key, std::size_t precalculated_hash) const {
592
+ return m_ht.contains(key, precalculated_hash);
593
+ }
594
+
595
+ std::pair<iterator, iterator> equal_range(const Key& key) {
596
+ return m_ht.equal_range(key);
597
+ }
598
+
599
+ /**
600
+ * Use the hash value 'precalculated_hash' instead of hashing the key. The
601
+ * hash value should be the same as hash_function()(key). Useful to speed-up
602
+ * the lookup if you already have the hash.
603
+ */
604
+ std::pair<iterator, iterator> equal_range(const Key& key,
605
+ std::size_t precalculated_hash) {
606
+ return m_ht.equal_range(key, precalculated_hash);
607
+ }
608
+
609
+ std::pair<const_iterator, const_iterator> equal_range(const Key& key) const {
610
+ return m_ht.equal_range(key);
611
+ }
612
+
613
+ /**
614
+ * @copydoc equal_range(const Key& key, std::size_t precalculated_hash)
615
+ */
616
+ std::pair<const_iterator, const_iterator> equal_range(
617
+ const Key& key, std::size_t precalculated_hash) const {
618
+ return m_ht.equal_range(key, precalculated_hash);
619
+ }
620
+
621
+ /**
622
+ * This overload only participates in the overload resolution if the typedef
623
+ * KeyEqual::is_transparent exists. If so, K must be hashable and comparable
624
+ * to Key.
625
+ */
626
+ template <
627
+ class K, class KE = KeyEqual,
628
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
629
+ std::pair<iterator, iterator> equal_range(const K& key) {
630
+ return m_ht.equal_range(key);
631
+ }
632
+
633
+ /**
634
+ * @copydoc equal_range(const K& key)
635
+ *
636
+ * Use the hash value 'precalculated_hash' instead of hashing the key. The
637
+ * hash value should be the same as hash_function()(key). Useful to speed-up
638
+ * the lookup if you already have the hash.
639
+ */
640
+ template <
641
+ class K, class KE = KeyEqual,
642
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
643
+ std::pair<iterator, iterator> equal_range(const K& key,
644
+ std::size_t precalculated_hash) {
645
+ return m_ht.equal_range(key, precalculated_hash);
646
+ }
647
+
648
+ /**
649
+ * @copydoc equal_range(const K& key)
650
+ */
651
+ template <
652
+ class K, class KE = KeyEqual,
653
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
654
+ std::pair<const_iterator, const_iterator> equal_range(const K& key) const {
655
+ return m_ht.equal_range(key);
656
+ }
657
+
658
+ /**
659
+ * @copydoc equal_range(const K& key, std::size_t precalculated_hash)
660
+ */
661
+ template <
662
+ class K, class KE = KeyEqual,
663
+ typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
664
+ std::pair<const_iterator, const_iterator> equal_range(
665
+ const K& key, std::size_t precalculated_hash) const {
666
+ return m_ht.equal_range(key, precalculated_hash);
667
+ }
668
+
669
+ /*
670
+ * Bucket interface
671
+ */
672
+ size_type bucket_count() const { return m_ht.bucket_count(); }
673
+ size_type max_bucket_count() const { return m_ht.max_bucket_count(); }
674
+
675
+ /*
676
+ * Hash policy
677
+ */
678
+ float load_factor() const { return m_ht.load_factor(); }
679
+
680
+ float min_load_factor() const { return m_ht.min_load_factor(); }
681
+ float max_load_factor() const { return m_ht.max_load_factor(); }
682
+
683
+ /**
684
+ * Set the `min_load_factor` to `ml`. When the `load_factor` of the map goes
685
+ * below `min_load_factor` after some erase operations, the map will be
686
+ * shrunk when an insertion occurs. The erase method itself never shrinks
687
+ * the map.
688
+ *
689
+ * The default value of `min_load_factor` is 0.0f, the map never shrinks by
690
+ * default.
691
+ */
692
+ void min_load_factor(float ml) { m_ht.min_load_factor(ml); }
693
+ void max_load_factor(float ml) { m_ht.max_load_factor(ml); }
694
+
695
+ void rehash(size_type count_) { m_ht.rehash(count_); }
696
+ void reserve(size_type count_) { m_ht.reserve(count_); }
697
+
698
+ /*
699
+ * Observers
700
+ */
701
+ hasher hash_function() const { return m_ht.hash_function(); }
702
+ key_equal key_eq() const { return m_ht.key_eq(); }
703
+
704
+ /*
705
+ * Other
706
+ */
707
+
708
+ /**
709
+ * Convert a const_iterator to an iterator.
710
+ */
711
+ iterator mutable_iterator(const_iterator pos) {
712
+ return m_ht.mutable_iterator(pos);
713
+ }
714
+
715
+ /**
716
+ * Serialize the map through the `serializer` parameter.
717
+ *
718
+ * The `serializer` parameter must be a function object that supports the
719
+ * following call:
720
+ * - `template<typename U> void operator()(const U& value);` where the types
721
+ * `std::int16_t`, `std::uint32_t`, `std::uint64_t`, `float` and
722
+ * `std::pair<Key, T>` must be supported for U.
723
+ *
724
+ * The implementation leaves binary compatibility (endianness, IEEE 754 for
725
+ * floats, ...) of the types it serializes in the hands of the `Serializer`
726
+ * function object if compatibility is required.
727
+ */
728
+ template <class Serializer>
729
+ void serialize(Serializer& serializer) const {
730
+ m_ht.serialize(serializer);
731
+ }
732
+
733
+ /**
734
+ * Deserialize a previously serialized map through the `deserializer`
735
+ * parameter.
736
+ *
737
+ * The `deserializer` parameter must be a function object that supports the
738
+ * following call:
739
+ * - `template<typename U> U operator()();` where the types `std::int16_t`,
740
+ * `std::uint32_t`, `std::uint64_t`, `float` and `std::pair<Key, T>` must be
741
+ * supported for U.
742
+ *
743
+ * If the deserialized hash map type is hash compatible with the serialized
744
+ * map, the deserialization process can be sped up by setting
745
+ * `hash_compatible` to true. To be hash compatible, the Hash, KeyEqual and
746
+ * GrowthPolicy must behave the same way than the ones used on the serialized
747
+ * map and the StoreHash must have the same value. The `std::size_t` must also
748
+ * be of the same size as the one on the platform used to serialize the map.
749
+ * If these criteria are not met, the behaviour is undefined with
750
+ * `hash_compatible` sets to true.
751
+ *
752
+ * The behaviour is undefined if the type `Key` and `T` of the `robin_map` are
753
+ * not the same as the types used during serialization.
754
+ *
755
+ * The implementation leaves binary compatibility (endianness, IEEE 754 for
756
+ * floats, size of int, ...) of the types it deserializes in the hands of the
757
+ * `Deserializer` function object if compatibility is required.
758
+ */
759
+ template <class Deserializer>
760
+ static robin_map deserialize(Deserializer& deserializer,
761
+ bool hash_compatible = false) {
762
+ robin_map map(0);
763
+ map.m_ht.deserialize(deserializer, hash_compatible);
764
+
765
+ return map;
766
+ }
767
+
768
+ friend bool operator==(const robin_map& lhs, const robin_map& rhs) {
769
+ if (lhs.size() != rhs.size()) {
770
+ return false;
771
+ }
772
+
773
+ for (const auto& element_lhs : lhs) {
774
+ const auto it_element_rhs = rhs.find(element_lhs.first);
775
+ if (it_element_rhs == rhs.cend() ||
776
+ element_lhs.second != it_element_rhs->second) {
777
+ return false;
778
+ }
779
+ }
780
+
781
+ return true;
782
+ }
783
+
784
+ friend bool operator!=(const robin_map& lhs, const robin_map& rhs) {
785
+ return !operator==(lhs, rhs);
786
+ }
787
+
788
+ friend void swap(robin_map& lhs, robin_map& rhs) { lhs.swap(rhs); }
789
+
790
+ private:
791
+ ht m_ht;
792
+ };
793
+
794
+ /**
795
+ * Same as `tsl::robin_map<Key, T, Hash, KeyEqual, Allocator, StoreHash,
796
+ * tsl::rh::prime_growth_policy>`.
797
+ */
798
+ template <class Key, class T, class Hash = std::hash<Key>,
799
+ class KeyEqual = std::equal_to<Key>,
800
+ class Allocator = std::allocator<std::pair<Key, T>>,
801
+ bool StoreHash = false>
802
+ using robin_pg_map = robin_map<Key, T, Hash, KeyEqual, Allocator, StoreHash,
803
+ tsl::rh::prime_growth_policy>;
804
+
805
+ } // end namespace tsl
806
+
807
+ #endif