ROOT logo
// @(#)root/base:$Id: TString.h 40340 2011-07-23 16:57:07Z rdm $
// Author: Fons Rademakers   04/08/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TString
#define ROOT_TString


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TString                                                              //
//                                                                      //
// Basic string class.                                                  //
//                                                                      //
// Cannot be stored in a TCollection... use TObjString instead.         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef __CINT__
#include <string.h>
#include <stdio.h>
#endif

#ifndef ROOT_Riosfwd
#include "Riosfwd.h"
#endif

#ifndef ROOT_TMathBase
#include "TMathBase.h"
#endif

#include <stdarg.h>
#include <string>

#ifdef R__GLOBALSTL
namespace std { using ::string; }
#endif

class TRegexp;
class TPRegexp;
class TString;
class TSubString;
class TObjArray;
class TVirtualMutex;

R__EXTERN TVirtualMutex *gStringMutex;

TString operator+(const TString &s1, const TString &s2);
TString operator+(const TString &s,  const char *cs);
TString operator+(const char *cs, const TString &s);
TString operator+(const TString &s, char c);
TString operator+(const TString &s, Long_t i);
TString operator+(const TString &s, ULong_t i);
TString operator+(const TString &s, Long64_t i);
TString operator+(const TString &s, ULong64_t i);
TString operator+(char c, const TString &s);
TString operator+(Long_t i, const TString &s);
TString operator+(ULong_t i, const TString &s);
TString operator+(Long64_t i, const TString &s);
TString operator+(ULong64_t i, const TString &s);
Bool_t  operator==(const TString &s1, const TString &s2);
Bool_t  operator==(const TString &s1, const char *s2);
Bool_t  operator==(const TSubString &s1, const TSubString &s2);
Bool_t  operator==(const TSubString &s1, const TString &s2);
Bool_t  operator==(const TSubString &s1, const char *s2);


//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TSubString                                                          //
//                                                                      //
//  The TSubString class allows selected elements to be addressed.      //
//  There are no public constructors.                                   //
//                                                                      //
//////////////////////////////////////////////////////////////////////////
class TSubString {

friend class TStringLong;
friend class TString;

friend Bool_t operator==(const TSubString &s1, const TSubString &s2);
friend Bool_t operator==(const TSubString &s1, const TString &s2);
friend Bool_t operator==(const TSubString &s1, const char *s2);

private:
   TString      &fStr;           // Referenced string
   Ssiz_t        fBegin;         // Index of starting character
   Ssiz_t        fExtent;        // Length of TSubString

   // NB: the only constructor is private
   TSubString(const TString &s, Ssiz_t start, Ssiz_t len);

protected:
   void          SubStringError(Ssiz_t, Ssiz_t, Ssiz_t) const;
   void          AssertElement(Ssiz_t i) const;  // Verifies i is valid index

public:
   TSubString(const TSubString &s)
     : fStr(s.fStr), fBegin(s.fBegin), fExtent(s.fExtent) { }

   TSubString   &operator=(const char *s);       // Assignment from a char*
   TSubString   &operator=(const TString &s);    // Assignment from a TString
   TSubString   &operator=(const TSubString &s); // Assignment from a TSubString
   char         &operator()(Ssiz_t i);           // Index with optional bounds checking
   char         &operator[](Ssiz_t i);           // Index with bounds checking
   char          operator()(Ssiz_t i) const;     // Index with optional bounds checking
   char          operator[](Ssiz_t i) const;     // Index with bounds checking

   const char   *Data() const;
   Ssiz_t        Length() const          { return fExtent; }
   Ssiz_t        Start() const           { return fBegin; }
   TString&      String()                { return fStr; }
   void          ToLower();              // Convert self to lower-case
   void          ToUpper();              // Convert self to upper-case

   // For detecting null substrings
   Bool_t        IsNull() const          { return fBegin == kNPOS; }
   int           operator!() const       { return fBegin == kNPOS; }
};


//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TString                                                             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////
class TString {

friend class TStringLong;
friend class TSubString;

friend TString operator+(const TString &s1, const TString &s2);
friend TString operator+(const TString &s,  const char *cs);
friend TString operator+(const char *cs, const TString &s);
friend TString operator+(const TString &s, char c);
friend TString operator+(const TString &s, Long_t i);
friend TString operator+(const TString &s, ULong_t i);
friend TString operator+(const TString &s, Long64_t i);
friend TString operator+(const TString &s, ULong64_t i);
friend TString operator+(char c, const TString &s);
friend TString operator+(Long_t i, const TString &s);
friend TString operator+(ULong_t i, const TString &s);
friend TString operator+(Long64_t i, const TString &s);
friend TString operator+(ULong64_t i, const TString &s);
friend Bool_t  operator==(const TString &s1, const TString &s2);
friend Bool_t  operator==(const TString &s1, const char *s2);

private:
#ifdef R__BYTESWAP
   enum { kShortMask = 0x01, kLongMask  = 0x1 };
#else
   enum { kShortMask = 0x80, kLongMask  = 0x80000000 };
#endif

   struct LongStr_t
   {
      Ssiz_t    fCap;    // Max string length (including null)
      Ssiz_t    fSize;   // String length (excluding null)
      char     *fData;   // Long string data
   };

   enum { kMinCap = (sizeof(LongStr_t) - 1)/sizeof(char) > 2 ?
                    (sizeof(LongStr_t) - 1)/sizeof(char) : 2 };
   
   struct ShortStr_t
   {
      unsigned char fSize;           // String length (excluding null)
      char          fData[kMinCap];  // Short string data
   };
   
   union UStr_t { LongStr_t fL; ShortStr_t fS; };
   
   enum { kNwords = sizeof(UStr_t) / sizeof(Ssiz_t)};
   
   struct RawStr_t
   {
      Ssiz_t fWords[kNwords];
   };
   
