String.h
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:34k
源码类别:

DVD

开发平台:

Unix_Linux

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /* 
  3. Copyright (C) 1988 Free Software Foundation
  4.     written by Doug Lea (dl@rocky.oswego.edu)
  5. This file is part of the GNU C++ Library.  This library is free
  6. software; you can redistribute it and/or modify it under the terms of
  7. the GNU Library General Public License as published by the Free
  8. Software Foundation; either version 2 of the License, or (at your
  9. option) any later version.  This library is distributed in the hope
  10. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  11. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE.  See the GNU Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #ifndef _String_h
  18. #ifdef __GNUG__
  19. #pragma interface
  20. #endif
  21. #define _String_h 1
  22. #include <iostream.h>
  23. #include <Regex.h>
  24. struct StrRep                     // internal String representations
  25. {
  26.   unsigned short    len;         // string length 
  27.   unsigned short    sz;          // allocated space
  28.   char              s[1];        // the string starts here 
  29.                                  // (at least 1 char for trailing null)
  30.                                  // allocated & expanded via non-public fcts
  31. };
  32. // primitive ops on StrReps -- nearly all String fns go through these.
  33. StrRep*     Salloc(StrRep*, const char*, int, int);
  34. StrRep*     Scopy(StrRep*, const StrRep*);
  35. StrRep*     Scat(StrRep*, const char*, int, const char*, int);
  36. StrRep*     Scat(StrRep*, const char*, int,const char*,int, const char*,int);
  37. StrRep*     Sprepend(StrRep*, const char*, int);
  38. StrRep*     Sreverse(const StrRep*, StrRep*);
  39. StrRep*     Supcase(const StrRep*, StrRep*);
  40. StrRep*     Sdowncase(const StrRep*, StrRep*);
  41. StrRep*     Scapitalize(const StrRep*, StrRep*);
  42. // These classes need to be defined in the order given
  43. class String;
  44. class SubString;
  45. class SubString
  46. {
  47.   friend class      String;
  48. protected:
  49.   String&           S;        // The String I'm a substring of
  50.   unsigned short    pos;      // starting position in S's rep
  51.   unsigned short    len;      // length of substring
  52.   void              assign(const StrRep*, const char*, int = -1);
  53.                     SubString(String& x, int p, int l);
  54.                     SubString(const SubString& x);
  55. public:
  56. // Note there are no public constructors. SubStrings are always
  57. // created via String operations
  58.                    ~SubString();
  59.   SubString&        operator =  (const String&     y);
  60.   SubString&        operator =  (const SubString&  y);
  61.   SubString&        operator =  (const char* t);
  62.   SubString&        operator =  (char        c);
  63. // return 1 if target appears anywhere in SubString; else 0
  64.   int               contains(char        c) const;
  65.   int               contains(const String&     y) const;
  66.   int               contains(const SubString&  y) const;
  67.   int               contains(const char* t) const;
  68.   int               contains(const Regex&       r) const;
  69. // return 1 if target matches entire SubString
  70.   int               matches(const Regex&  r) const;
  71. // IO 
  72.   friend ostream&   operator<<(ostream& s, const SubString& x);
  73. // status
  74.   unsigned int      length() const;
  75.   int               empty() const;
  76.   const char*       chars() const;
  77.   int               OK() const; 
  78. };
  79. class String
  80. {
  81.   friend class      SubString;
  82. protected:
  83.   StrRep*           rep;   // Strings are pointers to their representations
  84. // some helper functions
  85.   int               search(int, int, const char*, int = -1) const;
  86.   int               search(int, int, char) const;
  87.   int               match(int, int, int, const char*, int = -1) const;
  88.   int               _gsub(const char*, int, const char* ,int);
  89.   int               _gsub(const Regex&, const char*, int);
  90.   SubString         _substr(int, int);
  91. public:
  92. // constructors & assignment
  93.                     String();
  94.                     String(const String& x);
  95.                     String(const SubString&  x);
  96.                     String(const char* t);
  97.                     String(const char* t, int len);
  98.                     String(char c);
  99.                     ~String();
  100.   String&           operator =  (const String&     y);
  101.   String&           operator =  (const char* y);
  102.   String&           operator =  (char        c);
  103.   String&           operator =  (const SubString&  y);
  104. // concatenation
  105.   String&           operator += (const String&     y); 
  106.   String&           operator += (const SubString&  y);
  107.   String&           operator += (const char* t);
  108.   String&           operator += (char        c);
  109.   void              prepend(const String&     y); 
  110.   void              prepend(const SubString&  y);
  111.   void              prepend(const char* t);
  112.   void              prepend(char        c);
  113. // procedural versions:
  114. // concatenate first 2 args, store result in last arg
  115.   friend inline void     cat(const String&, const String&, String&);
  116.   friend inline void     cat(const String&, const SubString&, String&);
  117.   friend inline void     cat(const String&, const char*, String&);
  118.   friend inline void     cat(const String&, char, String&);
  119.   friend inline void     cat(const SubString&, const String&, String&);
  120.   friend inline void     cat(const SubString&, const SubString&, String&);
  121.   friend inline void     cat(const SubString&, const char*, String&);
  122.   friend inline void     cat(const SubString&, char, String&);
  123.   friend inline void     cat(const char*, const String&, String&);
  124.   friend inline void     cat(const char*, const SubString&, String&);
  125.   friend inline void     cat(const char*, const char*, String&);
  126.   friend inline void     cat(const char*, char, String&);
  127. // double concatenation, by request. (yes, there are too many versions, 
  128. // but if one is supported, then the others should be too...)
  129. // Concatenate first 3 args, store in last arg
  130.   friend inline void     cat(const String&,const String&, const String&,String&);
  131.   friend inline void     cat(const String&,const String&,const SubString&,String&);
  132.   friend inline void     cat(const String&,const String&, const char*, String&);
  133.   friend inline void     cat(const String&,const String&, char, String&);
  134.   friend inline void     cat(const String&,const SubString&,const String&,String&);
  135.   inline friend void     cat(const String&,const SubString&,const SubString&,String&);
  136.   friend inline void     cat(const String&,const SubString&, const char*, String&);
  137.   friend inline void     cat(const String&,const SubString&, char, String&);
  138.   friend inline void     cat(const String&,const char*, const String&,    String&);
  139.   friend inline void     cat(const String&,const char*, const SubString&, String&);
  140.   friend inline void     cat(const String&,const char*, const char*, String&);
  141.   friend inline void     cat(const String&,const char*, char, String&);
  142.   friend inline void     cat(const char*, const String&, const String&,String&);
  143.   friend inline void     cat(const char*,const String&,const SubString&,String&);
  144.   friend inline void     cat(const char*,const String&, const char*, String&);
  145.   friend inline void     cat(const char*,const String&, char, String&);
  146.   friend inline void     cat(const char*,const SubString&,const String&,String&);
  147.   friend inline void     cat(const char*,const SubString&,const SubString&,String&);
  148.   friend inline void     cat(const char*,const SubString&, const char*, String&);
  149.   friend inline void     cat(const char*,const SubString&, char, String&);
  150.   friend inline void     cat(const char*,const char*, const String&,    String&);
  151.   friend inline void     cat(const char*,const char*, const SubString&, String&);
  152.   friend inline void     cat(const char*,const char*, const char*, String&);
  153.   friend inline void     cat(const char*,const char*, char, String&);
  154. // searching & matching
  155. // return position of target in string or -1 for failure
  156.   int               index(char        c, int startpos = 0) const;      
  157.   int               index(const String&     y, int startpos = 0) const;      
  158.   int               index(const SubString&  y, int startpos = 0) const;      
  159.   int               index(const char* t, int startpos = 0) const;  
  160.   int               index(const Regex&      r, int startpos = 0) const;       
  161. // return 1 if target appears anyhere in String; else 0
  162.   int               contains(char        c) const;
  163.   int               contains(const String&     y) const;
  164.   int               contains(const SubString&  y) const;
  165.   int               contains(const char* t) const;
  166.   int               contains(const Regex&      r) const;
  167. // return 1 if target appears anywhere after position pos 
  168. // (or before, if pos is negative) in String; else 0
  169.   int               contains(char        c, int pos) const;
  170.   int               contains(const String&     y, int pos) const;
  171.   int               contains(const SubString&  y, int pos) const;
  172.   int               contains(const char* t, int pos) const;
  173.   int               contains(const Regex&      r, int pos) const;
  174. // return 1 if target appears at position pos in String; else 0
  175.   int               matches(char        c, int pos = 0) const;
  176.   int               matches(const String&     y, int pos = 0) const;
  177.   int               matches(const SubString&  y, int pos = 0) const;
  178.   int               matches(const char* t, int pos = 0) const;
  179.   int               matches(const Regex&      r, int pos = 0) const;
  180. //  return number of occurences of target in String
  181.   int               freq(char        c) const; 
  182.   int               freq(const String&     y) const;
  183.   int               freq(const SubString&  y) const;
  184.   int               freq(const char* t) const;
  185. // SubString extraction
  186. // Note that you can't take a substring of a const String, since
  187. // this leaves open the possiblility of indirectly modifying the
  188. // String through the SubString
  189.   SubString         at(int         pos, int len);
  190.   SubString         operator () (int         pos, int len); // synonym for at
  191.   SubString         at(const String&     x, int startpos = 0); 
  192.   SubString         at(const SubString&  x, int startpos = 0); 
  193.   SubString         at(const char* t, int startpos = 0);
  194.   SubString         at(char        c, int startpos = 0);
  195.   SubString         at(const Regex&      r, int startpos = 0); 
  196.   SubString         before(int          pos);
  197.   SubString         before(const String&      x, int startpos = 0);
  198.   SubString         before(const SubString&   x, int startpos = 0);
  199.   SubString         before(const char*  t, int startpos = 0);
  200.   SubString         before(char         c, int startpos = 0);
  201.   SubString         before(const Regex&       r, int startpos = 0);
  202.   SubString         through(int          pos);
  203.   SubString         through(const String&      x, int startpos = 0);
  204.   SubString         through(const SubString&   x, int startpos = 0);
  205.   SubString         through(const char*  t, int startpos = 0);
  206.   SubString         through(char         c, int startpos = 0);
  207.   SubString         through(const Regex&       r, int startpos = 0);
  208.   SubString         from(int          pos);
  209.   SubString         from(const String&      x, int startpos = 0);
  210.   SubString         from(const SubString&   x, int startpos = 0);
  211.   SubString         from(const char*  t, int startpos = 0);
  212.   SubString         from(char         c, int startpos = 0);
  213.   SubString         from(const Regex&       r, int startpos = 0);
  214.   SubString         after(int         pos);
  215.   SubString         after(const String&     x, int startpos = 0);
  216.   SubString         after(const SubString&  x, int startpos = 0);
  217.   SubString         after(const char* t, int startpos = 0);
  218.   SubString         after(char        c, int startpos = 0);
  219.   SubString         after(const Regex&      r, int startpos = 0);
  220. // deletion
  221. // delete len chars starting at pos
  222.   void              del(int         pos, int len);
  223. // delete the first occurrence of target after startpos
  224.   void              del(const String&     y, int startpos = 0);
  225.   void              del(const SubString&  y, int startpos = 0);
  226.   void              del(const char* t, int startpos = 0);
  227.   void              del(char        c, int startpos = 0);
  228.   void              del(const Regex&      r, int startpos = 0);
  229. // global substitution: substitute all occurrences of pat with repl
  230.   int               gsub(const String&     pat, const String&     repl);
  231.   int               gsub(const SubString&  pat, const String&     repl);
  232.   int               gsub(const char* pat, const String&     repl);
  233.   int               gsub(const char* pat, const char* repl);
  234.   int               gsub(const Regex&      pat, const String&     repl);
  235. // friends & utilities
  236. // split string into array res at separators; return number of elements
  237.   friend int        split(const String& x, String res[], int maxn, 
  238.                           const String& sep);
  239.   friend int        split(const String& x, String res[], int maxn, 
  240.                           const Regex&  sep);
  241.   friend String     common_prefix(const String& x, const String& y, 
  242.                                   int startpos = 0);
  243.   friend String     common_suffix(const String& x, const String& y, 
  244.                                   int startpos = -1);
  245.   friend String     replicate(char        c, int n);
  246.   friend String     replicate(const String&     y, int n);
  247.   friend String     join(String src[], int n, const String& sep);
  248. // simple builtin transformations
  249.   friend inline String     reverse(const String& x);
  250.   friend inline String     upcase(const String& x);
  251.   friend inline String     downcase(const String& x);
  252.   friend inline String     capitalize(const String& x);
  253. // in-place versions of above
  254.   void              reverse();
  255.   void              upcase();
  256.   void              downcase();
  257.   void              capitalize();
  258. // element extraction
  259.   char&             operator [] (int i);
  260.   const char&       operator [] (int i) const;
  261.   char              elem(int i) const;
  262.   char              firstchar() const;
  263.   char              lastchar() const;
  264. // conversion
  265.                     operator const char*() const;
  266.   const char*       chars() const;
  267. // IO
  268.   friend inline ostream&   operator<<(ostream& s, const String& x);
  269.   friend ostream&   operator<<(ostream& s, const SubString& x);
  270.   friend istream&   operator>>(istream& s, String& x);
  271.   friend int        readline(istream& s, String& x, 
  272.                              char terminator = 'n',
  273.                              int discard_terminator = 1);
  274. // status
  275.   unsigned int      length() const;
  276.   int               empty() const;
  277. // preallocate some space for String
  278.   void              alloc(int newsize);
  279. // report current allocation (not length!)
  280.   int               allocation() const;
  281.   void     error(const char* msg) const;
  282.   int               OK() const;
  283. };
  284. typedef String StrTmp; // for backward compatibility
  285. // other externs
  286. int        compare(const String&    x, const String&     y);
  287. int        compare(const String&    x, const SubString&  y);
  288. int        compare(const String&    x, const char* y);
  289. int        compare(const SubString& x, const String&     y);
  290. int        compare(const SubString& x, const SubString&  y);
  291. int        compare(const SubString& x, const char* y);
  292. int        fcompare(const String&   x, const String&     y); // ignore case
  293. extern StrRep  _nilStrRep;
  294. extern String _nilString;
  295. // status reports, needed before defining other things
  296. inline unsigned int String::length() const {  return rep->len; }
  297. inline int         String::empty() const { return rep->len == 0; }
  298. inline const char* String::chars() const { return &(rep->s[0]); }
  299. inline int         String::allocation() const { return rep->sz; }
  300. inline unsigned int SubString::length() const { return len; }
  301. inline int         SubString::empty() const { return len == 0; }
  302. inline const char* SubString::chars() const { return &(S.rep->s[pos]); }
  303. // constructors
  304. inline String::String() 
  305.   : rep(&_nilStrRep) {}
  306. inline String::String(const String& x) 
  307.   : rep(Scopy(0, x.rep)) {}
  308. inline String::String(const char* t) 
  309.   : rep(Salloc(0, t, -1, -1)) {}
  310. inline String::String(const char* t, int tlen)
  311.   : rep(Salloc(0, t, tlen, tlen)) {}
  312. inline String::String(const SubString& y)
  313.   : rep(Salloc(0, y.chars(), y.length(), y.length())) {}
  314. inline String::String(char c) 
  315.   : rep(Salloc(0, &c, 1, 1)) {}
  316. inline String::~String() { if (rep != &_nilStrRep) delete rep; }
  317. inline SubString::SubString(const SubString& x)
  318.   :S(x.S), pos(x.pos), len(x.len) {}
  319. inline SubString::SubString(String& x, int first, int l)
  320.   :S(x), pos(first), len(l) {}
  321. inline SubString::~SubString() {}
  322. // assignment
  323. inline String& String::operator =  (const String& y)
  324.   rep = Scopy(rep, y.rep);
  325.   return *this;
  326. }
  327. inline String& String::operator=(const char* t)
  328. {
  329.   rep = Salloc(rep, t, -1, -1);
  330.   return *this;
  331. }
  332. inline String& String::operator=(const SubString&  y)
  333. {
  334.   rep = Salloc(rep, y.chars(), y.length(), y.length());
  335.   return *this;
  336. }
  337. inline String& String::operator=(char c)
  338. {
  339.   rep = Salloc(rep, &c, 1, 1);
  340.   return *this;
  341. }
  342. inline SubString& SubString::operator = (const char* ys)
  343. {
  344.   assign(0, ys);
  345.   return *this;
  346. }
  347. inline SubString& SubString::operator = (char ch)
  348. {
  349.   assign(0, &ch, 1);
  350.   return *this;
  351. }
  352. inline SubString& SubString::operator = (const String& y)
  353. {
  354.   assign(y.rep, y.chars(), y.length());
  355.   return *this;
  356. }
  357. inline SubString& SubString::operator = (const SubString& y)
  358. {
  359.   assign(y.S.rep, y.chars(), y.length());
  360.   return *this;
  361. }
  362. // Zillions of cats...
  363. inline void cat(const String& x, const String& y, String& r)
  364. {
  365.   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  366. }
  367. inline void cat(const String& x, const SubString& y, String& r)
  368. {
  369.   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  370. }
  371. inline void cat(const String& x, const char* y, String& r)
  372. {
  373.   r.rep = Scat(r.rep, x.chars(), x.length(), y, -1);
  374. }
  375. inline void cat(const String& x, char y, String& r)
  376. {
  377.   r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
  378. }
  379. inline void cat(const SubString& x, const String& y, String& r)
  380. {
  381.   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  382. }
  383. inline void cat(const SubString& x, const SubString& y, String& r)
  384. {
  385.   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  386. }
  387. inline void cat(const SubString& x, const char* y, String& r)
  388. {
  389.   r.rep = Scat(r.rep, x.chars(), x.length(), y, -1);
  390. }
  391. inline void cat(const SubString& x, char y, String& r)
  392. {
  393.   r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
  394. }
  395. inline void cat(const char* x, const String& y, String& r)
  396. {
  397.   r.rep = Scat(r.rep, x, -1, y.chars(), y.length());
  398. }
  399. inline void cat(const char* x, const SubString& y, String& r)
  400. {
  401.   r.rep = Scat(r.rep, x, -1, y.chars(), y.length());
  402. }
  403. inline void cat(const char* x, const char* y, String& r)
  404. {
  405.   r.rep = Scat(r.rep, x, -1, y, -1);
  406. }
  407. inline void cat(const char* x, char y, String& r)
  408. {
  409.   r.rep = Scat(r.rep, x, -1, &y, 1);
  410. }
  411. inline void cat(const String& a, const String& x, const String& y, String& r)
  412. {
  413.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
  414. }
  415. inline void cat(const String& a, const String& x, const SubString& y, String& r)
  416. {
  417.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
  418. }
  419. inline void cat(const String& a, const String& x, const char* y, String& r)
  420. {
  421.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1);
  422. }
  423. inline void cat(const String& a, const String& x, char y, String& r)
  424. {
  425.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1);
  426. }
  427. inline void cat(const String& a, const SubString& x, const String& y, String& r)
  428. {
  429.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
  430. }
  431. inline void cat(const String& a, const SubString& x, const SubString& y, String& r)
  432. {
  433.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
  434. }
  435. inline void cat(const String& a, const SubString& x, const char* y, String& r)
  436. {
  437.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1);
  438. }
  439. inline void cat(const String& a, const SubString& x, char y, String& r)
  440. {
  441.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1);
  442. }
  443. inline void cat(const String& a, const char* x, const String& y, String& r)
  444. {
  445.   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length());
  446. }
  447. inline void cat(const String& a, const char* x, const SubString& y, String& r)
  448. {
  449.   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length());
  450. }
  451. inline void cat(const String& a, const char* x, const char* y, String& r)
  452. {
  453.   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y, -1);
  454. }
  455. inline void cat(const String& a, const char* x, char y, String& r)
  456. {
  457.   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, &y, 1);
  458. }
  459. inline void cat(const char* a, const String& x, const String& y, String& r)
  460. {
  461.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
  462. }
  463. inline void cat(const char* a, const String& x, const SubString& y, String& r)
  464. {
  465.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
  466. }
  467. inline void cat(const char* a, const String& x, const char* y, String& r)
  468. {
  469.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1);
  470. }
  471. inline void cat(const char* a, const String& x, char y, String& r)
  472. {
  473.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1);
  474. }
  475. inline void cat(const char* a, const SubString& x, const String& y, String& r)
  476. {
  477.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
  478. }
  479. inline void cat(const char* a, const SubString& x, const SubString& y, String& r)
  480. {
  481.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
  482. }
  483. inline void cat(const char* a, const SubString& x, const char* y, String& r)
  484. {
  485.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1);
  486. }
  487. inline void cat(const char* a, const SubString& x, char y, String& r)
  488. {
  489.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1);
  490. }
  491. inline void cat(const char* a, const char* x, const String& y, String& r)
  492. {
  493.   r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length());
  494. }
  495. inline void cat(const char* a, const char* x, const SubString& y, String& r)
  496. {
  497.   r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length());
  498. }
  499. inline void cat(const char* a, const char* x, const char* y, String& r)
  500. {
  501.   r.rep = Scat(r.rep, a, -1, x, -1, y, -1);
  502. }
  503. inline void cat(const char* a, const char* x, char y, String& r)
  504. {
  505.   r.rep = Scat(r.rep, a, -1, x, -1, &y, 1);
  506. }
  507. // operator versions
  508. inline String& String::operator +=(const String& y)
  509. {
  510.   cat(*this, y, *this);
  511.   return *this;
  512. }
  513. inline String& String::operator +=(const SubString& y)
  514. {
  515.   cat(*this, y, *this);
  516.   return *this;
  517. }
  518. inline String& String::operator += (const char* y)
  519. {
  520.   cat(*this, y, *this);
  521.   return *this;
  522. }
  523. inline String& String:: operator +=(char y)
  524. {
  525.   cat(*this, y, *this);
  526.   return *this;
  527. }
  528. // constructive concatenation
  529. #if defined(__GNUG__) && !defined(_G_NO_NRV)
  530. inline String operator + (const String& x, const String& y) return r;
  531. {
  532.   cat(x, y, r);
  533. }
  534. inline String operator + (const String& x, const SubString& y) return r;
  535. {
  536.   cat(x, y, r);
  537. }
  538. inline String operator + (const String& x, const char* y) return r;
  539. {
  540.   cat(x, y, r);
  541. }
  542. inline String operator + (const String& x, char y) return r;
  543. {
  544.   cat(x, y, r);
  545. }
  546. inline String operator + (const SubString& x, const String& y) return r;
  547. {
  548.   cat(x, y, r);
  549. }
  550. inline String operator + (const SubString& x, const SubString& y) return r;
  551. {
  552.   cat(x, y, r);
  553. }
  554. inline String operator + (const SubString& x, const char* y) return r;
  555. {
  556.   cat(x, y, r);
  557. }
  558. inline String operator + (const SubString& x, char y) return r;
  559. {
  560.   cat(x, y, r);
  561. }
  562. inline String operator + (const char* x, const String& y) return r;
  563. {
  564.   cat(x, y, r);
  565. }
  566. inline String operator + (const char* x, const SubString& y) return r;
  567. {
  568.   cat(x, y, r);
  569. }
  570. inline String reverse(const String& x) return r;
  571. {
  572.   r.rep = Sreverse(x.rep, r.rep);
  573. }
  574. inline String upcase(const String& x) return r;
  575. {
  576.   r.rep = Supcase(x.rep, r.rep);
  577. }
  578. inline String downcase(const String& x) return r;
  579. {
  580.   r.rep = Sdowncase(x.rep, r.rep);
  581. }
  582. inline String capitalize(const String& x) return r;
  583. {
  584.   r.rep = Scapitalize(x.rep, r.rep);
  585. }
  586. #else /* NO_NRV */
  587. inline String operator + (const String& x, const String& y)
  588. {
  589.   String r;  cat(x, y, r);  return r;
  590. }
  591. inline String operator + (const String& x, const SubString& y) 
  592. {
  593.   String r; cat(x, y, r); return r;
  594. }
  595. inline String operator + (const String& x, const char* y) 
  596. {
  597.   String r; cat(x, y, r); return r;
  598. }
  599. inline String operator + (const String& x, char y) 
  600. {
  601.   String r; cat(x, y, r); return r;
  602. }
  603. inline String operator + (const SubString& x, const String& y) 
  604. {
  605.   String r; cat(x, y, r); return r;
  606. }
  607. inline String operator + (const SubString& x, const SubString& y) 
  608. {
  609.   String r; cat(x, y, r); return r;
  610. }
  611. inline String operator + (const SubString& x, const char* y) 
  612. {
  613.   String r; cat(x, y, r); return r;
  614. }
  615. inline String operator + (const SubString& x, char y) 
  616. {
  617.   String r; cat(x, y, r); return r;
  618. }
  619. inline String operator + (const char* x, const String& y) 
  620. {
  621.   String r; cat(x, y, r); return r;
  622. }
  623. inline String operator + (const char* x, const SubString& y) 
  624. {
  625.   String r; cat(x, y, r); return r;
  626. }
  627. inline String reverse(const String& x) 
  628. {
  629.   String r; r.rep = Sreverse(x.rep, r.rep); return r;
  630. }
  631. inline String upcase(const String& x) 
  632. {
  633.   String r; r.rep = Supcase(x.rep, r.rep); return r;
  634. }
  635. inline String downcase(const String& x) 
  636. {
  637.   String r; r.rep = Sdowncase(x.rep, r.rep); return r;
  638. }
  639. inline String capitalize(const String& x) 
  640. {
  641.   String r; r.rep = Scapitalize(x.rep, r.rep); return r;
  642. }
  643. #endif
  644. // prepend
  645. inline void String::prepend(const String& y)
  646. {
  647.   rep = Sprepend(rep, y.chars(), y.length());
  648. }
  649. inline void String::prepend(const char* y)
  650. {
  651.   rep = Sprepend(rep, y, -1); 
  652. }
  653. inline void String::prepend(char y)
  654. {
  655.   rep = Sprepend(rep, &y, 1); 
  656. }
  657. inline void String::prepend(const SubString& y)
  658. {
  659.   rep = Sprepend(rep, y.chars(), y.length());
  660. }
  661. // misc transformations
  662. inline void String::reverse()
  663. {
  664.   rep = Sreverse(rep, rep);
  665. }
  666. inline void String::upcase()
  667. {
  668.   rep = Supcase(rep, rep);
  669. }
  670. inline void String::downcase()
  671. {
  672.   rep = Sdowncase(rep, rep);
  673. }
  674. inline void String::capitalize()
  675. {
  676.   rep = Scapitalize(rep, rep);
  677. }
  678. // element extraction
  679. inline char&  String::operator [] (int i) 
  680.   if (((unsigned)i) >= length()) error("invalid index");
  681.   return rep->s[i];
  682. }
  683. inline const char&  String::operator [] (int i) const
  684.   if (((unsigned)i) >= length()) error("invalid index");
  685.   return rep->s[i];
  686. }
  687. inline char  String::elem (int i) const
  688.   if (((unsigned)i) >= length()) error("invalid index");
  689.   return rep->s[i];
  690. }
  691. inline char  String::firstchar() const
  692.   return elem(0);
  693. }
  694. inline char  String::lastchar() const
  695.   return elem(length() - 1);
  696. }
  697. // searching
  698. inline int String::index(char c, int startpos) const
  699. {
  700.   return search(startpos, length(), c);
  701. }
  702. inline int String::index(const char* t, int startpos) const
  703. {   
  704.   return search(startpos, length(), t);
  705. }
  706. inline int String::index(const String& y, int startpos) const
  707. {   
  708.   return search(startpos, length(), y.chars(), y.length());
  709. }
  710. inline int String::index(const SubString& y, int startpos) const
  711. {   
  712.   return search(startpos, length(), y.chars(), y.length());
  713. }
  714. inline int String::index(const Regex& r, int startpos) const
  715. {
  716.   int unused;  return r.search(chars(), length(), unused, startpos);
  717. }
  718. inline int String::contains(char c) const
  719. {
  720.   return search(0, length(), c) >= 0;
  721. }
  722. inline int String::contains(const char* t) const
  723. {   
  724.   return search(0, length(), t) >= 0;
  725. }
  726. inline int String::contains(const String& y) const
  727. {   
  728.   return search(0, length(), y.chars(), y.length()) >= 0;
  729. }
  730. inline int String::contains(const SubString& y) const
  731. {   
  732.   return search(0, length(), y.chars(), y.length()) >= 0;
  733. }
  734. inline int String::contains(char c, int p) const
  735. {
  736.   return match(p, length(), 0, &c, 1) >= 0;
  737. }
  738. inline int String::contains(const char* t, int p) const
  739. {
  740.   return match(p, length(), 0, t) >= 0;
  741. }
  742. inline int String::contains(const String& y, int p) const
  743. {
  744.   return match(p, length(), 0, y.chars(), y.length()) >= 0;
  745. }
  746. inline int String::contains(const SubString& y, int p) const
  747. {
  748.   return match(p, length(), 0, y.chars(), y.length()) >= 0;
  749. }
  750. inline int String::contains(const Regex& r) const
  751. {
  752.   int unused;  return r.search(chars(), length(), unused, 0) >= 0;
  753. }
  754. inline int String::contains(const Regex& r, int p) const
  755. {
  756.   return r.match(chars(), length(), p) >= 0;
  757. }
  758. inline int String::matches(const SubString& y, int p) const
  759. {
  760.   return match(p, length(), 1, y.chars(), y.length()) >= 0;
  761. }
  762. inline int String::matches(const String& y, int p) const
  763. {
  764.   return match(p, length(), 1, y.chars(), y.length()) >= 0;
  765. }
  766. inline int String::matches(const char* t, int p) const
  767. {
  768.   return match(p, length(), 1, t) >= 0;
  769. }
  770. inline int String::matches(char c, int p) const
  771. {
  772.   return match(p, length(), 1, &c, 1) >= 0;
  773. }
  774. inline int String::matches(const Regex& r, int p) const
  775. {
  776.   int l = (p < 0)? -p : length() - p;
  777.   return r.match(chars(), length(), p) == l;
  778. }
  779. inline int SubString::contains(const char* t) const
  780. {   
  781.   return S.search(pos, pos+len, t) >= 0;
  782. }
  783. inline int SubString::contains(const String& y) const
  784. {   
  785.   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
  786. }
  787. inline int SubString::contains(const SubString&  y) const
  788. {   
  789.   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
  790. }
  791. inline int SubString::contains(char c) const
  792. {
  793.   return S.search(pos, pos+len, c) >= 0;
  794. }
  795. inline int SubString::contains(const Regex& r) const
  796. {
  797.   int unused;  return r.search(chars(), len, unused, 0) >= 0;
  798. }
  799. inline int SubString::matches(const Regex& r) const
  800. {
  801.   return r.match(chars(), len, 0) == len;
  802. }
  803. inline int String::gsub(const String& pat, const String& r)
  804. {
  805.   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
  806. }
  807. inline int String::gsub(const SubString&  pat, const String& r)
  808. {
  809.   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
  810. }
  811. inline int String::gsub(const Regex& pat, const String& r)
  812. {
  813.   return _gsub(pat, r.chars(), r.length());
  814. }
  815. inline int String::gsub(const char* pat, const String& r)
  816. {
  817.   return _gsub(pat, -1, r.chars(), r.length());
  818. }
  819. inline int String::gsub(const char* pat, const char* r)
  820. {
  821.   return _gsub(pat, -1, r, -1);
  822. }
  823. inline  ostream& operator<<(ostream& s, const String& x)
  824. {
  825.    s << x.chars(); return s;
  826. }
  827. // a zillion comparison operators
  828. inline int operator==(const String& x, const String& y) 
  829. {
  830.   return compare(x, y) == 0; 
  831. }
  832. inline int operator!=(const String& x, const String& y)
  833. {
  834.   return compare(x, y) != 0; 
  835. }
  836. inline int operator>(const String& x, const String& y)
  837. {
  838.   return compare(x, y) > 0; 
  839. }
  840. inline int operator>=(const String& x, const String& y)
  841. {
  842.   return compare(x, y) >= 0; 
  843. }
  844. inline int operator<(const String& x, const String& y)
  845. {
  846.   return compare(x, y) < 0; 
  847. }
  848. inline int operator<=(const String& x, const String& y)
  849. {
  850.   return compare(x, y) <= 0; 
  851. }
  852. inline int operator==(const String& x, const SubString&  y) 
  853. {
  854.   return compare(x, y) == 0; 
  855. }
  856. inline int operator!=(const String& x, const SubString&  y)
  857. {
  858.   return compare(x, y) != 0; 
  859. }
  860. inline int operator>(const String& x, const SubString&  y)      
  861. {
  862.   return compare(x, y) > 0; 
  863. }
  864. inline int operator>=(const String& x, const SubString&  y)
  865. {
  866.   return compare(x, y) >= 0; 
  867. }
  868. inline int operator<(const String& x, const SubString&  y) 
  869. {
  870.   return compare(x, y) < 0; 
  871. }
  872. inline int operator<=(const String& x, const SubString&  y)
  873. {
  874.   return compare(x, y) <= 0; 
  875. }
  876. inline int operator==(const String& x, const char* t) 
  877. {
  878.   return compare(x, t) == 0; 
  879. }
  880. inline int operator!=(const String& x, const char* t) 
  881. {
  882.   return compare(x, t) != 0; 
  883. }
  884. inline int operator>(const String& x, const char* t)  
  885. {
  886.   return compare(x, t) > 0; 
  887. }
  888. inline int operator>=(const String& x, const char* t) 
  889. {
  890.   return compare(x, t) >= 0; 
  891. }
  892. inline int operator<(const String& x, const char* t)  
  893. {
  894.   return compare(x, t) < 0; 
  895. }
  896. inline int operator<=(const String& x, const char* t) 
  897. {
  898.   return compare(x, t) <= 0; 
  899. }
  900. inline int operator==(const SubString& x, const String& y) 
  901. {
  902.   return compare(y, x) == 0; 
  903. }
  904. inline int operator!=(const SubString& x, const String& y)
  905. {
  906.   return compare(y, x) != 0;
  907. }
  908. inline int operator>(const SubString& x, const String& y)      
  909. {
  910.   return compare(y, x) < 0;
  911. }
  912. inline int operator>=(const SubString& x, const String& y)     
  913. {
  914.   return compare(y, x) <= 0;
  915. }
  916. inline int operator<(const SubString& x, const String& y)      
  917. {
  918.   return compare(y, x) > 0;
  919. }
  920. inline int operator<=(const SubString& x, const String& y)     
  921. {
  922.   return compare(y, x) >= 0;
  923. }
  924. inline int operator==(const SubString& x, const SubString&  y) 
  925. {
  926.   return compare(x, y) == 0; 
  927. }
  928. inline int operator!=(const SubString& x, const SubString&  y)
  929. {
  930.   return compare(x, y) != 0;
  931. }
  932. inline int operator>(const SubString& x, const SubString&  y)      
  933. {
  934.   return compare(x, y) > 0;
  935. }
  936. inline int operator>=(const SubString& x, const SubString&  y)
  937. {
  938.   return compare(x, y) >= 0;
  939. }
  940. inline int operator<(const SubString& x, const SubString&  y) 
  941. {
  942.   return compare(x, y) < 0;
  943. }
  944. inline int operator<=(const SubString& x, const SubString&  y)
  945. {
  946.   return compare(x, y) <= 0;
  947. }
  948. inline int operator==(const SubString& x, const char* t) 
  949. {
  950.   return compare(x, t) == 0; 
  951. }
  952. inline int operator!=(const SubString& x, const char* t) 
  953. {
  954.   return compare(x, t) != 0;
  955. }
  956. inline int operator>(const SubString& x, const char* t)  
  957. {
  958.   return compare(x, t) > 0; 
  959. }
  960. inline int operator>=(const SubString& x, const char* t) 
  961. {
  962.   return compare(x, t) >= 0; 
  963. }
  964. inline int operator<(const SubString& x, const char* t)  
  965. {
  966.   return compare(x, t) < 0; 
  967. }
  968. inline int operator<=(const SubString& x, const char* t) 
  969. {
  970.   return compare(x, t) <= 0; 
  971. }
  972. // a helper needed by at, before, etc.
  973. inline SubString String::_substr(int first, int l)
  974. {
  975.   if (first < 0 || (unsigned)(first + l) > length() )
  976.     return SubString(_nilString, 0, 0) ;
  977.   else 
  978.     return SubString(*this, first, l);
  979. }
  980. #endif