Skip to content

Commit ddd7ccf

Browse files
kevinbackhouseneheb
authored andcommitted
Use std::is_signed and std::enable_if.
1 parent 335e132 commit ddd7ccf

File tree

2 files changed

+25
-54
lines changed

2 files changed

+25
-54
lines changed

src/safe_op.hpp

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <limits>
77
#include <stdexcept>
8+
#include <type_traits>
89

910
#ifdef _MSC_VER
1011
#include <Intsafe.h>
@@ -37,35 +38,6 @@ namespace Safe {
3738
* is available.
3839
*/
3940
namespace Internal {
40-
/*!
41-
* @brief Helper struct to determine whether a type is signed or unsigned
42-
*
43-
* This struct is a backport of std::is_signed from C++11. It has a public
44-
* enum with the property VALUE which is true when the type is signed or
45-
* false if it is unsigned.
46-
*/
47-
template <typename T>
48-
struct is_signed {
49-
enum { VALUE = static_cast<T>(-1) < static_cast<T>(0) };
50-
};
51-
52-
/*!
53-
* @brief Helper struct for SFINAE, from C++11
54-
55-
* This struct has a public typedef called type typedef'd to T if B is
56-
* true. Otherwise there is no typedef.
57-
*/
58-
template <bool B, class T = void>
59-
struct enable_if {};
60-
61-
/*!
62-
* @brief Specialization of enable_if for the case B == true
63-
*/
64-
template <class T>
65-
struct enable_if<true, T> {
66-
using type = T;
67-
};
68-
6941
/*!
7042
* @brief Check the addition of two numbers for overflows for signed
7143
* integer types larger than int or with the same size as int.
@@ -84,9 +56,8 @@ struct enable_if<true, T> {
8456
* https://wiki.sei.cmu.edu/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow
8557
*/
8658
template <typename T>
87-
typename enable_if<is_signed<T>::VALUE && sizeof(T) >= sizeof(int), bool>::type fallback_add_overflow(T summand_1,
88-
T summand_2,
89-
T& result) {
59+
typename std::enable_if<std::is_signed<T>::value && sizeof(T) >= sizeof(int), bool>::type fallback_add_overflow(
60+
T summand_1, T summand_2, T& result) {
9061
if (((summand_2 >= 0) && (summand_1 > std::numeric_limits<T>::max() - summand_2)) ||
9162
((summand_2 < 0) && (summand_1 < std::numeric_limits<T>::min() - summand_2))) {
9263
return true;
@@ -116,9 +87,8 @@ typename enable_if<is_signed<T>::VALUE && sizeof(T) >= sizeof(int), bool>::type
11687
* https://wiki.sei.cmu.edu/confluence/display/c/INT02-C.+Understand+integer+conversion+rules
11788
*/
11889
template <typename T>
119-
typename enable_if<is_signed<T>::VALUE && sizeof(T) < sizeof(int), bool>::type fallback_add_overflow(T summand_1,
120-
T summand_2,
121-
T& result) {
90+
typename std::enable_if<std::is_signed<T>::value && sizeof(T) < sizeof(int), bool>::type fallback_add_overflow(
91+
T summand_1, T summand_2, T& result) {
12292
const int res = summand_1 + summand_2;
12393
if ((res > std::numeric_limits<T>::max()) || (res < std::numeric_limits<T>::min())) {
12494
return true;
@@ -145,7 +115,8 @@ typename enable_if<is_signed<T>::VALUE && sizeof(T) < sizeof(int), bool>::type f
145115
* https://wiki.sei.cmu.edu/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap
146116
*/
147117
template <typename T>
148-
typename enable_if<!is_signed<T>::VALUE, bool>::type fallback_add_overflow(T summand_1, T summand_2, T& result) {
118+
typename std::enable_if<!std::is_signed<T>::value, bool>::type fallback_add_overflow(T summand_1, T summand_2,
119+
T& result) {
149120
result = summand_1 + summand_2;
150121
return result < summand_1;
151122
}
@@ -255,7 +226,7 @@ T add(T summand_1, T summand_2) {
255226
* when `num == std::numeric_limits<T>::min()`.
256227
*/
257228
template <typename T>
258-
typename Internal::enable_if<Internal::is_signed<T>::VALUE, T>::type abs(T num) throw() {
229+
typename std::enable_if<std::is_signed<T>::value, T>::type abs(T num) throw() {
259230
if (num == std::numeric_limits<T>::min()) {
260231
return std::numeric_limits<T>::max();
261232
}

unitTests/test_safe_op.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,42 +26,42 @@ struct AdditionTestValues;
2626
* Overload for unsigned types.
2727
*/
2828
template <typename T>
29-
struct AdditionTestValues<T, typename si::enable_if<!si::is_signed<T>::VALUE>::type> {
29+
struct AdditionTestValues<T, typename std::enable_if<!std::is_signed<T>::VALUE>::type> {
3030
static const size_t case_count = 5;
3131
static const T summand[case_count];
3232
static const bool overflow[case_count][case_count];
3333
};
3434

3535
template <typename T>
36-
const T AdditionTestValues<T, typename si::enable_if<!si::is_signed<T>::VALUE>::type>::summand[] = {
36+
const T AdditionTestValues<T, typename std::enable_if<!std::is_signed<T>::VALUE>::type>::summand[] = {
3737
0, 1, 2, static_cast<T>(std::numeric_limits<T>::max() - 1), std::numeric_limits<T>::max()};
3838

3939
template <typename T>
40-
const bool
41-
AdditionTestValues<T, typename si::enable_if<!si::is_signed<T>::VALUE>::type>::overflow[case_count][case_count] = {
42-
// 0
43-
{false, false, false, false, false},
44-
// 1
45-
{false, false, false, false, true},
46-
// 2
47-
{false, false, false, true, true},
48-
// max - 1
49-
{false, false, true, true, true},
50-
// max
51-
{false, true, true, true, true}};
40+
const bool AdditionTestValues<
41+
T, typename std::enable_if<!std::is_signed<T>::VALUE>::type>::overflow[case_count][case_count] = {
42+
// 0
43+
{false, false, false, false, false},
44+
// 1
45+
{false, false, false, false, true},
46+
// 2
47+
{false, false, false, true, true},
48+
// max - 1
49+
{false, false, true, true, true},
50+
// max
51+
{false, true, true, true, true}};
5252

5353
/*!
5454
* Overload for signed integers
5555
*/
5656
template <typename T>
57-
struct AdditionTestValues<T, typename si::enable_if<si::is_signed<T>::VALUE>::type> {
57+
struct AdditionTestValues<T, typename std::enable_if<std::is_signed<T>::VALUE>::type> {
5858
static const size_t case_count = 8;
5959
static const T summand[case_count];
6060
static const bool overflow[case_count][case_count];
6161
};
6262

6363
template <typename T>
64-
const T AdditionTestValues<T, typename si::enable_if<si::is_signed<T>::VALUE>::type>::summand[] = {
64+
const T AdditionTestValues<T, typename std::enable_if<std::is_signed<T>::VALUE>::type>::summand[] = {
6565
std::numeric_limits<T>::min(),
6666
static_cast<T>(std::numeric_limits<T>::min() + 1),
6767
-1,
@@ -73,7 +73,7 @@ const T AdditionTestValues<T, typename si::enable_if<si::is_signed<T>::VALUE>::t
7373

7474
template <typename T>
7575
const bool
76-
AdditionTestValues<T, typename si::enable_if<si::is_signed<T>::VALUE>::type>::overflow[case_count][case_count] = {
76+
AdditionTestValues<T, typename std::enable_if<std::is_signed<T>::VALUE>::type>::overflow[case_count][case_count] = {
7777
// min
7878
{true, true, true, false, false, false, false, false},
7979
// min + 1

0 commit comments

Comments
 (0)