Chcę pod C++11 napisać taki szablon narrow_int_cast
template<class DestinationType, class OriginalType>
DestinationType CommonMinimum()
{
static_assert(std::is_integral<DestinationType>::value, "Only integer types are supported");
static_assert(std::is_integral<OriginalType>::value, "Only integer types are supported");
if (sizeof(DestinationType)>sizeof(OriginalType))
{
return static_cast<DestinationType>(CommonMinimum<OriginalType, DestinationType>());
}
return std::numeric_limits<DestinationType>::min();
}
template<class DestinationType, class OriginalType>
DestinationType CommonMaximum()
{
static_assert(std::is_integral<DestinationType>::value, "Only integer types are supported");
static_assert(std::is_integral<OriginalType>::value, "Only integer types are supported");
if (sizeof(DestinationType)>sizeof(OriginalType))
{
// both type have equal size but have sign difference
return static_cast<DestinationType>(CommonMaximum<OriginalType, DestinationType>());
}
return static_cast<DestinationType>(std::numeric_limits<DestinationType>::max());
}
template<class DestinationType, class OriginalType>
DestinationType narrow_int_cast(OriginalType x)
{
static_assert(std::is_integral<DestinationType>::value, "Only integer types are supported");
static_assert(std::is_integral<OriginalType>::value, "Only integer types are supported");
const auto minimumValue = CommonMinimum<DestinationType, OriginalType>();
const auto maximumValue = CommonMaximum<DestinationType, OriginalType>();
const auto result = std::max<OriginalType>(minimumValue, std::min<OriginalType>(x, maximumValue));
return static_cast<DestinationType>(result);
}
Wiem, że coś takiego jest w boost, ale rzuca wyjątek, a ja chcę by wartości były przycinane do poprawnego zakresu. Poza tym projekt nie korzysta z boost-a.
Napisanie tego szablony jeśli sizeof(DestinationType) < sizeof(OriginalType)
to nie problem.
Schody zaczynają się gdy sizeof(DestinationType) == sizeof(OriginalType)
i typy różnią się tylko znakiem.
Jak na razie nie mam pomysłu jak to rozwiązać, więc liczę na wasz feedback.
PS. Kod pisany na szybkiego nieprzetestowany, więc może mieć bugi. Najpierw muszę dopisać gtest-a do tego, ale liczę na świeże pomysły.