From ddd7ccf722e54d41fe4b389545003e15e5fb4488 Mon Sep 17 00:00:00 2001 From: Kevin Backhouse Date: Thu, 27 Oct 2022 11:09:25 +0100 Subject: [PATCH] Use std::is_signed and std::enable_if. --- src/safe_op.hpp | 45 +++++++------------------------------- unitTests/test_safe_op.cpp | 34 ++++++++++++++-------------- 2 files changed, 25 insertions(+), 54 deletions(-) diff --git a/src/safe_op.hpp b/src/safe_op.hpp index 27f542af..da602b0c 100644 --- a/src/safe_op.hpp +++ b/src/safe_op.hpp @@ -5,6 +5,7 @@ #include #include +#include #ifdef _MSC_VER #include @@ -37,35 +38,6 @@ namespace Safe { * is available. */ namespace Internal { -/*! - * @brief Helper struct to determine whether a type is signed or unsigned - * - * This struct is a backport of std::is_signed from C++11. It has a public - * enum with the property VALUE which is true when the type is signed or - * false if it is unsigned. - */ -template -struct is_signed { - enum { VALUE = static_cast(-1) < static_cast(0) }; -}; - -/*! - * @brief Helper struct for SFINAE, from C++11 - - * This struct has a public typedef called type typedef'd to T if B is - * true. Otherwise there is no typedef. - */ -template -struct enable_if {}; - -/*! - * @brief Specialization of enable_if for the case B == true - */ -template -struct enable_if { - using type = T; -}; - /*! * @brief Check the addition of two numbers for overflows for signed * integer types larger than int or with the same size as int. @@ -84,9 +56,8 @@ struct enable_if { * https://wiki.sei.cmu.edu/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow */ template -typename enable_if::VALUE && sizeof(T) >= sizeof(int), bool>::type fallback_add_overflow(T summand_1, - T summand_2, - T& result) { +typename std::enable_if::value && sizeof(T) >= sizeof(int), bool>::type fallback_add_overflow( + T summand_1, T summand_2, T& result) { if (((summand_2 >= 0) && (summand_1 > std::numeric_limits::max() - summand_2)) || ((summand_2 < 0) && (summand_1 < std::numeric_limits::min() - summand_2))) { return true; @@ -116,9 +87,8 @@ typename enable_if::VALUE && sizeof(T) >= sizeof(int), bool>::type * https://wiki.sei.cmu.edu/confluence/display/c/INT02-C.+Understand+integer+conversion+rules */ template -typename enable_if::VALUE && sizeof(T) < sizeof(int), bool>::type fallback_add_overflow(T summand_1, - T summand_2, - T& result) { +typename std::enable_if::value && sizeof(T) < sizeof(int), bool>::type fallback_add_overflow( + T summand_1, T summand_2, T& result) { const int res = summand_1 + summand_2; if ((res > std::numeric_limits::max()) || (res < std::numeric_limits::min())) { return true; @@ -145,7 +115,8 @@ typename enable_if::VALUE && sizeof(T) < sizeof(int), bool>::type f * https://wiki.sei.cmu.edu/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap */ template -typename enable_if::VALUE, bool>::type fallback_add_overflow(T summand_1, T summand_2, T& result) { +typename std::enable_if::value, bool>::type fallback_add_overflow(T summand_1, T summand_2, + T& result) { result = summand_1 + summand_2; return result < summand_1; } @@ -255,7 +226,7 @@ T add(T summand_1, T summand_2) { * when `num == std::numeric_limits::min()`. */ template -typename Internal::enable_if::VALUE, T>::type abs(T num) throw() { +typename std::enable_if::value, T>::type abs(T num) throw() { if (num == std::numeric_limits::min()) { return std::numeric_limits::max(); } diff --git a/unitTests/test_safe_op.cpp b/unitTests/test_safe_op.cpp index e0037e1b..438f2691 100644 --- a/unitTests/test_safe_op.cpp +++ b/unitTests/test_safe_op.cpp @@ -26,42 +26,42 @@ struct AdditionTestValues; * Overload for unsigned types. */ template -struct AdditionTestValues::VALUE>::type> { +struct AdditionTestValues::VALUE>::type> { static const size_t case_count = 5; static const T summand[case_count]; static const bool overflow[case_count][case_count]; }; template -const T AdditionTestValues::VALUE>::type>::summand[] = { +const T AdditionTestValues::VALUE>::type>::summand[] = { 0, 1, 2, static_cast(std::numeric_limits::max() - 1), std::numeric_limits::max()}; template -const bool - AdditionTestValues::VALUE>::type>::overflow[case_count][case_count] = { - // 0 - {false, false, false, false, false}, - // 1 - {false, false, false, false, true}, - // 2 - {false, false, false, true, true}, - // max - 1 - {false, false, true, true, true}, - // max - {false, true, true, true, true}}; +const bool AdditionTestValues< + T, typename std::enable_if::VALUE>::type>::overflow[case_count][case_count] = { + // 0 + {false, false, false, false, false}, + // 1 + {false, false, false, false, true}, + // 2 + {false, false, false, true, true}, + // max - 1 + {false, false, true, true, true}, + // max + {false, true, true, true, true}}; /*! * Overload for signed integers */ template -struct AdditionTestValues::VALUE>::type> { +struct AdditionTestValues::VALUE>::type> { static const size_t case_count = 8; static const T summand[case_count]; static const bool overflow[case_count][case_count]; }; template -const T AdditionTestValues::VALUE>::type>::summand[] = { +const T AdditionTestValues::VALUE>::type>::summand[] = { std::numeric_limits::min(), static_cast(std::numeric_limits::min() + 1), -1, @@ -73,7 +73,7 @@ const T AdditionTestValues::VALUE>::t template const bool - AdditionTestValues::VALUE>::type>::overflow[case_count][case_count] = { + AdditionTestValues::VALUE>::type>::overflow[case_count][case_count] = { // min {true, true, true, false, false, false, false, false}, // min + 1