   struct Rep_t
   {
      union
      {
         LongStr_t  fLong;
         ShortStr_t fShort;
         RawStr_t   fRaw;
      };
   };

protected:   
#ifndef __CINT__
   Rep_t          fRep;           // String data
#endif

   // Special concatenation constructor
   TString(const char *a1, Ssiz_t n1, const char *a2, Ssiz_t n2);
   void           AssertElement(Ssiz_t nc) const; // Index in range
   void           Clobber(Ssiz_t nc);             // Remove old contents
   void           InitChar(char c);               // Initialize from char

   enum { kAlignment = 16 };
   static Ssiz_t  Align(Ssiz_t s) { return (s + (kAlignment-1)) & ~(kAlignment-1); }
   static Ssiz_t  Recommend(Ssiz_t s) { return (s < kMinCap ? kMinCap : Align(s+1)) - 1; }
   static Ssiz_t  AdjustCapacity(Ssiz_t oldCap, Ssiz_t newCap);
   
private:
   Bool_t         IsLong() const { return Bool_t(fRep.fShort.fSize & kShortMask); }
#ifdef R__BYTESWAP
   void           SetShortSize(Ssiz_t s) { fRep.fShort.fSize = (unsigned char)(s << 1); }
   Ssiz_t         GetShortSize() const { return fRep.fShort.fSize >> 1; }
#else
   void           SetShortSize(Ssiz_t s) { fRep.fShort.fSize = (unsigned char)s; }
   Ssiz_t         GetShortSize() const { return fRep.fShort.fSize; }
#endif
   void           SetLongSize(Ssiz_t s) { fRep.fLong.fSize = s; }
   Ssiz_t         GetLongSize() const { return fRep.fLong.fSize; }
   void           SetSize(Ssiz_t s) { IsLong() ? SetLongSize(s) : SetShortSize(s); }
   void           SetLongCap(Ssiz_t s) { fRep.fLong.fCap = kLongMask | s; }
   Ssiz_t         GetLongCap() const { return fRep.fLong.fCap & ~kLongMask; }
   void           SetLongPointer(char *p) { fRep.fLong.fData = p; }
   char          *GetLongPointer() { return fRep.fLong.fData; }
   const char    *GetLongPointer() const { return fRep.fLong.fData; }
   char          *GetShortPointer() { return fRep.fShort.fData; }
   const char    *GetShortPointer() const { return fRep.fShort.fData; }
   char          *GetPointer() { return IsLong() ? GetLongPointer() : GetShortPointer(); }
   const char    *GetPointer() const { return IsLong() ? GetLongPointer() : GetShortPointer(); }
#ifdef R__BYTESWAP
   static Ssiz_t  MaxSize() { return kMaxInt - 1; }
#else
   static Ssiz_t  MaxSize() { return (kMaxInt >> 1) - 1; }
#endif
   void           UnLink() const { if (IsLong()) delete [] fRep.fLong.fData; }
   void           Zero() {
      Ssiz_t (&a)[kNwords] = fRep.fRaw.fWords;
      for (UInt_t i = 0; i < kNwords; ++i)
         a[i] = 0;
   }
   char          *Init(Ssiz_t capacity, Ssiz_t nchar);
   void           Clone(Ssiz_t nc); // Make self a distinct copy w. capacity nc
   void           FormImp(const char *fmt, va_list ap);
   UInt_t         HashCase() const;
   UInt_t         HashFoldCase() const;

public:
   enum EStripType   { kLeading = 0x1, kTrailing = 0x2, kBoth = 0x3 };
   enum ECaseCompare { kExact, kIgnoreCase };

   TString();                           // Null string
   explicit TString(Ssiz_t ic);         // Suggested capacity
   TString(const TString &s);           // Copy constructor
   TString(const char *s);              // Copy to embedded null
   TString(const char *s, Ssiz_t n);    // Copy past any embedded nulls
   TString(const std::string &s);
   TString(char c);
   TString(char c, Ssiz_t s);
   TString(const TSubString &sub);

   virtual ~TString();

   // ROOT I/O interface
   virtual void     FillBuffer(char *&buffer);
   virtual void     ReadBuffer(char *&buffer);
   virtual Int_t    Sizeof() const;

   static TString  *ReadString(TBuffer &b, const TClass *clReq);
   static void      WriteString(TBuffer &b, const TString *a);

   friend TBuffer &operator<<(TBuffer &b, const TString *obj);

   // C I/O interface
   Bool_t   Gets(FILE *fp, Bool_t chop=kTRUE);
   void     Puts(FILE *fp);

   // Type conversion
   operator const char*() const { return GetPointer(); }

   // Assignment
   TString    &operator=(char s);                // Replace string
   TString    &operator=(const char *s);
   TString    &operator=(const TString &s);
   TString    &operator=(const std::string &s);
   TString    &operator=(const TSubString &s);
   TString    &operator+=(const char *s);        // Append string
   TString    &operator+=(const TString &s);
   TString    &operator+=(char c);
   TString    &operator+=(Short_t i);
   TString    &operator+=(UShort_t i);
   TString    &operator+=(Int_t i);
   TString    &operator+=(UInt_t i);
   TString    &operator+=(Long_t i);
   TString    &operator+=(ULong_t i);
   TString    &operator+=(Float_t f);
   TString    &operator+=(Double_t f);
   TString    &operator+=(Long64_t i);
   TString    &operator+=(ULong64_t i);

   // Indexing operators
   char         &operator[](Ssiz_t i);         // Indexing with bounds checking
   char         &operator()(Ssiz_t i);         // Indexing with optional bounds checking
   char          operator[](Ssiz_t i) const;
   char          operator()(Ssiz_t i) const;
   TSubString    operator()(Ssiz_t start, Ssiz_t len) const;   // Sub-string operator
   TSubString    operator()(const TRegexp &re) const;          // Match the RE
   TSubString    operator()(const TRegexp &re, Ssiz_t start) const;
   TSubString    operator()(TPRegexp &re) const;               // Match the Perl compatible Regular Expression
   TSubString    operator()(TPRegexp &re, Ssiz_t start) const;
   TSubString    SubString(const char *pat, Ssiz_t start = 0,
                           ECaseCompare cmp = kExact) const;

