- //===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- //  This file defines the CharUnits class 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CLANG_AST_CHARUNITS_H 
- #define LLVM_CLANG_AST_CHARUNITS_H 
-   
- #include "llvm/ADT/DenseMapInfo.h" 
- #include "llvm/Support/Alignment.h" 
- #include "llvm/Support/DataTypes.h" 
- #include "llvm/Support/MathExtras.h" 
-   
- namespace clang { 
-   
-   /// CharUnits - This is an opaque type for sizes expressed in character units. 
-   /// Instances of this type represent a quantity as a multiple of the size 
-   /// of the standard C type, char, on the target architecture. As an opaque 
-   /// type, CharUnits protects you from accidentally combining operations on 
-   /// quantities in bit units and character units. 
-   /// 
-   /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned 
-   /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to 
-   /// the same quantity of storage. However, we use the term 'character unit' 
-   /// rather than 'byte' to avoid an implication that a character unit is 
-   /// exactly 8 bits. 
-   /// 
-   /// For portability, never assume that a target character is 8 bits wide. Use 
-   /// CharUnit values wherever you calculate sizes, offsets, or alignments 
-   /// in character units. 
-   class CharUnits { 
-     public: 
-       typedef int64_t QuantityType; 
-   
-     private: 
-       QuantityType Quantity = 0; 
-   
-       explicit CharUnits(QuantityType C) : Quantity(C) {} 
-   
-     public: 
-   
-       /// CharUnits - A default constructor. 
-       CharUnits() = default; 
-   
-       /// Zero - Construct a CharUnits quantity of zero. 
-       static CharUnits Zero() { 
-         return CharUnits(0); 
-       } 
-   
-       /// One - Construct a CharUnits quantity of one. 
-       static CharUnits One() { 
-         return CharUnits(1); 
-       } 
-   
-       /// fromQuantity - Construct a CharUnits quantity from a raw integer type. 
-       static CharUnits fromQuantity(QuantityType Quantity) { 
-         return CharUnits(Quantity); 
-       } 
-   
-       /// fromQuantity - Construct a CharUnits quantity from an llvm::Align 
-       /// quantity. 
-       static CharUnits fromQuantity(llvm::Align Quantity) { 
-         return CharUnits(Quantity.value()); 
-       } 
-   
-       // Compound assignment. 
-       CharUnits& operator+= (const CharUnits &Other) { 
-         Quantity += Other.Quantity; 
-         return *this; 
-       } 
-       CharUnits& operator++ () { 
-         ++Quantity; 
-         return *this; 
-       } 
-       CharUnits operator++ (int) { 
-         return CharUnits(Quantity++); 
-       } 
-       CharUnits& operator-= (const CharUnits &Other) { 
-         Quantity -= Other.Quantity; 
-         return *this; 
-       } 
-       CharUnits& operator-- () { 
-         --Quantity; 
-         return *this; 
-       } 
-       CharUnits operator-- (int) { 
-         return CharUnits(Quantity--); 
-       } 
-   
-       // Comparison operators. 
-       bool operator== (const CharUnits &Other) const { 
-         return Quantity == Other.Quantity; 
-       } 
-       bool operator!= (const CharUnits &Other) const { 
-         return Quantity != Other.Quantity; 
-       } 
-   
-       // Relational operators. 
-       bool operator<  (const CharUnits &Other) const { 
-         return Quantity <  Other.Quantity; 
-       } 
-       bool operator<= (const CharUnits &Other) const { 
-         return Quantity <= Other.Quantity; 
-       } 
-       bool operator>  (const CharUnits &Other) const { 
-         return Quantity >  Other.Quantity; 
-       } 
-       bool operator>= (const CharUnits &Other) const { 
-         return Quantity >= Other.Quantity; 
-       } 
-   
-       // Other predicates. 
-   
-       /// isZero - Test whether the quantity equals zero. 
-       bool isZero() const     { return Quantity == 0; } 
-   
-       /// isOne - Test whether the quantity equals one. 
-       bool isOne() const      { return Quantity == 1; } 
-   
-       /// isPositive - Test whether the quantity is greater than zero. 
-       bool isPositive() const { return Quantity  > 0; } 
-   
-       /// isNegative - Test whether the quantity is less than zero. 
-       bool isNegative() const { return Quantity  < 0; } 
-   
-       /// isPowerOfTwo - Test whether the quantity is a power of two. 
-       /// Zero is not a power of two. 
-       bool isPowerOfTwo() const { 
-         return (Quantity & -Quantity) == Quantity; 
-       } 
-   
-       /// Test whether this is a multiple of the other value. 
-       /// 
-       /// Among other things, this promises that 
-       /// self.alignTo(N) will just return self. 
-       bool isMultipleOf(CharUnits N) const { 
-         return (*this % N) == 0; 
-       } 
-   
-       // Arithmetic operators. 
-       CharUnits operator* (QuantityType N) const { 
-         return CharUnits(Quantity * N); 
-       } 
-       CharUnits &operator*= (QuantityType N) { 
-         Quantity *= N; 
-         return *this; 
-       } 
-       CharUnits operator/ (QuantityType N) const { 
-         return CharUnits(Quantity / N); 
-       } 
-       CharUnits &operator/= (QuantityType N) { 
-         Quantity /= N; 
-         return *this; 
-       } 
-       QuantityType operator/ (const CharUnits &Other) const { 
-         return Quantity / Other.Quantity; 
-       } 
-       CharUnits operator% (QuantityType N) const { 
-         return CharUnits(Quantity % N); 
-       } 
-       QuantityType operator% (const CharUnits &Other) const { 
-         return Quantity % Other.Quantity; 
-       } 
-       CharUnits operator+ (const CharUnits &Other) const { 
-         return CharUnits(Quantity + Other.Quantity); 
-       } 
-       CharUnits operator- (const CharUnits &Other) const { 
-         return CharUnits(Quantity - Other.Quantity); 
-       } 
-       CharUnits operator- () const { 
-         return CharUnits(-Quantity); 
-       } 
-   
-   
-       // Conversions. 
-   
-       /// getQuantity - Get the raw integer representation of this quantity. 
-       QuantityType getQuantity() const { return Quantity; } 
-   
-       /// getAsAlign - Returns Quantity as a valid llvm::Align, 
-       /// Beware llvm::Align assumes power of two 8-bit bytes. 
-       llvm::Align getAsAlign() const { return llvm::Align(Quantity); } 
-   
-       /// getAsMaybeAlign - Returns Quantity as a valid llvm::Align or 
-       /// std::nullopt, Beware llvm::MaybeAlign assumes power of two 8-bit 
-       /// bytes. 
-       llvm::MaybeAlign getAsMaybeAlign() const { 
-         return llvm::MaybeAlign(Quantity); 
-       } 
-   
-       /// alignTo - Returns the next integer (mod 2**64) that is 
-       /// greater than or equal to this quantity and is a multiple of \p Align. 
-       /// Align must be non-zero. 
-       CharUnits alignTo(const CharUnits &Align) const { 
-         return CharUnits(llvm::alignTo(Quantity, Align.Quantity)); 
-       } 
-   
-       /// Given that this is a non-zero alignment value, what is the 
-       /// alignment at the given offset? 
-       CharUnits alignmentAtOffset(CharUnits offset) const { 
-         assert(Quantity != 0 && "offsetting from unknown alignment?"); 
-         return CharUnits(llvm::MinAlign(Quantity, offset.Quantity)); 
-       } 
-   
-       /// Given that this is the alignment of the first element of an 
-       /// array, return the minimum alignment of any element in the array. 
-       CharUnits alignmentOfArrayElement(CharUnits elementSize) const { 
-         // Since we don't track offsetted alignments, the alignment of 
-         // the second element (or any odd element) will be minimally 
-         // aligned. 
-         return alignmentAtOffset(elementSize); 
-       } 
-   
-   
-   }; // class CharUnit 
- } // namespace clang 
-   
- inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, 
-                                    const clang::CharUnits &CU) { 
-   return CU * Scale; 
- } 
-   
- namespace llvm { 
-   
- template<> struct DenseMapInfo<clang::CharUnits> { 
-   static clang::CharUnits getEmptyKey() { 
-     clang::CharUnits::QuantityType Quantity = 
-       DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey(); 
-   
-     return clang::CharUnits::fromQuantity(Quantity); 
-   } 
-   
-   static clang::CharUnits getTombstoneKey() { 
-     clang::CharUnits::QuantityType Quantity = 
-       DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey(); 
-   
-     return clang::CharUnits::fromQuantity(Quantity); 
-   } 
-   
-   static unsigned getHashValue(const clang::CharUnits &CU) { 
-     clang::CharUnits::QuantityType Quantity = CU.getQuantity(); 
-     return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity); 
-   } 
-   
-   static bool isEqual(const clang::CharUnits &LHS, 
-                       const clang::CharUnits &RHS) { 
-     return LHS == RHS; 
-   } 
- }; 
-   
- } // end namespace llvm 
-   
- #endif // LLVM_CLANG_AST_CHARUNITS_H 
-