Summary:
In order to be consistent with integral-to-bool conversion, this
change allows conversion from floating point values to bool following
the same rule that is to be consistent with C(++) conventions. Also,
any arithmetic value can be converted to bool without potential for
undefined behaviour, so no extra checks are required.
Differential Revision:
D3483760
fbshipit-source-id:
024b58d348ef679079aba4d9d5277acb46aba2a1
}
/*******************************************************************************
}
/*******************************************************************************
+ * Arithmetic to boolean
******************************************************************************/
/**
******************************************************************************/
/**
- * Unchecked conversion from integral to boolean. This is different from the
- * other integral conversions because we use the C convention of treating any
+ * Unchecked conversion from arithmetic to boolean. This is different from the
+ * other arithmetic conversions because we use the C convention of treating any
* non-zero value as true, instead of range checking.
*/
template <class Tgt, class Src>
typename std::enable_if<
* non-zero value as true, instead of range checking.
*/
template <class Tgt, class Src>
typename std::enable_if<
- std::is_integral<Src>::value
- && !std::is_same<Tgt, Src>::value
- && std::is_same<Tgt, bool>::value,
- Tgt>::type
-to(const Src & value) {
- return value != 0;
+ std::is_arithmetic<Src>::value && !std::is_same<Tgt, Src>::value &&
+ std::is_same<Tgt, bool>::value,
+ Tgt>::type
+to(const Src& value) {
+ return value != Src();
+/*******************************************************************************
+ * Integral to integral
+ ******************************************************************************/
+
/**
* Checked conversion from integral to integral. The checks are only
* performed when meaningful, e.g. conversion from int to long goes
/**
* Checked conversion from integral to integral. The checks are only
* performed when meaningful, e.g. conversion from int to long goes
*/
template <class Tgt, class Src>
typename std::enable_if<
*/
template <class Tgt, class Src>
typename std::enable_if<
- (std::is_integral<Src>::value && std::is_floating_point<Tgt>::value)
- ||
- (std::is_floating_point<Src>::value && std::is_integral<Tgt>::value),
- Tgt>::type
-to(const Src & value) {
+ (std::is_integral<Src>::value && std::is_floating_point<Tgt>::value) ||
+ (std::is_floating_point<Src>::value && std::is_integral<Tgt>::value &&
+ !std::is_same<Tgt, bool>::value),
+ Tgt>::type
+to(const Src& value) {
if (detail::checkConversion<Tgt>(value)) {
Tgt result = Tgt(value);
if (detail::checkConversion<Src>(result)) {
if (detail::checkConversion<Tgt>(value)) {
Tgt result = Tgt(value);
if (detail::checkConversion<Src>(result)) {
TEST(Conv, FloatToBool) {
EXPECT_EQ(to<bool>(1.0), true);
EXPECT_EQ(to<bool>(0.0), false);
TEST(Conv, FloatToBool) {
EXPECT_EQ(to<bool>(1.0), true);
EXPECT_EQ(to<bool>(0.0), false);
+ EXPECT_EQ(to<bool>(2.7), true);
+ EXPECT_EQ(to<bool>(std::numeric_limits<double>::max()), true);
+ EXPECT_EQ(to<bool>(std::numeric_limits<double>::min()), true);
+ EXPECT_EQ(to<bool>(std::numeric_limits<double>::lowest()), true);
+ EXPECT_EQ(to<bool>(std::numeric_limits<double>::quiet_NaN()), true);
+ EXPECT_EQ(to<bool>(std::numeric_limits<double>::infinity()), true);
+ EXPECT_EQ(to<bool>(-std::numeric_limits<double>::infinity()), true);
}
TEST(Conv, NewUint64ToString) {
}
TEST(Conv, NewUint64ToString) {