   // Non-static member functions
   TString     &Append(const char *cs);
   TString     &Append(const char *cs, Ssiz_t n);
   TString     &Append(const TString &s);
   TString     &Append(const TString &s, Ssiz_t n);
   TString     &Append(char c, Ssiz_t rep = 1);   // Append c rep times
   Int_t        Atoi() const;
   Long64_t     Atoll() const;
   Double_t     Atof() const;
   Bool_t       BeginsWith(const char *s,      ECaseCompare cmp = kExact) const;
   Bool_t       BeginsWith(const TString &pat, ECaseCompare cmp = kExact) const;
   Ssiz_t       Capacity() const { return (IsLong() ? GetLongCap() : kMinCap) - 1; }
   Ssiz_t       Capacity(Ssiz_t n);
   TString     &Chop();
   void         Clear();
   int          CompareTo(const char *cs,    ECaseCompare cmp = kExact) const;
   int          CompareTo(const TString &st, ECaseCompare cmp = kExact) const;
   Bool_t       Contains(const char *pat,    ECaseCompare cmp = kExact) const;
   Bool_t       Contains(const TString &pat, ECaseCompare cmp = kExact) const;
   Bool_t       Contains(const TRegexp &pat) const;
   Bool_t       Contains(TPRegexp &pat) const;
   Int_t        CountChar(Int_t c) const;
   TString      Copy() const;
   const char  *Data() const { return GetPointer(); }
   Bool_t       EndsWith(const char *pat, ECaseCompare cmp = kExact) const;
   Bool_t       EqualTo(const char *cs,    ECaseCompare cmp = kExact) const;
   Bool_t       EqualTo(const TString &st, ECaseCompare cmp = kExact) const;
   Ssiz_t       First(char c) const;
   Ssiz_t       First(const char *cs) const;
   void         Form(const char *fmt, ...)
#if defined(__GNUC__) && !defined(__CINT__)
   __attribute__((format(printf, 2, 3)))   /* 1 is the this pointer */
#endif
   ;
   UInt_t       Hash(ECaseCompare cmp = kExact) const;
   Ssiz_t       Index(const char *pat, Ssiz_t i = 0,
                      ECaseCompare cmp = kExact) const;
   Ssiz_t       Index(const TString &s, Ssiz_t i = 0,
                      ECaseCompare cmp = kExact) const;
   Ssiz_t       Index(const char *pat, Ssiz_t patlen, Ssiz_t i,
                      ECaseCompare cmp) const;
   Ssiz_t       Index(const TString &s, Ssiz_t patlen, Ssiz_t i,
                      ECaseCompare cmp) const;
   Ssiz_t       Index(const TRegexp &pat, Ssiz_t i = 0) const;
   Ssiz_t       Index(const TRegexp &pat, Ssiz_t *ext, Ssiz_t i = 0) const;
   Ssiz_t       Index(TPRegexp &pat, Ssiz_t i = 0) const;
   Ssiz_t       Index(TPRegexp &pat, Ssiz_t *ext, Ssiz_t i = 0) const;
   TString     &Insert(Ssiz_t pos, const char *s);
   TString     &Insert(Ssiz_t pos, const char *s, Ssiz_t extent);
   TString     &Insert(Ssiz_t pos, const TString &s);
   TString     &Insert(Ssiz_t pos, const TString &s, Ssiz_t extent);
   Bool_t       IsAscii() const;
   Bool_t       IsAlpha() const;
   Bool_t       IsAlnum() const;
   Bool_t       IsDigit() const;
   Bool_t       IsFloat() const;
   Bool_t       IsHex() const;
   Bool_t       IsNull() const         { return Length() == 0; }
   Bool_t       IsWhitespace() const   { return (Length() == CountChar(' ')); }
   Ssiz_t       Last(char c) const;
   Ssiz_t       Length() const         { return IsLong() ? GetLongSize() : GetShortSize(); }
   Bool_t       MaybeRegexp() const;
   Bool_t       MaybeWildcard() const;
   TString     &Prepend(const char *cs);     // Prepend a character string
   TString     &Prepend(const char *cs, Ssiz_t n);
   TString     &Prepend(const TString &s);
   TString     &Prepend(const TString &s, Ssiz_t n);
   TString     &Prepend(char c, Ssiz_t rep = 1);  // Prepend c rep times
   istream     &ReadFile(istream &str);      // Read to EOF or null character
   istream     &ReadLine(istream &str,
                         Bool_t skipWhite = kTRUE);   // Read to EOF or newline
   istream     &ReadString(istream &str);             // Read to EOF or null character
   istream     &ReadToDelim(istream &str, char delim = '\n'); // Read to EOF or delimitor
   istream     &ReadToken(istream &str);                // Read separated by white space
   TString     &Remove(Ssiz_t pos);                     // Remove pos to end of string
   TString     &Remove(Ssiz_t pos, Ssiz_t n);           // Remove n chars starting at pos
   TString     &Remove(EStripType s, char c);           // Like Strip() but changing string directly
   TString     &Replace(Ssiz_t pos, Ssiz_t n, const char *s);
   TString     &Replace(Ssiz_t pos, Ssiz_t n, const char *s, Ssiz_t ns);
   TString     &Replace(Ssiz_t pos, Ssiz_t n, const TString &s);
   TString     &Replace(Ssiz_t pos, Ssiz_t n1, const TString &s, Ssiz_t n2);
   TString     &ReplaceAll(const TString &s1, const TString &s2); // Find&Replace all s1 with s2 if any
   TString     &ReplaceAll(const TString &s1, const char *s2);    // Find&Replace all s1 with s2 if any
   TString     &ReplaceAll(const    char *s1, const TString &s2); // Find&Replace all s1 with s2 if any
   TString     &ReplaceAll(const char *s1, const char *s2);       // Find&Replace all s1 with s2 if any
   TString     &ReplaceAll(const char *s1, Ssiz_t ls1, const char *s2, Ssiz_t ls2);  // Find&Replace all s1 with s2 if any
   void         Resize(Ssiz_t n);                       // Truncate or add blanks as necessary
   TSubString   Strip(EStripType s = kTrailing, char c = ' ') const;
   void         ToLower();                              // Change self to lower-case
   void         ToUpper();                              // Change self to upper-case
   TObjArray   *Tokenize(const TString &delim) const;
   Bool_t       Tokenize(TString &tok, Ssiz_t &from, const char *delim = " ") const;

