diff --git a/include/tsl/robin_hash.h b/include/tsl/robin_hash.h index 163e0e2..c40e9df 100644 --- a/include/tsl/robin_hash.h +++ b/include/tsl/robin_hash.h @@ -75,8 +75,8 @@ static T numeric_cast(U value, } const bool is_same_signedness = - (std::is_unsigned::value && std::is_unsigned::value) || - (std::is_signed::value && std::is_signed::value); + (std::is_unsigned_v && std::is_unsigned_v) || + (std::is_signed_v && std::is_signed_v); if (!is_same_signedness && (ret < T{}) != (value < U{})) { TSL_RH_THROW_OR_TERMINATE(std::runtime_error, error_message); } @@ -183,7 +183,7 @@ class bucket_entry : public bucket_entry_hash { } bucket_entry(const bucket_entry& other) noexcept( - std::is_nothrow_copy_constructible::value) + std::is_nothrow_copy_constructible_v) : bucket_hash(other), m_dist_from_ideal_bucket(EMPTY_MARKER_DIST_FROM_IDEAL_BUCKET), m_last_bucket(other.m_last_bucket) { @@ -201,7 +201,7 @@ class bucket_entry : public bucket_entry_hash { * robin_hash constructor for details. */ bucket_entry(bucket_entry&& other) noexcept( - std::is_nothrow_move_constructible::value) + std::is_nothrow_move_constructible_v) : bucket_hash(std::move(other)), m_dist_from_ideal_bucket(EMPTY_MARKER_DIST_FROM_IDEAL_BUCKET), m_last_bucket(other.m_last_bucket) { @@ -214,7 +214,7 @@ class bucket_entry : public bucket_entry_hash { } bucket_entry& operator=(const bucket_entry& other) noexcept( - std::is_nothrow_copy_constructible::value) { + std::is_nothrow_copy_constructible_v) { if (this != &other) { clear(); @@ -349,7 +349,7 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy { private: template using has_mapped_type = - typename std::integral_constant::value>; + typename std::integral_constant>; static_assert( noexcept(std::declval().bucket_for_hash(std::size_t(0))), @@ -388,8 +388,8 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy { (sizeof(std::size_t) == sizeof(truncated_hash_type) || is_power_of_two_policy::value) && // Don't store the hash for primitive types with default hash. - (!std::is_arithmetic::value || - !std::is_same>::value)); + (!std::is_arithmetic_v || + !std::is_same_v>)); /** * Only use the stored hash on lookup if we are explicitly asked. We are not @@ -444,8 +444,7 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy { private: using bucket_entry_ptr = - typename std::conditional::type; + std::conditional_t; robin_iterator(bucket_entry_ptr bucket) noexcept : m_bucket(bucket) {} @@ -459,8 +458,7 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy { robin_iterator() noexcept {} // Copy constructor from iterator to const_iterator. - template ::type* = nullptr> + template * = nullptr> robin_iterator(const robin_iterator& other) noexcept : m_bucket(other.m_bucket) {} @@ -474,15 +472,14 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy { } template ::value && - IsConst>::type* = nullptr> + std::enable_if_t::value && IsConst>* = nullptr> const typename U::value_type& value() const { return U()(m_bucket->value()); } - template ::value && - !IsConst>::type* = nullptr> + template < + class U = ValueSelect, + std::enable_if_t::value && !IsConst>* = nullptr> typename U::value_type& value() const { return U()(m_bucket->value()); } @@ -571,10 +568,10 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy { m_try_shrink_on_next_insert(other.m_try_shrink_on_next_insert) {} robin_hash(robin_hash&& other) noexcept( - std::is_nothrow_move_constructible< - Hash>::value&& std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_constructible::value) + std::is_nothrow_move_constructible_v && + std::is_nothrow_move_constructible_v && + std::is_nothrow_move_constructible_v && + std::is_nothrow_move_constructible_v) : Hash(std::move(static_cast(other))), KeyEqual(std::move(static_cast(other))), GrowthPolicy(std::move(static_cast(other))), @@ -698,9 +695,9 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy { template void insert(InputIt first, InputIt last) { - if (std::is_base_of< + if (std::is_base_of_v< std::forward_iterator_tag, - typename std::iterator_traits::iterator_category>::value) { + typename std::iterator_traits::iterator_category>) { const auto nb_elements_insert = std::distance(first, last); const size_type nb_free_buckets = m_load_threshold - size(); tsl_rh_assert(m_load_threshold >= size()); @@ -764,9 +761,7 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy { return try_emplace(std::forward(key), std::forward(args)...).first; } - void erase_fast(iterator pos) { - erase_from_bucket(pos); - } + void erase_fast(iterator pos) { erase_from_bucket(pos); } /** * Here to avoid `template size_type erase(const K& key)` being used @@ -889,26 +884,26 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy { * Lookup */ template ::value>::type* = nullptr> + std::enable_if_t::value>* = nullptr> typename U::value_type& at(const K& key) { return at(key, hash_key(key)); } template ::value>::type* = nullptr> + std::enable_if_t::value>* = nullptr> typename U::value_type& at(const K& key, std::size_t hash) { return const_cast( static_cast(this)->at(key, hash)); } template ::value>::type* = nullptr> + std::enable_if_t::value>* = nullptr> const typename U::value_type& at(const K& key) const { return at(key, hash_key(key)); } template ::value>::type* = nullptr> + std::enable_if_t::value>* = nullptr> const typename U::value_type& at(const K& key, std::size_t hash) const { auto it = find(key, hash); if (it != cend()) { @@ -919,7 +914,7 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy { } template ::value>::type* = nullptr> + std::enable_if_t::value>* = nullptr> typename U::value_type& operator[](K&& key) { return try_emplace(std::forward(key)).first.value(); } @@ -1082,8 +1077,7 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy { } template ::value>::type* = - nullptr> + std::enable_if_t::value>* = nullptr> std::size_t next_bucket(std::size_t index) const noexcept { tsl_rh_assert(index < bucket_count()); @@ -1091,8 +1085,7 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy { } template ::value>::type* = - nullptr> + std::enable_if_t::value>* = nullptr> std::size_t next_bucket(std::size_t index) const noexcept { tsl_rh_assert(index < bucket_count()); diff --git a/include/tsl/robin_map.h b/include/tsl/robin_map.h index b594810..298ee3d 100644 --- a/include/tsl/robin_map.h +++ b/include/tsl/robin_map.h @@ -234,8 +234,8 @@ class robin_map { return m_ht.insert(value); } - template ::value>::type* = nullptr> + template >* = nullptr> std::pair insert(P&& value) { return m_ht.emplace(std::forward

(value)); } @@ -248,8 +248,8 @@ class robin_map { return m_ht.insert_hint(hint, value); } - template ::value>::type* = nullptr> + template >* = nullptr> iterator insert(const_iterator hint, P&& value) { return m_ht.emplace_hint(hint, std::forward

(value)); } @@ -361,9 +361,8 @@ class robin_map { * KeyEqual::is_transparent exists. If so, K must be hashable and comparable * to Key. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> size_type erase(const K& key) { return m_ht.erase(key); } @@ -375,9 +374,8 @@ class robin_map { * hash value should be the same as hash_function()(key). Useful to speed-up * the lookup to the value if you already have the hash. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> size_type erase(const K& key, std::size_t precalculated_hash) { return m_ht.erase(key, precalculated_hash); } @@ -412,9 +410,8 @@ class robin_map { * KeyEqual::is_transparent exists. If so, K must be hashable and comparable * to Key. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> T& at(const K& key) { return m_ht.at(key); } @@ -426,9 +423,8 @@ class robin_map { * hash value should be the same as hash_function()(key). Useful to speed-up * the lookup if you already have the hash. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> T& at(const K& key, std::size_t precalculated_hash) { return m_ht.at(key, precalculated_hash); } @@ -436,9 +432,8 @@ class robin_map { /** * @copydoc at(const K& key) */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> const T& at(const K& key) const { return m_ht.at(key); } @@ -446,9 +441,8 @@ class robin_map { /** * @copydoc at(const K& key, std::size_t precalculated_hash) */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> const T& at(const K& key, std::size_t precalculated_hash) const { return m_ht.at(key, precalculated_hash); } @@ -472,9 +466,8 @@ class robin_map { * KeyEqual::is_transparent exists. If so, K must be hashable and comparable * to Key. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> size_type count(const K& key) const { return m_ht.count(key); } @@ -486,9 +479,8 @@ class robin_map { * hash value should be the same as hash_function()(key). Useful to speed-up * the lookup if you already have the hash. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> size_type count(const K& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); } @@ -518,9 +510,8 @@ class robin_map { * KeyEqual::is_transparent exists. If so, K must be hashable and comparable * to Key. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> iterator find(const K& key) { return m_ht.find(key); } @@ -532,9 +523,8 @@ class robin_map { * hash value should be the same as hash_function()(key). Useful to speed-up * the lookup if you already have the hash. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); } @@ -542,9 +532,8 @@ class robin_map { /** * @copydoc find(const K& key) */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> const_iterator find(const K& key) const { return m_ht.find(key); } @@ -556,9 +545,8 @@ class robin_map { * hash value should be the same as hash_function()(key). Useful to speed-up * the lookup if you already have the hash. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> const_iterator find(const K& key, std::size_t precalculated_hash) const { return m_ht.find(key, precalculated_hash); } @@ -579,9 +567,8 @@ class robin_map { * KeyEqual::is_transparent exists. If so, K must be hashable and comparable * to Key. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> bool contains(const K& key) const { return m_ht.contains(key); } @@ -593,9 +580,8 @@ class robin_map { * hash value should be the same as hash_function()(key). Useful to speed-up * the lookup if you already have the hash. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> bool contains(const K& key, std::size_t precalculated_hash) const { return m_ht.contains(key, precalculated_hash); } @@ -631,9 +617,8 @@ class robin_map { * KeyEqual::is_transparent exists. If so, K must be hashable and comparable * to Key. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> std::pair equal_range(const K& key) { return m_ht.equal_range(key); } @@ -645,9 +630,8 @@ class robin_map { * hash value should be the same as hash_function()(key). Useful to speed-up * the lookup if you already have the hash. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> std::pair equal_range(const K& key, std::size_t precalculated_hash) { return m_ht.equal_range(key, precalculated_hash); @@ -656,9 +640,8 @@ class robin_map { /** * @copydoc equal_range(const K& key) */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> std::pair equal_range(const K& key) const { return m_ht.equal_range(key); } @@ -666,9 +649,8 @@ class robin_map { /** * @copydoc equal_range(const K& key, std::size_t precalculated_hash) */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> std::pair equal_range( const K& key, std::size_t precalculated_hash) const { return m_ht.equal_range(key, precalculated_hash); diff --git a/include/tsl/robin_set.h b/include/tsl/robin_set.h index e115007..310894e 100644 --- a/include/tsl/robin_set.h +++ b/include/tsl/robin_set.h @@ -285,9 +285,8 @@ class robin_set { * KeyEqual::is_transparent exists. If so, K must be hashable and comparable * to Key. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> size_type erase(const K& key) { return m_ht.erase(key); } @@ -299,9 +298,8 @@ class robin_set { * hash value should be the same as hash_function()(key). Useful to speed-up * the lookup to the value if you already have the hash. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> size_type erase(const K& key, std::size_t precalculated_hash) { return m_ht.erase(key, precalculated_hash); } @@ -327,9 +325,8 @@ class robin_set { * KeyEqual::is_transparent exists. If so, K must be hashable and comparable * to Key. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> size_type count(const K& key) const { return m_ht.count(key); } @@ -341,9 +338,8 @@ class robin_set { * hash value should be the same as hash_function()(key). Useful to speed-up * the lookup if you already have the hash. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> size_type count(const K& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); } @@ -373,9 +369,8 @@ class robin_set { * KeyEqual::is_transparent exists. If so, K must be hashable and comparable * to Key. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> iterator find(const K& key) { return m_ht.find(key); } @@ -387,9 +382,8 @@ class robin_set { * hash value should be the same as hash_function()(key). Useful to speed-up * the lookup if you already have the hash. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); } @@ -397,9 +391,8 @@ class robin_set { /** * @copydoc find(const K& key) */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> const_iterator find(const K& key) const { return m_ht.find(key); } @@ -411,9 +404,8 @@ class robin_set { * hash value should be the same as hash_function()(key). Useful to speed-up * the lookup if you already have the hash. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> const_iterator find(const K& key, std::size_t precalculated_hash) const { return m_ht.find(key, precalculated_hash); } @@ -434,9 +426,8 @@ class robin_set { * KeyEqual::is_transparent exists. If so, K must be hashable and comparable * to Key. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> bool contains(const K& key) const { return m_ht.contains(key); } @@ -448,9 +439,8 @@ class robin_set { * hash value should be the same as hash_function()(key). Useful to speed-up * the lookup if you already have the hash. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> bool contains(const K& key, std::size_t precalculated_hash) const { return m_ht.contains(key, precalculated_hash); } @@ -486,9 +476,8 @@ class robin_set { * KeyEqual::is_transparent exists. If so, K must be hashable and comparable * to Key. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> std::pair equal_range(const K& key) { return m_ht.equal_range(key); } @@ -500,9 +489,8 @@ class robin_set { * hash value should be the same as hash_function()(key). Useful to speed-up * the lookup if you already have the hash. */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> std::pair equal_range(const K& key, std::size_t precalculated_hash) { return m_ht.equal_range(key, precalculated_hash); @@ -511,9 +499,8 @@ class robin_set { /** * @copydoc equal_range(const K& key) */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> std::pair equal_range(const K& key) const { return m_ht.equal_range(key); } @@ -521,9 +508,8 @@ class robin_set { /** * @copydoc equal_range(const K& key, std::size_t precalculated_hash) */ - template < - class K, class KE = KeyEqual, - typename std::enable_if::value>::type* = nullptr> + template ::value>* = nullptr> std::pair equal_range( const K& key, std::size_t precalculated_hash) const { return m_ht.equal_range(key, precalculated_hash); diff --git a/tests/utils.h b/tests/utils.h index 74433a3..556161d 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -374,8 +374,7 @@ class serializer { serialize_impl(val.value()); } - template ::value>::type* = nullptr> + template >* = nullptr> void serialize_impl(const T& val) { m_ostream.write(reinterpret_cast(&val), sizeof(val)); } @@ -398,16 +397,15 @@ class deserializer { } private: - template ::value>::type* = nullptr> + template ::value>* = nullptr> T deserialize_impl() { auto first = deserialize_impl(); return std::make_pair(std::move(first), deserialize_impl()); } - template ::value>::type* = nullptr> + template >* = nullptr> T deserialize_impl() { const std::size_t str_size = tsl::detail_robin_hash::numeric_cast( @@ -421,14 +419,13 @@ class deserializer { return std::string(chars.data(), chars.size()); } - template ::value>::type* = nullptr> + template >* = nullptr> move_only_test deserialize_impl() { return move_only_test(deserialize_impl()); } - template ::value>::type* = nullptr> + template >* = nullptr> T deserialize_impl() { T val; m_istream.read(reinterpret_cast(&val), sizeof(val));