constexpr type_id get_integral_type()

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.
  }
}