整数型が別の整数型のサブセットであるかどうかをチェックするメタ関数を実装しようとしています。プラットフォームに依存せず、少なくとも C++ 標準で定義されているすべての数値型で動作する必要があります。私の現在の実装には 5 つのブランチがあります。それについて 2 つの質問があります。
- 見逃すケースはありますか?
- 4番目のブランチは必要ですか?
template <typename T1, typename T2>
constexpr bool is_subset(T1, T2)
{
if constexpr (std::is_same_v<T1, T2>)
{
return true;
}
if constexpr (std::is_same_v<T1, std::uintmax_t>)
{
return false;
}
else if constexpr (std::is_same_v<T1, std::intmax_t>)
{
return false;
}
else if constexpr (std::is_unsigned_v<T1> && std::is_unsigned_v<T2>)
{
return static_cast<std::uintmax_t>(std::numeric_limits<T1>::min()) >= static_cast<std::uintmax_t>(std::numeric_limits<T2>::min()) &&
static_cast<std::uintmax_t>(std::numeric_limits<T1>::max()) <= static_cast<std::uintmax_t>(std::numeric_limits<T2>::max())
}
else
{
return static_cast<std::intmax_t>(std::numeric_limits<T1>::min()) >= static_cast<std::intmax_t>(std::numeric_limits<T2>::min()) &&
static_cast<std::intmax_t>(std::numeric_limits<T1>::max()) <= static_cast<std::intmax_t>(std::numeric_limits<T2>::max())
}
}
intmax_t == long の修正された実装:
template <typename T1, typename T2>
constexpr bool is_subset2(T1, T2) noexcept
{
if constexpr (sizeof(T1) == sizeof(T2) && std::is_signed_v<T1> == std::is_signed_v<T2>)
{
return true;
}
else if constexpr (sizeof(T1) == sizeof(std::intmax_t))
{
return false;
}
else if constexpr (std::is_unsigned_v<T1> && std::is_unsigned_v<T2>)
{
return static_cast<std::uintmax_t>(std::numeric_limits<T1>::min()) >= static_cast<std::uintmax_t>(std::numeric_limits<T2>::min()) &&
static_cast<std::uintmax_t>(std::numeric_limits<T1>::max()) <= static_cast<std::uintmax_t>(std::numeric_limits<T2>::max());
}
else
{
return static_cast<std::intmax_t>(std::numeric_limits<T1>::min()) >= static_cast<std::intmax_t>(std::numeric_limits<T2>::min()) &&
static_cast<std::intmax_t>(std::numeric_limits<T1>::max()) <= static_cast<std::intmax_t>(std::numeric_limits<T2>::max());
}
}