1 //===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the APSInt class, which is a simple class that
11 // represents an arbitrary sized integer that knows its signedness.
13 //===----------------------------------------------------------------------===//
18 #include "llvm/ADT/APInt.h"
22 class APSInt : public APInt {
25 /// Default constructor that creates an uninitialized APInt.
28 /// APSInt ctor - Create an APSInt with the specified width, default to
30 explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
31 : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
33 explicit APSInt(const APInt &I, bool isUnsigned = true)
34 : APInt(I), IsUnsigned(isUnsigned) {}
36 APSInt &operator=(const APSInt &RHS) {
37 APInt::operator=(RHS);
38 IsUnsigned = RHS.IsUnsigned;
42 APSInt &operator=(const APInt &RHS) {
43 // Retain our current sign.
44 APInt::operator=(RHS);
48 APSInt &operator=(uint64_t RHS) {
49 // Retain our current sign.
50 APInt::operator=(RHS);
54 // Query sign information.
55 bool isSigned() const { return !IsUnsigned; }
56 bool isUnsigned() const { return IsUnsigned; }
57 void setIsUnsigned(bool Val) { IsUnsigned = Val; }
58 void setIsSigned(bool Val) { IsUnsigned = !Val; }
60 /// toString - Append this APSInt to the specified SmallString.
61 void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
62 return APInt::toString(Str, Radix, isSigned());
64 /// toString - Converts an APInt to a std::string. This is an inefficient
65 /// method, your should prefer passing in a SmallString instead.
66 std::string toString(unsigned Radix) const {
67 return APInt::toString(Radix, isSigned());
69 using APInt::toString;
71 APSInt& extend(uint32_t width) {
79 APSInt& extOrTrunc(uint32_t width) {
87 const APSInt &operator%=(const APSInt &RHS) {
88 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
95 const APSInt &operator/=(const APSInt &RHS) {
96 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
103 APSInt operator%(const APSInt &RHS) const {
104 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
105 return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
107 APSInt operator/(const APSInt &RHS) const {
108 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
109 return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
112 APSInt operator>>(unsigned Amt) const {
113 return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
115 APSInt& operator>>=(unsigned Amt) {
116 *this = *this >> Amt;
120 inline bool operator<(const APSInt& RHS) const {
121 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
122 return IsUnsigned ? ult(RHS) : slt(RHS);
124 inline bool operator>(const APSInt& RHS) const {
125 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
126 return IsUnsigned ? ugt(RHS) : sgt(RHS);
128 inline bool operator<=(const APSInt& RHS) const {
129 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
130 return IsUnsigned ? ule(RHS) : sle(RHS);
132 inline bool operator>=(const APSInt& RHS) const {
133 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
134 return IsUnsigned ? uge(RHS) : sge(RHS);
137 // The remaining operators just wrap the logic of APInt, but retain the
138 // signedness information.
140 APSInt operator<<(unsigned Bits) const {
141 return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
143 APSInt& operator<<=(unsigned Amt) {
144 *this = *this << Amt;
148 APSInt& operator++() {
149 static_cast<APInt&>(*this)++;
152 APSInt& operator--() {
153 static_cast<APInt&>(*this)++;
156 APSInt operator++(int) {
157 return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
159 APSInt operator--(int) {
160 return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
162 APSInt operator-() const {
163 return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
165 APSInt& operator+=(const APSInt& RHS) {
166 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
167 static_cast<APInt&>(*this) += RHS;
170 APSInt& operator-=(const APSInt& RHS) {
171 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
172 static_cast<APInt&>(*this) -= RHS;
175 APSInt& operator*=(const APSInt& RHS) {
176 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
177 static_cast<APInt&>(*this) *= RHS;
180 APSInt& operator&=(const APSInt& RHS) {
181 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
182 static_cast<APInt&>(*this) &= RHS;
185 APSInt& operator|=(const APSInt& RHS) {
186 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
187 static_cast<APInt&>(*this) |= RHS;
190 APSInt& operator^=(const APSInt& RHS) {
191 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
192 static_cast<APInt&>(*this) ^= RHS;
196 APSInt operator&(const APSInt& RHS) const {
197 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
198 return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
200 APSInt And(const APSInt& RHS) const {
201 return this->operator&(RHS);
204 APSInt operator|(const APSInt& RHS) const {
205 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
206 return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
208 APSInt Or(const APSInt& RHS) const {
209 return this->operator|(RHS);
213 APSInt operator^(const APSInt& RHS) const {
214 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
215 return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
217 APSInt Xor(const APSInt& RHS) const {
218 return this->operator^(RHS);
221 APSInt operator*(const APSInt& RHS) const {
222 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
223 return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
225 APSInt operator+(const APSInt& RHS) const {
226 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
227 return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
229 APSInt operator-(const APSInt& RHS) const {
230 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
231 return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
233 APSInt operator~() const {
234 return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
237 /// getMaxValue - Return the APSInt representing the maximum integer value
238 /// with the given bit width and signedness.
239 static APSInt getMaxValue(uint32_t numBits, bool Signed) {
240 return APSInt(Signed ? APInt::getSignedMaxValue(numBits)
241 : APInt::getMaxValue(numBits), Signed);
244 /// getMinValue - Return the APSInt representing the minimum integer value
245 /// with the given bit width and signedness.
246 static APSInt getMinValue(uint32_t numBits, bool Signed) {
247 return APSInt(Signed ? APInt::getSignedMinValue(numBits)
248 : APInt::getMinValue(numBits), Signed);
251 /// Profile - Used to insert APSInt objects, or objects that contain APSInt
252 /// objects, into FoldingSets.
253 void Profile(FoldingSetNodeID& ID) const;
256 inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) {
257 I.print(OS, I.isSigned());
262 } // end namespace llvm