   // Static member functions
   static UInt_t  Hash(const void *txt, Int_t ntxt);    // Calculates hash index from any char string.
   static Ssiz_t  InitialCapacity(Ssiz_t ic = 15);      // Initial allocation capacity
   static Ssiz_t  MaxWaste(Ssiz_t mw = 15);             // Max empty space before reclaim
   static Ssiz_t  ResizeIncrement(Ssiz_t ri = 16);      // Resizing increment
   static Ssiz_t  GetInitialCapacity();
   static Ssiz_t  GetResizeIncrement();
   static Ssiz_t  GetMaxWaste();
   static TString Format(const char *fmt, ...)
#if defined(__GNUC__) && !defined(__CINT__)
   __attribute__((format(printf, 1, 2)))
#endif
   ;

   ClassDef(TString,2)  //Basic string class
};

// Related global functions
istream  &operator>>(istream &str,       TString &s);
ostream  &operator<<(ostream &str, const TString &s);
#if defined(R__TEMPLATE_OVERLOAD_BUG)
template <>
#endif
TBuffer  &operator>>(TBuffer &buf,       TString *&sp);

TString ToLower(const TString &s);    // Return lower-case version of argument
TString ToUpper(const TString &s);    // Return upper-case version of argument

inline UInt_t Hash(const TString &s) { return s.Hash(); }
inline UInt_t Hash(const TString *s) { return s->Hash(); }
       UInt_t Hash(const char *s);

extern char *Form(const char *fmt, ...)      // format in circular buffer
#if defined(__GNUC__) && !defined(__CINT__)
__attribute__((format(printf, 1, 2)))
#endif
;
extern void  Printf(const char *fmt, ...)    // format and print
#if defined(__GNUC__) && !defined(__CINT__)
__attribute__((format(printf, 1, 2)))
#endif
;
extern char *Strip(const char *str, char c = ' '); // strip c off str, free with delete []
extern char *StrDup(const char *str);        // duplicate str, free with delete []
extern char *Compress(const char *str);      // remove blanks from string, free with delele []
extern int   EscChar(const char *src, char *dst, int dstlen, char *specchars,
                     char escchar);          // copy from src to dst escaping specchars by escchar
extern int   UnEscChar(const char *src, char *dst, int dstlen, char *specchars,
                       char escchar);        // copy from src to dst removing escchar from specchars

#ifdef NEED_STRCASECMP
extern int strcasecmp(const char *str1, const char *str2);
extern int strncasecmp(const char *str1, const char *str2, Ssiz_t n);
#endif

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  Inlines                                                             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

inline TString &TString::Append(const char *cs)
{ return Replace(Length(), 0, cs, cs ? strlen(cs) : 0); }

inline TString &TString::Append(const char *cs, Ssiz_t n)
{ return Replace(Length(), 0, cs, n); }

inline TString &TString::Append(const TString &s)
{ return Replace(Length(), 0, s.Data(), s.Length()); }

inline TString &TString::Append(const TString &s, Ssiz_t n)
{ return Replace(Length(), 0, s.Data(), TMath::Min(n, s.Length())); }

inline TString &TString::operator+=(const char *cs)
{ return Append(cs, cs ? strlen(cs) : 0); }

inline TString &TString::operator+=(const TString &s)
{ return Append(s.Data(), s.Length()); }

inline TString &TString::operator+=(char c)
{ return Append(c); }

inline TString &TString::operator+=(Long_t i)
{ char s[32]; sprintf(s, "%ld", i); return operator+=(s); }

inline TString &TString::operator+=(ULong_t i)
{ char s[32]; sprintf(s, "%lu", i); return operator+=(s); }

inline TString &TString::operator+=(Short_t i)
{ return operator+=((Long_t) i); }

inline TString &TString::operator+=(UShort_t i)
{ return operator+=((ULong_t) i); }

inline TString &TString::operator+=(Int_t i)
{ return operator+=((Long_t) i); }

inline TString &TString::operator+=(UInt_t i)
{ return operator+=((ULong_t) i); }

inline TString &TString::operator+=(Double_t f)
{
   char s[32];
   // coverity[secure_coding] Buffer is large enough: width specified in format
   sprintf(s, "%.17g", f);
   return operator+=(s);
}

inline TString &TString::operator+=(Float_t f)
{ return operator+=((Double_t) f); }

inline TString &TString::operator+=(Long64_t l)
{
   char s[32];
   // coverity[secure_coding] Buffer is large enough (2^64 = 20 digits).
   sprintf(s, "%lld", l);
   return operator+=(s);
}

inline TString &TString::operator+=(ULong64_t ul)
{
   char s[32];
   // coverity[secure_coding] Buffer is large enough (2^64 = 20 digits).
   sprintf(s, "%llu", ul);
   return operator+=(s);
}

inline Bool_t TString::BeginsWith(const char *s, ECaseCompare cmp) const
{ return Index(s, s ? strlen(s) : (Ssiz_t)0, (Ssiz_t)0, cmp) == 0; }

inline Bool_t TString::BeginsWith(const TString &pat, ECaseCompare cmp) const
{ return Index(pat.Data(), pat.Length(), (Ssiz_t)0, cmp) == 0; }

inline Bool_t TString::Contains(const TString &pat, ECaseCompare cmp) const
{ return Index(pat.Data(), pat.Length(), (Ssiz_t)0, cmp) != kNPOS; }

