[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master b67ea92 1/2: Copy unit tests demonstrating bo
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master b67ea92 1/2: Copy unit tests demonstrating boost anomalies from mailing list |
Date: |
Sat, 1 Apr 2017 08:57:08 -0400 (EDT) |
branch: master
commit b67ea92e51cad9a555f9e545306c10773f592d1a
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>
Copy unit tests demonstrating boost anomalies from mailing list
---
bourn_cast_test.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/bourn_cast_test.cpp b/bourn_cast_test.cpp
index 3f9d418..e97df7e 100644
--- a/bourn_cast_test.cpp
+++ b/bourn_cast_test.cpp
@@ -27,6 +27,8 @@
#include "test_tools.hpp"
#include "timer.hpp"
+#include <boost/cast.hpp>
+
#include <climits> // INT_MIN, LLONG_MIN, SCHAR_MIN
#include <type_traits> // std::conditional
@@ -151,6 +153,63 @@ void test_signednesses(char const* file, int line)
INVOKE_BOOST_TEST_EQUAL(ITo(-9), bourn_cast<ITo>(LFrom(-9)), file, line);
}
+/// Test boost::numeric_cast anomalies reported here:
+/// http://lists.nongnu.org/archive/html/lmi/2017-03/msg00127.html
+/// and confirmed here:
+/// http://lists.nongnu.org/archive/html/lmi/2017-03/msg00128.html
+
+void test_boost_anomalies()
+{
+ using double_limits = std::numeric_limits<double>;
+
+ // IEEE 754-2008 [5.8, conversion to integer]: "When a NaN or infinite
+ // operand cannot be represented in the destination format and this
+ // cannot otherwise be indicated, the invalid operation exception shall
+ // be signaled."
+ int nan = boost::numeric_cast<int>(double_limits::quiet_NaN());
+ std::cout << "Integer converted from NaN = " << nan << std::endl;
+
+ // IEEE 754-2008 [6.1]: "Operations on infinite operands are usually
+ // exact and therefore signal no exceptions, including ... conversion of
+ // an infinity into the same infinity in another format."
+ try
+ {
+ boost::numeric_cast<long double>(double_limits::infinity());
+ std::cout << "That worked, so this should too..." << std::endl;
+ boost::numeric_cast<float>(double_limits::infinity());
+ std::cout << "...because all infinities are convertible." << std::endl;
+ }
+ catch(...){std::cout << "Line " << __LINE__ << ": bad throw." <<
std::endl;}
+
+ try
+ {
+ boost::numeric_cast<int>(INT_MIN);
+ boost::numeric_cast<int>((double)INT_MIN);
+ std::cout << "That worked, so this should too..." << std::endl;
+ boost::numeric_cast<int>((float)INT_MIN);
+ std::cout << "...because INT_MIN = an exact power of 2." << std::endl;
+ }
+ catch(...){std::cout << "Line " << __LINE__ << ": bad throw." <<
std::endl;}
+
+ try
+ {
+ boost::numeric_cast<long long int>((long double)LLONG_MIN);
+ std::cout << "That worked, so this should too..." << std::endl;
+ boost::numeric_cast<long long int>((float)LLONG_MIN);
+ std::cout << "...because LLONG_MIN = an exact power of 2." <<
std::endl;
+ }
+ catch(...){std::cout << "Line " << __LINE__ << ": bad throw." <<
std::endl;}
+
+ try
+ {
+ boost::numeric_cast<long long int>((long double)LLONG_MIN);
+ std::cout << "That worked, so this should too..." << std::endl;
+ boost::numeric_cast<long long int>((double)LLONG_MIN);
+ std::cout << "...because LLONG_MIN = an exact power of 2." <<
std::endl;
+ }
+ catch(...){std::cout << "Line " << __LINE__ << ": bad throw." <<
std::endl;}
+}
+
/// Speed test: convert one million times, using static_cast.
template<typename To, typename From>
@@ -345,6 +404,10 @@ int test_main(int, char*[])
,"Cast would transgress upper limit."
);
+ // Test boost::numeric_cast anomalies.
+
+ test_boost_anomalies();
+
// Time representative casts.
assay_speed();