#pragma once #include #include #include #include #include #include using Int8 = int8_t; using Int16 = int16_t; using Int32 = int32_t; using Int64 = int64_t; #if __cplusplus <= 201703L using char8_t = unsigned char; #endif /// This is needed for more strict aliasing. https://godbolt.org/z/xpJBSb https://stackoverflow.com/a/57453713 using UInt8 = char8_t; using UInt16 = uint16_t; using UInt32 = uint32_t; using UInt64 = uint64_t; using Int128 = __int128; using wInt256 = std::wide_integer<256, signed>; using wUInt256 = std::wide_integer<256, unsigned>; static_assert(sizeof(wInt256) == 32); static_assert(sizeof(wUInt256) == 32); using String = std::string; /// The standard library type traits, such as std::is_arithmetic, with one exception /// (std::common_type), are "set in stone". Attempting to specialize them causes undefined behavior. /// So instead of using the std type_traits, we use our own version which allows extension. template struct is_signed { static constexpr bool value = std::is_signed_v; }; template <> struct is_signed { static constexpr bool value = true; }; template <> struct is_signed { static constexpr bool value = true; }; template inline constexpr bool is_signed_v = is_signed::value; template struct is_unsigned { static constexpr bool value = std::is_unsigned_v; }; template <> struct is_unsigned { static constexpr bool value = true; }; template inline constexpr bool is_unsigned_v = is_unsigned::value; /// TODO: is_integral includes char, char8_t and wchar_t. template struct is_integer { static constexpr bool value = std::is_integral_v; }; template <> struct is_integer { static constexpr bool value = true; }; template <> struct is_integer { static constexpr bool value = true; }; template <> struct is_integer { static constexpr bool value = true; }; template inline constexpr bool is_integer_v = is_integer::value; template struct is_arithmetic { static constexpr bool value = std::is_arithmetic_v; }; template <> struct is_arithmetic<__int128> { static constexpr bool value = true; }; template inline constexpr bool is_arithmetic_v = is_arithmetic::value; template struct make_unsigned { typedef std::make_unsigned_t type; }; template <> struct make_unsigned { using type = unsigned __int128; }; template <> struct make_unsigned { using type = wUInt256; }; template <> struct make_unsigned { using type = wUInt256; }; template using make_unsigned_t = typename make_unsigned::type; template struct make_signed { typedef std::make_signed_t type; }; template <> struct make_signed { using type = wInt256; }; template <> struct make_signed { using type = wInt256; }; template using make_signed_t = typename make_signed::type; template struct is_big_int { static constexpr bool value = false; }; template <> struct is_big_int { static constexpr bool value = true; }; template <> struct is_big_int { static constexpr bool value = true; }; template inline constexpr bool is_big_int_v = is_big_int::value; template inline std::string bigintToString(const T & x) { return to_string(x); } template inline To bigint_cast(const From & x [[maybe_unused]]) { return static_cast(x); }