#ifndef _TYPES_H #define _TYPES_H #include #include #include #include #include #ifdef _MSC_VER #define __restrict__ __restrict #endif namespace types { enum Type_t { AINT, AFLOAT, ASTR, ADOUBLE, ALDOUBLE, ALONG, ASHORT, ADATE, ATIME, ACHAR, AUINT, AULONG, AUSHORT, AUCHAR, NONE, ERROR }; static constexpr const char* printf_str[] = { "%d", "%f", "%s", "%lf", "%llf", "%ld", "%hi", "%s", "%s", "%c", "%u", "%lu", "%hu", "%hhu", "NULL" }; // TODO: deal with data/time <=> str/uint conversion struct date_t { uint32_t val; date_t(const char* d) { } std::string toString() const; }; struct time_t { uint32_t val; time_t(const char* d) { } std::string toString() const; }; template struct Types { typedef T type; constexpr Types() noexcept = default; #define ConnectTypes(f) \ f(int, AINT) \ f(float, AFLOAT) \ f(const char*, ASTR) \ f(double, ADOUBLE) \ f(long double, ALDOUBLE) \ f(long, ALONG) \ f(short, ASHORT) \ f(date_t, ADATE) \ f(time_t, ATIME) \ f(unsigned char, ACHAR) \ f(unsigned int, AUINT) \ f(unsigned long, AULONG) \ f(unsigned short, AUSHORT) \ f(unsigned char, AUCHAR) constexpr static Type_t getType() { #define TypeConnect(x, y) if(typeid(T) == typeid(x)) return y; else ConnectTypes(TypeConnect) return NONE; } //static constexpr inline void print(T& v); }; #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, long double)); }; template using GetFPType = typename GetFPTypeImpl::type>::type; template struct GetLongTypeImpl { using type = Cond(_U(T), unsigned long long, Cond(Fp(T), long double, long long)); }; template using GetLongType = typename GetLongTypeImpl::type>::type; } #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