Skip to content

Commit 6b964f5

Browse files
committed
Update robin_map 1.2.1 ==> 1.3.0-054ec5a
1 parent 55f7508 commit 6b964f5

File tree

5 files changed

+44
-68
lines changed

5 files changed

+44
-68
lines changed

3rdparty/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,10 @@
212212

213213
## robin-map
214214
- [![Upstream](https://img.shields.io/github/v/tag/Tessil/robin-map?label=Upstream)](https://github.com/Tessil/robin-map)
215-
- Version: 1.2.1 with modified for more compatible with stl
215+
- Version: 1.3.0-054ec5a (until Mar 17, 2025) with modified for stl compatibility
216216
- Modify `robin_map::iterator->second` to mutable same with `stl map/unordered_map`
217217
- Forward `robin_map::operator[]` key by `std::forward` same with `stl map/unordered_map`
218+
- Improve code compiler compatibility, i.g. `std::max` ==> `(std::max)`
218219
- License: MIT
219220

220221
## simdjson

3rdparty/robin-map/include/tsl/robin_growth_policy.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@
3535
#include <ratio>
3636
#include <stdexcept>
3737

38+
// A change of the major version indicates an API and/or ABI break (change of
39+
// in-memory layout of the data structure)
40+
#define TSL_RH_VERSION_MAJOR 1
41+
// A change of the minor version indicates the addition of a feature without
42+
// impact on the API/ABI
43+
#define TSL_RH_VERSION_MINOR 3
44+
// A change of the patch version indicates a bugfix without additional
45+
// functionality
46+
#define TSL_RH_VERSION_PATCH 0
47+
3848
#ifdef TSL_DEBUG
3949
#define tsl_rh_assert(expr) assert(expr)
4050
#else
@@ -243,7 +253,7 @@ namespace detail {
243253
#define TSL_RH_NB_PRIMES 23
244254
#endif
245255

246-
static constexpr const std::array<std::size_t, TSL_RH_NB_PRIMES> PRIMES = {{
256+
inline constexpr std::array<std::size_t, TSL_RH_NB_PRIMES> PRIMES = {{
247257
1u,
248258
5u,
249259
17u,
@@ -309,8 +319,7 @@ static constexpr std::size_t mod(std::size_t hash) {
309319
// MOD_PRIME[iprime](hash) returns hash % PRIMES[iprime]. This table allows for
310320
// faster modulo as the compiler can optimize the modulo code better with a
311321
// constant known at the compilation.
312-
static constexpr const std::array<std::size_t (*)(std::size_t),
313-
TSL_RH_NB_PRIMES>
322+
inline constexpr std::array<std::size_t (*)(std::size_t), TSL_RH_NB_PRIMES>
314323
MOD_PRIME = {{
315324
&mod<0>, &mod<1>, &mod<2>, &mod<3>, &mod<4>, &mod<5>,
316325
&mod<6>, &mod<7>, &mod<8>, &mod<9>, &mod<10>, &mod<11>,

3rdparty/robin-map/include/tsl/robin_hash.h

Lines changed: 14 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,6 @@ template <std::size_t GrowthFactor>
6666
struct is_power_of_two_policy<tsl::rh::power_of_two_growth_policy<GrowthFactor>>
6767
: std::true_type {};
6868

69-
// Only available in C++17, we need to be compatible with C++11
70-
template <class T>
71-
const T& clamp(const T& v, const T& lo, const T& hi) {
72-
return (std::min)(hi, (std::max)(lo, v));
73-
}
74-
7569
template <typename T, typename U>
7670
static T numeric_cast(U value,
7771
const char* error_message = "numeric_cast() failed.") {
@@ -87,6 +81,8 @@ static T numeric_cast(U value,
8781
TSL_RH_THROW_OR_TERMINATE(std::runtime_error, error_message);
8882
}
8983

84+
TSL_RH_UNUSED(error_message);
85+
9086
return ret;
9187
}
9288

@@ -252,22 +248,14 @@ class bucket_entry : public bucket_entry_hash<StoreHash> {
252248

253249
value_type& value() noexcept {
254250
tsl_rh_assert(!empty());
255-
#if defined(__cplusplus) && __cplusplus >= 201703L
256251
return *std::launder(
257252
reinterpret_cast<value_type*>(std::addressof(m_value)));
258-
#else
259-
return *reinterpret_cast<value_type*>(std::addressof(m_value));
260-
#endif
261253
}
262254

263255
const value_type& value() const noexcept {
264256
tsl_rh_assert(!empty());
265-
#if defined(__cplusplus) && __cplusplus >= 201703L
266257
return *std::launder(
267258
reinterpret_cast<const value_type*>(std::addressof(m_value)));
268-
#else
269-
return *reinterpret_cast<const value_type*>(std::addressof(m_value));
270-
#endif
271259
}
272260

273261
distance_type dist_from_ideal_bucket() const noexcept {
@@ -597,7 +585,6 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
597585
using const_iterator = robin_const_iterator;
598586

599587
public:
600-
#if defined(__cplusplus) && __cplusplus >= 201402L
601588
robin_hash(size_type bucket_count, const Hash& hash, const KeyEqual& equal,
602589
const Allocator& alloc,
603590
float min_load_factor = DEFAULT_MIN_LOAD_FACTOR,
@@ -625,47 +612,6 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
625612
this->min_load_factor(min_load_factor);
626613
this->max_load_factor(max_load_factor);
627614
}
628-
#else
629-
/**
630-
* C++11 doesn't support the creation of a std::vector with a custom allocator
631-
* and 'count' default-inserted elements. The needed contructor `explicit
632-
* vector(size_type count, const Allocator& alloc = Allocator());` is only
633-
* available in C++14 and later. We thus must resize after using the
634-
* `vector(const Allocator& alloc)` constructor.
635-
*
636-
* We can't use `vector(size_type count, const T& value, const Allocator&
637-
* alloc)` as it requires the value T to be copyable.
638-
*/
639-
robin_hash(size_type bucket_count, const Hash& hash, const KeyEqual& equal,
640-
const Allocator& alloc,
641-
float min_load_factor = DEFAULT_MIN_LOAD_FACTOR,
642-
float max_load_factor = DEFAULT_MAX_LOAD_FACTOR)
643-
: Hash(hash),
644-
KeyEqual(equal),
645-
GrowthPolicy(bucket_count),
646-
m_buckets_data(alloc),
647-
m_buckets(static_empty_bucket_ptr()),
648-
m_bucket_count(bucket_count),
649-
m_nb_elements(0),
650-
m_grow_on_next_insert(false),
651-
m_try_shrink_on_next_insert(false) {
652-
if (bucket_count > max_bucket_count()) {
653-
TSL_RH_THROW_OR_TERMINATE(std::length_error,
654-
"The map exceeds its maximum bucket count.");
655-
}
656-
657-
if (m_bucket_count > 0) {
658-
m_buckets_data.resize(m_bucket_count);
659-
m_buckets = m_buckets_data.data();
660-
661-
tsl_rh_assert(!m_buckets_data.empty());
662-
m_buckets_data.back().set_as_last_bucket();
663-
}
664-
665-
this->min_load_factor(min_load_factor);
666-
this->max_load_factor(max_load_factor);
667-
}
668-
#endif
669615

670616
robin_hash(const robin_hash& other)
671617
: Hash(other),
@@ -876,6 +822,10 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
876822
return try_emplace(std::forward<K>(key), std::forward<Args>(args)...).first;
877823
}
878824

825+
void erase_fast(iterator pos) {
826+
erase_from_bucket(pos);
827+
}
828+
879829
/**
880830
* Here to avoid `template<class K> size_type erase(const K& key)` being used
881831
* when we use an `iterator` instead of a `const_iterator`.
@@ -892,8 +842,6 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
892842
++pos;
893843
}
894844

895-
m_try_shrink_on_next_insert = true;
896-
897845
return pos;
898846
}
899847

@@ -972,8 +920,6 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
972920
auto it = find(key, hash);
973921
if (it != end()) {
974922
erase_from_bucket(it);
975-
m_try_shrink_on_next_insert = true;
976-
977923
return 1;
978924
} else {
979925
return 0;
@@ -1129,13 +1075,13 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
11291075
float max_load_factor() const { return m_max_load_factor; }
11301076

11311077
void min_load_factor(float ml) {
1132-
m_min_load_factor = clamp(ml, float(MINIMUM_MIN_LOAD_FACTOR),
1133-
float(MAXIMUM_MIN_LOAD_FACTOR));
1078+
m_min_load_factor = std::clamp(ml, float(MINIMUM_MIN_LOAD_FACTOR),
1079+
float(MAXIMUM_MIN_LOAD_FACTOR));
11341080
}
11351081

11361082
void max_load_factor(float ml) {
1137-
m_max_load_factor = clamp(ml, float(MINIMUM_MAX_LOAD_FACTOR),
1138-
float(MAXIMUM_MAX_LOAD_FACTOR));
1083+
m_max_load_factor = std::clamp(ml, float(MINIMUM_MAX_LOAD_FACTOR),
1084+
float(MAXIMUM_MAX_LOAD_FACTOR));
11391085
m_load_threshold = size_type(float(bucket_count()) * m_max_load_factor);
11401086
tsl_rh_assert(bucket_count() == 0 || m_load_threshold < bucket_count());
11411087
}
@@ -1267,6 +1213,7 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
12671213
previous_ibucket = ibucket;
12681214
ibucket = next_bucket(ibucket);
12691215
}
1216+
m_try_shrink_on_next_insert = true;
12701217
}
12711218

12721219
template <class K, class... Args>
@@ -1579,6 +1526,9 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
15791526
} else {
15801527
m_bucket_count = numeric_cast<size_type>(
15811528
bucket_count_ds, "Deserialized bucket_count is too big.");
1529+
// Recompute m_load_threshold, during max_load_factor() the bucket count
1530+
// was still 0 which would trigger rehash on first insert
1531+
m_load_threshold = size_type(float(bucket_count()) * m_max_load_factor);
15821532

15831533
GrowthPolicy::operator=(GrowthPolicy(m_bucket_count));
15841534
// GrowthPolicy should not modify the bucket count we got from

3rdparty/robin-map/include/tsl/robin_map.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,14 @@ class robin_map {
344344
}
345345
size_type erase(const key_type& key) { return m_ht.erase(key); }
346346

347+
/**
348+
* Erase the element at position 'pos'. In contrast to the regular erase()
349+
* function, erase_fast() does not return an iterator. This allows it to be
350+
* faster especially in hash tables with a low load factor, where finding the
351+
* next nonempty bucket would be costly.
352+
*/
353+
void erase_fast(iterator pos) { return m_ht.erase_fast(pos); }
354+
347355
/**
348356
* Use the hash value 'precalculated_hash' instead of hashing the key. The
349357
* hash value should be the same as hash_function()(key). Useful to speed-up

3rdparty/robin-map/include/tsl/robin_set.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,14 @@ class robin_set {
264264
}
265265
size_type erase(const key_type& key) { return m_ht.erase(key); }
266266

267+
/**
268+
* Erase the element at position 'pos'. In contrast to the regular erase()
269+
* function, erase_fast() does not return an iterator. This allows it to be
270+
* faster especially in hash sets with a low load factor, where finding the
271+
* next nonempty bucket would be costly.
272+
*/
273+
void erase_fast(iterator pos) { return m_ht.erase_fast(pos); }
274+
267275
/**
268276
* Use the hash value 'precalculated_hash' instead of hashing the key. The
269277
* hash value should be the same as hash_function()(key). Useful to speed-up

0 commit comments

Comments
 (0)