00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 #ifndef LLVM_ADT_TWINE_H
00011 #define LLVM_ADT_TWINE_H
00012 
00013 #include "llvm/ADT/StringRef.h"
00014 #include "llvm/Support/DataTypes.h"
00015 #include <cassert>
00016 #include <string>
00017 #include <iostream>
00018 
00019 namespace llvm {
00020   template <typename T>
00021   class SmallVectorImpl;
00022   class StringRef;
00023 
00080   class Twine {
00082     enum NodeKind {
00085       NullKind,
00086 
00088       EmptyKind,
00089 
00091       TwineKind,
00092 
00094       CStringKind,
00095 
00097       StdStringKind,
00098 
00100       StringRefKind,
00101 
00103       CharKind,
00104 
00107       DecUIKind,
00108 
00111       DecIKind,
00112 
00115       DecULKind,
00116 
00118       DecLKind,
00119 
00122       DecULLKind,
00123 
00125       DecLLKind,
00126 
00129       UHexKind
00130     };
00131 
00132     union Child
00133     {
00134       const Twine *twine;
00135       const char *cString;
00136       const std::string *stdString;
00137       const StringRef *stringRef;
00138       char character;
00139       unsigned int decUI;
00140       int decI;
00141       const unsigned long *decUL;
00142       const long *decL;
00143       const unsigned long long *decULL;
00144       const long long *decLL;
00145       const uint64_t *uHex;
00146     };
00147 
00148   private:
00151     Child LHS;
00154     Child RHS;
00155     
00156     
00158     unsigned char LHSKind;
00160     unsigned char RHSKind;
00161 
00162   private:
00164     explicit Twine(NodeKind Kind)
00165       : LHSKind(Kind), RHSKind(EmptyKind) {
00166       assert(isNullary() && "Invalid kind!");
00167     }
00168 
00170     explicit Twine(const Twine &_LHS, const Twine &_RHS)
00171       : LHSKind(TwineKind), RHSKind(TwineKind) {
00172       LHS.twine = &_LHS;
00173       RHS.twine = &_RHS;
00174       assert(isValid() && "Invalid twine!");
00175     }
00176 
00178     explicit Twine(Child _LHS, NodeKind _LHSKind,
00179                    Child _RHS, NodeKind _RHSKind)
00180       : LHS(_LHS), RHS(_RHS), LHSKind(_LHSKind), RHSKind(_RHSKind) {
00181       assert(isValid() && "Invalid twine!");
00182     }
00183 
00185     bool isNull() const {
00186       return getLHSKind() == NullKind;
00187     }
00188 
00190     bool isEmpty() const {
00191       return getLHSKind() == EmptyKind;
00192     }
00193 
00195     bool isNullary() const {
00196       return isNull() || isEmpty();
00197     }
00198 
00200     bool isUnary() const {
00201       return getRHSKind() == EmptyKind && !isNullary();
00202     }
00203 
00205     bool isBinary() const {
00206       return getLHSKind() != NullKind && getRHSKind() != EmptyKind;
00207     }
00208 
00211     bool isValid() const {
00212       
00213       if (isNullary() && getRHSKind() != EmptyKind)
00214         return false;
00215 
00216       
00217       if (getRHSKind() == NullKind)
00218         return false;
00219 
00220       
00221       if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind)
00222         return false;
00223 
00224       
00225       if (getLHSKind() == TwineKind &&
00226           !LHS.twine->isBinary())
00227         return false;
00228       if (getRHSKind() == TwineKind &&
00229           !RHS.twine->isBinary())
00230         return false;
00231 
00232       return true;
00233     }
00234 
00236     NodeKind getLHSKind() const { return (NodeKind) LHSKind; }
00237 
00239     NodeKind getRHSKind() const { return (NodeKind) RHSKind; }
00240 
00242     void printOneChild(std::ostream &OS, Child Ptr, NodeKind Kind) const;
00243 
00245     void printOneChildRepr(std::ostream &OS, Child Ptr,
00246                            NodeKind Kind) const;
00247 
00248   public:
00251 
00253      Twine() : LHSKind(EmptyKind), RHSKind(EmptyKind) {
00254       assert(isValid() && "Invalid twine!");
00255     }
00256 
00262      Twine(const char *Str)
00263       : RHSKind(EmptyKind) {
00264       if (Str[0] != '\0') {
00265         LHS.cString = Str;
00266         LHSKind = CStringKind;
00267       } else
00268         LHSKind = EmptyKind;
00269 
00270       assert(isValid() && "Invalid twine!");
00271     }
00272 
00274      Twine(const std::string &Str)
00275       : LHSKind(StdStringKind), RHSKind(EmptyKind) {
00276       LHS.stdString = &Str;
00277       assert(isValid() && "Invalid twine!");
00278     }
00279 
00281      Twine(const StringRef &Str)
00282       : LHSKind(StringRefKind), RHSKind(EmptyKind) {
00283       LHS.stringRef = &Str;
00284       assert(isValid() && "Invalid twine!");
00285     }
00286 
00288     explicit Twine(char Val)
00289       : LHSKind(CharKind), RHSKind(EmptyKind) {
00290       LHS.character = Val;
00291     }
00292 
00294     explicit Twine(signed char Val)
00295       : LHSKind(CharKind), RHSKind(EmptyKind) {
00296       LHS.character = static_cast<char>(Val);
00297     }
00298 
00300     explicit Twine(unsigned char Val)
00301       : LHSKind(CharKind), RHSKind(EmptyKind) {
00302       LHS.character = static_cast<char>(Val);
00303     }
00304 
00306     explicit Twine(unsigned Val)
00307       : LHSKind(DecUIKind), RHSKind(EmptyKind) {
00308       LHS.decUI = Val;
00309     }
00310 
00312     explicit Twine(int Val)
00313       : LHSKind(DecIKind), RHSKind(EmptyKind) {
00314       LHS.decI = Val;
00315     }
00316 
00318     explicit Twine(const unsigned long &Val)
00319       : LHSKind(DecULKind), RHSKind(EmptyKind) {
00320       LHS.decUL = &Val;
00321     }
00322 
00324     explicit Twine(const long &Val)
00325       : LHSKind(DecLKind), RHSKind(EmptyKind) {
00326       LHS.decL = &Val;
00327     }
00328 
00330     explicit Twine(const unsigned long long &Val)
00331       : LHSKind(DecULLKind), RHSKind(EmptyKind) {
00332       LHS.decULL = &Val;
00333     }
00334 
00336     explicit Twine(const long long &Val)
00337       : LHSKind(DecLLKind), RHSKind(EmptyKind) {
00338       LHS.decLL = &Val;
00339     }
00340 
00341     
00342     
00343     
00344     
00345 
00347      Twine(const char *_LHS, const StringRef &_RHS)
00348       : LHSKind(CStringKind), RHSKind(StringRefKind) {
00349       LHS.cString = _LHS;
00350       RHS.stringRef = &_RHS;
00351       assert(isValid() && "Invalid twine!");
00352     }
00353 
00355      Twine(const StringRef &_LHS, const char *_RHS)
00356       : LHSKind(StringRefKind), RHSKind(CStringKind) {
00357       LHS.stringRef = &_LHS;
00358       RHS.cString = _RHS;
00359       assert(isValid() && "Invalid twine!");
00360     }
00361 
00364     static Twine createNull() {
00365       return Twine(NullKind);
00366     }
00367 
00371 
00372     
00373     static Twine utohexstr(const uint64_t &Val) {
00374       Child LHS, RHS;
00375       LHS.uHex = &Val;
00376       RHS.twine = 0;
00377       return Twine(LHS, UHexKind, RHS, EmptyKind);
00378     }
00379 
00383 
00386     bool isTriviallyEmpty() const {
00387       return isNullary();
00388     }
00389 
00392     bool isSingleStringRef() const {
00393       if (getRHSKind() != EmptyKind) return false;
00394 
00395       switch (getLHSKind()) {
00396       case EmptyKind:
00397       case CStringKind:
00398       case StdStringKind:
00399       case StringRefKind:
00400         return true;
00401       default:
00402         return false;
00403       }
00404     }
00405 
00409 
00410     Twine concat(const Twine &Suffix) const;
00411 
00415 
00417     std::string str() const;
00418 
00421     void toVector(SmallVectorImpl<char> &Out) const;
00422 
00425     StringRef getSingleStringRef() const {
00426       assert(isSingleStringRef() &&"This cannot be had as a single stringref!");
00427       switch (getLHSKind()) {
00428       default: assert(0 && "Out of sync with isSingleStringRef");
00429       case EmptyKind:      return StringRef();
00430       case CStringKind:    return StringRef(LHS.cString);
00431       case StdStringKind:  return StringRef(*LHS.stdString);
00432       case StringRefKind:  return *LHS.stringRef;
00433       }
00434     }
00435 
00439     StringRef toStringRef(SmallVectorImpl<char> &Out) const;
00440 
00447     StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
00448 
00451     void print(std::ostream &OS) const;
00452 
00454     void dump() const;
00455 
00457     void printRepr(std::ostream &OS) const;
00458 
00460     void dumpRepr() const;
00461 
00463   };
00464 
00467 
00468   inline Twine Twine::concat(const Twine &Suffix) const {
00469     
00470     if (isNull() || Suffix.isNull())
00471       return Twine(NullKind);
00472 
00473     
00474     if (isEmpty())
00475       return Suffix;
00476     if (Suffix.isEmpty())
00477       return *this;
00478 
00479     
00480     
00481     Child NewLHS, NewRHS;
00482     NewLHS.twine = this;
00483     NewRHS.twine = &Suffix;
00484     NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
00485     if (isUnary()) {
00486       NewLHS = LHS;
00487       NewLHSKind = getLHSKind();
00488     }
00489     if (Suffix.isUnary()) {
00490       NewRHS = Suffix.LHS;
00491       NewRHSKind = Suffix.getLHSKind();
00492     }
00493 
00494     return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind);
00495   }
00496 
00497   inline Twine operator+(const Twine &LHS, const Twine &RHS) {
00498     return LHS.concat(RHS);
00499   }
00500 
00503 
00504   inline Twine operator+(const char *LHS, const StringRef &RHS) {
00505     return Twine(LHS, RHS);
00506   }
00507 
00510 
00511   inline Twine operator+(const StringRef &LHS, const char *RHS) {
00512     return Twine(LHS, RHS);
00513   }
00514 
00515 inline std::ostream &operator<<(std::ostream &OS, const Twine &RHS) {
00516     RHS.print(OS);
00517     return OS;
00518   }
00519 
00521 }
00522 
00523 #endif