Fixed g++ std::hash<__uint128_t> undefined problem

dev
Bill 2 years ago
parent 52b2412c01
commit 406593a311

@ -16,7 +16,7 @@ RUN git clone https://github.com/sunyinqi0508/AQuery2
RUN python3 -m pip install -r AQuery2/requirements.txt RUN python3 -m pip install -r AQuery2/requirements.txt
ENV IS_DOCKER_IMAGE=1 CXX=clang-14 ENV IS_DOCKER_IMAGE=1 CXX=clang++-14
CMD cd AQuery2 && python3 prompt.py CMD cd AQuery2 && python3 prompt.py

@ -55,7 +55,7 @@ There're multiple options to run AQuery on Windows. You can use the native toolc
- Install monetdb, see [Monetdb Easy Setup](https://www.monetdb.org/easy-setup/) for instructions. - Install monetdb, see [Monetdb Easy Setup](https://www.monetdb.org/easy-setup/) for instructions.
- Install python3, C++ compiler and git. (For Ubuntu, run `apt update && apt install -y python3 python3-pip clang-14 libmonetdbe-dev git `) - Install python3, C++ compiler and git. (For Ubuntu, run `apt update && apt install -y python3 python3-pip clang-14 libmonetdbe-dev git `)
- Install required python packages by `python3 -m pip install -r requirements.txt` - Install required python packages by `python3 -m pip install -r requirements.txt`
- If you have multiple C++ compilers on the system. Specify C++ compiler by setting the **CXX** environment variable. e.g. `export CXX=clang-14` - If you have multiple C++ compilers on the system. Specify C++ compiler by setting the **CXX** environment variable. e.g. `export CXX=clang++-14`
### Docker: ### Docker:
- Alternatively, you can also use docker to run AQuery. - Alternatively, you can also use docker to run AQuery.
- Type `make docker` to build the docker image from scratch. - Type `make docker` to build the docker image from scratch.

@ -104,7 +104,8 @@ class build_manager:
def __init__(self, mgr : 'build_manager') -> None: def __init__(self, mgr : 'build_manager') -> None:
super().__init__(mgr) super().__init__(mgr)
os.environ['PCH'] = f'{mgr.PCH}' os.environ['PCH'] = f'{mgr.PCH}'
os.environ['CXX'] = mgr.cxx if mgr.cxx else 'c++' if 'CXX' not in os.environ:
os.environ['CXX'] = mgr.cxx if mgr.cxx else 'c++'
def libaquery_a(self): def libaquery_a(self):
self.build_cmd = [['rm', 'libaquery.a'],['make', 'libaquery.a']] self.build_cmd = [['rm', 'libaquery.a'],['make', 'libaquery.a']]

@ -2,6 +2,7 @@
#include <type_traits> #include <type_traits>
#include <tuple> #include <tuple>
#include <functional>
#include "types.h" #include "types.h"
// only works for 64 bit systems // only works for 64 bit systems
constexpr size_t _FNV_offset_basis = 14695981039346656037ULL; 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); 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> template <class ...Types>
struct hasher { struct hasher {
template <size_t i = 0> typename std::enable_if< i == sizeof...(Types), 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), template <size_t i = 0> typename std::enable_if < i < sizeof ...(Types),
size_t>::type hashi(const std::tuple<Types...>& record) const { 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; using current_type = typename std::decay<typename std::tuple_element<i, std::tuple<Types...>>::type>::type;
#ifdef __SIZEOF_INT128__
return std::hash<current_type>()(std::get<i>(record)) ^ hashi<i + 1>(record); 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 { size_t operator()(const std::tuple<Types...>& record) const {
return hashi(record); return hashi(record);
@ -75,7 +107,15 @@ namespace std{
std::hash<types::time_t>()(_Keyval.time); 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> template <class ...Types>
struct hash<std::tuple<Types...>> : public hasher<Types...>{ }; struct hash<std::tuple<Types...>> : public hasher<Types...>{ };

@ -3,6 +3,7 @@
#include <cstdint> #include <cstdint>
#include <type_traits> #include <type_traits>
#include <tuple> #include <tuple>
using std::size_t;
#if defined(__SIZEOF_INT128__) and not defined(_WIN32) #if defined(__SIZEOF_INT128__) and not defined(_WIN32)
#define __AQ__HAS__INT128__ #define __AQ__HAS__INT128__
@ -194,19 +195,19 @@ namespace types {
} }
struct astring_view { union astring_view {
const unsigned char* str = 0; const unsigned char* str = 0;
const signed char* sstr;
const char* rstr;
size_t ptr;
#if defined(__clang__) || !defined(__GNUC__)
constexpr constexpr
#endif
astring_view(const char* str) noexcept : astring_view(const char* str) noexcept :
str((const unsigned char*)(str)) {} rstr(str) {}
#if defined(__clang__) || !defined(__GNUC__)
constexpr constexpr
#endif
astring_view(const signed char* str) noexcept : astring_view(const signed char* str) noexcept :
str((const unsigned char*)(str)) {} sstr(str) {}
constexpr constexpr
astring_view(const unsigned char* str) noexcept : astring_view(const unsigned char* str) noexcept :
@ -225,16 +226,27 @@ struct astring_view {
return !(*this_str || *other_str); return !(*this_str || *other_str);
} }
bool operator >(const astring_view&r) const{ 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 { operator const char* () const {
return reinterpret_cast<const char*>(str); return rstr;
} }
operator const unsigned char* () const { operator const unsigned char* () const {
return reinterpret_cast<const unsigned char*>(str); return str;
} }
operator const signed char* () const { operator const signed char* () const {
return reinterpret_cast<const signed char*>(str); return sstr;
} }
}; };

Loading…
Cancel
Save