Clang Project

clang_source_code/include/clang/AST/CharUnits.h
1//===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//  This file defines the CharUnits class
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_CHARUNITS_H
14#define LLVM_CLANG_AST_CHARUNITS_H
15
16#include "llvm/ADT/DenseMapInfo.h"
17#include "llvm/Support/DataTypes.h"
18#include "llvm/Support/MathExtras.h"
19
20namespace clang {
21
22  /// CharUnits - This is an opaque type for sizes expressed in character units.
23  /// Instances of this type represent a quantity as a multiple of the size
24  /// of the standard C type, char, on the target architecture. As an opaque
25  /// type, CharUnits protects you from accidentally combining operations on
26  /// quantities in bit units and character units.
27  ///
28  /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned
29  /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to
30  /// the same quantity of storage. However, we use the term 'character unit'
31  /// rather than 'byte' to avoid an implication that a character unit is
32  /// exactly 8 bits.
33  ///
34  /// For portability, never assume that a target character is 8 bits wide. Use
35  /// CharUnit values wherever you calculate sizes, offsets, or alignments
36  /// in character units.
37  class CharUnits {
38    public:
39      typedef int64_t QuantityType;
40
41    private:
42      QuantityType Quantity = 0;
43
44      explicit CharUnits(QuantityType C) : Quantity(C) {}
45
46    public:
47
48      /// CharUnits - A default constructor.
49      CharUnits() = default;
50
51      /// Zero - Construct a CharUnits quantity of zero.
52      static CharUnits Zero() {
53        return CharUnits(0);
54      }
55
56      /// One - Construct a CharUnits quantity of one.
57      static CharUnits One() {
58        return CharUnits(1);
59      }
60
61      /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
62      static CharUnits fromQuantity(QuantityType Quantity) {
63        return CharUnits(Quantity);
64      }
65
66      // Compound assignment.
67      CharUnitsoperator+= (const CharUnits &Other) {
68        Quantity += Other.Quantity;
69        return *this;
70      }
71      CharUnitsoperator++ () {
72        ++Quantity;
73        return *this;
74      }
75      CharUnits operator++ (int) {
76        return CharUnits(Quantity++);
77      }
78      CharUnitsoperator-= (const CharUnits &Other) {
79        Quantity -= Other.Quantity;
80        return *this;
81      }
82      CharUnitsoperator-- () {
83        --Quantity;
84        return *this;
85      }
86      CharUnits operator-- (int) {
87        return CharUnits(Quantity--);
88      }
89
90      // Comparison operators.
91      bool operator== (const CharUnits &Otherconst {
92        return Quantity == Other.Quantity;
93      }
94      bool operator!= (const CharUnits &Otherconst {
95        return Quantity != Other.Quantity;
96      }
97
98      // Relational operators.
99      bool operator<  (const CharUnits &Otherconst {
100        return Quantity <  Other.Quantity;
101      }
102      bool operator<= (const CharUnits &Otherconst {
103        return Quantity <= Other.Quantity;
104      }
105      bool operator>  (const CharUnits &Otherconst {
106        return Quantity >  Other.Quantity;
107      }
108      bool operator>= (const CharUnits &Otherconst {
109        return Quantity >= Other.Quantity;
110      }
111
112      // Other predicates.
113
114      /// isZero - Test whether the quantity equals zero.
115      bool isZero() const     { return Quantity == 0; }
116
117      /// isOne - Test whether the quantity equals one.
118      bool isOne() const      { return Quantity == 1; }
119
120      /// isPositive - Test whether the quantity is greater than zero.
121      bool isPositive() const { return Quantity  > 0; }
122
123      /// isNegative - Test whether the quantity is less than zero.
124      bool isNegative() const { return Quantity  < 0; }
125
126      /// isPowerOfTwo - Test whether the quantity is a power of two.
127      /// Zero is not a power of two.
128      bool isPowerOfTwo() const {
129        return (Quantity & -Quantity) == Quantity;
130      }
131
132      /// Test whether this is a multiple of the other value.
133      ///
134      /// Among other things, this promises that
135      /// self.alignTo(N) will just return self.
136      bool isMultipleOf(CharUnits Nconst {
137        return (*this % N) == 0;
138      }
139
140      // Arithmetic operators.
141      CharUnits operator* (QuantityType Nconst {
142        return CharUnits(Quantity * N);
143      }
144      CharUnits &operator*= (QuantityType N) {
145        Quantity *= N;
146        return *this;
147      }
148      CharUnits operator/ (QuantityType Nconst {
149        return CharUnits(Quantity / N);
150      }
151      CharUnits &operator/= (QuantityType N) {
152        Quantity /= N;
153        return *this;
154      }
155      QuantityType operator/ (const CharUnits &Otherconst {
156        return Quantity / Other.Quantity;
157      }
158      CharUnits operator% (QuantityType Nconst {
159        return CharUnits(Quantity % N);
160      }
161      QuantityType operator% (const CharUnits &Otherconst {
162        return Quantity % Other.Quantity;
163      }
164      CharUnits operator+ (const CharUnits &Otherconst {
165        return CharUnits(Quantity + Other.Quantity);
166      }
167      CharUnits operator- (const CharUnits &Otherconst {
168        return CharUnits(Quantity - Other.Quantity);
169      }
170      CharUnits operator- () const {
171        return CharUnits(-Quantity);
172      }
173
174
175      // Conversions.
176
177      /// getQuantity - Get the raw integer representation of this quantity.
178      QuantityType getQuantity() const { return Quantity; }
179
180      /// alignTo - Returns the next integer (mod 2**64) that is
181      /// greater than or equal to this quantity and is a multiple of \p Align.
182      /// Align must be non-zero.
183      CharUnits alignTo(const CharUnits &Alignconst {
184        return CharUnits(llvm::alignTo(Quantity, Align.Quantity));
185      }
186
187      /// Given that this is a non-zero alignment value, what is the
188      /// alignment at the given offset?
189      CharUnits alignmentAtOffset(CharUnits offsetconst {
190         (0) . __assert_fail ("Quantity != 0 && \"offsetting from unknown alignment?\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/CharUnits.h", 190, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Quantity != 0 && "offsetting from unknown alignment?");
191        return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
192      }
193
194      /// Given that this is the alignment of the first element of an
195      /// array, return the minimum alignment of any element in the array.
196      CharUnits alignmentOfArrayElement(CharUnits elementSizeconst {
197        // Since we don't track offsetted alignments, the alignment of
198        // the second element (or any odd element) will be minimally
199        // aligned.
200        return alignmentAtOffset(elementSize);
201      }
202
203
204  }; // class CharUnit
205// namespace clang
206
207inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
208                                   const clang::CharUnits &CU) {
209  return CU * Scale;
210}
211
212namespace llvm {
213
214template<> struct DenseMapInfo<clang::CharUnits> {
215  static clang::CharUnits getEmptyKey() {
216    clang::CharUnits::QuantityType Quantity =
217      DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
218
219    return clang::CharUnits::fromQuantity(Quantity);
220  }
221
222  static clang::CharUnits getTombstoneKey() {
223    clang::CharUnits::QuantityType Quantity =
224      DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
225
226    return clang::CharUnits::fromQuantity(Quantity);
227  }
228
229  static unsigned getHashValue(const clang::CharUnits &CU) {
230    clang::CharUnits::QuantityType Quantity = CU.getQuantity();
231    return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
232  }
233
234  static bool isEqual(const clang::CharUnits &LHS,
235                      const clang::CharUnits &RHS) {
236    return LHS == RHS;
237  }
238};
239
240// end namespace llvm
241
242#endif // LLVM_CLANG_AST_CHARUNITS_H
243
clang::CharUnits::Quantity
clang::CharUnits::Zero
clang::CharUnits::One
clang::CharUnits::fromQuantity
clang::CharUnits::isZero
clang::CharUnits::isOne
clang::CharUnits::isPositive
clang::CharUnits::isNegative
clang::CharUnits::isPowerOfTwo
clang::CharUnits::isMultipleOf
clang::CharUnits::getQuantity
clang::CharUnits::alignTo
clang::CharUnits::alignmentAtOffset
clang::CharUnits::alignmentOfArrayElement
llvm::DenseMapInfo::getEmptyKey
llvm::DenseMapInfo::getTombstoneKey
llvm::DenseMapInfo::getHashValue
llvm::DenseMapInfo::isEqual
clang::CharUnits::fromQuantity
llvm::DenseMapInfo::getEmptyKey
llvm::DenseMapInfo::getTombstoneKey
llvm::DenseMapInfo::getHashValue
llvm::DenseMapInfo::isEqual