in include/ylt/struct_pack/type_id.hpp [130:247]
constexpr type_id get_integral_type() {
if constexpr (std::is_same_v<int32_t, T>) {
return type_id::int32_t;
}
else if constexpr (std::is_same_v<uint32_t, T>) {
return type_id::uint32_t;
}
else if constexpr (std::is_same_v<int64_t, T> ||
(sizeof(long long) == 8 && std::is_same_v<T, long long>)) {
return type_id::int64_t;
}
else if constexpr (std::is_same_v<uint64_t, T> ||
(sizeof(unsigned long long) == 8 &&
std::is_same_v<T, unsigned long long>)) {
return type_id::uint64_t;
}
else if constexpr (std::is_same_v<int8_t, T> ||
std::is_same_v<signed char, T>) {
return type_id::int8_t;
}
else if constexpr (std::is_same_v<uint8_t, T> ||
std::is_same_v<unsigned char, T>) {
return type_id::uint8_t;
}
else if constexpr (std::is_same_v<int16_t, T>) {
return type_id::int16_t;
}
else if constexpr (std::is_same_v<uint16_t, T>) {
return type_id::uint16_t;
}
// In struct_pack, the char will be saved as unsigned!
else if constexpr (std::is_same_v<char, T>
#ifdef __cpp_lib_char8_t
|| std::is_same_v<char8_t, T>
#endif
) {
return type_id::char_8_t;
}
#ifdef STRUCT_PACK_ENABLE_UNPORTABLE_TYPE
else if constexpr (std::is_same_v<wchar_t, T>) {
return type_id::w_char_t;
}
#endif
// char16_t's size maybe bigger than 16 bits, which is not supported.
else if constexpr (std::is_same_v<char16_t, T>) {
static_assert(sizeof(char16_t) == 2,
"sizeof(char16_t)!=2, which is not supported.");
return type_id::char_16_t;
}
// char32_t's size maybe bigger than 32bits, which is not supported.
else if constexpr (std::is_same_v<char32_t, T> && sizeof(char32_t) == 4) {
static_assert(sizeof(char32_t) == 4,
"sizeof(char32_t)!=4, which is not supported.");
return type_id::char_32_t;
}
else if constexpr (std::is_same_v<bool, T> && sizeof(bool)) {
static_assert(sizeof(bool) == 1,
"sizeof(bool)!=1, which is not supported.");
return type_id::bool_t;
}
#if (__GNUC__ || __clang__) && defined(STRUCT_PACK_ENABLE_INT128)
//-std=gnu++20
else if constexpr (std::is_same_v<__int128, T>) {
return type_id::int128_t;
}
else if constexpr (std::is_same_v<unsigned __int128, T>) {
return type_id::uint128_t;
}
#endif
else if constexpr (std::is_same_v<long, T>) {
if constexpr (sizeof(long) == sizeof(int32_t)) {
return type_id::int32_t;
}
else if constexpr (sizeof(long) == sizeof(int64_t)) {
return type_id::int64_t;
}
else {
static_assert(!sizeof(T), "unsupport size of long type");
}
}
else if constexpr (std::is_same_v<unsigned long, T>) {
if constexpr (sizeof(unsigned long) == sizeof(uint32_t)) {
return type_id::uint32_t;
}
else if constexpr (sizeof(unsigned long) == sizeof(uint64_t)) {
return type_id::uint64_t;
}
else {
static_assert(!sizeof(T), "unsupport size of long type");
}
}
else {
/*
* Due to different data model,
* the following types are not allowed on macOS
* but work on Linux
* For example,
* on macOS, `typedef unsigned long long uint64_t;`
* on Linux, `typedef unsigned long int uint64_t;`
*
* - long
* - long int
* - signed long
* - signed long int
* - unsigned long
* - unsigned long int
*
* We add this static_assert to give more information about not supported
* type.
*/
static_assert(
!std::is_same_v<wchar_t, T>,
"Tips: Add macro STRUCT_PACK_ENABLE_UNPORTABLE_TYPE to support "
"wchar_t");
static_assert(!sizeof(T), "not supported type");
// This branch will always compiled error.
}
}