CharUnits.h revision 372fe788f8ea815071d0ddffe46dd3abc397106e
1//===--- CharUnits.h - Character units for sizes and offsets ----*- 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 defines the CharUnits class
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_CHARUNITS_H
15#define LLVM_CLANG_AST_CHARUNITS_H
16
17#include "llvm/ADT/DenseMapInfo.h"
18#include "llvm/Support/DataTypes.h"
19#include "llvm/Support/MathExtras.h"
20
21namespace clang {
22
23  /// CharUnits - This is an opaque type for sizes expressed in character units.
24  /// Instances of this type represent a quantity as a multiple of the size
25  /// of the standard C type, char, on the target architecture. As an opaque
26  /// type, CharUnits protects you from accidentally combining operations on
27  /// quantities in bit units and character units.
28  ///
29  /// It should be noted that characters and bytes are distinct concepts. Bytes
30  /// refer to addressable units of data storage on the target machine, and
31  /// characters are members of a set of elements used for the organization,
32  /// control, or representation of data. According to C99, bytes are allowed
33  /// to exceed characters in size, although currently, clang only supports
34  /// architectures where the two are the same size.
35  ///
36  /// For portability, never assume that a target character is 8 bits wide. Use
37  /// CharUnit values wherever you calculate sizes, offsets, or alignments
38  /// in character units.
39  class CharUnits {
40    public:
41      typedef int64_t QuantityType;
42
43    private:
44      QuantityType Quantity;
45
46      explicit CharUnits(QuantityType C) : Quantity(C) {}
47
48    public:
49
50      /// CharUnits - A default constructor.
51      CharUnits() : Quantity(0) {}
52
53      /// Zero - Construct a CharUnits quantity of zero.
54      static CharUnits Zero() {
55        return CharUnits(0);
56      }
57
58      /// One - Construct a CharUnits quantity of one.
59      static CharUnits One() {
60        return CharUnits(1);
61      }
62
63      /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
64      static CharUnits fromQuantity(QuantityType Quantity) {
65        return CharUnits(Quantity);
66      }
67
68      // Compound assignment.
69      CharUnits& operator+= (const CharUnits &Other) {
70        Quantity += Other.Quantity;
71        return *this;
72      }
73      CharUnits& operator++ () {
74        ++Quantity;
75        return *this;
76      }
77      CharUnits operator++ (int) {
78        return CharUnits(Quantity++);
79      }
80      CharUnits& operator-= (const CharUnits &Other) {
81        Quantity -= Other.Quantity;
82        return *this;
83      }
84      CharUnits& operator-- () {
85        --Quantity;
86        return *this;
87      }
88      CharUnits operator-- (int) {
89        return CharUnits(Quantity--);
90      }
91
92      // Comparison operators.
93      bool operator== (const CharUnits &Other) const {
94        return Quantity == Other.Quantity;
95      }
96      bool operator!= (const CharUnits &Other) const {
97        return Quantity != Other.Quantity;
98      }
99
100      // Relational operators.
101      bool operator<  (const CharUnits &Other) const {
102        return Quantity <  Other.Quantity;
103      }
104      bool operator<= (const CharUnits &Other) const {
105        return Quantity <= Other.Quantity;
106      }
107      bool operator>  (const CharUnits &Other) const {
108        return Quantity >  Other.Quantity;
109      }
110      bool operator>= (const CharUnits &Other) const {
111        return Quantity >= Other.Quantity;
112      }
113
114      // Other predicates.
115
116      /// isZero - Test whether the quantity equals zero.
117      bool isZero() const     { return Quantity == 0; }
118
119      /// isOne - Test whether the quantity equals one.
120      bool isOne() const      { return Quantity == 1; }
121
122      /// isPositive - Test whether the quantity is greater than zero.
123      bool isPositive() const { return Quantity  > 0; }
124
125      /// isNegative - Test whether the quantity is less than zero.
126      bool isNegative() const { return Quantity  < 0; }
127
128      /// isPowerOfTwo - Test whether the quantity is a power of two.
129      /// Zero is not a power of two.
130      bool isPowerOfTwo() const {
131        return (Quantity & -Quantity) == Quantity;
132      }
133
134      // Arithmetic operators.
135      CharUnits operator* (QuantityType N) const {
136        return CharUnits(Quantity * N);
137      }
138      CharUnits operator/ (QuantityType N) const {
139        return CharUnits(Quantity / N);
140      }
141      QuantityType operator/ (const CharUnits &Other) const {
142        return Quantity / Other.Quantity;
143      }
144      CharUnits operator% (QuantityType N) const {
145        return CharUnits(Quantity % N);
146      }
147      QuantityType operator% (const CharUnits &Other) const {
148        return Quantity % Other.Quantity;
149      }
150      CharUnits operator+ (const CharUnits &Other) const {
151        return CharUnits(Quantity + Other.Quantity);
152      }
153      CharUnits operator- (const CharUnits &Other) const {
154        return CharUnits(Quantity - Other.Quantity);
155      }
156      CharUnits operator- () const {
157        return CharUnits(-Quantity);
158      }
159
160
161      // Conversions.
162
163      /// getQuantity - Get the raw integer representation of this quantity.
164      QuantityType getQuantity() const { return Quantity; }
165
166      /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
167      /// greater than or equal to this quantity and is a multiple of \p Align.
168      /// Align must be non-zero.
169      CharUnits RoundUpToAlignment(const CharUnits &Align) {
170        return CharUnits(llvm::RoundUpToAlignment(Quantity,
171                                                  Align.Quantity));
172      }
173
174      /// Given that this is a non-zero alignment value, what is the
175      /// alignment at the given offset?
176      CharUnits alignmentAtOffset(CharUnits offset) {
177        // alignment: 0010000
178        // offset:    1011100
179        // lowBits:   0001011
180        // result:    0000100
181        QuantityType lowBits = (Quantity-1) & (offset.Quantity-1);
182        return CharUnits((lowBits + 1) & ~lowBits);
183      }
184
185
186  }; // class CharUnit
187} // namespace clang
188
189inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
190                                   const clang::CharUnits &CU) {
191  return CU * Scale;
192}
193
194namespace llvm {
195
196template<> struct DenseMapInfo<clang::CharUnits> {
197  static clang::CharUnits getEmptyKey() {
198    clang::CharUnits::QuantityType Quantity =
199      DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
200
201    return clang::CharUnits::fromQuantity(Quantity);
202  }
203
204  static clang::CharUnits getTombstoneKey() {
205    clang::CharUnits::QuantityType Quantity =
206      DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
207
208    return clang::CharUnits::fromQuantity(Quantity);
209  }
210
211  static unsigned getHashValue(const clang::CharUnits &CU) {
212    clang::CharUnits::QuantityType Quantity = CU.getQuantity();
213    return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
214  }
215
216  static bool isEqual(const clang::CharUnits &LHS,
217                      const clang::CharUnits &RHS) {
218    return LHS == RHS;
219  }
220};
221
222template <> struct isPodLike<clang::CharUnits> {
223  static const bool value = true;
224};
225
226} // end namespace llvm
227
228#endif // LLVM_CLANG_AST_CHARUNITS_H
229