hashers: Mark hash updates noexcept
All those methods end up with library calls, whose code is not marked noexcept, but is such according to code itself or docs. The primary goal is to make some repair partition_hasher methods noexcept (next patch). Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
namespace query {
|
||||
|
||||
struct noop_hasher {
|
||||
void update(const char* ptr, size_t length) { }
|
||||
void update(const char* ptr, size_t length) noexcept { }
|
||||
std::array<uint8_t, 16> finalize_array() { return std::array<uint8_t, 16>(); };
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
|
||||
template<typename T, typename... Args>
|
||||
void feed_hash(const T& value, Args&&... args) {
|
||||
std::visit([&] (auto& hasher) {
|
||||
std::visit([&] (auto& hasher) noexcept -> void {
|
||||
::feed_hash(hasher, value, std::forward<Args>(args)...);
|
||||
}, _impl);
|
||||
};
|
||||
@@ -75,4 +75,4 @@ using using_hash_of_hash = std::negation<std::disjunction<std::is_same<Hasher, m
|
||||
template<typename Hasher>
|
||||
inline constexpr bool using_hash_of_hash_v = using_hash_of_hash<Hasher>::value;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
14
hashers.cc
14
hashers.cc
@@ -29,12 +29,20 @@ template <typename T> struct hasher_traits;
|
||||
template <> struct hasher_traits<md5_hasher> { using impl_type = CryptoPP::Weak::MD5; };
|
||||
template <> struct hasher_traits<sha256_hasher> { using impl_type = CryptoPP::SHA256; };
|
||||
|
||||
template <typename T, size_t size> struct cryptopp_hasher<T, size>::impl {
|
||||
template<typename H>
|
||||
concept HashUpdater =
|
||||
requires(hasher_traits<H>::impl_type& h, const CryptoPP::byte* ptr, size_t size) {
|
||||
{ h.Update(ptr, size) } noexcept -> std::same_as<void>;
|
||||
};
|
||||
|
||||
template <typename T, size_t size>
|
||||
requires HashUpdater<T>
|
||||
struct cryptopp_hasher<T, size>::impl {
|
||||
using impl_type = typename hasher_traits<T>::impl_type;
|
||||
|
||||
impl_type hash{};
|
||||
|
||||
void update(const char* ptr, size_t length) {
|
||||
void update(const char* ptr, size_t length) noexcept {
|
||||
using namespace CryptoPP;
|
||||
static_assert(sizeof(char) == sizeof(byte), "Assuming lengths will be the same");
|
||||
hash.Update(reinterpret_cast<const byte*>(ptr), length * sizeof(byte));
|
||||
@@ -74,7 +82,7 @@ template <typename T, size_t size> std::array<uint8_t, size> cryptopp_hasher<T,
|
||||
return _impl->finalize_array();
|
||||
}
|
||||
|
||||
template <typename T, size_t size> void cryptopp_hasher<T, size>::update(const char* ptr, size_t length) { _impl->update(ptr, length); }
|
||||
template <typename T, size_t size> void cryptopp_hasher<T, size>::update(const char* ptr, size_t length) noexcept { _impl->update(ptr, length); }
|
||||
|
||||
template <typename T, size_t size> bytes cryptopp_hasher<T, size>::calculate(const std::string_view& s) {
|
||||
typename cryptopp_hasher<T, size>::impl::impl_type hash;
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
|
||||
bytes finalize();
|
||||
std::array<uint8_t, size> finalize_array();
|
||||
void update(const char* ptr, size_t length) override;
|
||||
void update(const char* ptr, size_t length) noexcept override;
|
||||
|
||||
// Use update and finalize to compute the hash over the full view.
|
||||
static bytes calculate(const std::string_view& s);
|
||||
|
||||
28
hashing.hh
28
hashing.hh
@@ -45,13 +45,13 @@
|
||||
template<typename H>
|
||||
concept Hasher =
|
||||
requires(H& h, const char* ptr, size_t size) {
|
||||
{ h.update(ptr, size) } -> std::same_as<void>;
|
||||
{ h.update(ptr, size) } noexcept -> std::same_as<void>;
|
||||
};
|
||||
|
||||
class hasher {
|
||||
public:
|
||||
virtual ~hasher() = default;
|
||||
virtual void update(const char* ptr, size_t size) = 0;
|
||||
virtual void update(const char* ptr, size_t size) noexcept = 0;
|
||||
};
|
||||
|
||||
static_assert(Hasher<hasher>);
|
||||
@@ -62,7 +62,7 @@ struct appending_hash;
|
||||
template<typename H, typename T, typename... Args>
|
||||
requires Hasher<H>
|
||||
inline
|
||||
void feed_hash(H& h, const T& value, Args&&... args) {
|
||||
void feed_hash(H& h, const T& value, Args&&... args) noexcept {
|
||||
appending_hash<T>()(h, value, std::forward<Args>(args)...);
|
||||
};
|
||||
|
||||
@@ -70,7 +70,7 @@ template<typename T>
|
||||
struct appending_hash<T, std::enable_if_t<std::is_arithmetic<T>::value>> {
|
||||
template<typename H>
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, T value) const {
|
||||
void operator()(H& h, T value) const noexcept {
|
||||
auto value_le = cpu_to_le(value);
|
||||
h.update(reinterpret_cast<const char*>(&value_le), sizeof(T));
|
||||
}
|
||||
@@ -80,7 +80,7 @@ template<>
|
||||
struct appending_hash<bool> {
|
||||
template<typename H>
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, bool value) const {
|
||||
void operator()(H& h, bool value) const noexcept {
|
||||
feed_hash(h, static_cast<uint8_t>(value));
|
||||
}
|
||||
};
|
||||
@@ -89,7 +89,7 @@ template<typename T>
|
||||
struct appending_hash<T, std::enable_if_t<std::is_enum<T>::value>> {
|
||||
template<typename H>
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const T& value) const {
|
||||
void operator()(H& h, const T& value) const noexcept {
|
||||
feed_hash(h, static_cast<std::underlying_type_t<T>>(value));
|
||||
}
|
||||
};
|
||||
@@ -98,7 +98,7 @@ template<typename T>
|
||||
struct appending_hash<std::optional<T>> {
|
||||
template<typename H>
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const std::optional<T>& value) const {
|
||||
void operator()(H& h, const std::optional<T>& value) const noexcept {
|
||||
if (value) {
|
||||
feed_hash(h, true);
|
||||
feed_hash(h, *value);
|
||||
@@ -112,7 +112,7 @@ template<size_t N>
|
||||
struct appending_hash<char[N]> {
|
||||
template<typename H>
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const char (&value) [N]) const {
|
||||
void operator()(H& h, const char (&value) [N]) const noexcept {
|
||||
feed_hash(h, N);
|
||||
h.update(value, N);
|
||||
}
|
||||
@@ -122,7 +122,7 @@ template<typename T>
|
||||
struct appending_hash<std::vector<T>> {
|
||||
template<typename H>
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const std::vector<T>& value) const {
|
||||
void operator()(H& h, const std::vector<T>& value) const noexcept {
|
||||
feed_hash(h, value.size());
|
||||
for (auto&& v : value) {
|
||||
appending_hash<T>()(h, v);
|
||||
@@ -134,7 +134,7 @@ template<typename K, typename V>
|
||||
struct appending_hash<std::map<K, V>> {
|
||||
template<typename H>
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const std::map<K, V>& value) const {
|
||||
void operator()(H& h, const std::map<K, V>& value) const noexcept {
|
||||
feed_hash(h, value.size());
|
||||
for (auto&& e : value) {
|
||||
appending_hash<K>()(h, e.first);
|
||||
@@ -147,7 +147,7 @@ template<>
|
||||
struct appending_hash<sstring> {
|
||||
template<typename H>
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const sstring& v) const {
|
||||
void operator()(H& h, const sstring& v) const noexcept {
|
||||
feed_hash(h, v.size());
|
||||
h.update(reinterpret_cast<const char*>(v.cbegin()), v.size() * sizeof(sstring::value_type));
|
||||
}
|
||||
@@ -157,7 +157,7 @@ template<>
|
||||
struct appending_hash<std::string> {
|
||||
template<typename H>
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const std::string& v) const {
|
||||
void operator()(H& h, const std::string& v) const noexcept {
|
||||
feed_hash(h, v.size());
|
||||
h.update(reinterpret_cast<const char*>(v.data()), v.size() * sizeof(std::string::value_type));
|
||||
}
|
||||
@@ -167,7 +167,7 @@ template<typename T, typename R>
|
||||
struct appending_hash<std::chrono::duration<T, R>> {
|
||||
template<typename H>
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, std::chrono::duration<T, R> v) const {
|
||||
void operator()(H& h, std::chrono::duration<T, R> v) const noexcept {
|
||||
feed_hash(h, v.count());
|
||||
}
|
||||
};
|
||||
@@ -176,7 +176,7 @@ template<typename Clock, typename Duration>
|
||||
struct appending_hash<std::chrono::time_point<Clock, Duration>> {
|
||||
template<typename H>
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, std::chrono::time_point<Clock, Duration> v) const {
|
||||
void operator()(H& h, std::chrono::time_point<Clock, Duration> v) const noexcept {
|
||||
feed_hash(h, v.time_since_epoch().count());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
XXH64_reset(&_state, seed);
|
||||
}
|
||||
|
||||
void update(const char* ptr, size_t length) {
|
||||
void update(const char* ptr, size_t length) noexcept {
|
||||
XXH64_update(&_state, ptr, length);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user