isotree 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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