mirror of https://github.com/axmolengine/axmol.git
Update robin_map to v1.2.1
This commit is contained in:
parent
100a688ce5
commit
b032ba2f56
|
@ -196,7 +196,7 @@
|
|||
|
||||
## robin-map
|
||||
- [![Upstream](https://img.shields.io/github/v/tag/Tessil/robin-map?label=Upstream)](https://github.com/Tessil/robin-map)
|
||||
- Version: 1.0.1 with modified for more compatible with stl
|
||||
- Version: 1.2.1 with modified for more compatible with stl
|
||||
- Modify `robin_map::iterator->second` to mutable same with `stl map/unordered_map`
|
||||
- Forward `robin_map::operator[]` key by `std::forward` same with `stl map/unordered_map`
|
||||
- License: MIT
|
||||
|
|
|
@ -51,15 +51,15 @@
|
|||
#define TSL_RH_THROW_OR_TERMINATE(ex, msg) throw ex(msg)
|
||||
#else
|
||||
#define TSL_RH_NO_EXCEPTIONS
|
||||
#ifdef NDEBUG
|
||||
#define TSL_RH_THROW_OR_TERMINATE(ex, msg) std::terminate()
|
||||
#else
|
||||
#ifdef TSL_DEBUG
|
||||
#include <iostream>
|
||||
#define TSL_RH_THROW_OR_TERMINATE(ex, msg) \
|
||||
do { \
|
||||
std::cerr << msg << std::endl; \
|
||||
std::terminate(); \
|
||||
} while (0)
|
||||
#else
|
||||
#define TSL_RH_THROW_OR_TERMINATE(ex, msg) std::terminate()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
@ -195,6 +196,7 @@ class bucket_entry : public bucket_entry_hash<StoreHash> {
|
|||
value_type(other.value());
|
||||
m_dist_from_ideal_bucket = other.m_dist_from_ideal_bucket;
|
||||
}
|
||||
tsl_rh_assert(empty() == other.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -212,6 +214,7 @@ class bucket_entry : public bucket_entry_hash<StoreHash> {
|
|||
value_type(std::move(other.value()));
|
||||
m_dist_from_ideal_bucket = other.m_dist_from_ideal_bucket;
|
||||
}
|
||||
tsl_rh_assert(empty() == other.empty());
|
||||
}
|
||||
|
||||
bucket_entry& operator=(const bucket_entry& other) noexcept(
|
||||
|
@ -249,12 +252,22 @@ class bucket_entry : public bucket_entry_hash<StoreHash> {
|
|||
|
||||
value_type& value() noexcept {
|
||||
tsl_rh_assert(!empty());
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L
|
||||
return *std::launder(
|
||||
reinterpret_cast<value_type*>(std::addressof(m_value)));
|
||||
#else
|
||||
return *reinterpret_cast<value_type*>(std::addressof(m_value));
|
||||
#endif
|
||||
}
|
||||
|
||||
const value_type& value() const noexcept {
|
||||
tsl_rh_assert(!empty());
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L
|
||||
return *std::launder(
|
||||
reinterpret_cast<const value_type*>(std::addressof(m_value)));
|
||||
#else
|
||||
return *reinterpret_cast<const value_type*>(std::addressof(m_value));
|
||||
#endif
|
||||
}
|
||||
|
||||
distance_type dist_from_ideal_bucket() const noexcept {
|
||||
|
@ -283,6 +296,7 @@ class bucket_entry : public bucket_entry_hash<StoreHash> {
|
|||
void swap_with_value_in_bucket(distance_type& dist_from_ideal_bucket,
|
||||
truncated_hash_type& hash, value_type& value) {
|
||||
tsl_rh_assert(!empty());
|
||||
tsl_rh_assert(dist_from_ideal_bucket > m_dist_from_ideal_bucket);
|
||||
|
||||
using std::swap;
|
||||
swap(value, this->value());
|
||||
|
@ -310,19 +324,16 @@ class bucket_entry : public bucket_entry_hash<StoreHash> {
|
|||
|
||||
public:
|
||||
static const distance_type EMPTY_MARKER_DIST_FROM_IDEAL_BUCKET = -1;
|
||||
static const distance_type DIST_FROM_IDEAL_BUCKET_LIMIT = 4096;
|
||||
static const distance_type DIST_FROM_IDEAL_BUCKET_LIMIT = 8192;
|
||||
static_assert(DIST_FROM_IDEAL_BUCKET_LIMIT <=
|
||||
(std::numeric_limits<distance_type>::max)() - 1,
|
||||
"DIST_FROM_IDEAL_BUCKET_LIMIT must be <= "
|
||||
"std::numeric_limits<distance_type>::max() - 1.");
|
||||
|
||||
private:
|
||||
using storage = typename std::aligned_storage<sizeof(value_type),
|
||||
alignof(value_type)>::type;
|
||||
|
||||
distance_type m_dist_from_ideal_bucket;
|
||||
bool m_last_bucket;
|
||||
storage m_value;
|
||||
alignas(value_type) unsigned char m_value[sizeof(value_type)];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -415,14 +426,15 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
|
|||
}
|
||||
}
|
||||
|
||||
public:
|
||||
using bucket_entry =
|
||||
tsl::detail_robin_hash::bucket_entry<value_type, STORE_HASH>;
|
||||
using distance_type = typename bucket_entry::distance_type;
|
||||
|
||||
using buckets_allocator = typename std::allocator_traits<allocator_type>::template rebind_alloc<bucket_entry>;
|
||||
using buckets_allocator = typename std::allocator_traits<
|
||||
allocator_type>::template rebind_alloc<bucket_entry>;
|
||||
using buckets_container_type = std::vector<bucket_entry, buckets_allocator>;
|
||||
|
||||
public:
|
||||
/**
|
||||
* The 'operator*()' and 'operator->()' methods return a const reference and
|
||||
* const pointer respectively to the stored value type.
|
||||
|
@ -716,7 +728,7 @@ public:
|
|||
|
||||
robin_hash& operator=(robin_hash&& other) {
|
||||
other.swap(*this);
|
||||
other.clear();
|
||||
other.clear_and_shrink();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -1125,6 +1137,7 @@ public:
|
|||
m_max_load_factor = clamp(ml, float(MINIMUM_MAX_LOAD_FACTOR),
|
||||
float(MAXIMUM_MAX_LOAD_FACTOR));
|
||||
m_load_threshold = size_type(float(bucket_count()) * m_max_load_factor);
|
||||
tsl_rh_assert(bucket_count() == 0 || m_load_threshold < bucket_count());
|
||||
}
|
||||
|
||||
void rehash(size_type count_) {
|
||||
|
@ -1276,7 +1289,7 @@ public:
|
|||
dist_from_ideal_bucket++;
|
||||
}
|
||||
|
||||
if (rehash_on_extreme_load()) {
|
||||
while (rehash_on_extreme_load(dist_from_ideal_bucket)) {
|
||||
ibucket = bucket_for_hash(hash);
|
||||
dist_from_ideal_bucket = 0;
|
||||
|
||||
|
@ -1328,6 +1341,8 @@ public:
|
|||
void insert_value_impl(std::size_t ibucket,
|
||||
distance_type dist_from_ideal_bucket,
|
||||
truncated_hash_type hash, value_type& value) {
|
||||
tsl_rh_assert(dist_from_ideal_bucket >
|
||||
m_buckets[ibucket].dist_from_ideal_bucket());
|
||||
m_buckets[ibucket].swap_with_value_in_bucket(dist_from_ideal_bucket, hash,
|
||||
value);
|
||||
ibucket = next_bucket(ibucket);
|
||||
|
@ -1336,7 +1351,7 @@ public:
|
|||
while (!m_buckets[ibucket].empty()) {
|
||||
if (dist_from_ideal_bucket >
|
||||
m_buckets[ibucket].dist_from_ideal_bucket()) {
|
||||
if (dist_from_ideal_bucket >=
|
||||
if (dist_from_ideal_bucket >
|
||||
bucket_entry::DIST_FROM_IDEAL_BUCKET_LIMIT) {
|
||||
/**
|
||||
* The number of probes is really high, rehash the map on the next
|
||||
|
@ -1361,6 +1376,7 @@ public:
|
|||
robin_hash new_table(count_, static_cast<Hash&>(*this),
|
||||
static_cast<KeyEqual&>(*this), get_allocator(),
|
||||
m_min_load_factor, m_max_load_factor);
|
||||
tsl_rh_assert(size() <= new_table.m_load_threshold);
|
||||
|
||||
const bool use_stored_hash =
|
||||
USE_STORED_HASH_ON_REHASH(new_table.bucket_count());
|
||||
|
@ -1421,8 +1437,11 @@ public:
|
|||
*
|
||||
* Return true if the table has been rehashed.
|
||||
*/
|
||||
bool rehash_on_extreme_load() {
|
||||
if (m_grow_on_next_insert || size() >= m_load_threshold) {
|
||||
bool rehash_on_extreme_load(distance_type curr_dist_from_ideal_bucket) {
|
||||
if (m_grow_on_next_insert ||
|
||||
curr_dist_from_ideal_bucket >
|
||||
bucket_entry::DIST_FROM_IDEAL_BUCKET_LIMIT ||
|
||||
size() >= m_load_threshold) {
|
||||
rehash_impl(GrowthPolicy::next_bucket_count());
|
||||
m_grow_on_next_insert = false;
|
||||
|
||||
|
@ -1628,6 +1647,7 @@ public:
|
|||
*/
|
||||
bucket_entry* static_empty_bucket_ptr() noexcept {
|
||||
static bucket_entry empty_bucket(true);
|
||||
tsl_rh_assert(empty_bucket.empty());
|
||||
return &empty_bucket;
|
||||
}
|
||||
|
||||
|
|
|
@ -97,8 +97,8 @@ class robin_map {
|
|||
public:
|
||||
using key_type = Key;
|
||||
|
||||
const key_type& operator()(const std::pair<Key, T>& key_value) const
|
||||
noexcept {
|
||||
const key_type& operator()(
|
||||
const std::pair<Key, T>& key_value) const noexcept {
|
||||
return key_value.first;
|
||||
}
|
||||
|
||||
|
@ -111,8 +111,8 @@ class robin_map {
|
|||
public:
|
||||
using value_type = T;
|
||||
|
||||
const value_type& operator()(const std::pair<Key, T>& key_value) const
|
||||
noexcept {
|
||||
const value_type& operator()(
|
||||
const std::pair<Key, T>& key_value) const noexcept {
|
||||
return key_value.second;
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,9 @@ class robin_map {
|
|||
return key_value.second;
|
||||
}
|
||||
|
||||
value_type& operator()(std::pair<const Key, T>& key_value) noexcept { return key_value.second; }
|
||||
value_type& operator()(std::pair<const Key, T>& key_value) noexcept {
|
||||
return key_value.second;
|
||||
}
|
||||
};
|
||||
|
||||
using ht = detail_robin_hash::robin_hash<std::pair<Key, T>, std::pair<const Key, T>, KeySelect,
|
||||
|
|
Loading…
Reference in New Issue