inline Bool_t TString::Contains(const char *s, ECaseCompare cmp) const
{ return Index(s, s ? strlen(s) : 0, (Ssiz_t)0, cmp) != kNPOS; }

inline Bool_t TString::Contains(const TRegexp &pat) const
{ return Index(pat, (Ssiz_t)0) != kNPOS; }

inline Bool_t TString::Contains(TPRegexp &pat) const
{ return Index(pat, (Ssiz_t)0) != kNPOS; }

inline Bool_t TString::EqualTo(const char *cs, ECaseCompare cmp) const
{ return (CompareTo(cs, cmp) == 0) ? kTRUE : kFALSE; }

inline Bool_t TString::EqualTo(const TString &st, ECaseCompare cmp) const
{ return (CompareTo(st, cmp) == 0) ? kTRUE : kFALSE; }

inline Ssiz_t TString::Index(const char *s, Ssiz_t i, ECaseCompare cmp) const
{ return Index(s, s ? strlen(s) : 0, i, cmp); }

inline Ssiz_t TString::Index(const TString &s, Ssiz_t i, ECaseCompare cmp) const
{ return Index(s.Data(), s.Length(), i, cmp); }

inline Ssiz_t TString::Index(const TString &pat, Ssiz_t patlen, Ssiz_t i,
                             ECaseCompare cmp) const
{ return Index(pat.Data(), patlen, i, cmp); }

inline TString &TString::Insert(Ssiz_t pos, const char *cs)
{ return Replace(pos, 0, cs, cs ? strlen(cs) : 0); }

inline TString &TString::Insert(Ssiz_t pos, const char *cs, Ssiz_t n)
{ return Replace(pos, 0, cs, n); }

inline TString &TString::Insert(Ssiz_t pos, const TString &s)
{ return Replace(pos, 0, s.Data(), s.Length()); }

inline TString &TString::Insert(Ssiz_t pos, const TString &s, Ssiz_t n)
{ return Replace(pos, 0, s.Data(), TMath::Min(n, s.Length())); }

inline TString &TString::Prepend(const char *cs)
{ return Replace(0, 0, cs, cs ? strlen(cs) : 0); }

inline TString &TString::Prepend(const char *cs, Ssiz_t n)
{ return Replace(0, 0, cs, n); }

inline TString &TString::Prepend(const TString &s)
{ return Replace(0, 0, s.Data(), s.Length()); }

inline TString &TString::Prepend(const TString &s, Ssiz_t n)
{ return Replace(0, 0, s.Data(), TMath::Min(n, s.Length())); }

inline TString &TString::Remove(Ssiz_t pos)
{ return Replace(pos, TMath::Max(0, Length()-pos), 0, 0); }

inline TString &TString::Remove(Ssiz_t pos, Ssiz_t n)
{ return Replace(pos, n, 0, 0); }

inline TString &TString::Chop()
{ return Remove(TMath::Max(0, Length()-1)); }

inline TString &TString::Replace(Ssiz_t pos, Ssiz_t n, const char *cs)
{ return Replace(pos, n, cs, cs ? strlen(cs) : 0); }

inline TString &TString::Replace(Ssiz_t pos, Ssiz_t n, const TString& s)
{ return Replace(pos, n, s.Data(), s.Length()); }

inline TString &TString::Replace(Ssiz_t pos, Ssiz_t n1, const TString &s,
                                 Ssiz_t n2)
{ return Replace(pos, n1, s.Data(), TMath::Min(s.Length(), n2)); }

inline TString &TString::ReplaceAll(const TString &s1, const TString &s2)
{ return ReplaceAll(s1.Data(), s1.Length(), s2.Data(), s2.Length()) ; }

inline TString &TString::ReplaceAll(const TString &s1, const char *s2)
{ return ReplaceAll(s1.Data(), s1.Length(), s2, s2 ? strlen(s2) : 0); }

inline TString &TString::ReplaceAll(const char *s1, const TString &s2)
{ return ReplaceAll(s1, s1 ? strlen(s1) : 0, s2.Data(), s2.Length()); }

inline TString &TString::ReplaceAll(const char *s1,const char *s2)
{ return ReplaceAll(s1, s1 ? strlen(s1) : 0, s2, s2 ? strlen(s2) : 0); }

inline char &TString::operator()(Ssiz_t i)
{ return GetPointer()[i]; }

inline char TString::operator()(Ssiz_t i) const
{ return GetPointer()[i]; }

inline char &TString::operator[](Ssiz_t i)
{ AssertElement(i); return GetPointer()[i]; }

inline char TString::operator[](Ssiz_t i) const
{ AssertElement(i); return GetPointer()[i]; }

inline const char *TSubString::Data() const
{
   // Return a pointer to the beginning of the substring. Note that the
   // terminating null is in the same place as for the original
   // TString, so this method is not appropriate for converting the
   // TSubString to a string. To do that, construct a TString from the
   // TSubString. For example:
   //
   //   root [0] TString s("hello world")
   //   root [1] TSubString sub=s(0, 5)
   //   root [2] sub.Data()
   //   (const char* 0x857c8b8)"hello world"
   //   root [3] TString substr(sub)
   //   root [4] substr
   //   (class TString)"hello"

   return fStr.Data() + fBegin;
}

// Access to elements of sub-string with bounds checking
inline char TSubString::operator[](Ssiz_t i) const
{ AssertElement(i); return fStr.GetPointer()[fBegin+i]; }

inline char TSubString::operator()(Ssiz_t i) const
{ return fStr.GetPointer()[fBegin+i]; }

inline TSubString &TSubString::operator=(const TSubString &s)
{ fStr = s.fStr; fBegin = s.fBegin; fExtent = s.fExtent; return *this; }


// String Logical operators
inline Bool_t operator==(const TString &s1, const TString &s2)
{
   return ((s1.Length() == s2.Length()) &&
            !memcmp(s1.Data(), s2.Data(), s1.Length()));
}

