Open krofik opened 3 years ago
Hi, the warning is telling you that the result of all theese if-statements could be resolved in compile time, so the compiler is encouriging us to use different strategies to avoid expending time in checking conditions in runtine, in case the compiler doesnt perform any unfolding. In my case, I silenced the warning using SFINAE techniques. Just substitute the code on lines 2209 to 2261:
template<class Units, typename T, template<typename> class NonLinearScale>
inline std::ostream& operator<<(std::ostream& os, const unit_t<Units, T, NonLinearScale>& obj) noexcept
{
using BaseUnits = unit<std::ratio<1>, typename traits::unit_traits<Units>::base_unit_type>;
os << convert<Units, BaseUnits>(obj());
if (traits::unit_traits<Units>::base_unit_type::meter_ratio::num != 0) { os << " m"; }
if (traits::unit_traits<Units>::base_unit_type::meter_ratio::num != 0 &&
traits::unit_traits<Units>::base_unit_type::meter_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::meter_ratio::num; }
if (traits::unit_traits<Units>::base_unit_type::meter_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::meter_ratio::den; }
if (traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num != 0) { os << " kg"; }
if (traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num != 0 &&
traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num; }
if (traits::unit_traits<Units>::base_unit_type::kilogram_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::kilogram_ratio::den; }
if (traits::unit_traits<Units>::base_unit_type::second_ratio::num != 0) { os << " s"; }
if (traits::unit_traits<Units>::base_unit_type::second_ratio::num != 0 &&
traits::unit_traits<Units>::base_unit_type::second_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::second_ratio::num; }
if (traits::unit_traits<Units>::base_unit_type::second_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::second_ratio::den; }
if (traits::unit_traits<Units>::base_unit_type::ampere_ratio::num != 0) { os << " A"; }
if (traits::unit_traits<Units>::base_unit_type::ampere_ratio::num != 0 &&
traits::unit_traits<Units>::base_unit_type::ampere_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::ampere_ratio::num; }
if (traits::unit_traits<Units>::base_unit_type::ampere_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::ampere_ratio::den; }
if (traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num != 0) { os << " K"; }
if (traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num != 0 &&
traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num; }
if (traits::unit_traits<Units>::base_unit_type::kelvin_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::kelvin_ratio::den; }
if (traits::unit_traits<Units>::base_unit_type::mole_ratio::num != 0) { os << " mol"; }
if (traits::unit_traits<Units>::base_unit_type::mole_ratio::num != 0 &&
traits::unit_traits<Units>::base_unit_type::mole_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::mole_ratio::num; }
if (traits::unit_traits<Units>::base_unit_type::mole_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::mole_ratio::den; }
if (traits::unit_traits<Units>::base_unit_type::candela_ratio::num != 0) { os << " cd"; }
if (traits::unit_traits<Units>::base_unit_type::candela_ratio::num != 0 &&
traits::unit_traits<Units>::base_unit_type::candela_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::candela_ratio::num; }
if (traits::unit_traits<Units>::base_unit_type::candela_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::candela_ratio::den; }
if (traits::unit_traits<Units>::base_unit_type::radian_ratio::num != 0) { os << " rad"; }
if (traits::unit_traits<Units>::base_unit_type::radian_ratio::num != 0 &&
traits::unit_traits<Units>::base_unit_type::radian_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::radian_ratio::num; }
if (traits::unit_traits<Units>::base_unit_type::radian_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::radian_ratio::den; }
if (traits::unit_traits<Units>::base_unit_type::byte_ratio::num != 0) { os << " b"; }
if (traits::unit_traits<Units>::base_unit_type::byte_ratio::num != 0 &&
traits::unit_traits<Units>::base_unit_type::byte_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::byte_ratio::num; }
if (traits::unit_traits<Units>::base_unit_type::byte_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::byte_ratio::den; }
return os;
}
with this
template<class Units>
inline typename std::enable_if<
Units::base_unit_type::meter_ratio::num != 0 &&
Units::base_unit_type::meter_ratio::num != 1
>::type
print_num_value(std::ostream& os) noexcept
{
os << "^" << traits::unit_traits<Units>::base_unit_type::meter_ratio::num;
}
template<class Units>
inline typename std::enable_if<
Units::base_unit_type::kilogram_ratio::num != 0 &&
Units::base_unit_type::kilogram_ratio::num != 1
>::type
print_num_value(std::ostream& os) noexcept
{
os << "^" << traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num;
}
template<class Units>
inline typename std::enable_if<
Units::base_unit_type::second_ratio::num != 0 &&
Units::base_unit_type::second_ratio::num != 1
>::type
print_num_value(std::ostream& os) noexcept
{
os << "^" << traits::unit_traits<Units>::base_unit_type::second_ratio::num;
}
template<class Units>
inline typename std::enable_if<
Units::base_unit_type::ampere_ratio::num != 0 &&
Units::base_unit_type::ampere_ratio::num != 1
>::type
print_num_value(std::ostream& os) noexcept
{
os << "^" << traits::unit_traits<Units>::base_unit_type::ampere_ratio::num;
}
template<class Units>
inline typename std::enable_if<
Units::base_unit_type::kelvin_ratio::num != 0 &&
Units::base_unit_type::kelvin_ratio::num != 1
>::type
print_num_value(std::ostream& os) noexcept
{
os << "^" << traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num;
}
template<class Units>
inline typename std::enable_if<
Units::base_unit_type::mole_ratio::num != 0 &&
Units::base_unit_type::mole_ratio::num != 1
>::type
print_num_value(std::ostream& os) noexcept
{
os << "^" << traits::unit_traits<Units>::base_unit_type::mole_ratio::num;
}
template<class Units>
inline typename std::enable_if<
Units::base_unit_type::candela_ratio::num != 0 &&
Units::base_unit_type::candela_ratio::num != 1
>::type
print_num_value(std::ostream& os) noexcept
{
os << "^" << traits::unit_traits<Units>::base_unit_type::candela_ratio::num;
}
template<class Units>
inline typename std::enable_if<
Units::base_unit_type::radian_ratio::num != 0 &&
Units::base_unit_type::radian_ratio::num != 1
>::type
print_num_value(std::ostream& os) noexcept
{
os << "^" << traits::unit_traits<Units>::base_unit_type::radian_ratio::num;
}
template<class Units>
inline typename std::enable_if<
Units::base_unit_type::byte_ratio::num != 0 &&
Units::base_unit_type::byte_ratio::num != 1
>::type
print_num_value(std::ostream& os) noexcept
{
os << "^" << traits::unit_traits<Units>::base_unit_type::byte_ratio::num;
}
template<class Units>
inline typename std::enable_if<
(
Units::base_unit_type::meter_ratio::num == 0 ||
Units::base_unit_type::meter_ratio::num == 1
) &&
(
Units::base_unit_type::kilogram_ratio::num == 0 ||
Units::base_unit_type::kilogram_ratio::num == 1
) &&
(
Units::base_unit_type::second_ratio::num == 0 ||
Units::base_unit_type::second_ratio::num == 1
) &&
(
Units::base_unit_type::ampere_ratio::num == 0 ||
Units::base_unit_type::ampere_ratio::num == 1
) &&
(
Units::base_unit_type::kelvin_ratio::num == 0 ||
Units::base_unit_type::kelvin_ratio::num == 1
) &&
(
Units::base_unit_type::mole_ratio::num == 0 ||
Units::base_unit_type::mole_ratio::num == 1
) &&
(
Units::base_unit_type::candela_ratio::num == 0 ||
Units::base_unit_type::candela_ratio::num == 1
) &&
(
Units::base_unit_type::radian_ratio::num == 0 ||
Units::base_unit_type::radian_ratio::num == 1
) &&
(
Units::base_unit_type::byte_ratio::num == 0 ||
Units::base_unit_type::byte_ratio::num == 1
)
>::type
print_num_value(std::ostream& os) noexcept
{
os;
}
/****************print ratios****************/
// length
template<class Units>
inline typename std::enable_if<Units::base_unit_type::meter_ratio::num != 0>::type
print_num(std::ostream& os) noexcept
{
os << " m";
}
template<class Units>
inline typename std::enable_if<Units::base_unit_type::meter_ratio::den != 1>::type
print_den(std::ostream& os) noexcept
{
os << "/" << traits::unit_traits<Units>::base_unit_type::meter_ratio::den;
}
// mass
template<class Units>
inline typename std::enable_if<Units::base_unit_type::kilogram_ratio::num != 0>::type
print_num(std::ostream& os) noexcept
{
os << " kg";
}
template<class Units>
inline typename std::enable_if<Units::base_unit_type::kilogram_ratio::den != 1>::type
print_den(std::ostream& os) noexcept
{
os << "/" << traits::unit_traits<Units>::base_unit_type::kilogram_ratio::den;
}
// time
template<class Units>
inline typename std::enable_if<Units::base_unit_type::second_ratio::num != 0>::type
print_num(std::ostream& os) noexcept
{
os << " s";
}
template<class Units>
inline typename std::enable_if<Units::base_unit_type::second_ratio::den != 1>::type
print_den(std::ostream& os) noexcept
{
os << "/" << traits::unit_traits<Units>::base_unit_type::second_ratio::den;
}
// electric intesity
template<class Units>
inline typename std::enable_if<Units::base_unit_type::ampere_ratio::num != 0>::type
print_num(std::ostream& os) noexcept
{
os << " A";
}
template<class Units>
inline typename std::enable_if<Units::base_unit_type::ampere_ratio::den != 1>::type
print_den(std::ostream& os) noexcept
{
os << "/" << traits::unit_traits<Units>::base_unit_type::ampere_ratio::den;
}
// temperature
template<class Units>
inline typename std::enable_if<Units::base_unit_type::kelvin_ratio::num != 0>::type
print_num(std::ostream& os) noexcept
{
os << " K";
}
template<class Units>
inline typename std::enable_if<Units::base_unit_type::kelvin_ratio::den != 1>::type
print_den(std::ostream& os) noexcept
{
os << "/" << traits::unit_traits<Units>::base_unit_type::kelvin_ratio::den;
}
// moles
template<class Units>
inline typename std::enable_if<Units::base_unit_type::mole_ratio::num != 0>::type
print_num(std::ostream& os) noexcept
{
os << " mol";
}
template<class Units>
inline typename std::enable_if<Units::base_unit_type::mole_ratio::den != 1>::type
print_den(std::ostream& os) noexcept
{
os << "/" << traits::unit_traits<Units>::base_unit_type::mole_ratio::den;
}
// luminosity
template<class Units>
inline typename std::enable_if<Units::base_unit_type::candela_ratio::num != 0>::type
print_num(std::ostream& os) noexcept
{
os << " cd";
}
template<class Units>
inline typename std::enable_if<Units::base_unit_type::candela_ratio::den != 1>::type
print_den(std::ostream& os) noexcept
{
os << "/" << traits::unit_traits<Units>::base_unit_type::candela_ratio::den;
}
// angles
template<class Units>
inline typename std::enable_if<Units::base_unit_type::radian_ratio::num != 0>::type
print_num(std::ostream& os) noexcept
{
os << " rad";
}
template<class Units>
inline typename std::enable_if<Units::base_unit_type::radian_ratio::den != 1>::type
print_den(std::ostream& os) noexcept
{
os << "/" << traits::unit_traits<Units>::base_unit_type::radian_ratio::den;
}
// bytes
template<class Units>
inline typename std::enable_if<Units::base_unit_type::byte_ratio::num != 0>::type
print_num(std::ostream& os) noexcept
{
os << " b";
}
template<class Units>
inline typename std::enable_if<Units::base_unit_type::byte_ratio::den != 1>::type
print_den(std::ostream& os) noexcept
{
os << "/" << traits::unit_traits<Units>::base_unit_type::byte_ratio::den;
}
template<class Units>
inline typename std::enable_if<
Units::base_unit_type::byte_ratio::num == 0 &&
Units::base_unit_type::kilogram_ratio::num == 0 &&
Units::base_unit_type::second_ratio::num == 0 &&
Units::base_unit_type::ampere_ratio::num == 0 &&
Units::base_unit_type::kelvin_ratio::num == 0 &&
Units::base_unit_type::mole_ratio::num == 0 &&
Units::base_unit_type::candela_ratio::num == 0 &&
Units::base_unit_type::radian_ratio::num == 0 &&
Units::base_unit_type::byte_ratio::num == 0
>::type
print_num(std::ostream& os) noexcept
{
os;
}
template<class Units>
inline typename std::enable_if<
Units::base_unit_type::byte_ratio::den == 1 &&
Units::base_unit_type::kilogram_ratio::den == 1 &&
Units::base_unit_type::second_ratio::den == 1 &&
Units::base_unit_type::ampere_ratio::den == 1 &&
Units::base_unit_type::kelvin_ratio::den == 1 &&
Units::base_unit_type::mole_ratio::den == 1 &&
Units::base_unit_type::candela_ratio::den == 1 &&
Units::base_unit_type::radian_ratio::den == 1 &&
Units::base_unit_type::byte_ratio::den == 1
>::type
print_den(std::ostream& os) noexcept
{
os;
}
template<class Units, typename T, template<typename> class NonLinearScale>
inline std::ostream& operator<<(std::ostream& os, const unit_t<Units, T, NonLinearScale>& obj) noexcept
{
using BaseUnits = unit<std::ratio<1>, typename traits::unit_traits<Units>::base_unit_type>;
os << convert<Units, BaseUnits>(obj());
print_num<Units>(os);
print_num_value<Units>(os);
print_den<Units>(os);
return os;
}
I havent tested yet but it should behave the same way, so it is up to you to use it or not. Of course, I included it in my code, so if i have further notice I'll post it
Facing the same problem, I replaced the if statements with if constexpr which did away with the warnings. Note that if-constexpr is a c++17 feature.
On MSVC with
/W4
I am getting 27 warnings of typeC4127
on lines 2215 to 2258 about that all these if-statements could be constant expression.