CharUnits.h revision 651f13cea278ec967336033dd032faef0e9fc2ec
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  /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned
30  /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to
31  /// the same quantity of storage. However, we use the term 'character unit'
32  /// rather than 'byte' to avoid an implication that a character unit is
33  /// exactly 8 bits.
34  ///
35  /// For portability, never assume that a target character is 8 bits wide. Use
36  /// CharUnit values wherever you calculate sizes, offsets, or alignments
37  /// in character units.
38  class CharUnits {
39    public:
40      typedef int64_t QuantityType;
41
42    private:
43      QuantityType Quantity;
44
45      explicit CharUnits(QuantityType C) : Quantity(C) {}
46
47    public:
48
49      /// CharUnits - A default constructor.
50      CharUnits() : Quantity(0) {}
51
52      /// Zero - Construct a CharUnits quantity of zero.
53      static CharUnits Zero() {
54        return CharUnits(0);
55      }
56
57      /// One - Construct a CharUnits quantity of one.
58      static CharUnits One() {
59        return CharUnits(1);
60      }
61
62      /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
63      static CharUnits fromQuantity(QuantityType Quantity) {
64        return CharUnits(Quantity);
65      }
66
67      // Compound assignment.
68      CharUnits& operator+= (const CharUnits &Other) {
69        Quantity += Other.Quantity;
70        return *this;
71      }
72      CharUnits& operator++ () {
73        ++Quantity;
74        return *this;
75      }
76      CharUnits operator++ (int) {
77        return CharUnits(Quantity++);
78      }
79      CharUnits& operator-= (const CharUnits &Other) {
80        Quantity -= Other.Quantity;
81        return *this;
82      }
83      CharUnits& operator-- () {
84        --Quantity;
85        return *this;
86      }
87      CharUnits operator-- (int) {
88        return CharUnits(Quantity--);
89      }
90
91      // Comparison operators.
92      bool operator== (const CharUnits &Other) const {
93        return Quantity == Other.Quantity;
94      }
95      bool operator!= (const CharUnits &Other) const {
96        return Quantity != Other.Quantity;
97      }
98
99      // Relational operators.
100      bool operator<  (const CharUnits &Other) const {
101        return Quantity <  Other.Quantity;
102      }
103      bool operator<= (const CharUnits &Other) const {
104        return Quantity <= Other.Quantity;
105      }
106      bool operator>  (const CharUnits &Other) const {
107        return Quantity >  Other.Quantity;
108      }
109      bool operator>= (const CharUnits &Other) const {
110        return Quantity >= Other.Quantity;
111      }
112
113      // Other predicates.
114
115      /// isZero - Test whether the quantity equals zero.
116      bool isZero() const     { return Quantity == 0; }
117
118      /// isOne - Test whether the quantity equals one.
119      bool isOne() const      { return Quantity == 1; }
120
121      /// isPositive - Test whether the quantity is greater than zero.
122      bool isPositive() const { return Quantity  > 0; }
123
124      /// isNegative - Test whether the quantity is less than zero.
125      bool isNegative() const { return Quantity  < 0; }
126
127      /// isPowerOfTwo - Test whether the quantity is a power of two.
128      /// Zero is not a power of two.
129      bool isPowerOfTwo() const {
130        return (Quantity & -Quantity) == Quantity;
131      }
132
133      // Arithmetic operators.
134      CharUnits operator* (QuantityType N) const {
135        return CharUnits(Quantity * N);
136      }
137      CharUnits operator/ (QuantityType N) const {
138        return CharUnits(Quantity / N);
139      }
140      QuantityType operator/ (const CharUnits &Other) const {
141        return Quantity / Other.Quantity;
142      }
143      CharUnits operator% (QuantityType N) const {
144        return CharUnits(Quantity % N);
145      }
146      QuantityType operator% (const CharUnits &Other) const {
147        return Quantity % Other.Quantity;
148      }
149      CharUnits operator+ (const CharUnits &Other) const {
150        return CharUnits(Quantity + Other.Quantity);
151      }
152      CharUnits operator- (const CharUnits &Other) const {
153        return CharUnits(Quantity - Other.Quantity);
154      }
155      CharUnits operator- () const {
156        return CharUnits(-Quantity);
157      }
158
159
160      // Conversions.
161
162      /// getQuantity - Get the raw integer representation of this quantity.
163      QuantityType getQuantity() const { return Quantity; }
164
165      /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
166      /// greater than or equal to this quantity and is a multiple of \p Align.
167      /// Align must be non-zero.
168      CharUnits RoundUpToAlignment(const CharUnits &Align) const {
169        return CharUnits(llvm::RoundUpToAlignment(Quantity,
170                                                  Align.Quantity));
171      }
172
173      /// Given that this is a non-zero alignment value, what is the
174      /// alignment at the given offset?
175      CharUnits alignmentAtOffset(CharUnits offset) {
176        return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
177      }
178
179
180  }; // class CharUnit
181} // namespace clang
182
183inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
184                                   const clang::CharUnits &CU) {
185  return CU * Scale;
186}
187
188namespace llvm {
189
190template<> struct DenseMapInfo<clang::CharUnits> {
191  static clang::CharUnits getEmptyKey() {
192    clang::CharUnits::QuantityType Quantity =
193      DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
194
195    return clang::CharUnits::fromQuantity(Quantity);
196  }
197
198  static clang::CharUnits getTombstoneKey() {
199    clang::CharUnits::QuantityType Quantity =
200      DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
201
202    return clang::CharUnits::fromQuantity(Quantity);
203  }
204
205  static unsigned getHashValue(const clang::CharUnits &CU) {
206    clang::CharUnits::QuantityType Quantity = CU.getQuantity();
207    return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
208  }
209
210  static bool isEqual(const clang::CharUnits &LHS,
211                      const clang::CharUnits &RHS) {
212    return LHS == RHS;
213  }
214};
215
216template <> struct isPodLike<clang::CharUnits> {
217  static const bool value = true;
218};
219
220} // end namespace llvm
221
222#endif // LLVM_CLANG_AST_CHARUNITS_H
223