@@ -35,10 +35,18 @@ template <bool Signed> class IntegralAP final {
35
35
friend IntegralAP<!Signed>;
36
36
APInt V;
37
37
38
- template <typename T> static T truncateCast (const APInt &V) {
38
+ template <typename T, bool InputSigned>
39
+ static T truncateCast (const APInt &V) {
39
40
constexpr unsigned BitSize = sizeof (T) * 8 ;
40
- if (BitSize >= V.getBitWidth ())
41
- return std::is_signed_v<T> ? V.getSExtValue () : V.getZExtValue ();
41
+ if (BitSize >= V.getBitWidth ()) {
42
+ APInt Extended;
43
+ if constexpr (InputSigned)
44
+ Extended = V.sext (BitSize);
45
+ else
46
+ Extended = V.zext (BitSize);
47
+ return std::is_signed_v<T> ? Extended.getSExtValue ()
48
+ : Extended.getZExtValue ();
49
+ }
42
50
43
51
return std::is_signed_v<T> ? V.trunc (BitSize).getSExtValue ()
44
52
: V.trunc (BitSize).getZExtValue ();
@@ -80,15 +88,10 @@ template <bool Signed> class IntegralAP final {
80
88
return V.ult (RHS.V );
81
89
}
82
90
83
- explicit operator bool () const { return !V.isZero (); }
84
- explicit operator int8_t () const { return truncateCast<int8_t >(V); }
85
- explicit operator uint8_t () const { return truncateCast<uint8_t >(V); }
86
- explicit operator int16_t () const { return truncateCast<int16_t >(V); }
87
- explicit operator uint16_t () const { return truncateCast<uint16_t >(V); }
88
- explicit operator int32_t () const { return truncateCast<int32_t >(V); }
89
- explicit operator uint32_t () const { return truncateCast<uint32_t >(V); }
90
- explicit operator int64_t () const { return truncateCast<int64_t >(V); }
91
- explicit operator uint64_t () const { return truncateCast<uint64_t >(V); }
91
+ template <typename Ty, typename = std::enable_if_t <std::is_integral_v<Ty>>>
92
+ explicit operator Ty () const {
93
+ return truncateCast<Ty, Signed>(V);
94
+ }
92
95
93
96
template <typename T> static IntegralAP from (T Value, unsigned NumBits = 0 ) {
94
97
assert (NumBits > 0 );
0 commit comments