#ifndef _TYPES_H #define _TYPES_H #include #include #include using std::size_t; #if defined(__SIZEOF_INT128__) and not defined(_WIN32) #define __AQ__HAS__INT128__ #endif #ifdef _MSC_VER #define __restrict__ __restrict #endif template constexpr static inline bool is_vector(const T&) { return false; } template struct is_vector_impl : std::false_type {}; template constexpr static bool is_vector_type = is_vector_impl::value; namespace types { enum Type_t { AINT32, AFLOAT, ASTR, ADOUBLE, ALDOUBLE, AINT64, AINT128, AINT16, ADATE, ATIME, AINT8, AUINT32, AUINT64, AUINT128, AUINT16, AUINT8, ABOOL, VECTOR, ATIMESTAMP, NONE, ERROR }; static constexpr const char* printf_str[] = { "%d", "%f", "%s", "%lf", "%Lf", "%ld", "%d", "%hi", "%s", "%s", "%c", "%u", "%lu", "%s", "%hu", "%hhu", "%s", "%s", "Vector<%s>", "%s", "NULL", "ERROR" }; static constexpr const char* SQL_Type[] = { "INT", "REAL", "TEXT", "DOUBLE", "DOUBLE", "BIGINT", "HUGEINT", "SMALLINT", "DATE", "TIME", "TINYINT", "INT", "BIGINT", "HUGEINT", "SMALLINT", "TINYINT", "BOOL", "HUGEINT", "TIMESTAMP", "NULL", "ERROR"}; // TODO: deal with data/time <=> str/uint conversion struct date_t{ unsigned char day = 0; unsigned char month = 0; short year = 0; date_t() = default; date_t(unsigned char day, unsigned char month, short year) : day (day), month (month), year(year) {} date_t(const char*); date_t& fromString(const char*); bool validate() const; constexpr static unsigned string_length(){ return 11; }; char* toString(char* buf) const; bool operator > (const date_t&) const; bool operator < (const date_t&) const; bool operator >= (const date_t&) const; bool operator <= (const date_t&) const; bool operator == (const date_t&) const; bool operator != (const date_t&) const; }; struct time_t{ unsigned int ms = 0; unsigned char seconds = 0; unsigned char minutes = 0; unsigned char hours = 0; time_t() = default; time_t(unsigned int ms, unsigned char seconds, unsigned char minutes, unsigned char hours) : ms (ms), seconds (seconds), minutes(minutes), hours(hours) {}; time_t(const char*); time_t& fromString(const char*); bool validate() const; constexpr static unsigned string_length() { return 16; }; char* toString(char* buf) const; bool operator > (const time_t&) const; bool operator < (const time_t&) const; bool operator >= (const time_t&) const; bool operator <= (const time_t&) const; bool operator == (const time_t&) const; bool operator != (const time_t&) const; }; struct timestamp_t{ date_t date; time_t time; timestamp_t() = default; timestamp_t(const date_t& d, const time_t& t) : date(d), time(t) {} timestamp_t(const char*); timestamp_t& fromString(const char*); bool validate() const; constexpr static unsigned string_length(){ return date_t::string_length() + time_t::string_length(); }; char* toString(char* buf) const; bool operator > (const timestamp_t&) const; bool operator < (const timestamp_t&) const; bool operator >= (const timestamp_t&) const; bool operator <= (const timestamp_t&) const; bool operator == (const timestamp_t&) const; bool operator != (const timestamp_t&) const; }; template struct Types { typedef T type; constexpr Types() noexcept = default; #ifdef __AQ__HAS__INT128__ #define F_INT128(__F_) __F_(__int128_t, AINT128) \ __F_(__uint128_t, AUINT128) #define ULL_Type __uint128_t #define LL_Type __int128_t #else #define F_INT128(__F_) #define ULL_Type unsigned long long #define LL_Type long long #endif #define ConnectTypes(f) \ f(int, AINT32) \ f(float, AFLOAT) \ f(const char*, ASTR) \ f(double, ADOUBLE) \ f(long double, ALDOUBLE) \ f(long, AINT64) \ f(short, AINT16) \ f(date_t, ADATE) \ f(time_t, ATIME) \ f(unsigned char, AINT8) \ f(unsigned int, AUINT32) \ f(unsigned long, AUINT64) \ f(unsigned short, AUINT16) \ f(unsigned char, AUINT8) \ f(bool, ABOOL) \ f(timestamp_t, ATIMESTAMP) \ F_INT128(f) inline constexpr static Type_t getType() { #define TypeConnect(x, y) if constexpr(std::is_same::value) return y; else ConnectTypes(TypeConnect) if constexpr (is_vector_type) return VECTOR; else return NONE; } }; #define ATypeSize(t, at) sizeof(t), static constexpr size_t AType_sizes[] = { ConnectTypes(ATypeSize) 1 }; #define Cond(c, x, y) typename std::conditional::type #define Comp(o) (sizeof(T1) o sizeof(T2)) #define Same(x, y) (std::is_same_v) #define __U(x) std::is_unsigned::value #define Fp(x) std::is_floating_point::value template struct Coercion { using t1 = Cond(Comp(<= ), Cond(Comp(== ), Cond(Fp(T1), T1, Cond(Fp(T2), T2, Cond(__U(T1), T2, T1))), T2), T1); using t2 = Cond(Same(T1, T2), T1, Cond(Same(T1, const char*) || Same(T2, const char*), const char*, void)); using type = Cond(Same(t2, void), Cond(Same(T1, date_t) && Same(T2, time_t) || Same(T1, time_t) && Same(T2, time_t), void, t1), t2); }; #define __Eq(x) (sizeof(T) == sizeof(x)) template struct GetFPTypeImpl { using type = Cond(__Eq(float), float, Cond(__Eq(double), double, double)); }; template using GetFPType = typename GetFPTypeImpl::type>::type; template struct GetLongTypeImpl { using type = Cond(__U(T), ULL_Type, Cond(Fp(T), double, LL_Type)); }; template using GetLongType = typename GetLongTypeImpl::type>::type; template struct GetLongerTypeImpl { using type = Cond( __U(T), Cond(__Eq(char), unsigned short, Cond(__Eq(short), unsigned int, Cond(__Eq(int), unsigned long long, ULL_Type ))), Cond(Fp(T), double, Cond(__Eq(char), short, Cond(__Eq(short), int, Cond(__Eq(int), long, LL_Type )))) ); }; template using GetLongerType = typename GetLongerTypeImpl::type>::type; } union astring_view { const unsigned char* str = 0; const signed char* sstr; const char* rstr; size_t ptr; constexpr astring_view(const char* str) noexcept : rstr(str) {} constexpr astring_view(const signed char* str) noexcept : sstr(str) {} constexpr astring_view(const unsigned char* str) noexcept : str(str) {} constexpr astring_view() noexcept = default; bool operator==(const astring_view& r) const { auto this_str = str; auto other_str = r.str; while (*this_str && *other_str) { if (*this_str != *other_str) return false; this_str++; other_str++; } 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 rstr; } operator const unsigned char* () const { return str; } operator const signed char* () const { return sstr; } }; template constexpr bool is_cstr() { using namespace std; typedef decay_t dT; return is_same_v || is_same_v || is_same_v || is_same_v || is_same_v || is_same_v || is_same_v; } #define getT(i, t) std::tuple_element_t> template class T, typename ...Types> struct applyTemplates { using type = T; }; template class rT> struct transTypes_s; template class lT, typename ...T, template class rT> struct transTypes_s, rT> { using type = rT; }; // static_assert(std::is_same, std::unordered_map>, std::unordered_map>::value); template class rT> using transTypes = typename transTypes_s::type; template struct record_types {}; template using record = std::tuple; template struct decayS { using type = typename std::decay::type; }; template class T, typename ...Types> struct decayS >{ using type = T::type ...>; }; template using decays = typename decayS::type>::type; template using decay_inner = typename decayS::type; template class T> struct instance_of_impl : std::false_type {}; template class T2> struct instance_of_impl, T2> : std::true_type {}; template struct same_class_impl : std::false_type {}; template class T1> struct same_class_impl, T1> : std::true_type {}; template bool same_class = same_class_impl::value; template class T2> bool instance_of = instance_of_impl::value; template class rT> using transTypes = typename transTypes_s::type; template class rT> struct transValues_s; template class lT, vT ...T, template class rT> struct transValues_s, vT, rT> { using type = rT; }; #include template class rT> using transValues = typename transValues_s, vT, rT>::type; template class rT> using applyIntegerSequence = typename transValues_s, int, rT>::type; template