clang API Documentation

CharUnits.h
Go to the documentation of this file.
00001 //===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines the CharUnits class
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_AST_CHARUNITS_H
00015 #define LLVM_CLANG_AST_CHARUNITS_H
00016 
00017 #include "llvm/ADT/DenseMapInfo.h"
00018 #include "llvm/Support/DataTypes.h"
00019 #include "llvm/Support/MathExtras.h"
00020 
00021 namespace clang {
00022 
00023   /// CharUnits - This is an opaque type for sizes expressed in character units.
00024   /// Instances of this type represent a quantity as a multiple of the size
00025   /// of the standard C type, char, on the target architecture. As an opaque
00026   /// type, CharUnits protects you from accidentally combining operations on
00027   /// quantities in bit units and character units.
00028   ///
00029   /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned
00030   /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to
00031   /// the same quantity of storage. However, we use the term 'character unit'
00032   /// rather than 'byte' to avoid an implication that a character unit is
00033   /// exactly 8 bits.
00034   ///
00035   /// For portability, never assume that a target character is 8 bits wide. Use
00036   /// CharUnit values wherever you calculate sizes, offsets, or alignments
00037   /// in character units.
00038   class CharUnits {
00039     public:
00040       typedef int64_t QuantityType;
00041 
00042     private:
00043       QuantityType Quantity;
00044 
00045       explicit CharUnits(QuantityType C) : Quantity(C) {}
00046 
00047     public:
00048 
00049       /// CharUnits - A default constructor.
00050       CharUnits() : Quantity(0) {}
00051 
00052       /// Zero - Construct a CharUnits quantity of zero.
00053       static CharUnits Zero() {
00054         return CharUnits(0);
00055       }
00056 
00057       /// One - Construct a CharUnits quantity of one.
00058       static CharUnits One() {
00059         return CharUnits(1);
00060       }
00061 
00062       /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
00063       static CharUnits fromQuantity(QuantityType Quantity) {
00064         return CharUnits(Quantity); 
00065       }
00066 
00067       // Compound assignment.
00068       CharUnits& operator+= (const CharUnits &Other) {
00069         Quantity += Other.Quantity;
00070         return *this;
00071       }
00072       CharUnits& operator++ () {
00073         ++Quantity;
00074         return *this;
00075       }
00076       CharUnits operator++ (int) {
00077         return CharUnits(Quantity++);
00078       }
00079       CharUnits& operator-= (const CharUnits &Other) {
00080         Quantity -= Other.Quantity;
00081         return *this;
00082       }
00083       CharUnits& operator-- () {
00084         --Quantity;
00085         return *this;
00086       }
00087       CharUnits operator-- (int) {
00088         return CharUnits(Quantity--);
00089       }
00090        
00091       // Comparison operators.
00092       bool operator== (const CharUnits &Other) const {
00093         return Quantity == Other.Quantity;
00094       }
00095       bool operator!= (const CharUnits &Other) const {
00096         return Quantity != Other.Quantity;
00097       }
00098 
00099       // Relational operators.
00100       bool operator<  (const CharUnits &Other) const { 
00101         return Quantity <  Other.Quantity; 
00102       }
00103       bool operator<= (const CharUnits &Other) const { 
00104         return Quantity <= Other.Quantity;
00105       }
00106       bool operator>  (const CharUnits &Other) const { 
00107         return Quantity >  Other.Quantity; 
00108       }
00109       bool operator>= (const CharUnits &Other) const { 
00110         return Quantity >= Other.Quantity; 
00111       }
00112 
00113       // Other predicates.
00114       
00115       /// isZero - Test whether the quantity equals zero.
00116       bool isZero() const     { return Quantity == 0; }
00117 
00118       /// isOne - Test whether the quantity equals one.
00119       bool isOne() const      { return Quantity == 1; }
00120 
00121       /// isPositive - Test whether the quantity is greater than zero.
00122       bool isPositive() const { return Quantity  > 0; }
00123 
00124       /// isNegative - Test whether the quantity is less than zero.
00125       bool isNegative() const { return Quantity  < 0; }
00126 
00127       /// isPowerOfTwo - Test whether the quantity is a power of two.
00128       /// Zero is not a power of two.
00129       bool isPowerOfTwo() const {
00130         return (Quantity & -Quantity) == Quantity;
00131       }
00132 
00133       // Arithmetic operators.
00134       CharUnits operator* (QuantityType N) const {
00135         return CharUnits(Quantity * N);
00136       }
00137       CharUnits operator/ (QuantityType N) const {
00138         return CharUnits(Quantity / N);
00139       }
00140       QuantityType operator/ (const CharUnits &Other) const {
00141         return Quantity / Other.Quantity;
00142       }
00143       CharUnits operator% (QuantityType N) const {
00144         return CharUnits(Quantity % N);
00145       }
00146       QuantityType operator% (const CharUnits &Other) const {
00147         return Quantity % Other.Quantity;
00148       }
00149       CharUnits operator+ (const CharUnits &Other) const {
00150         return CharUnits(Quantity + Other.Quantity);
00151       }
00152       CharUnits operator- (const CharUnits &Other) const {
00153         return CharUnits(Quantity - Other.Quantity);
00154       }
00155       CharUnits operator- () const {
00156         return CharUnits(-Quantity);
00157       }
00158 
00159       
00160       // Conversions.
00161 
00162       /// getQuantity - Get the raw integer representation of this quantity.
00163       QuantityType getQuantity() const { return Quantity; }
00164 
00165       /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
00166       /// greater than or equal to this quantity and is a multiple of \p Align.
00167       /// Align must be non-zero.
00168       CharUnits RoundUpToAlignment(const CharUnits &Align) const {
00169         return CharUnits(llvm::RoundUpToAlignment(Quantity, 
00170                                                   Align.Quantity));
00171       }
00172 
00173       /// Given that this is a non-zero alignment value, what is the
00174       /// alignment at the given offset?
00175       CharUnits alignmentAtOffset(CharUnits offset) {
00176         return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
00177       }
00178 
00179 
00180   }; // class CharUnit
00181 } // namespace clang
00182 
00183 inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, 
00184                                    const clang::CharUnits &CU) {
00185   return CU * Scale;
00186 }
00187 
00188 namespace llvm {
00189 
00190 template<> struct DenseMapInfo<clang::CharUnits> {
00191   static clang::CharUnits getEmptyKey() {
00192     clang::CharUnits::QuantityType Quantity =
00193       DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
00194 
00195     return clang::CharUnits::fromQuantity(Quantity);
00196   }
00197 
00198   static clang::CharUnits getTombstoneKey() {
00199     clang::CharUnits::QuantityType Quantity =
00200       DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
00201     
00202     return clang::CharUnits::fromQuantity(Quantity);    
00203   }
00204 
00205   static unsigned getHashValue(const clang::CharUnits &CU) {
00206     clang::CharUnits::QuantityType Quantity = CU.getQuantity();
00207     return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
00208   }
00209 
00210   static bool isEqual(const clang::CharUnits &LHS, 
00211                       const clang::CharUnits &RHS) {
00212     return LHS == RHS;
00213   }
00214 };
00215 
00216 template <> struct isPodLike<clang::CharUnits> {
00217   static const bool value = true;
00218 };
00219   
00220 } // end namespace llvm
00221 
00222 #endif // LLVM_CLANG_AST_CHARUNITS_H