inline Bool_t operator!=(const TString &s1, const TString &s2)
{ return !(s1 == s2); }

inline Bool_t operator<(const TString &s1, const TString &s2)
{ return s1.CompareTo(s2) < 0; }

inline Bool_t operator>(const TString &s1, const TString &s2)
{ return s1.CompareTo(s2) > 0; }

inline Bool_t operator<=(const TString &s1, const TString &s2)
{ return s1.CompareTo(s2) <= 0; }

inline Bool_t operator>=(const TString &s1, const TString &s2)
{ return s1.CompareTo(s2) >= 0; }

//     Bool_t operator==(const TString &s1, const char *s2);
inline Bool_t operator!=(const TString &s1, const char *s2)
{ return !(s1 == s2); }

inline Bool_t operator<(const TString &s1, const char *s2)
{ return s1.CompareTo(s2) < 0; }

inline Bool_t operator>(const TString &s1, const char *s2)
{ return s1.CompareTo(s2) > 0; }

inline Bool_t operator<=(const TString &s1, const char *s2)
{ return s1.CompareTo(s2) <= 0; }

inline Bool_t operator>=(const TString &s1, const char *s2)
{ return s1.CompareTo(s2) >= 0; }

inline Bool_t operator==(const char *s1, const TString &s2)
{ return (s2 == s1); }

inline Bool_t operator!=(const char *s1, const TString &s2)
{ return !(s2 == s1); }

inline Bool_t operator<(const char *s1, const TString &s2)
{ return s2.CompareTo(s1) > 0; }

inline Bool_t operator>(const char *s1, const TString &s2)
{ return s2.CompareTo(s1) < 0; }

inline Bool_t operator<=(const char *s1, const TString &s2)
{ return s2.CompareTo(s1) >= 0; }

inline Bool_t operator>=(const char *s1, const TString &s2)
{ return s2.CompareTo(s1) <= 0; }

// SubString Logical operators
//     Bool_t operator==(const TSubString &s1, const TSubString &s2);
//     Bool_t operator==(const TSubString &s1, const char *s2);
//     Bool_t operator==(const TSubString &s1, const TString &s2);
inline Bool_t operator==(const TString &s1, const TSubString &s2)
{ return (s2 == s1); }

inline Bool_t operator==(const char *s1, const TSubString &s2)
{ return (s2 == s1); }

inline Bool_t operator!=(const TSubString &s1, const char *s2)
{ return !(s1 == s2); }

inline Bool_t operator!=(const TSubString &s1, const TString &s2)
{ return !(s1 == s2); }

inline Bool_t operator!=(const TSubString &s1, const TSubString &s2)
{ return !(s1 == s2); }

inline Bool_t operator!=(const TString &s1, const TSubString &s2)
{ return !(s2 == s1); }

inline Bool_t operator!=(const char *s1, const TSubString &s2)
{ return !(s2 == s1); }

