Fixed g++ std::hash<__uint128_t> undefined problem
This commit is contained in:
+43
-3
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <functional>
|
||||
#include "types.h"
|
||||
// only works for 64 bit systems
|
||||
constexpr size_t _FNV_offset_basis = 14695981039346656037ULL;
|
||||
@@ -21,7 +22,31 @@ inline size_t append_bytes(const astring_view& view) noexcept {
|
||||
return append_bytes(view.str);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __SIZEOF_INT128__
|
||||
union int128_struct
|
||||
{
|
||||
struct {
|
||||
uint64_t low, high;
|
||||
}__struct;
|
||||
__int128_t value = 0;
|
||||
__uint128_t uvalue;
|
||||
constexpr int128_struct() : value(0) {}
|
||||
constexpr int128_struct(const __int128_t &value) noexcept : value(value) {}
|
||||
constexpr int128_struct(const __uint128_t &value) noexcept : uvalue(value) {}
|
||||
operator __int128_t () const {
|
||||
return value;
|
||||
}
|
||||
operator __uint128_t () const {
|
||||
return uvalue;
|
||||
}
|
||||
operator __int128_t& () {
|
||||
return value;
|
||||
}
|
||||
operator __uint128_t& () {
|
||||
return uvalue;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
template <class ...Types>
|
||||
struct hasher {
|
||||
template <size_t i = 0> typename std::enable_if< i == sizeof...(Types),
|
||||
@@ -32,8 +57,15 @@ struct hasher {
|
||||
template <size_t i = 0> typename std::enable_if < i < sizeof ...(Types),
|
||||
size_t>::type hashi(const std::tuple<Types...>& record) const {
|
||||
using current_type = typename std::decay<typename std::tuple_element<i, std::tuple<Types...>>::type>::type;
|
||||
|
||||
return std::hash<current_type>()(std::get<i>(record)) ^ hashi<i + 1>(record);
|
||||
#ifdef __SIZEOF_INT128__
|
||||
using _current_type = typename std::conditional_t<
|
||||
std::is_same_v<current_type, __uint128_t> ||
|
||||
std::is_same_v<current_type, __int128_t>,
|
||||
int128_struct, current_type>;
|
||||
#else
|
||||
#define _current_type current_type
|
||||
#endif
|
||||
return std::hash<_current_type>()(std::get<i>(record)) ^ hashi<i + 1>(record);
|
||||
}
|
||||
size_t operator()(const std::tuple<Types...>& record) const {
|
||||
return hashi(record);
|
||||
@@ -75,7 +107,15 @@ namespace std{
|
||||
std::hash<types::time_t>()(_Keyval.time);
|
||||
}
|
||||
};
|
||||
#ifdef __SIZEOF_INT128__
|
||||
|
||||
template<>
|
||||
struct hash<int128_struct>{
|
||||
size_t operator() (const int128_struct& _Keyval) const noexcept {
|
||||
return std::hash<uint64_t>()(_Keyval.__struct.low) ^ std::hash<uint64_t>()(_Keyval.__struct.high);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
template <class ...Types>
|
||||
struct hash<std::tuple<Types...>> : public hasher<Types...>{ };
|
||||
|
||||
|
||||
+22
-10
@@ -3,6 +3,7 @@
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
using std::size_t;
|
||||
|
||||
#if defined(__SIZEOF_INT128__) and not defined(_WIN32)
|
||||
#define __AQ__HAS__INT128__
|
||||
@@ -194,19 +195,19 @@ namespace types {
|
||||
}
|
||||
|
||||
|
||||
struct astring_view {
|
||||
union astring_view {
|
||||
const unsigned char* str = 0;
|
||||
const signed char* sstr;
|
||||
const char* rstr;
|
||||
size_t ptr;
|
||||
|
||||
|
||||
#if defined(__clang__) || !defined(__GNUC__)
|
||||
constexpr
|
||||
#endif
|
||||
astring_view(const char* str) noexcept :
|
||||
str((const unsigned char*)(str)) {}
|
||||
#if defined(__clang__) || !defined(__GNUC__)
|
||||
rstr(str) {}
|
||||
constexpr
|
||||
#endif
|
||||
astring_view(const signed char* str) noexcept :
|
||||
str((const unsigned char*)(str)) {}
|
||||
sstr(str) {}
|
||||
|
||||
constexpr
|
||||
astring_view(const unsigned char* str) noexcept :
|
||||
@@ -225,16 +226,27 @@ struct astring_view {
|
||||
return !(*this_str || *other_str);
|
||||
}
|
||||
bool operator >(const astring_view&r) const{
|
||||
auto this_str = str;
|
||||
auto other_str = r.str;
|
||||
bool ret = true;
|
||||
while (*this_str && *other_str) {
|
||||
if (*this_str <= *other_str)
|
||||
ret = false;
|
||||
this_str++;
|
||||
other_str++;
|
||||
}
|
||||
|
||||
return (*this_str && !*other_str) ||
|
||||
(ret && !*this_str && *other_str);
|
||||
}
|
||||
operator const char* () const {
|
||||
return reinterpret_cast<const char*>(str);
|
||||
return rstr;
|
||||
}
|
||||
operator const unsigned char* () const {
|
||||
return reinterpret_cast<const unsigned char*>(str);
|
||||
return str;
|
||||
}
|
||||
operator const signed char* () const {
|
||||
return reinterpret_cast<const signed char*>(str);
|
||||
return sstr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user