lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master a51043a 2/2: Optionally test boost::numeric_c


From: Greg Chicares
Subject: [lmi-commits] [lmi] master a51043a 2/2: Optionally test boost::numeric_cast instead of bourn_cast
Date: Sat, 1 Apr 2017 08:57:08 -0400 (EDT)

branch: master
commit a51043a042c3c5c04f5ec7a85f04a9765f908023
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    Optionally test boost::numeric_cast instead of bourn_cast
---
 bourn_cast_test.cpp | 83 ++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 57 insertions(+), 26 deletions(-)

diff --git a/bourn_cast_test.cpp b/bourn_cast_test.cpp
index e97df7e..4f423e2 100644
--- a/bourn_cast_test.cpp
+++ b/bourn_cast_test.cpp
@@ -21,14 +21,38 @@
 
 #include "pchfile.hpp"
 
-#include "bourn_cast.hpp"
+//#define TEST_BOOST_CAST_INSTEAD
+#if defined TEST_BOOST_CAST_INSTEAD
+#   include <boost/cast.hpp>
+template<typename To, typename From>
+inline To bourn_cast(From from)
+{
+    try
+        {
+        return boost::numeric_cast<To>(from);
+        }
+    catch(boost::numeric::positive_overflow)
+        {
+        throw std::runtime_error("Cast would transgress upper limit.");
+        }
+    catch(boost::numeric::negative_overflow)
+        {
+        using   to_traits = std::numeric_limits<To  >;
+        using from_traits = std::numeric_limits<From>;
+        if(from_traits::is_integer && !to_traits::is_signed && from < 0)
+            throw std::runtime_error("Cannot cast negative to unsigned.");
+        else
+            throw std::runtime_error("Cast would transgress lower limit.");
+        }
+}
+#else  // !defined TEST_BOOST_CAST_INSTEAD
+#   include "bourn_cast.hpp"
+#endif // !defined TEST_BOOST_CAST_INSTEAD
 
 #include "miscellany.hpp"               // stifle_warning_for_unused_variable()
 #include "test_tools.hpp"
 #include "timer.hpp"
 
-#include <boost/cast.hpp>
-
 #include <climits>                      // INT_MIN, LLONG_MIN, SCHAR_MIN
 #include <type_traits>                  // std::conditional
 
@@ -166,48 +190,55 @@ void test_boost_anomalies()
     // 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;
+    BOOST_TEST_THROW
+        (bourn_cast<int>(double_limits::quiet_NaN())
+        ,std::runtime_error
+        ,"Cannot cast NaN to integral."
+        );
 
     // 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;
+        bourn_cast<long double>(double_limits::infinity());
+        // That worked, so this should too...
+        bourn_cast<float>(double_limits::infinity());
+        // ...because all infinities are convertible.
+        BOOST_TEST(true);
         }
-    catch(...){std::cout << "Line " << __LINE__ << ": bad throw." << 
std::endl;}
+    catch(...) {BOOST_TEST(false);}
 
     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;
+        bourn_cast<int>(INT_MIN);
+        bourn_cast<int>((double)INT_MIN);
+        // That worked, so this should too...
+        bourn_cast<int>((float)INT_MIN);
+        // ...because INT_MIN = an exact power of 2.
+        BOOST_TEST(true);
         }
-    catch(...){std::cout << "Line " << __LINE__ << ": bad throw." << 
std::endl;}
+    catch(...) {BOOST_TEST(false);}
 
     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;
+        bourn_cast<long long int>((long double)LLONG_MIN);
+        // That worked, so this should too...
+        bourn_cast<long long int>((float)LLONG_MIN);
+        // ...because LLONG_MIN = an exact power of 2.
+        BOOST_TEST(true);
         }
-    catch(...){std::cout << "Line " << __LINE__ << ": bad throw." << 
std::endl;}
+    catch(...) {BOOST_TEST(false);}
 
     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;
+        bourn_cast<long long int>((long double)LLONG_MIN);
+        // That worked, so this should too...
+        bourn_cast<long long int>((double)LLONG_MIN);
+        // ...because LLONG_MIN = an exact power of 2.
+        BOOST_TEST(true);
         }
-    catch(...){std::cout << "Line " << __LINE__ << ": bad throw." << 
std::endl;}
+    catch(...) {BOOST_TEST(false);}
 }
 
 /// Speed test: convert one million times, using static_cast.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]