@@ -14,40 +14,19 @@ C10_CLANG_DIAGNOSTIC_IGNORE("-Wimplicit-int-float-conversion")
1414
1515namespace c10 {
1616
17- // / Returns false since we cannot have x < 0 if x is unsigned.
18- template <typename T>
19- inline constexpr bool is_negative (
20- const T& /* x*/ ,
21- std::true_type /* is_unsigned*/ ) {
22- return false ;
23- }
24-
25- // / Returns true if a signed variable x < 0
26- template <typename T>
27- inline constexpr bool is_negative (const T& x, std::false_type /* is_unsigned*/ ) {
28- return x < T (0 );
29- }
30-
3117// / Returns true if x < 0
3218// / NOTE: Will fail on an unsigned custom type
3319// / For the most part it's possible to fix this if
3420// / the custom type has a constexpr constructor.
3521// / However, notably, c10::Half does not :-(
3622template <typename T>
3723inline constexpr bool is_negative (const T& x) {
38- return is_negative (x, std::is_unsigned<T>());
39- }
40-
41- // / Returns the sign of an unsigned variable x as 0, 1
42- template <typename T>
43- inline constexpr int signum (const T& x, std::true_type /* is_unsigned*/ ) {
44- return T (0 ) < x;
45- }
46-
47- // / Returns the sign of a signed variable x as -1, 0, 1
48- template <typename T>
49- inline constexpr int signum (const T& x, std::false_type /* is_unsigned*/ ) {
50- return (T (0 ) < x) - (x < T (0 ));
24+ if constexpr (std::is_unsigned_v<T>) {
25+ // An unsigned value can never be less than zero.
26+ return false ;
27+ } else {
28+ return x < T (0 );
29+ }
5130}
5231
5332// / Returns the sign of x as -1, 0, 1
@@ -57,7 +36,11 @@ inline constexpr int signum(const T& x, std::false_type /*is_unsigned*/) {
5736// / However, notably, c10::Half does not :-(
5837template <typename T>
5938inline constexpr int signum (const T& x) {
60- return signum (x, std::is_unsigned<T>());
39+ if constexpr (std::is_unsigned_v<T>) {
40+ return T (0 ) < x;
41+ } else {
42+ return (T (0 ) < x) - (x < T (0 ));
43+ }
6144}
6245
6346// / Returns true if a and b are not both negative
@@ -86,53 +69,22 @@ inline constexpr bool greater_than_max(const T& x) {
8669#pragma GCC diagnostic pop
8770#endif
8871
89- // / Returns true if x < lowest(Limit). Standard comparison
90- template <typename Limit, typename T>
91- inline constexpr bool less_than_lowest (
92- const T& x,
93- std::false_type /* limit_is_unsigned*/ ,
94- std::false_type /* x_is_unsigned*/ ) {
95- return x < std::numeric_limits<Limit>::lowest ();
96- }
97-
98- // / Returns false since all the limit is signed and therefore includes
99- // / negative values but x cannot be negative because it is unsigned
100- template <typename Limit, typename T>
101- inline constexpr bool less_than_lowest (
102- const T& /* x*/ ,
103- std::false_type /* limit_is_unsigned*/ ,
104- std::true_type /* x_is_unsigned*/ ) {
105- return false ;
106- }
107-
108- // / Returns true if x < 0, where 0 is constructed from T.
109- // / Limit is not signed, so its lower value is zero
110- template <typename Limit, typename T>
111- inline constexpr bool less_than_lowest (
112- const T& x,
113- std::true_type /* limit_is_unsigned*/ ,
114- std::false_type /* x_is_unsigned*/ ) {
115- return x < T (0 );
116- }
117-
118- // / Returns false sign both types are unsigned
119- template <typename Limit, typename T>
120- inline constexpr bool less_than_lowest (
121- const T& /* x*/ ,
122- std::true_type /* limit_is_unsigned*/ ,
123- std::true_type /* x_is_unsigned*/ ) {
124- return false ;
125- }
126-
127- // / Returns true if x is less than the lowest value of type T
72+ // / Returns true if x is less than the lowest value of type Limit
12873// / NOTE: Will fail on an unsigned custom type
12974// / For the most part it's possible to fix this if
13075// / the custom type has a constexpr constructor.
13176// / However, notably, c10::Half does not :
13277template <typename Limit, typename T>
13378inline constexpr bool less_than_lowest (const T& x) {
134- return less_than_lowest<Limit>(
135- x, std::is_unsigned<Limit>(), std::is_unsigned<T>());
79+ if constexpr (std::is_unsigned_v<T>) {
80+ // x is unsigned, so it can never be below the lowest value of any type.
81+ return false ;
82+ } else if constexpr (std::is_unsigned_v<Limit>) {
83+ // Limit is unsigned, so its lowest value is zero.
84+ return x < T (0 );
85+ } else {
86+ return x < std::numeric_limits<Limit>::lowest ();
87+ }
13688}
13789
13890} // namespace c10
0 commit comments