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   /// It should be noted that characters and bytes are distinct concepts. Bytes
00030   /// refer to addressable units of data storage on the target machine, and
00031   /// characters are members of a set of elements used for the organization,
00032   /// control, or representation of data. According to C99, bytes are allowed
00033   /// to exceed characters in size, although currently, clang only supports
00034   /// architectures where the two are the same size.
00035   /// 
00036   /// For portability, never assume that a target character is 8 bits wide. Use 
00037   /// CharUnit values wherever you calculate sizes, offsets, or alignments
00038   /// in character units.
00039   class CharUnits {
00040     public:
00041       typedef int64_t QuantityType;
00042 
00043     private:
00044       QuantityType Quantity;
00045 
00046       explicit CharUnits(QuantityType C) : Quantity(C) {}
00047 
00048     public:
00049 
00050       /// CharUnits - A default constructor.
00051       CharUnits() : Quantity(0) {}
00052 
00053       /// Zero - Construct a CharUnits quantity of zero.
00054       static CharUnits Zero() {
00055         return CharUnits(0);
00056       }
00057 
00058       /// One - Construct a CharUnits quantity of one.
00059       static CharUnits One() {
00060         return CharUnits(1);
00061       }
00062 
00063       /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
00064       static CharUnits fromQuantity(QuantityType Quantity) {
00065         return CharUnits(Quantity); 
00066       }
00067 
00068       // Compound assignment.
00069       CharUnits& operator+= (const CharUnits &Other) {
00070         Quantity += Other.Quantity;
00071         return *this;
00072       }
00073       CharUnits& operator++ () {
00074         ++Quantity;
00075         return *this;
00076       }
00077       CharUnits operator++ (int) {
00078         return CharUnits(Quantity++);
00079       }
00080       CharUnits& operator-= (const CharUnits &Other) {
00081         Quantity -= Other.Quantity;
00082         return *this;
00083       }
00084       CharUnits& operator-- () {
00085         --Quantity;
00086         return *this;
00087       }
00088       CharUnits operator-- (int) {
00089         return CharUnits(Quantity--);
00090       }
00091        
00092       // Comparison operators.
00093       bool operator== (const CharUnits &Other) const {
00094         return Quantity == Other.Quantity;
00095       }
00096       bool operator!= (const CharUnits &Other) const {
00097         return Quantity != Other.Quantity;
00098       }
00099 
00100       // Relational operators.
00101       bool operator<  (const CharUnits &Other) const { 
00102         return Quantity <  Other.Quantity; 
00103       }
00104       bool operator<= (const CharUnits &Other) const { 
00105         return Quantity <= Other.Quantity;
00106       }
00107       bool operator>  (const CharUnits &Other) const { 
00108         return Quantity >  Other.Quantity; 
00109       }
00110       bool operator>= (const CharUnits &Other) const { 
00111         return Quantity >= Other.Quantity; 
00112       }
00113 
00114       // Other predicates.
00115       
00116       /// isZero - Test whether the quantity equals zero.
00117       bool isZero() const     { return Quantity == 0; }
00118 
00119       /// isOne - Test whether the quantity equals one.
00120       bool isOne() const      { return Quantity == 1; }
00121 
00122       /// isPositive - Test whether the quantity is greater than zero.
00123       bool isPositive() const { return Quantity  > 0; }
00124 
00125       /// isNegative - Test whether the quantity is less than zero.
00126       bool isNegative() const { return Quantity  < 0; }
00127 
00128       /// isPowerOfTwo - Test whether the quantity is a power of two.
00129       /// Zero is not a power of two.
00130       bool isPowerOfTwo() const {
00131         return (Quantity & -Quantity) == Quantity;
00132       }
00133 
00134       // Arithmetic operators.
00135       CharUnits operator* (QuantityType N) const {
00136         return CharUnits(Quantity * N);
00137       }
00138       CharUnits operator/ (QuantityType N) const {
00139         return CharUnits(Quantity / N);
00140       }
00141       QuantityType operator/ (const CharUnits &Other) const {
00142         return Quantity / Other.Quantity;
00143       }
00144       CharUnits operator% (QuantityType N) const {
00145         return CharUnits(Quantity % N);
00146       }
00147       QuantityType operator% (const CharUnits &Other) const {
00148         return Quantity % Other.Quantity;
00149       }
00150       CharUnits operator+ (const CharUnits &Other) const {
00151         return CharUnits(Quantity + Other.Quantity);
00152       }
00153       CharUnits operator- (const CharUnits &Other) const {
00154         return CharUnits(Quantity - Other.Quantity);
00155       }
00156       CharUnits operator- () const {
00157         return CharUnits(-Quantity);
00158       }
00159 
00160       
00161       // Conversions.
00162 
00163       /// getQuantity - Get the raw integer representation of this quantity.
00164       QuantityType getQuantity() const { return Quantity; }
00165 
00166       /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
00167       /// greater than or equal to this quantity and is a multiple of \arg
00168       /// Align. Align must be non-zero.
00169       CharUnits RoundUpToAlignment(const CharUnits &Align) {
00170         return CharUnits(llvm::RoundUpToAlignment(Quantity, 
00171                                                   Align.Quantity));
00172       }
00173 
00174 
00175   }; // class CharUnit
00176 } // namespace clang
00177 
00178 inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, 
00179                                    const clang::CharUnits &CU) {
00180   return CU * Scale;
00181 }
00182 
00183 namespace llvm {
00184 
00185 template<> struct DenseMapInfo<clang::CharUnits> {
00186   static clang::CharUnits getEmptyKey() {
00187     clang::CharUnits::QuantityType Quantity =
00188       DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
00189 
00190     return clang::CharUnits::fromQuantity(Quantity);
00191   }
00192 
00193   static clang::CharUnits getTombstoneKey() {
00194     clang::CharUnits::QuantityType Quantity =
00195       DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
00196     
00197     return clang::CharUnits::fromQuantity(Quantity);    
00198   }
00199 
00200   static unsigned getHashValue(const clang::CharUnits &CU) {
00201     clang::CharUnits::QuantityType Quantity = CU.getQuantity();
00202     return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
00203   }
00204 
00205   static bool isEqual(const clang::CharUnits &LHS, 
00206                       const clang::CharUnits &RHS) {
00207     return LHS == RHS;
00208   }
00209 };
00210 
00211 template <> struct isPodLike<clang::CharUnits> {
00212   static const bool value = true;
00213 };
00214   
00215 } // end namespace llvm
00216 
00217 #endif // LLVM_CLANG_AST_CHARUNITS_H