#endif
 TString.h:1
 TString.h:2
 TString.h:3
 TString.h:4
 TString.h:5
 TString.h:6
 TString.h:7
 TString.h:8
 TString.h:9
 TString.h:10
 TString.h:11
 TString.h:12
 TString.h:13
 TString.h:14
 TString.h:15
 TString.h:16
 TString.h:17
 TString.h:18
 TString.h:19
 TString.h:20
 TString.h:21
 TString.h:22
 TString.h:23
 TString.h:24
 TString.h:25
 TString.h:26
 TString.h:27
 TString.h:28
 TString.h:29
 TString.h:30
 TString.h:31
 TString.h:32
 TString.h:33
 TString.h:34
 TString.h:35
 TString.h:36
 TString.h:37
 TString.h:38
 TString.h:39
 TString.h:40
 TString.h:41
 TString.h:42
 TString.h:43
 TString.h:44
 TString.h:45
 TString.h:46
 TString.h:47
 TString.h:48
 TString.h:49
 TString.h:50
 TString.h:51
 TString.h:52
 TString.h:53
 TString.h:54
 TString.h:55
 TString.h:56
 TString.h:57
 TString.h:58
 TString.h:59
 TString.h:60
 TString.h:61
 TString.h:62
 TString.h:63
 TString.h:64
 TString.h:65
 TString.h:66
 TString.h:67
 TString.h:68
 TString.h:69
 TString.h:70
 TString.h:71
 TString.h:72
 TString.h:73
 TString.h:74
 TString.h:75
 TString.h:76
 TString.h:77
 TString.h:78
 TString.h:79
 TString.h:80
 TString.h:81
 TString.h:82
 TString.h:83
 TString.h:84
 TString.h:85
 TString.h:86
 TString.h:87
 TString.h:88
 TString.h:89
 TString.h:90
 TString.h:91
 TString.h:92
 TString.h:93
 TString.h:94
 TString.h:95
 TString.h:96
 TString.h:97
 TString.h:98
 TString.h:99
 TString.h:100
 TString.h:101
 TString.h:102
 TString.h:103
 TString.h:104
 TString.h:105
 TString.h:106
 TString.h:107
 TString.h:108
 TString.h:109
 TString.h:110
 TString.h:111
 TString.h:112
 TString.h:113
 TString.h:114
 TString.h:115
 TString.h:116
 TString.h:117
 TString.h:118
 TString.h:119
 TString.h:120
 TString.h:121
 TString.h:122
 TString.h:123
 TString.h:124
 TString.h:125
 TString.h:126
 TString.h:127
 TString.h:128
 TString.h:129
 TString.h:130
 TString.h:131
 TString.h:132
 TString.h:133
 TString.h:134
 TString.h:135
 TString.h:136
 TString.h:137
 TString.h:138
 TString.h:139
 TString.h:140
 TString.h:141
 TString.h:142
 TString.h:143
 TString.h:144
 TString.h:145
 TString.h:146
 TString.h:147
 TString.h:148
 TString.h:149
 TString.h:150
 TString.h:151
 TString.h:152
 TString.h:153
 TString.h:154
 TString.h:155
 TString.h:156
 TString.h:157
 TString.h:158
 TString.h:159
 TString.h:160
 TString.h:161
 TString.h:162
 TString.h:163
 TString.h:164
 TString.h:165
 TString.h:166
 TString.h:167
 TString.h:168
 TString.h:169
 TString.h:170
 TString.h:171
 TString.h:172
 TString.h:173
 TString.h:174
 TString.h:175
 TString.h:176
 TString.h:177
 TString.h:178
 TString.h:179
 TString.h:180
 TString.h:181
 TString.h:182
 TString.h:183
 TString.h:184
 TString.h:185
 TString.h:186
 TString.h:187
 TString.h:188
 TString.h:189
 TString.h:190
 TString.h:191
 TString.h:192
 TString.h:193
 TString.h:194
 TString.h:195
 TString.h:196
 TString.h:197
 TString.h:198
 TString.h:199
 TString.h:200
 TString.h:201
 TString.h:202
 TString.h:203
 TString.h:204
 TString.h:205
 TString.h:206
 TString.h:207
 TString.h:208
 TString.h:209
 TString.h:210
 TString.h:211
 TString.h:212
 TString.h:213
 TString.h:214
 TString.h:215
 TString.h:216
 TString.h:217
 TString.h:218
 TString.h:219
 TString.h:220
 TString.h:221
 TString.h:222
 TString.h:223
 TString.h:224
 TString.h:225
 TString.h:226
 TString.h:227
 TString.h:228
 TString.h:229
 TString.h:230
 TString.h:231
 TString.h:232
 TString.h:233
 TString.h:234
 TString.h:235
 TString.h:236
 TString.h:237
 TString.h:238
 TString.h:239
 TString.h:240
 TString.h:241
 TString.h:242
 TString.h:243
 TString.h:244
 TString.h:245
 TString.h:246
 TString.h:247
 TString.h:248
 TString.h:249
 TString.h:250
 TString.h:251
 TString.h:252
 TString.h:253
 TString.h:254
 TString.h:255
 TString.h:256
 TString.h:257
 TString.h:258
 TString.h:259
 TString.h:260
 TString.h:261
 TString.h:262
 TString.h:263
 TString.h:264
 TString.h:265
 TString.h:266
 TString.h:267
 TString.h:268
 TString.h:269
 TString.h:270
 TString.h:271
 TString.h:272
 TString.h:273
 TString.h:274
 TString.h:275
 TString.h:276
 TString.h:277
 TString.h:278
 TString.h:279
 TString.h:280
 TString.h:281
 TString.h:282
 TString.h:283
 TString.h:284
 TString.h:285
 TString.h:286
 TString.h:287
 TString.h:288
 TString.h:289
 TString.h:290
 TString.h:291
 TString.h:292
 TString.h:293
 TString.h:294
 TString.h:295
 TString.h:296
 TString.h:297
 TString.h:298
 TString.h:299
 TString.h:300
 TString.h:301
 TString.h:302
 TString.h:303
 TString.h:304
 TString.h:305
 TString.h:306
 TString.h:307
 TString.h:308
 TString.h:309
 TString.h:310
 TString.h:311
 TString.h:312
 TString.h:313
 TString.h:314
 TString.h:315
 TString.h:316
 TString.h:317
 TString.h:318
 TString.h:319
 TString.h:320
 TString.h:321
 TString.h:322
 TString.h:323
 TString.h:324
 TString.h:325
 TString.h:326
 TString.h:327
 TString.h:328
 TString.h:329
 TString.h:330
 TString.h:331
 TString.h:332
 TString.h:333
 TString.h:334
 TString.h:335
 TString.h:336
 TString.h:337
 TString.h:338
 TString.h:339
 TString.h:340
 TString.h:341
 TString.h:342
 TString.h:343
 TString.h:344
 TString.h:345
 TString.h:346
 TString.h:347
 TString.h:348
 TString.h:349
 TString.h:350
 TString.h:351
 TString.h:352
 TString.h:353
 TString.h:354
 TString.h:355
 TString.h:356
 TString.h:357
 TString.h:358
 TString.h:359
 TString.h:360
 TString.h:361
 TString.h:362
 TString.h:363
 TString.h:364
 TString.h:365
 TString.h:366
 TString.h:367
 TString.h:368
 TString.h:369
 TString.h:370
 TString.h:371
 TString.h:372
 TString.h:373
 TString.h:374
 TString.h:375
 TString.h:376
 TString.h:377
 TString.h:378
 TString.h:379
 TString.h:380
 TString.h:381
 TString.h:382
 TString.h:383
 TString.h:384
 TString.h:385
 TString.h:386
 TString.h:387
 TString.h:388
 TString.h:389
 TString.h:390
 TString.h:391
 TString.h:392
 TString.h:393
 TString.h:394
 TString.h:395
 TString.h:396
 TString.h:397
 TString.h:398
 TString.h:399
 TString.h:400
 TString.h:401
 TString.h:402
 TString.h:403
 TString.h:404
 TString.h:405
 TString.h:406
 TString.h:407
 TString.h:408
 TString.h:409
 TString.h:410
 TString.h:411
 TString.h:412
 TString.h:413
 TString.h:414
 TString.h:415
 TString.h:416
 TString.h:417
 TString.h:418
 TString.h:419
 TString.h:420
 TString.h:421
 TString.h:422
 TString.h:423
 TString.h:424
 TString.h:425
 TString.h:426
 TString.h:427
 TString.h:428
 TString.h:429
 TString.h:430
 TString.h:431
 TString.h:432
 TString.h:433
 TString.h:434
 TString.h:435
 TString.h:436
 TString.h:437
 TString.h:438
 TString.h:439
 TString.h:440
 TString.h:441
 TString.h:442
 TString.h:443
 TString.h:444
 TString.h:445
 TString.h:446
 TString.h:447
 TString.h:448
 TString.h:449
 TString.h:450
 TString.h:451
 TString.h:452
 TString.h:453
 TString.h:454
 TString.h:455
 TString.h:456
 TString.h:457
 TString.h:458
 TString.h:459
 TString.h:460
 TString.h:461
 TString.h:462
 TString.h:463
 TString.h:464
 TString.h:465
 TString.h:466
 TString.h:467
 TString.h:468
 TString.h:469
 TString.h:470
 TString.h:471
 TString.h:472
 TString.h:473
 TString.h:474
 TString.h:475
 TString.h:476
 TString.h:477
 TString.h:478
 TString.h:479
 TString.h:480
 TString.h:481
 TString.h:482
 TString.h:483
 TString.h:484
 TString.h:485
 TString.h:486
 TString.h:487
 TString.h:488
 TString.h:489
 TString.h:490
 TString.h:491
 TString.h:492
 TString.h:493
 TString.h:494
 TString.h:495
 TString.h:496
 TString.h:497
 TString.h:498
 TString.h:499
 TString.h:500
 TString.h:501
 TString.h:502
 TString.h:503
 TString.h:504
 TString.h:505
 TString.h:506
 TString.h:507
 TString.h:508
 TString.h:509
 TString.h:510
 TString.h:511
 TString.h:512
 TString.h:513
 TString.h:514
 TString.h:515
 TString.h:516
 TString.h:517
 TString.h:518
 TString.h:519
 TString.h:520
 TString.h:521
 TString.h:522
 TString.h:523
 TString.h:524
 TString.h:525
 TString.h:526
 TString.h:527
 TString.h:528
 TString.h:529
 TString.h:530
 TString.h:531
 TString.h:532
 TString.h:533
 TString.h:534
 TString.h:535
 TString.h:536
 TString.h:537
 TString.h:538
 TString.h:539
 TString.h:540
 TString.h:541
 TString.h:542
 TString.h:543
 TString.h:544
 TString.h:545
 TString.h:546
 TString.h:547
 TString.h:548
 TString.h:549
 TString.h:550
 TString.h:551
 TString.h:552
 TString.h:553
 TString.h:554
 TString.h:555
 TString.h:556
 TString.h:557
 TString.h:558
 TString.h:559
 TString.h:560
 TString.h:561
 TString.h:562
 TString.h:563
 TString.h:564
 TString.h:565
 TString.h:566
 TString.h:567
 TString.h:568
 TString.h:569
 TString.h:570
 TString.h:571
 TString.h:572
 TString.h:573
 TString.h:574
 TString.h:575
 TString.h:576
 TString.h:577
 TString.h:578
 TString.h:579
 TString.h:580
 TString.h:581
 TString.h:582
 TString.h:583
 TString.h:584
 TString.h:585
 TString.h:586
 TString.h:587
 TString.h:588
 TString.h:589
 TString.h:590
 TString.h:591
 TString.h:592
 TString.h:593
 TString.h:594
 TString.h:595
 TString.h:596
 TString.h:597
 TString.h:598
 TString.h:599
 TString.h:600
 TString.h:601
 TString.h:602
 TString.h:603
 TString.h:604
 TString.h:605
 TString.h:606
 TString.h:607
 TString.h:608
 TString.h:609
 TString.h:610
 TString.h:611
 TString.h:612
 TString.h:613
 TString.h:614
 TString.h:615
 TString.h:616
 TString.h:617
 TString.h:618
 TString.h:619
 TString.h:620
 TString.h:621
 TString.h:622
 TString.h:623
 TString.h:624
 TString.h:625
 TString.h:626
 TString.h:627
 TString.h:628
 TString.h:629
 TString.h:630
 TString.h:631
 TString.h:632
 TString.h:633
 TString.h:634
 TString.h:635
 TString.h:636
 TString.h:637
 TString.h:638
 TString.h:639
 TString.h:640
 TString.h:641
 TString.h:642
 TString.h:643
 TString.h:644
 TString.h:645
 TString.h:646
 TString.h:647
 TString.h:648
 TString.h:649
 TString.h:650
 TString.h:651
 TString.h:652
 TString.h:653
 TString.h:654
 TString.h:655
 TString.h:656
 TString.h:657
 TString.h:658
 TString.h:659
 TString.h:660
 TString.h:661
 TString.h:662
 TString.h:663
 TString.h:664
 TString.h:665
 TString.h:666
 TString.h:667
 TString.h:668
 TString.h:669
 TString.h:670
 TString.h:671
 TString.h:672
 TString.h:673
 TString.h:674
 TString.h:675
 TString.h:676
 TString.h:677
 TString.h:678
 TString.h:679
 TString.h:680
 TString.h:681
 TString.h:682
 TString.h:683
 TString.h:684
 TString.h:685
 TString.h:686
 TString.h:687
 TString.h:688
 TString.h:689
 TString.h:690
 TString.h:691
 TString.h:692
 TString.h:693
 TString.h:694
 TString.h:695
 TString.h:696
 TString.h:697
 TString.h:698
 TString.h:699
 TString.h:700
 TString.h:701
 TString.h:702
 TString.h:703
 TString.h:704
 TString.h:705
 TString.h:706
 TString.h:707
 TString.h:708
 TString.h:709
 TString.h:710
 TString.h:711
 TString.h:712
 TString.h:713
 TString.h:714
 TString.h:715
 TString.h:716
 TString.h:717
 TString.h:718
 TString.h:719
 TString.h:720
 TString.h:721
 TString.h:722
 TString.h:723
 TString.h:724
 TString.h:725
 TString.h:726
 TString.h:727
 TString.h:728
 TString.h:729
 TString.h:730
 TString.h:731
 TString.h:732
 TString.h:733
 TString.h:734
 TString.h:735
 TString.h:736
 TString.h:737
 TString.h:738
 TString.h:739
 TString.h:740
 TString.h:741
 TString.h:742
 TString.h:743
 TString.h:744
 TString.h:745
 TString.h:746
 TString.h:747
 TString.h:748
 TString.h:749