annotate src/win32/7zip/7z/CPP/Common/MyString.h @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
rev   line source
rlm@1 1 // Common/String.h
rlm@1 2
rlm@1 3 #ifndef __COMMON_STRING_H
rlm@1 4 #define __COMMON_STRING_H
rlm@1 5
rlm@1 6 #include <string.h>
rlm@1 7 // #include <wchar.h>
rlm@1 8
rlm@1 9 #include "MyVector.h"
rlm@1 10
rlm@1 11 #ifdef _WIN32
rlm@1 12 #include "MyWindows.h"
rlm@1 13 #endif
rlm@1 14
rlm@1 15 template <class T>
rlm@1 16 inline int MyStringLen(const T *s)
rlm@1 17 {
rlm@1 18 int i;
rlm@1 19 for (i = 0; s[i] != '\0'; i++);
rlm@1 20 return i;
rlm@1 21 }
rlm@1 22
rlm@1 23 template <class T>
rlm@1 24 inline T * MyStringCopy(T *dest, const T *src)
rlm@1 25 {
rlm@1 26 T *destStart = dest;
rlm@1 27 while ((*dest++ = *src++) != 0);
rlm@1 28 return destStart;
rlm@1 29 }
rlm@1 30
rlm@1 31 inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
rlm@1 32 { return (p + 1); }
rlm@1 33 inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
rlm@1 34 { return (p + 1); }
rlm@1 35 inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)
rlm@1 36 { return (p - 1); }
rlm@1 37 inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)
rlm@1 38 { return (p - 1); }
rlm@1 39
rlm@1 40 #ifdef _WIN32
rlm@1 41
rlm@1 42 inline char* MyStringGetNextCharPointer(char *p)
rlm@1 43 { return CharNextA(p); }
rlm@1 44 inline const char* MyStringGetNextCharPointer(const char *p)
rlm@1 45 { return CharNextA(p); }
rlm@1 46
rlm@1 47 inline char* MyStringGetPrevCharPointer(char *base, char *p)
rlm@1 48 { return CharPrevA(base, p); }
rlm@1 49 inline const char* MyStringGetPrevCharPointer(const char *base, const char *p)
rlm@1 50 { return CharPrevA(base, p); }
rlm@1 51
rlm@1 52 inline char MyCharUpper(char c)
rlm@1 53 { return (char)(unsigned int)(UINT_PTR)CharUpperA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
rlm@1 54 #ifdef _UNICODE
rlm@1 55 inline wchar_t MyCharUpper(wchar_t c)
rlm@1 56 { return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); }
rlm@1 57 #else
rlm@1 58 wchar_t MyCharUpper(wchar_t c);
rlm@1 59 #endif
rlm@1 60
rlm@1 61 inline char MyCharLower(char c)
rlm@1 62 { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
rlm@1 63 #ifdef _UNICODE
rlm@1 64 inline wchar_t MyCharLower(wchar_t c)
rlm@1 65 { return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); }
rlm@1 66 #else
rlm@1 67 wchar_t MyCharLower(wchar_t c);
rlm@1 68 #endif
rlm@1 69
rlm@1 70 inline char * MyStringUpper(char *s) { return CharUpperA(s); }
rlm@1 71 #ifdef _UNICODE
rlm@1 72 inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
rlm@1 73 #else
rlm@1 74 wchar_t * MyStringUpper(wchar_t *s);
rlm@1 75 #endif
rlm@1 76
rlm@1 77 inline char * MyStringLower(char *s) { return CharLowerA(s); }
rlm@1 78 #ifdef _UNICODE
rlm@1 79 inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
rlm@1 80 #else
rlm@1 81 wchar_t * MyStringLower(wchar_t *s);
rlm@1 82 #endif
rlm@1 83
rlm@1 84 #else // Standard-C
rlm@1 85 wchar_t MyCharUpper(wchar_t c);
rlm@1 86 #endif
rlm@1 87
rlm@1 88 //////////////////////////////////////
rlm@1 89 // Compare
rlm@1 90
rlm@1 91 /*
rlm@1 92 #ifndef _WIN32_WCE
rlm@1 93 int MyStringCollate(const char *s1, const char *s2);
rlm@1 94 int MyStringCollateNoCase(const char *s1, const char *s2);
rlm@1 95 #endif
rlm@1 96 int MyStringCollate(const wchar_t *s1, const wchar_t *s2);
rlm@1 97 int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);
rlm@1 98 */
rlm@1 99
rlm@1 100 int MyStringCompare(const char *s1, const char *s2);
rlm@1 101 int MyStringCompare(const wchar_t *s1, const wchar_t *s2);
rlm@1 102
rlm@1 103 #ifdef _WIN32
rlm@1 104 int MyStringCompareNoCase(const char *s1, const char *s2);
rlm@1 105 #endif
rlm@1 106
rlm@1 107 int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);
rlm@1 108
rlm@1 109 template <class T>
rlm@1 110 class CStringBase
rlm@1 111 {
rlm@1 112 void TrimLeftWithCharSet(const CStringBase &charSet)
rlm@1 113 {
rlm@1 114 const T *p = _chars;
rlm@1 115 while (charSet.Find(*p) >= 0 && (*p != 0))
rlm@1 116 p = GetNextCharPointer(p);
rlm@1 117 Delete(0, (int)(p - _chars));
rlm@1 118 }
rlm@1 119 void TrimRightWithCharSet(const CStringBase &charSet)
rlm@1 120 {
rlm@1 121 const T *p = _chars;
rlm@1 122 const T *pLast = NULL;
rlm@1 123 while (*p != 0)
rlm@1 124 {
rlm@1 125 if (charSet.Find(*p) >= 0)
rlm@1 126 {
rlm@1 127 if (pLast == NULL)
rlm@1 128 pLast = p;
rlm@1 129 }
rlm@1 130 else
rlm@1 131 pLast = NULL;
rlm@1 132 p = GetNextCharPointer(p);
rlm@1 133 }
rlm@1 134 if (pLast != NULL)
rlm@1 135 {
rlm@1 136 int i = (int)(pLast - _chars);
rlm@1 137 Delete(i, _length - i);
rlm@1 138 }
rlm@1 139
rlm@1 140 }
rlm@1 141 void MoveItems(int destIndex, int srcIndex)
rlm@1 142 {
rlm@1 143 memmove(_chars + destIndex, _chars + srcIndex,
rlm@1 144 sizeof(T) * (_length - srcIndex + 1));
rlm@1 145 }
rlm@1 146
rlm@1 147 void InsertSpace(int &index, int size)
rlm@1 148 {
rlm@1 149 CorrectIndex(index);
rlm@1 150 GrowLength(size);
rlm@1 151 MoveItems(index + size, index);
rlm@1 152 }
rlm@1 153
rlm@1 154 static T *GetNextCharPointer(T *p)
rlm@1 155 { return MyStringGetNextCharPointer(p); }
rlm@1 156 static const T *GetNextCharPointer(const T *p)
rlm@1 157 { return MyStringGetNextCharPointer(p); }
rlm@1 158 static T *GetPrevCharPointer(T *base, T *p)
rlm@1 159 { return MyStringGetPrevCharPointer(base, p); }
rlm@1 160 static const T *GetPrevCharPointer(const T *base, const T *p)
rlm@1 161 { return MyStringGetPrevCharPointer(base, p); }
rlm@1 162 protected:
rlm@1 163 T *_chars;
rlm@1 164 int _length;
rlm@1 165 int _capacity;
rlm@1 166
rlm@1 167 void SetCapacity(int newCapacity)
rlm@1 168 {
rlm@1 169 int realCapacity = newCapacity + 1;
rlm@1 170 if (realCapacity == _capacity)
rlm@1 171 return;
rlm@1 172 /*
rlm@1 173 const int kMaxStringSize = 0x20000000;
rlm@1 174 #ifndef _WIN32_WCE
rlm@1 175 if (newCapacity > kMaxStringSize || newCapacity < _length)
rlm@1 176 throw 1052337;
rlm@1 177 #endif
rlm@1 178 */
rlm@1 179 T *newBuffer = new T[realCapacity];
rlm@1 180 if (_capacity > 0)
rlm@1 181 {
rlm@1 182 for (int i = 0; i < _length; i++)
rlm@1 183 newBuffer[i] = _chars[i];
rlm@1 184 delete []_chars;
rlm@1 185 }
rlm@1 186 _chars = newBuffer;
rlm@1 187 _chars[_length] = 0;
rlm@1 188 _capacity = realCapacity;
rlm@1 189 }
rlm@1 190
rlm@1 191 void GrowLength(int n)
rlm@1 192 {
rlm@1 193 int freeSize = _capacity - _length - 1;
rlm@1 194 if (n <= freeSize)
rlm@1 195 return;
rlm@1 196 int delta;
rlm@1 197 if (_capacity > 64)
rlm@1 198 delta = _capacity / 2;
rlm@1 199 else if (_capacity > 8)
rlm@1 200 delta = 16;
rlm@1 201 else
rlm@1 202 delta = 4;
rlm@1 203 if (freeSize + delta < n)
rlm@1 204 delta = n - freeSize;
rlm@1 205 SetCapacity(_capacity + delta);
rlm@1 206 }
rlm@1 207
rlm@1 208 void CorrectIndex(int &index) const
rlm@1 209 {
rlm@1 210 if (index > _length)
rlm@1 211 index = _length;
rlm@1 212 }
rlm@1 213
rlm@1 214 public:
rlm@1 215 CStringBase(): _chars(0), _length(0), _capacity(0) { SetCapacity(3); }
rlm@1 216 CStringBase(T c): _chars(0), _length(0), _capacity(0)
rlm@1 217 {
rlm@1 218 SetCapacity(1);
rlm@1 219 _chars[0] = c;
rlm@1 220 _chars[1] = 0;
rlm@1 221 _length = 1;
rlm@1 222 }
rlm@1 223 CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)
rlm@1 224 {
rlm@1 225 int length = MyStringLen(chars);
rlm@1 226 SetCapacity(length);
rlm@1 227 MyStringCopy(_chars, chars); // can be optimized by memove()
rlm@1 228 _length = length;
rlm@1 229 }
rlm@1 230 CStringBase(const CStringBase &s): _chars(0), _length(0), _capacity(0)
rlm@1 231 {
rlm@1 232 SetCapacity(s._length);
rlm@1 233 MyStringCopy(_chars, s._chars);
rlm@1 234 _length = s._length;
rlm@1 235 }
rlm@1 236 ~CStringBase() { delete []_chars; }
rlm@1 237
rlm@1 238 operator const T*() const { return _chars;}
rlm@1 239
rlm@1 240 // The minimum size of the character buffer in characters.
rlm@1 241 // This value does not include space for a null terminator.
rlm@1 242 T* GetBuffer(int minBufLength)
rlm@1 243 {
rlm@1 244 if (minBufLength >= _capacity)
rlm@1 245 SetCapacity(minBufLength);
rlm@1 246 return _chars;
rlm@1 247 }
rlm@1 248 void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
rlm@1 249 void ReleaseBuffer(int newLength)
rlm@1 250 {
rlm@1 251 /*
rlm@1 252 #ifndef _WIN32_WCE
rlm@1 253 if (newLength >= _capacity)
rlm@1 254 throw 282217;
rlm@1 255 #endif
rlm@1 256 */
rlm@1 257 _chars[newLength] = 0;
rlm@1 258 _length = newLength;
rlm@1 259 }
rlm@1 260
rlm@1 261 CStringBase& operator=(T c)
rlm@1 262 {
rlm@1 263 Empty();
rlm@1 264 SetCapacity(1);
rlm@1 265 _chars[0] = c;
rlm@1 266 _chars[1] = 0;
rlm@1 267 _length = 1;
rlm@1 268 return *this;
rlm@1 269 }
rlm@1 270 CStringBase& operator=(const T *chars)
rlm@1 271 {
rlm@1 272 Empty();
rlm@1 273 int length = MyStringLen(chars);
rlm@1 274 SetCapacity(length);
rlm@1 275 MyStringCopy(_chars, chars);
rlm@1 276 _length = length;
rlm@1 277 return *this;
rlm@1 278 }
rlm@1 279 CStringBase& operator=(const CStringBase& s)
rlm@1 280 {
rlm@1 281 if (&s == this)
rlm@1 282 return *this;
rlm@1 283 Empty();
rlm@1 284 SetCapacity(s._length);
rlm@1 285 MyStringCopy(_chars, s._chars);
rlm@1 286 _length = s._length;
rlm@1 287 return *this;
rlm@1 288 }
rlm@1 289
rlm@1 290 CStringBase& operator+=(T c)
rlm@1 291 {
rlm@1 292 GrowLength(1);
rlm@1 293 _chars[_length] = c;
rlm@1 294 _chars[++_length] = 0;
rlm@1 295 return *this;
rlm@1 296 }
rlm@1 297 CStringBase& operator+=(const T *s)
rlm@1 298 {
rlm@1 299 int len = MyStringLen(s);
rlm@1 300 GrowLength(len);
rlm@1 301 MyStringCopy(_chars + _length, s);
rlm@1 302 _length += len;
rlm@1 303 return *this;
rlm@1 304 }
rlm@1 305 CStringBase& operator+=(const CStringBase &s)
rlm@1 306 {
rlm@1 307 GrowLength(s._length);
rlm@1 308 MyStringCopy(_chars + _length, s._chars);
rlm@1 309 _length += s._length;
rlm@1 310 return *this;
rlm@1 311 }
rlm@1 312 void Empty()
rlm@1 313 {
rlm@1 314 _length = 0;
rlm@1 315 _chars[0] = 0;
rlm@1 316 }
rlm@1 317 int Length() const { return _length; }
rlm@1 318 bool IsEmpty() const { return (_length == 0); }
rlm@1 319
rlm@1 320 CStringBase Mid(int startIndex) const
rlm@1 321 { return Mid(startIndex, _length - startIndex); }
rlm@1 322 CStringBase Mid(int startIndex, int count ) const
rlm@1 323 {
rlm@1 324 if (startIndex + count > _length)
rlm@1 325 count = _length - startIndex;
rlm@1 326
rlm@1 327 if (startIndex == 0 && startIndex + count == _length)
rlm@1 328 return *this;
rlm@1 329
rlm@1 330 CStringBase<T> result;
rlm@1 331 result.SetCapacity(count);
rlm@1 332 // MyStringNCopy(result._chars, _chars + startIndex, count);
rlm@1 333 for (int i = 0; i < count; i++)
rlm@1 334 result._chars[i] = _chars[startIndex + i];
rlm@1 335 result._chars[count] = 0;
rlm@1 336 result._length = count;
rlm@1 337 return result;
rlm@1 338 }
rlm@1 339 CStringBase Left(int count) const
rlm@1 340 { return Mid(0, count); }
rlm@1 341 CStringBase Right(int count) const
rlm@1 342 {
rlm@1 343 if (count > _length)
rlm@1 344 count = _length;
rlm@1 345 return Mid(_length - count, count);
rlm@1 346 }
rlm@1 347
rlm@1 348 void MakeUpper()
rlm@1 349 { MyStringUpper(_chars); }
rlm@1 350 void MakeLower()
rlm@1 351 { MyStringLower(_chars); }
rlm@1 352
rlm@1 353 int Compare(const CStringBase& s) const
rlm@1 354 { return MyStringCompare(_chars, s._chars); }
rlm@1 355
rlm@1 356 int Compare(const T *s) const
rlm@1 357 { return MyStringCompare(_chars, s); }
rlm@1 358
rlm@1 359 int CompareNoCase(const CStringBase& s) const
rlm@1 360 { return MyStringCompareNoCase(_chars, s._chars); }
rlm@1 361
rlm@1 362 int CompareNoCase(const T *s) const
rlm@1 363 { return MyStringCompareNoCase(_chars, s); }
rlm@1 364
rlm@1 365 /*
rlm@1 366 int Collate(const CStringBase& s) const
rlm@1 367 { return MyStringCollate(_chars, s._chars); }
rlm@1 368 int CollateNoCase(const CStringBase& s) const
rlm@1 369 { return MyStringCollateNoCase(_chars, s._chars); }
rlm@1 370 */
rlm@1 371
rlm@1 372 int Find(T c) const { return Find(c, 0); }
rlm@1 373 int Find(T c, int startIndex) const
rlm@1 374 {
rlm@1 375 T *p = _chars + startIndex;
rlm@1 376 for (;;)
rlm@1 377 {
rlm@1 378 if (*p == c)
rlm@1 379 return (int)(p - _chars);
rlm@1 380 if (*p == 0)
rlm@1 381 return -1;
rlm@1 382 p = GetNextCharPointer(p);
rlm@1 383 }
rlm@1 384 }
rlm@1 385 int Find(const CStringBase &s) const { return Find(s, 0); }
rlm@1 386 int Find(const CStringBase &s, int startIndex) const
rlm@1 387 {
rlm@1 388 if (s.IsEmpty())
rlm@1 389 return startIndex;
rlm@1 390 for (; startIndex < _length; startIndex++)
rlm@1 391 {
rlm@1 392 int j;
rlm@1 393 for (j = 0; j < s._length && startIndex + j < _length; j++)
rlm@1 394 if (_chars[startIndex+j] != s._chars[j])
rlm@1 395 break;
rlm@1 396 if (j == s._length)
rlm@1 397 return startIndex;
rlm@1 398 }
rlm@1 399 return -1;
rlm@1 400 }
rlm@1 401 int ReverseFind(T c) const
rlm@1 402 {
rlm@1 403 if (_length == 0)
rlm@1 404 return -1;
rlm@1 405 T *p = _chars + _length - 1;
rlm@1 406 for (;;)
rlm@1 407 {
rlm@1 408 if (*p == c)
rlm@1 409 return (int)(p - _chars);
rlm@1 410 if (p == _chars)
rlm@1 411 return -1;
rlm@1 412 p = GetPrevCharPointer(_chars, p);
rlm@1 413 }
rlm@1 414 }
rlm@1 415 int FindOneOf(const CStringBase &s) const
rlm@1 416 {
rlm@1 417 for (int i = 0; i < _length; i++)
rlm@1 418 if (s.Find(_chars[i]) >= 0)
rlm@1 419 return i;
rlm@1 420 return -1;
rlm@1 421 }
rlm@1 422
rlm@1 423 void TrimLeft(T c)
rlm@1 424 {
rlm@1 425 const T *p = _chars;
rlm@1 426 while (c == *p)
rlm@1 427 p = GetNextCharPointer(p);
rlm@1 428 Delete(0, p - _chars);
rlm@1 429 }
rlm@1 430 private:
rlm@1 431 CStringBase GetTrimDefaultCharSet()
rlm@1 432 {
rlm@1 433 CStringBase<T> charSet;
rlm@1 434 charSet += (T)' ';
rlm@1 435 charSet += (T)'\n';
rlm@1 436 charSet += (T)'\t';
rlm@1 437 return charSet;
rlm@1 438 }
rlm@1 439 public:
rlm@1 440
rlm@1 441 void TrimLeft()
rlm@1 442 {
rlm@1 443 TrimLeftWithCharSet(GetTrimDefaultCharSet());
rlm@1 444 }
rlm@1 445 void TrimRight()
rlm@1 446 {
rlm@1 447 TrimRightWithCharSet(GetTrimDefaultCharSet());
rlm@1 448 }
rlm@1 449 void TrimRight(T c)
rlm@1 450 {
rlm@1 451 const T *p = _chars;
rlm@1 452 const T *pLast = NULL;
rlm@1 453 while (*p != 0)
rlm@1 454 {
rlm@1 455 if (*p == c)
rlm@1 456 {
rlm@1 457 if (pLast == NULL)
rlm@1 458 pLast = p;
rlm@1 459 }
rlm@1 460 else
rlm@1 461 pLast = NULL;
rlm@1 462 p = GetNextCharPointer(p);
rlm@1 463 }
rlm@1 464 if (pLast != NULL)
rlm@1 465 {
rlm@1 466 int i = pLast - _chars;
rlm@1 467 Delete(i, _length - i);
rlm@1 468 }
rlm@1 469 }
rlm@1 470 void Trim()
rlm@1 471 {
rlm@1 472 TrimRight();
rlm@1 473 TrimLeft();
rlm@1 474 }
rlm@1 475
rlm@1 476 int Insert(int index, T c)
rlm@1 477 {
rlm@1 478 InsertSpace(index, 1);
rlm@1 479 _chars[index] = c;
rlm@1 480 _length++;
rlm@1 481 return _length;
rlm@1 482 }
rlm@1 483 int Insert(int index, const CStringBase &s)
rlm@1 484 {
rlm@1 485 CorrectIndex(index);
rlm@1 486 if (s.IsEmpty())
rlm@1 487 return _length;
rlm@1 488 int numInsertChars = s.Length();
rlm@1 489 InsertSpace(index, numInsertChars);
rlm@1 490 for (int i = 0; i < numInsertChars; i++)
rlm@1 491 _chars[index + i] = s[i];
rlm@1 492 _length += numInsertChars;
rlm@1 493 return _length;
rlm@1 494 }
rlm@1 495
rlm@1 496 // !!!!!!!!!!!!!!! test it if newChar = '\0'
rlm@1 497 int Replace(T oldChar, T newChar)
rlm@1 498 {
rlm@1 499 if (oldChar == newChar)
rlm@1 500 return 0;
rlm@1 501 int number = 0;
rlm@1 502 int pos = 0;
rlm@1 503 while (pos < Length())
rlm@1 504 {
rlm@1 505 pos = Find(oldChar, pos);
rlm@1 506 if (pos < 0)
rlm@1 507 break;
rlm@1 508 _chars[pos] = newChar;
rlm@1 509 pos++;
rlm@1 510 number++;
rlm@1 511 }
rlm@1 512 return number;
rlm@1 513 }
rlm@1 514 int Replace(const CStringBase &oldString, const CStringBase &newString)
rlm@1 515 {
rlm@1 516 if (oldString.IsEmpty())
rlm@1 517 return 0;
rlm@1 518 if (oldString == newString)
rlm@1 519 return 0;
rlm@1 520 int oldStringLength = oldString.Length();
rlm@1 521 int newStringLength = newString.Length();
rlm@1 522 int number = 0;
rlm@1 523 int pos = 0;
rlm@1 524 while (pos < _length)
rlm@1 525 {
rlm@1 526 pos = Find(oldString, pos);
rlm@1 527 if (pos < 0)
rlm@1 528 break;
rlm@1 529 Delete(pos, oldStringLength);
rlm@1 530 Insert(pos, newString);
rlm@1 531 pos += newStringLength;
rlm@1 532 number++;
rlm@1 533 }
rlm@1 534 return number;
rlm@1 535 }
rlm@1 536 int Delete(int index, int count = 1 )
rlm@1 537 {
rlm@1 538 if (index + count > _length)
rlm@1 539 count = _length - index;
rlm@1 540 if (count > 0)
rlm@1 541 {
rlm@1 542 MoveItems(index, index + count);
rlm@1 543 _length -= count;
rlm@1 544 }
rlm@1 545 return _length;
rlm@1 546 }
rlm@1 547 };
rlm@1 548
rlm@1 549 template <class T>
rlm@1 550 CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)
rlm@1 551 {
rlm@1 552 CStringBase<T> result(s1);
rlm@1 553 result += s2;
rlm@1 554 return result;
rlm@1 555 }
rlm@1 556
rlm@1 557 template <class T>
rlm@1 558 CStringBase<T> operator+(const CStringBase<T>& s, T c)
rlm@1 559 {
rlm@1 560 CStringBase<T> result(s);
rlm@1 561 result += c;
rlm@1 562 return result;
rlm@1 563 }
rlm@1 564
rlm@1 565 template <class T>
rlm@1 566 CStringBase<T> operator+(T c, const CStringBase<T>& s)
rlm@1 567 {
rlm@1 568 CStringBase<T> result(c);
rlm@1 569 result += s;
rlm@1 570 return result;
rlm@1 571 }
rlm@1 572
rlm@1 573 template <class T>
rlm@1 574 CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)
rlm@1 575 {
rlm@1 576 CStringBase<T> result(s);
rlm@1 577 result += chars;
rlm@1 578 return result;
rlm@1 579 }
rlm@1 580
rlm@1 581 template <class T>
rlm@1 582 CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)
rlm@1 583 {
rlm@1 584 CStringBase<T> result(chars);
rlm@1 585 result += s;
rlm@1 586 return result;
rlm@1 587 }
rlm@1 588
rlm@1 589 template <class T>
rlm@1 590 bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)
rlm@1 591 { return (s1.Compare(s2) == 0); }
rlm@1 592
rlm@1 593 template <class T>
rlm@1 594 bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)
rlm@1 595 { return (s1.Compare(s2) < 0); }
rlm@1 596
rlm@1 597 template <class T>
rlm@1 598 bool operator==(const T *s1, const CStringBase<T>& s2)
rlm@1 599 { return (s2.Compare(s1) == 0); }
rlm@1 600
rlm@1 601 template <class T>
rlm@1 602 bool operator==(const CStringBase<T>& s1, const T *s2)
rlm@1 603 { return (s1.Compare(s2) == 0); }
rlm@1 604
rlm@1 605 template <class T>
rlm@1 606 bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)
rlm@1 607 { return (s1.Compare(s2) != 0); }
rlm@1 608
rlm@1 609 template <class T>
rlm@1 610 bool operator!=(const T *s1, const CStringBase<T>& s2)
rlm@1 611 { return (s2.Compare(s1) != 0); }
rlm@1 612
rlm@1 613 template <class T>
rlm@1 614 bool operator!=(const CStringBase<T>& s1, const T *s2)
rlm@1 615 { return (s1.Compare(s2) != 0); }
rlm@1 616
rlm@1 617 typedef CStringBase<char> AString;
rlm@1 618 typedef CStringBase<wchar_t> UString;
rlm@1 619
rlm@1 620 typedef CObjectVector<AString> AStringVector;
rlm@1 621 typedef CObjectVector<UString> UStringVector;
rlm@1 622
rlm@1 623 #ifdef _UNICODE
rlm@1 624 typedef UString CSysString;
rlm@1 625 #else
rlm@1 626 typedef AString CSysString;
rlm@1 627 #endif
rlm@1 628
rlm@1 629 typedef CObjectVector<CSysString> CSysStringVector;
rlm@1 630
rlm@1 631 #endif