Constified operator<< in APSInt.
[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   
23 class APSInt : public APInt {
24   bool IsUnsigned;
25 public:
26   /// APSInt ctor - Create an APSInt with the specified width, default to
27   /// unsigned.
28   explicit APSInt(uint32_t BitWidth, bool isUnsigned = true) 
29    : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
30
31   explicit APSInt(const APInt &I, bool isUnsigned = true) 
32    : APInt(I), IsUnsigned(isUnsigned) {}
33
34   APSInt &operator=(const APSInt &RHS) {
35     APInt::operator=(RHS); 
36     IsUnsigned = RHS.IsUnsigned;
37     return *this;
38   }
39
40   APSInt &operator=(const APInt &RHS) {
41     // Retain our current sign.
42     APInt::operator=(RHS); 
43     return *this;
44   }
45
46   APSInt &operator=(uint64_t RHS) {
47     // Retain our current sign.
48     APInt::operator=(RHS); 
49     return *this;
50   }
51
52   // Query sign information.
53   bool isSigned() const { return !IsUnsigned; }
54   bool isUnsigned() const { return IsUnsigned; }
55   void setIsUnsigned(bool Val) { IsUnsigned = Val; }
56   void setIsSigned(bool Val) { IsUnsigned = !Val; }
57   
58   /// This is used internally to convert an APInt to a string.
59   /// @brief Converts an APInt to a std::string
60   std::string toString(uint8_t Radix = 10) const {
61     return APInt::toString(Radix, isSigned());
62   }
63   
64   APSInt& extend(uint32_t width) {
65     if (IsUnsigned)
66       zext(width);
67     else
68       sext(width);
69     return *this;
70   }
71   
72   APSInt& extOrTrunc(uint32_t width) {
73       if (IsUnsigned)
74         zextOrTrunc(width);
75       else
76         sextOrTrunc(width);
77       return *this;
78   }
79   
80   const APSInt &operator%=(const APSInt &RHS) {
81     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
82     if (IsUnsigned)
83       *this = urem(RHS);
84     else
85       *this = srem(RHS);
86     return *this;
87   }
88   const APSInt &operator/=(const APSInt &RHS) {
89     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
90     if (IsUnsigned)
91       *this = udiv(RHS);
92     else
93       *this = sdiv(RHS);
94     return *this;
95   }
96   APSInt operator%(const APSInt &RHS) const {
97     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
98     return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
99   }
100   APSInt operator/(const APSInt &RHS) const {
101     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
102     return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
103   }
104   
105   APSInt operator>>(unsigned Amt) const {
106     return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
107   }
108   APSInt& operator>>=(unsigned Amt) {
109     *this = *this >> Amt;
110     return *this;
111   }
112   
113   inline bool operator<(const APSInt& RHS) const {
114     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
115     return IsUnsigned ? ult(RHS) : slt(RHS);
116   }
117   inline bool operator>(const APSInt& RHS) const {
118     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
119     return IsUnsigned ? ugt(RHS) : sgt(RHS);
120   }
121   inline bool operator<=(const APSInt& RHS) const {
122     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
123     return IsUnsigned ? ule(RHS) : sle(RHS);
124   }
125   inline bool operator>=(const APSInt& RHS) const {
126     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
127     return IsUnsigned ? uge(RHS) : sge(RHS);
128   }
129   
130   // The remaining operators just wrap the logic of APInt, but retain the
131   // signedness information.
132   
133   APSInt operator<<(unsigned Bits) const {
134     return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
135   }  
136   APSInt& operator<<=(unsigned Amt) {
137     *this = *this << Amt;
138     return *this;
139   }
140   
141   APSInt& operator++() {
142     static_cast<APInt&>(*this)++;
143     return *this;
144   }
145   APSInt& operator--() {
146     static_cast<APInt&>(*this)++;
147     return *this;
148   }
149   APSInt operator++(int) {
150     return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
151   }
152   APSInt operator--(int) {
153     return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
154   } 
155   APSInt operator-() const {
156     return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
157   }  
158   APSInt& operator+=(const APSInt& RHS) {
159     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
160     static_cast<APInt&>(*this) += RHS;
161     return *this;
162   }  
163   APSInt& operator-=(const APSInt& RHS) {
164     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
165     static_cast<APInt&>(*this) -= RHS;
166     return *this;
167   }    
168   APSInt& operator*=(const APSInt& RHS) {
169     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
170     static_cast<APInt&>(*this) *= RHS;
171     return *this;
172   }
173   APSInt& operator&=(const APSInt& RHS) {
174     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
175     static_cast<APInt&>(*this) &= RHS;
176     return *this;
177   }
178   APSInt& operator|=(const APSInt& RHS) {
179     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
180     static_cast<APInt&>(*this) |= RHS;
181     return *this;
182   }
183   APSInt& operator^=(const APSInt& RHS) {
184     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
185     static_cast<APInt&>(*this) ^= RHS;
186     return *this;
187   }
188
189   APSInt operator&(const APSInt& RHS) const {    
190     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
191     return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
192   }
193   APSInt And(const APSInt& RHS) const {
194     return this->operator&(RHS);
195   }
196   
197   APSInt operator|(const APSInt& RHS) const {    
198     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
199     return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
200   }
201   APSInt Or(const APSInt& RHS) const {
202     return this->operator|(RHS);
203   }
204   
205   
206   APSInt operator^(const APSInt& RHS) const {    
207     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
208     return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
209   }
210   APSInt Xor(const APSInt& RHS) const {
211     return this->operator^(RHS);
212   }  
213   
214   APSInt operator*(const APSInt& RHS) const {
215     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
216     return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
217   }
218   APSInt operator+(const APSInt& RHS) const {    
219     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
220     return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
221   }
222   APSInt operator-(const APSInt& RHS) const {
223     assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
224     return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
225   }
226   APSInt operator~() const {    
227     return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
228   }
229   
230   /// Profile - Used to insert APSInt objects, or objects that contain APSInt
231   ///  objects, into FoldingSets.
232   void Profile(FoldingSetNodeID& ID) const;
233 };
234   
235 } // end namespace llvm
236
237 #endif