Added static methods to APSInt: getMinValue and getMaxValue.
[oota-llvm.git] / include / llvm / ADT / APSInt.h
1 //===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the APSInt class, which is a simple class that
11 // represents an arbitrary sized integer that knows its signedness.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_APSINT_H
16 #define LLVM_APSINT_H
17
18 #include "llvm/ADT/APInt.h"
19
20 namespace llvm {
21   
22 class APSInt : public APInt {
23   bool IsUnsigned;
24 public:
25   /// Default constructor that creates an uninitialized APInt.
26   explicit APSInt() {}
27
28   /// APSInt ctor - Create an APSInt with the specified width, default to
29   /// unsigned.
30   explicit APSInt(uint32_t BitWidth, bool isUnsigned = true) 
31    : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
32
33   explicit APSInt(const APInt &I, bool isUnsigned = true) 
34    : APInt(I), IsUnsigned(isUnsigned) {}
35
36   APSInt &operator=(const APSInt &RHS) {
37     APInt::operator=(RHS); 
38     IsUnsigned = RHS.IsUnsigned;
39     return *this;
40   }
41
42   APSInt &operator=(const APInt &RHS) {
43     // Retain our current sign.
44     APInt::operator=(RHS); 
45     return *this;
46   }
47
48   APSInt &operator=(uint64_t RHS) {
49     // Retain our current sign.
50     APInt::operator=(RHS); 
51     return *this;
52   }
53
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; }
59   
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());
63   }
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());
68   }
69   using APInt::toString;
70   
71   APSInt& extend(uint32_t width) {
72     if (IsUnsigned)
73       zext(width);
74     else
75       sext(width);
76     return *this;
77   }
78   
79   APSInt& extOrTrunc(uint32_t width) {
80       if (IsUnsigned)
81         zextOrTrunc(width);
82       else
83         sextOrTrunc(width);
84       return *this;
85   }
86   
87   const APSInt &operator%=(const APSInt &RHS) {
88     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
89     if (IsUnsigned)
90       *this = urem(RHS);
91     else
92       *this = srem(RHS);
93     return *this;
94   }
95   const APSInt &operator/=(const APSInt &RHS) {
96     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
97     if (IsUnsigned)
98       *this = udiv(RHS);
99     else
100       *this = sdiv(RHS);
101     return *this;
102   }
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);
106   }
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);
110   }
111   
112   APSInt operator>>(unsigned Amt) const {
113     return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
114   }
115   APSInt& operator>>=(unsigned Amt) {
116     *this = *this >> Amt;
117     return *this;
118   }
119   
120   inline bool operator<(const APSInt& RHS) const {
121     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
122     return IsUnsigned ? ult(RHS) : slt(RHS);
123   }
124   inline bool operator>(const APSInt& RHS) const {
125     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
126     return IsUnsigned ? ugt(RHS) : sgt(RHS);
127   }
128   inline bool operator<=(const APSInt& RHS) const {
129     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
130     return IsUnsigned ? ule(RHS) : sle(RHS);
131   }
132   inline bool operator>=(const APSInt& RHS) const {
133     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
134     return IsUnsigned ? uge(RHS) : sge(RHS);
135   }
136   
137   // The remaining operators just wrap the logic of APInt, but retain the
138   // signedness information.
139   
140   APSInt operator<<(unsigned Bits) const {
141     return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
142   }  
143   APSInt& operator<<=(unsigned Amt) {
144     *this = *this << Amt;
145     return *this;
146   }
147   
148   APSInt& operator++() {
149     static_cast<APInt&>(*this)++;
150     return *this;
151   }
152   APSInt& operator--() {
153     static_cast<APInt&>(*this)++;
154     return *this;
155   }
156   APSInt operator++(int) {
157     return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
158   }
159   APSInt operator--(int) {
160     return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
161   } 
162   APSInt operator-() const {
163     return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
164   }  
165   APSInt& operator+=(const APSInt& RHS) {
166     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
167     static_cast<APInt&>(*this) += RHS;
168     return *this;
169   }  
170   APSInt& operator-=(const APSInt& RHS) {
171     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
172     static_cast<APInt&>(*this) -= RHS;
173     return *this;
174   }    
175   APSInt& operator*=(const APSInt& RHS) {
176     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
177     static_cast<APInt&>(*this) *= RHS;
178     return *this;
179   }
180   APSInt& operator&=(const APSInt& RHS) {
181     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
182     static_cast<APInt&>(*this) &= RHS;
183     return *this;
184   }
185   APSInt& operator|=(const APSInt& RHS) {
186     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
187     static_cast<APInt&>(*this) |= RHS;
188     return *this;
189   }
190   APSInt& operator^=(const APSInt& RHS) {
191     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
192     static_cast<APInt&>(*this) ^= RHS;
193     return *this;
194   }
195
196   APSInt operator&(const APSInt& RHS) const {    
197     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
198     return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
199   }
200   APSInt And(const APSInt& RHS) const {
201     return this->operator&(RHS);
202   }
203   
204   APSInt operator|(const APSInt& RHS) const {    
205     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
206     return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
207   }
208   APSInt Or(const APSInt& RHS) const {
209     return this->operator|(RHS);
210   }
211   
212   
213   APSInt operator^(const APSInt& RHS) const {    
214     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
215     return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
216   }
217   APSInt Xor(const APSInt& RHS) const {
218     return this->operator^(RHS);
219   }  
220   
221   APSInt operator*(const APSInt& RHS) const {
222     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
223     return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
224   }
225   APSInt operator+(const APSInt& RHS) const {    
226     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
227     return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
228   }
229   APSInt operator-(const APSInt& RHS) const {
230     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
231     return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
232   }
233   APSInt operator~() const {    
234     return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
235   }
236   
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);
242   }
243   
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);
249   }
250   
251   /// Profile - Used to insert APSInt objects, or objects that contain APSInt
252   ///  objects, into FoldingSets.
253   void Profile(FoldingSetNodeID& ID) const;
254 };
255   
256 inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) {
257   I.print(OS, I.isSigned());
258   return OS;
259 }
260   
261   
262 } // end namespace llvm
263
264 #endif