summaryrefslogtreecommitdiffhomepage
path: root/misc/benchmarks/external/ankerl/unordered_dense.h
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2023-02-11 23:55:24 +0100
committerTyge Løvset <[email protected]>2023-02-11 23:55:24 +0100
commite730c593429bdd5a73da5b02e7559b1f0fd21e19 (patch)
tree3613172419e4c4821e45f41c15e8d16423b5e6da /misc/benchmarks/external/ankerl/unordered_dense.h
parent921c06f1b46d449668881ebd1c35a83dc32ad38a (diff)
downloadSTC-modified-e730c593429bdd5a73da5b02e7559b1f0fd21e19.tar.gz
STC-modified-e730c593429bdd5a73da5b02e7559b1f0fd21e19.zip
Some more docs. Renamed (half-)internal template parameter i_size => i_ssize. Updated external cpp maps for benchmarks.
Diffstat (limited to 'misc/benchmarks/external/ankerl/unordered_dense.h')
-rw-r--r--misc/benchmarks/external/ankerl/unordered_dense.h87
1 files changed, 73 insertions, 14 deletions
diff --git a/misc/benchmarks/external/ankerl/unordered_dense.h b/misc/benchmarks/external/ankerl/unordered_dense.h
index 05c7e928..faad051d 100644
--- a/misc/benchmarks/external/ankerl/unordered_dense.h
+++ b/misc/benchmarks/external/ankerl/unordered_dense.h
@@ -1,12 +1,12 @@
///////////////////////// ankerl::unordered_dense::{map, set} /////////////////////////
// A fast & densely stored hashmap and hashset based on robin-hood backward shift deletion.
-// Version 3.0.0
+// Version 3.1.0
// https://github.com/martinus/unordered_dense
//
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
// SPDX-License-Identifier: MIT
-// Copyright (c) 2022 Martin Leitner-Ankerl <[email protected]>
+// Copyright (c) 2022-2023 Martin Leitner-Ankerl <[email protected]>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -31,7 +31,7 @@
// see https://semver.org/spec/v2.0.0.html
#define ANKERL_UNORDERED_DENSE_VERSION_MAJOR 3 // NOLINT(cppcoreguidelines-macro-usage) incompatible API changes
-#define ANKERL_UNORDERED_DENSE_VERSION_MINOR 0 // NOLINT(cppcoreguidelines-macro-usage) backwards compatible functionality
+#define ANKERL_UNORDERED_DENSE_VERSION_MINOR 1 // NOLINT(cppcoreguidelines-macro-usage) backwards compatible functionality
#define ANKERL_UNORDERED_DENSE_VERSION_PATCH 0 // NOLINT(cppcoreguidelines-macro-usage) backwards compatible bug fixes
// API versioning with inline namespace, see https://www.foonathan.net/2018/11/inline-namespaces/
@@ -55,6 +55,18 @@
# define ANKERL_UNORDERED_DENSE_PACK(decl) __pragma(pack(push, 1)) decl __pragma(pack(pop))
#endif
+// exceptions
+#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
+# define ANKERL_UNORDERED_DENSE_HAS_EXCEPTIONS() 1
+#else
+# define ANKERL_UNORDERED_DENSE_HAS_EXCEPTIONS() 0
+#endif
+#ifdef _MSC_VER
+# define ANKERL_UNORDERED_DENSE_NOINLINE __declspec(noinline)
+#else
+# define ANKERL_UNORDERED_DENSE_NOINLINE __attribute__((noinline))
+#endif
+
#if ANKERL_UNORDERED_DENSE_CPP_VERSION < 201703L
# error ankerl::unordered_dense requires C++17 or higher
#else
@@ -73,13 +85,24 @@
# include <type_traits> // for enable_if_t, declval, conditional_t, ena...
# include <utility> // for forward, exchange, pair, as_const, piece...
# include <vector> // for vector
+# if ANKERL_UNORDERED_DENSE_HAS_EXCEPTIONS() == 0
+# include <cstdlib> // for abort
+# endif
# define ANKERL_UNORDERED_DENSE_PMR 0 // NOLINT(cppcoreguidelines-macro-usage)
# if defined(__has_include)
# if __has_include(<memory_resource>)
# undef ANKERL_UNORDERED_DENSE_PMR
# define ANKERL_UNORDERED_DENSE_PMR 1 // NOLINT(cppcoreguidelines-macro-usage)
-# include <memory_resource> // for polymorphic_allocator
+# define ANKERL_UNORDERED_DENSE_PMR_ALLOCATOR \
+ std::pmr::polymorphic_allocator // NOLINT(cppcoreguidelines-macro-usage)
+# include <memory_resource> // for polymorphic_allocator
+# elif __has_include(<experimental/memory_resource>)
+# undef ANKERL_UNORDERED_DENSE_PMR
+# define ANKERL_UNORDERED_DENSE_PMR 1 // NOLINT(cppcoreguidelines-macro-usage)
+# define ANKERL_UNORDERED_DENSE_PMR_ALLOCATOR \
+ std::experimental::pmr::polymorphic_allocator // NOLINT(cppcoreguidelines-macro-usage)
+# include <experimental/memory_resource> // for polymorphic_allocator
# endif
# endif
@@ -99,6 +122,38 @@
namespace ankerl::unordered_dense {
inline namespace ANKERL_UNORDERED_DENSE_NAMESPACE {
+namespace detail {
+
+# if ANKERL_UNORDERED_DENSE_HAS_EXCEPTIONS()
+
+// make sure this is not inlined as it is slow and dramatically enlarges code, thus making other
+// inlinings more difficult. Throws are also generally the slow path.
+[[noreturn]] inline ANKERL_UNORDERED_DENSE_NOINLINE void on_error_key_not_found() {
+ throw std::out_of_range("ankerl::unordered_dense::map::at(): key not found");
+}
+[[noreturn]] inline ANKERL_UNORDERED_DENSE_NOINLINE void on_error_bucket_overflow() {
+ throw std::overflow_error("ankerl::unordered_dense: reached max bucket size, cannot increase size");
+}
+[[noreturn]] inline ANKERL_UNORDERED_DENSE_NOINLINE void on_error_too_many_elements() {
+ throw std::out_of_range("ankerl::unordered_dense::map::replace(): too many elements");
+}
+
+# else
+
+[[noreturn]] inline void on_error_key_not_found() {
+ abort();
+}
+[[noreturn]] inline void on_error_bucket_overflow() {
+ abort();
+}
+[[noreturn]] inline void on_error_too_many_elements() {
+ abort();
+}
+
+# endif
+
+} // namespace detail
+
// hash ///////////////////////////////////////////////////////////////////////
// This is a stripped-down implementation of wyhash: https://github.com/wangyi-fudan/wyhash
@@ -371,8 +426,10 @@ using detect_reserve = decltype(std::declval<T&>().reserve(size_t{}));
template <typename Mapped>
constexpr bool is_map_v = !std::is_void_v<Mapped>;
+// clang-format off
template <typename Hash, typename KeyEqual>
constexpr bool is_transparent_v = is_detected_v<detect_is_transparent, Hash>&& is_detected_v<detect_is_transparent, KeyEqual>;
+// clang-format on
template <typename From, typename To1, typename To2>
constexpr bool is_neither_convertible_v = !std::is_convertible_v<From, To1> && !std::is_convertible_v<From, To2>;
@@ -590,7 +647,7 @@ private:
void increase_size() {
if (ANKERL_UNORDERED_DENSE_UNLIKELY(m_max_bucket_capacity == max_bucket_count())) {
- throw std::overflow_error("ankerl::unordered_dense: reached max bucket size, cannot increase size");
+ on_error_bucket_overflow();
}
--m_shifts;
deallocate_buckets();
@@ -745,10 +802,10 @@ private:
template <typename K, typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>
auto do_at(K const& key) -> Q& {
- if (auto it = find(key); end() != it) {
+ if (auto it = find(key); ANKERL_UNORDERED_DENSE_LIKELY(end() != it)) {
return it->second;
}
- throw std::out_of_range("ankerl::unordered_dense::map::at(): key not found");
+ on_error_key_not_found();
}
template <typename K, typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>
@@ -842,8 +899,10 @@ public:
: table(init, bucket_count, hash, KeyEqual(), alloc) {}
~table() {
- auto ba = bucket_alloc(m_values.get_allocator());
- bucket_alloc_traits::deallocate(ba, m_buckets, bucket_count());
+ if (nullptr != m_buckets) {
+ auto ba = bucket_alloc(m_values.get_allocator());
+ bucket_alloc_traits::deallocate(ba, m_buckets, bucket_count());
+ }
}
auto operator=(table const& other) -> table& {
@@ -985,10 +1044,9 @@ public:
// nonstandard API:
// Discards the internally held container and replaces it with the one passed. Erases non-unique elements.
auto replace(value_container_type&& container) {
- if (container.size() > max_size()) {
- throw std::out_of_range("ankerl::unordered_dense::map::replace(): too many elements");
+ if (ANKERL_UNORDERED_DENSE_UNLIKELY(container.size() > max_size())) {
+ on_error_too_many_elements();
}
-
auto shifts = calc_shifts_for_size(container.size());
if (0 == m_num_buckets || shifts < m_shifts || container.get_allocator() != m_values.get_allocator()) {
m_shifts = shifts;
@@ -1479,10 +1537,10 @@ template <class Key,
class Hash = hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Bucket = bucket_type::standard>
-using map = detail::table<Key, T, Hash, KeyEqual, std::pmr::polymorphic_allocator<std::pair<Key, T>>, Bucket>;
+using map = detail::table<Key, T, Hash, KeyEqual, ANKERL_UNORDERED_DENSE_PMR_ALLOCATOR<std::pair<Key, T>>, Bucket>;
template <class Key, class Hash = hash<Key>, class KeyEqual = std::equal_to<Key>, class Bucket = bucket_type::standard>
-using set = detail::table<Key, void, Hash, KeyEqual, std::pmr::polymorphic_allocator<Key>, Bucket>;
+using set = detail::table<Key, void, Hash, KeyEqual, ANKERL_UNORDERED_DENSE_PMR_ALLOCATOR<Key>, Bucket>;
} // namespace pmr
@@ -1501,6 +1559,7 @@ using set = detail::table<Key, void, Hash, KeyEqual, std::pmr::polymorphic_alloc
namespace std { // NOLINT(cert-dcl58-cpp)
template <class Key, class T, class Hash, class KeyEqual, class AllocatorOrContainer, class Bucket, class Pred>
+// NOLINTNEXTLINE(cert-dcl58-cpp)
auto erase_if(ankerl::unordered_dense::detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket>& map, Pred pred)
-> size_t {
using map_t = ankerl::unordered_dense::detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket>;