home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Dev / GCC / GNU / lib / g++-include / _String.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-31  |  35.6 KB  |  1,329 lines

  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.  
  6. This file is part of the GNU C++ Library.  This library is free
  7. software; you can redistribute it and/or modify it under the terms of
  8. the GNU Library General Public License as published by the Free
  9. Software Foundation; either version 2 of the License, or (at your
  10. option) any later version.  This library is distributed in the hope
  11. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  12. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  13. PURPOSE.  See the GNU Library General Public License for more details.
  14. You should have received a copy of the GNU Library General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19.  
  20. #ifndef _String_h
  21. #ifdef __GNUG__
  22. #pragma interface
  23. #endif
  24. #define _String_h 1
  25.  
  26. #include <iostream.h>
  27. #include <Regex.h>
  28.  
  29. struct StrRep                     // internal String representations
  30. {
  31.   unsigned short    len;         // string length 
  32.   unsigned short    sz;          // allocated space
  33.   char              s[1];        // the string starts here 
  34.                                  // (at least 1 char for trailing null)
  35.                                  // allocated & expanded via non-public fcts
  36. };
  37.  
  38. // primitive ops on StrReps -- nearly all String fns go through these.
  39.  
  40. StrRep*     Salloc(StrRep*, const char*, int, int);
  41. StrRep*     Scopy(StrRep*, const StrRep*);
  42. StrRep*     Sresize(StrRep*, int);
  43. StrRep*     Scat(StrRep*, const char*, int, const char*, int);
  44. StrRep*     Scat(StrRep*, const char*, int,const char*,int, const char*,int);
  45. StrRep*     Sprepend(StrRep*, const char*, int);
  46. StrRep*     Sreverse(const StrRep*, StrRep*);
  47. StrRep*     Supcase(const StrRep*, StrRep*);
  48. StrRep*     Sdowncase(const StrRep*, StrRep*);
  49. StrRep*     Scapitalize(const StrRep*, StrRep*);
  50.  
  51. // These classes need to be defined in the order given
  52.  
  53. class String;
  54. class SubString;
  55.  
  56. class SubString
  57. {
  58.   friend class      String;
  59. protected:
  60.  
  61.   String&           S;        // The String I'm a substring of
  62.   unsigned short    pos;      // starting position in S's rep
  63.   unsigned short    len;      // length of substring
  64.  
  65.   void              assign(const StrRep*, const char*, int = -1);
  66.                     SubString(String& x, int p, int l);
  67.                     SubString(const SubString& x);
  68.  
  69. public:
  70.  
  71. // Note there are no public constructors. SubStrings are always
  72. // created via String operations
  73.  
  74.                    ~SubString();
  75.  
  76.   SubString&        operator =  (const String&     y);
  77.   SubString&        operator =  (const SubString&  y);
  78.   SubString&        operator =  (const char* t);
  79.   SubString&        operator =  (char        c);
  80.  
  81. // return 1 if target appears anywhere in SubString; else 0
  82.  
  83.   int               contains(char        c) const;
  84.   int               contains(const String&     y) const;
  85.   int               contains(const SubString&  y) const;
  86.   int               contains(const char* t) const;
  87.   int               contains(const Regex&       r) const;
  88.  
  89. // return 1 if target matches entire SubString
  90.  
  91.   int               matches(const Regex&  r) const;
  92.  
  93. // IO 
  94.  
  95.   friend ostream&   operator<<(ostream& s, const SubString& x);
  96.  
  97. // status
  98.  
  99.   unsigned int      length() const;
  100.   int               empty() const;
  101.   const char*       chars() const;
  102.  
  103.   int               OK() const; 
  104.  
  105. };
  106.  
  107.  
  108. class String
  109. {
  110.   friend class      SubString;
  111.  
  112. protected:
  113.   StrRep*           rep;   // Strings are pointers to their representations
  114.  
  115. // some helper functions
  116.  
  117.   int               search(int, int, const char*, int = -1) const;
  118.   int               search(int, int, char) const;
  119.   int               match(int, int, int, const char*, int = -1) const;
  120.   int               _gsub(const char*, int, const char* ,int);
  121.   int               _gsub(const Regex&, const char*, int);
  122.   SubString         _substr(int, int);
  123.  
  124. public:
  125.  
  126. // constructors & assignment
  127.  
  128.                     String();
  129.                     String(const String& x);
  130.                     String(const SubString&  x);
  131.                     String(const char* t);
  132.                     String(const char* t, int len);
  133.                     String(char c);
  134.  
  135.                     ~String();
  136.  
  137.   String&           operator =  (const String&     y);
  138.   String&           operator =  (const char* y);
  139.   String&           operator =  (char        c);
  140.   String&           operator =  (const SubString&  y);
  141.  
  142. // concatenation
  143.  
  144.   String&           operator += (const String&     y); 
  145.   String&           operator += (const SubString&  y);
  146.   String&           operator += (const char* t);
  147.   String&           operator += (char        c);
  148.  
  149.   void              prepend(const String&     y); 
  150.   void              prepend(const SubString&  y);
  151.   void              prepend(const char* t);
  152.   void              prepend(char        c);
  153.  
  154.  
  155. // procedural versions:
  156. // concatenate first 2 args, store result in last arg
  157.  
  158.   friend void     cat(const String&, const String&, String&);
  159.   friend void     cat(const String&, const SubString&, String&);
  160.   friend void     cat(const String&, const char*, String&);
  161.   friend void     cat(const String&, char, String&);
  162.  
  163.   friend void     cat(const SubString&, const String&, String&);
  164.   friend void     cat(const SubString&, const SubString&, String&);
  165.   friend void     cat(const SubString&, const char*, String&);
  166.   friend void     cat(const SubString&, char, String&);
  167.  
  168.   friend void     cat(const char*, const String&, String&);
  169.   friend void     cat(const char*, const SubString&, String&);
  170.   friend void     cat(const char*, const char*, String&);
  171.   friend void     cat(const char*, char, String&);
  172.  
  173. // double concatenation, by request. (yes, there are too many versions, 
  174. // but if one is supported, then the others should be too...)
  175. // Concatenate first 3 args, store in last arg
  176.  
  177.   friend void     cat(const String&,const String&, const String&,String&);
  178.   friend void     cat(const String&,const String&,const SubString&,String&);
  179.   friend void     cat(const String&,const String&, const char*, String&);
  180.   friend void     cat(const String&,const String&, char, String&);
  181.   friend void     cat(const String&,const SubString&,const String&,String&);
  182.   friend void     cat(const String&,const SubString&,const SubString&,String&);
  183.   friend void     cat(const String&,const SubString&, const char*, String&);
  184.   friend void     cat(const String&,const SubString&, char, String&);
  185.   friend void     cat(const String&,const char*, const String&,    String&);
  186.   friend void     cat(const String&,const char*, const SubString&, String&);
  187.   friend void     cat(const String&,const char*, const char*, String&);
  188.   friend void     cat(const String&,const char*, char, String&);
  189.  
  190.   friend void     cat(const char*, const String&, const String&,String&);
  191.   friend void     cat(const char*,const String&,const SubString&,String&);
  192.   friend void     cat(const char*,const String&, const char*, String&);
  193.   friend void     cat(const char*,const String&, char, String&);
  194.   friend void     cat(const char*,const SubString&,const String&,String&);
  195.   friend void     cat(const char*,const SubString&,const SubString&,String&);
  196.   friend void     cat(const char*,const SubString&, const char*, String&);
  197.   friend void     cat(const char*,const SubString&, char, String&);
  198.   friend void     cat(const char*,const char*, const String&,    String&);
  199.   friend void     cat(const char*,const char*, const SubString&, String&);
  200.   friend void     cat(const char*,const char*, const char*, String&);
  201.   friend void     cat(const char*,const char*, char, String&);
  202.  
  203.  
  204. // searching & matching
  205.  
  206. // return position of target in string or -1 for failure
  207.  
  208.   int               index(char        c, int startpos = 0) const;      
  209.   int               index(const String&     y, int startpos = 0) const;      
  210.   int               index(const SubString&  y, int startpos = 0) const;      
  211.   int               index(const char* t, int startpos = 0) const;  
  212.   int               index(const Regex&      r, int startpos = 0) const;       
  213.  
  214. // return 1 if target appears anyhere in String; else 0
  215.  
  216.   int               contains(char        c) const;
  217.   int               contains(const String&     y) const;
  218.   int               contains(const SubString&  y) const;
  219.   int               contains(const char* t) const;
  220.   int               contains(const Regex&      r) const;
  221.  
  222. // return 1 if target appears anywhere after position pos 
  223. // (or before, if pos is negative) in String; else 0
  224.  
  225.   int               contains(char        c, int pos) const;
  226.   int               contains(const String&     y, int pos) const;
  227.   int               contains(const SubString&  y, int pos) const;
  228.   int               contains(const char* t, int pos) const;
  229.   int               contains(const Regex&      r, int pos) const;
  230.  
  231. // return 1 if target appears at position pos in String; else 0
  232.  
  233.   int               matches(char        c, int pos = 0) const;
  234.   int               matches(const String&     y, int pos = 0) const;
  235.   int               matches(const SubString&  y, int pos = 0) const;
  236.   int               matches(const char* t, int pos = 0) const;
  237.   int               matches(const Regex&      r, int pos = 0) const;
  238.  
  239. //  return number of occurences of target in String
  240.  
  241.   int               freq(char        c) const; 
  242.   int               freq(const String&     y) const;
  243.   int               freq(const SubString&  y) const;
  244.   int               freq(const char* t) const;
  245.  
  246. // SubString extraction
  247.  
  248. // Note that you can't take a substring of a const String, since
  249. // this leaves open the possiblility of indirectly modifying the
  250. // String through the SubString
  251.  
  252.   SubString         at(int         pos, int len);
  253.   SubString         operator () (int         pos, int len); // synonym for at
  254.  
  255.   SubString         at(const String&     x, int startpos = 0); 
  256.   SubString         at(const SubString&  x, int startpos = 0); 
  257.   SubString         at(const char* t, int startpos = 0);
  258.   SubString         at(char        c, int startpos = 0);
  259.   SubString         at(const Regex&      r, int startpos = 0); 
  260.  
  261.   SubString         before(int          pos);
  262.   SubString         before(const String&      x, int startpos = 0);
  263.   SubString         before(const SubString&   x, int startpos = 0);
  264.   SubString         before(const char*  t, int startpos = 0);
  265.   SubString         before(char         c, int startpos = 0);
  266.   SubString         before(const Regex&       r, int startpos = 0);
  267.  
  268.   SubString         through(int          pos);
  269.   SubString         through(const String&      x, int startpos = 0);
  270.   SubString         through(const SubString&   x, int startpos = 0);
  271.   SubString         through(const char*  t, int startpos = 0);
  272.   SubString         through(char         c, int startpos = 0);
  273.   SubString         through(const Regex&       r, int startpos = 0);
  274.  
  275.   SubString         from(int          pos);
  276.   SubString         from(const String&      x, int startpos = 0);
  277.   SubString         from(const SubString&   x, int startpos = 0);
  278.   SubString         from(const char*  t, int startpos = 0);
  279.   SubString         from(char         c, int startpos = 0);
  280.   SubString         from(const Regex&       r, int startpos = 0);
  281.  
  282.   SubString         after(int         pos);
  283.   SubString         after(const String&     x, int startpos = 0);
  284.   SubString         after(const SubString&  x, int startpos = 0);
  285.   SubString         after(const char* t, int startpos = 0);
  286.   SubString         after(char        c, int startpos = 0);
  287.   SubString         after(const Regex&      r, int startpos = 0);
  288.  
  289.  
  290. // deletion
  291.  
  292. // delete len chars starting at pos
  293.   void              del(int         pos, int len);
  294.  
  295. // delete the first occurrence of target after startpos
  296.  
  297.   void              del(const String&     y, int startpos = 0);
  298.   void              del(const SubString&  y, int startpos = 0);
  299.   void              del(const char* t, int startpos = 0);
  300.   void              del(char        c, int startpos = 0);
  301.   void              del(const Regex&      r, int startpos = 0);
  302.  
  303. // global substitution: substitute all occurrences of pat with repl
  304.  
  305.   int               gsub(const String&     pat, const String&     repl);
  306.   int               gsub(const SubString&  pat, const String&     repl);
  307.   int               gsub(const char* pat, const String&     repl);
  308.   int               gsub(const char* pat, const char* repl);
  309.   int               gsub(const Regex&      pat, const String&     repl);
  310.  
  311. // friends & utilities
  312.  
  313. // split string into array res at separators; return number of elements
  314.  
  315.   friend int        split(const String& x, String res[], int maxn, 
  316.                           const String& sep);
  317.   friend int        split(const String& x, String res[], int maxn, 
  318.                           const Regex&  sep);
  319.  
  320.   friend String     common_prefix(const String& x, const String& y, 
  321.                                   int startpos = 0);
  322.   friend String     common_suffix(const String& x, const String& y, 
  323.                                   int startpos = -1);
  324.   friend String     replicate(char        c, int n);
  325.   friend String     replicate(const String&     y, int n);
  326.   friend String     join(String src[], int n, const String& sep);
  327.  
  328. // simple builtin transformations
  329.  
  330.   friend String     reverse(const String& x);
  331.   friend String     upcase(const String& x);
  332.   friend String     downcase(const String& x);
  333.   friend String     capitalize(const String& x);
  334.  
  335. // in-place versions of above
  336.  
  337.   void              reverse();
  338.   void              upcase();
  339.   void              downcase();
  340.   void              capitalize();
  341.  
  342. // element extraction
  343.  
  344.   char&             operator [] (int i);
  345.   char              elem(int i) const;
  346.   char              firstchar() const;
  347.   char              lastchar() const;
  348.  
  349. // conversion
  350.  
  351.                     operator const char*() const;
  352.   const char*       chars() const;
  353.  
  354.  
  355. // IO
  356.  
  357.   friend ostream&   operator<<(ostream& s, const String& x);
  358.   friend ostream&   operator<<(ostream& s, const SubString& x);
  359.   friend istream&   operator>>(istream& s, String& x);
  360.  
  361.   friend int        readline(istream& s, String& x, 
  362.                              char terminator = '\n',
  363.                              int discard_terminator = 1);
  364.  
  365. // status
  366.  
  367.   unsigned int      length() const;
  368.   int               empty() const;
  369.  
  370. // preallocate some space for String
  371.   void              alloc(int newsize);
  372.  
  373. // report current allocation (not length!)
  374.  
  375.   int               allocation() const;
  376.  
  377.  
  378.   void     error(const char* msg) const;
  379.  
  380.   int               OK() const;
  381. };
  382.  
  383. typedef String StrTmp; // for backward compatibility
  384.  
  385. // other externs
  386.  
  387. int        compare(const String&    x, const String&     y);
  388. int        compare(const String&    x, const SubString&  y);
  389. int        compare(const String&    x, const char* y);
  390. int        compare(const SubString& x, const String&     y);
  391. int        compare(const SubString& x, const SubString&  y);
  392. int        compare(const SubString& x, const char* y);
  393. int        fcompare(const String&   x, const String&     y); // ignore case
  394.  
  395. extern StrRep  _nilStrRep;
  396. extern String _nilString;
  397.  
  398. // other inlines
  399.  
  400. String operator + (const String& x, const String& y);
  401. String operator + (const String& x, const SubString& y);
  402. String operator + (const String& x, const char* y);
  403. String operator + (const String& x, char y);
  404. String operator + (const SubString& x, const String& y);
  405. String operator + (const SubString& x, const SubString& y);
  406. String operator + (const SubString& x, const char* y);
  407. String operator + (const SubString& x, char y);
  408. String operator + (const char* x, const String& y);
  409. String operator + (const char* x, const SubString& y);
  410.  
  411. int operator==(const String& x, const String& y); 
  412. int operator!=(const String& x, const String& y);
  413. int operator> (const String& x, const String& y);
  414. int operator>=(const String& x, const String& y);
  415. int operator< (const String& x, const String& y);
  416. int operator<=(const String& x, const String& y);
  417. int operator==(const String& x, const SubString&  y);
  418. int operator!=(const String& x, const SubString&  y);
  419. int operator> (const String& x, const SubString&  y);
  420. int operator>=(const String& x, const SubString&  y);
  421. int operator< (const String& x, const SubString&  y);
  422. int operator<=(const String& x, const SubString&  y);
  423. int operator==(const String& x, const char* t);
  424. int operator!=(const String& x, const char* t);
  425. int operator> (const String& x, const char* t);
  426. int operator>=(const String& x, const char* t);
  427. int operator< (const String& x, const char* t);
  428. int operator<=(const String& x, const char* t);
  429. int operator==(const SubString& x, const String& y);
  430. int operator!=(const SubString& x, const String& y);
  431. int operator> (const SubString& x, const String& y);
  432. int operator>=(const SubString& x, const String& y);
  433. int operator< (const SubString& x, const String& y);
  434. int operator<=(const SubString& x, const String& y);
  435. int operator==(const SubString& x, const SubString&  y);
  436. int operator!=(const SubString& x, const SubString&  y);
  437. int operator> (const SubString& x, const SubString&  y);
  438. int operator>=(const SubString& x, const SubString&  y);
  439. int operator< (const SubString& x, const SubString&  y);
  440. int operator<=(const SubString& x, const SubString&  y);
  441. int operator==(const SubString& x, const char* t);
  442. int operator!=(const SubString& x, const char* t);
  443. int operator> (const SubString& x, const char* t);
  444. int operator>=(const SubString& x, const char* t);
  445. int operator< (const SubString& x, const char* t);
  446. int operator<=(const SubString& x, const char* t);
  447.  
  448.  
  449. // status reports, needed before defining other things
  450.  
  451. inline unsigned int String::length() const {  return rep->len; }
  452. inline int         String::empty() const { return rep->len == 0; }
  453. inline const char* String::chars() const { return &(rep->s[0]); }
  454. inline int         String::allocation() const { return rep->sz; }
  455. inline void        String::alloc(int newsize) { rep = Sresize(rep, newsize); }
  456.  
  457. inline unsigned int SubString::length() const { return len; }
  458. inline int         SubString::empty() const { return len == 0; }
  459. inline const char* SubString::chars() const { return &(S.rep->s[pos]); }
  460.  
  461.  
  462. // constructors
  463.  
  464. inline String::String() 
  465.   : rep(&_nilStrRep) {}
  466. inline String::String(const String& x) 
  467.   : rep(Scopy(0, x.rep)) {}
  468. inline String::String(const char* t) 
  469.   : rep(Salloc(0, t, -1, -1)) {}
  470. inline String::String(const char* t, int tlen)
  471.   : rep(Salloc(0, t, tlen, tlen)) {}
  472. inline String::String(const SubString& y)
  473.   : rep(Salloc(0, y.chars(), y.length(), y.length())) {}
  474. inline String::String(char c) 
  475.   : rep(Salloc(0, &c, 1, 1)) {}
  476.  
  477. inline String::~String() { if (rep != &_nilStrRep) delete rep; }
  478.  
  479. inline SubString::SubString(const SubString& x)
  480.   :S(x.S), pos(x.pos), len(x.len) {}
  481. inline SubString::SubString(String& x, int first, int l)
  482.   :S(x), pos(first), len(l) {}
  483.  
  484. inline SubString::~SubString() {}
  485.  
  486. // assignment
  487.  
  488. inline String& String::operator =  (const String& y)
  489.   rep = Scopy(rep, y.rep);
  490.   return *this;
  491. }
  492.  
  493. inline String& String::operator=(const char* t)
  494. {
  495.   rep = Salloc(rep, t, -1, -1);
  496.   return *this;
  497. }
  498.  
  499. inline String& String::operator=(const SubString&  y)
  500. {
  501.   rep = Salloc(rep, y.chars(), y.length(), y.length());
  502.   return *this;
  503. }
  504.  
  505. inline String& String::operator=(char c)
  506. {
  507.   rep = Salloc(rep, &c, 1, 1);
  508.   return *this;
  509. }
  510.  
  511.  
  512. inline SubString& SubString::operator = (const char* ys)
  513. {
  514.   assign(0, ys);
  515.   return *this;
  516. }
  517.  
  518. inline SubString& SubString::operator = (char ch)
  519. {
  520.   assign(0, &ch, 1);
  521.   return *this;
  522. }
  523.  
  524. inline SubString& SubString::operator = (const String& y)
  525. {
  526.   assign(y.rep, y.chars(), y.length());
  527.   return *this;
  528. }
  529.  
  530. inline SubString& SubString::operator = (const SubString& y)
  531. {
  532.   assign(y.S.rep, y.chars(), y.length());
  533.   return *this;
  534. }
  535.  
  536. // Zillions of cats...
  537.  
  538. inline void cat(const String& x, const String& y, String& r)
  539. {
  540.   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  541. }
  542.  
  543. inline void cat(const String& x, const SubString& y, String& r)
  544. {
  545.   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  546. }
  547.  
  548. inline void cat(const String& x, const char* y, String& r)
  549. {
  550.   r.rep = Scat(r.rep, x.chars(), x.length(), y, -1);
  551. }
  552.  
  553. inline void cat(const String& x, char y, String& r)
  554. {
  555.   r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
  556. }
  557.  
  558. inline void cat(const SubString& x, const String& y, String& r)
  559. {
  560.   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  561. }
  562.  
  563. inline void cat(const SubString& x, const SubString& y, String& r)
  564. {
  565.   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  566. }
  567.  
  568. inline void cat(const SubString& x, const char* y, String& r)
  569. {
  570.   r.rep = Scat(r.rep, x.chars(), x.length(), y, -1);
  571. }
  572.  
  573. inline void cat(const SubString& x, char y, String& r)
  574. {
  575.   r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
  576. }
  577.  
  578. inline void cat(const char* x, const String& y, String& r)
  579. {
  580.   r.rep = Scat(r.rep, x, -1, y.chars(), y.length());
  581. }
  582.  
  583. inline void cat(const char* x, const SubString& y, String& r)
  584. {
  585.   r.rep = Scat(r.rep, x, -1, y.chars(), y.length());
  586. }
  587.  
  588. inline void cat(const char* x, const char* y, String& r)
  589. {
  590.   r.rep = Scat(r.rep, x, -1, y, -1);
  591. }
  592.  
  593. inline void cat(const char* x, char y, String& r)
  594. {
  595.   r.rep = Scat(r.rep, x, -1, &y, 1);
  596. }
  597.  
  598. inline void cat(const String& a, const String& x, const String& y, String& r)
  599. {
  600.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
  601. }
  602.  
  603. inline void cat(const String& a, const String& x, const SubString& y, String& r)
  604. {
  605.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
  606. }
  607.  
  608. inline void cat(const String& a, const String& x, const char* y, String& r)
  609. {
  610.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1);
  611. }
  612.  
  613. inline void cat(const String& a, const String& x, char y, String& r)
  614. {
  615.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1);
  616. }
  617.  
  618. inline void cat(const String& a, const SubString& x, const String& y, String& r)
  619. {
  620.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
  621. }
  622.  
  623. inline void cat(const String& a, const SubString& x, const SubString& y, String& r)
  624. {
  625.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
  626. }
  627.  
  628. inline void cat(const String& a, const SubString& x, const char* y, String& r)
  629. {
  630.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1);
  631. }
  632.  
  633. inline void cat(const String& a, const SubString& x, char y, String& r)
  634. {
  635.   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1);
  636. }
  637.  
  638. inline void cat(const String& a, const char* x, const String& y, String& r)
  639. {
  640.   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length());
  641. }
  642.  
  643. inline void cat(const String& a, const char* x, const SubString& y, String& r)
  644. {
  645.   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length());
  646. }
  647.  
  648. inline void cat(const String& a, const char* x, const char* y, String& r)
  649. {
  650.   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y, -1);
  651. }
  652.  
  653. inline void cat(const String& a, const char* x, char y, String& r)
  654. {
  655.   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, &y, 1);
  656. }
  657.  
  658.  
  659. inline void cat(const char* a, const String& x, const String& y, String& r)
  660. {
  661.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
  662. }
  663.  
  664. inline void cat(const char* a, const String& x, const SubString& y, String& r)
  665. {
  666.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
  667. }
  668.  
  669. inline void cat(const char* a, const String& x, const char* y, String& r)
  670. {
  671.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1);
  672. }
  673.  
  674. inline void cat(const char* a, const String& x, char y, String& r)
  675. {
  676.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1);
  677. }
  678.  
  679. inline void cat(const char* a, const SubString& x, const String& y, String& r)
  680. {
  681.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
  682. }
  683.  
  684. inline void cat(const char* a, const SubString& x, const SubString& y, String& r)
  685. {
  686.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
  687. }
  688.  
  689. inline void cat(const char* a, const SubString& x, const char* y, String& r)
  690. {
  691.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1);
  692. }
  693.  
  694. inline void cat(const char* a, const SubString& x, char y, String& r)
  695. {
  696.   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1);
  697. }
  698.  
  699. inline void cat(const char* a, const char* x, const String& y, String& r)
  700. {
  701.   r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length());
  702. }
  703.  
  704. inline void cat(const char* a, const char* x, const SubString& y, String& r)
  705. {
  706.   r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length());
  707. }
  708.  
  709. inline void cat(const char* a, const char* x, const char* y, String& r)
  710. {
  711.   r.rep = Scat(r.rep, a, -1, x, -1, y, -1);
  712. }
  713.  
  714. inline void cat(const char* a, const char* x, char y, String& r)
  715. {
  716.   r.rep = Scat(r.rep, a, -1, x, -1, &y, 1);
  717. }
  718.  
  719.  
  720. // operator versions
  721.  
  722. inline String& String::operator +=(const String& y)
  723. {
  724.   cat(*this, y, *this);
  725.   return *this;
  726. }
  727.  
  728. inline String& String::operator +=(const SubString& y)
  729. {
  730.   cat(*this, y, *this);
  731.   return *this;
  732. }
  733.  
  734. inline String& String::operator += (const char* y)
  735. {
  736.   cat(*this, y, *this);
  737.   return *this;
  738. }
  739.  
  740. inline String& String:: operator +=(char y)
  741. {
  742.   cat(*this, y, *this);
  743.   return *this;
  744. }
  745.  
  746. // constructive concatenation
  747.  
  748. #if defined(__GNUG__) && !defined(_G_NO_NRV)
  749.  
  750. inline String operator + (const String& x, const String& y) return r;
  751. {
  752.   cat(x, y, r);
  753. }
  754.  
  755. inline String operator + (const String& x, const SubString& y) return r;
  756. {
  757.   cat(x, y, r);
  758. }
  759.  
  760. inline String operator + (const String& x, const char* y) return r;
  761. {
  762.   cat(x, y, r);
  763. }
  764.  
  765. inline String operator + (const String& x, char y) return r;
  766. {
  767.   cat(x, y, r);
  768. }
  769.  
  770. inline String operator + (const SubString& x, const String& y) return r;
  771. {
  772.   cat(x, y, r);
  773. }
  774.  
  775. inline String operator + (const SubString& x, const SubString& y) return r;
  776. {
  777.   cat(x, y, r);
  778. }
  779.  
  780. inline String operator + (const SubString& x, const char* y) return r;
  781. {
  782.   cat(x, y, r);
  783. }
  784.  
  785. inline String operator + (const SubString& x, char y) return r;
  786. {
  787.   cat(x, y, r);
  788. }
  789.  
  790. inline String operator + (const char* x, const String& y) return r;
  791. {
  792.   cat(x, y, r);
  793. }
  794.  
  795. inline String operator + (const char* x, const SubString& y) return r;
  796. {
  797.   cat(x, y, r);
  798. }
  799.  
  800. inline String reverse(const String& x) return r;
  801. {
  802.   r.rep = Sreverse(x.rep, r.rep);
  803. }
  804.  
  805. inline String upcase(const String& x) return r;
  806. {
  807.   r.rep = Supcase(x.rep, r.rep);
  808. }
  809.  
  810. inline String downcase(const String& x) return r;
  811. {
  812.   r.rep = Sdowncase(x.rep, r.rep);
  813. }
  814.  
  815. inline String capitalize(const String& x) return r;
  816. {
  817.   r.rep = Scapitalize(x.rep, r.rep);
  818. }
  819.  
  820. #else /* NO_NRV */
  821.  
  822. inline String operator + (const String& x, const String& y)
  823. {
  824.   String r;  cat(x, y, r);  return r;
  825. }
  826.  
  827. inline String operator + (const String& x, const SubString& y) 
  828. {
  829.   String r; cat(x, y, r); return r;
  830. }
  831.  
  832. inline String operator + (const String& x, const char* y) 
  833. {
  834.   String r; cat(x, y, r); return r;
  835. }
  836.  
  837. inline String operator + (const String& x, char y) 
  838. {
  839.   String r; cat(x, y, r); return r;
  840. }
  841.  
  842. inline String operator + (const SubString& x, const String& y) 
  843. {
  844.   String r; cat(x, y, r); return r;
  845. }
  846.  
  847. inline String operator + (const SubString& x, const SubString& y) 
  848. {
  849.   String r; cat(x, y, r); return r;
  850. }
  851.  
  852. inline String operator + (const SubString& x, const char* y) 
  853. {
  854.   String r; cat(x, y, r); return r;
  855. }
  856.  
  857. inline String operator + (const SubString& x, char y) 
  858. {
  859.   String r; cat(x, y, r); return r;
  860. }
  861.  
  862. inline String operator + (const char* x, const String& y) 
  863. {
  864.   String r; cat(x, y, r); return r;
  865. }
  866.  
  867. inline String operator + (const char* x, const SubString& y) 
  868. {
  869.   String r; cat(x, y, r); return r;
  870. }
  871.  
  872. inline String reverse(const String& x) 
  873. {
  874.   String r; r.rep = Sreverse(x.rep, r.rep); return r;
  875. }
  876.  
  877. inline String upcase(const String& x) 
  878. {
  879.   String r; r.rep = Supcase(x.rep, r.rep); return r;
  880. }
  881.  
  882. inline String downcase(const String& x) 
  883. {
  884.   String r; r.rep = Sdowncase(x.rep, r.rep); return r;
  885. }
  886.  
  887. inline String capitalize(const String& x) 
  888. {
  889.   String r; r.rep = Scapitalize(x.rep, r.rep); return r;
  890. }
  891.  
  892. #endif
  893.  
  894. // prepend
  895.  
  896. inline void String::prepend(const String& y)
  897. {
  898.   rep = Sprepend(rep, y.chars(), y.length());
  899. }
  900.  
  901. inline void String::prepend(const char* y)
  902. {
  903.   rep = Sprepend(rep, y, -1); 
  904. }
  905.  
  906. inline void String::prepend(char y)
  907. {
  908.   rep = Sprepend(rep, &y, 1); 
  909. }
  910.  
  911. inline void String::prepend(const SubString& y)
  912. {
  913.   rep = Sprepend(rep, y.chars(), y.length());
  914. }
  915.  
  916. // misc transformations
  917.  
  918.  
  919. inline void String::reverse()
  920. {
  921.   rep = Sreverse(rep, rep);
  922. }
  923.  
  924.  
  925. inline void String::upcase()
  926. {
  927.   rep = Supcase(rep, rep);
  928. }
  929.  
  930.  
  931. inline void String::downcase()
  932. {
  933.   rep = Sdowncase(rep, rep);
  934. }
  935.  
  936.  
  937. inline void String::capitalize()
  938. {
  939.   rep = Scapitalize(rep, rep);
  940. }
  941.  
  942. // element extraction
  943.  
  944. inline char&  String::operator [] (int i) 
  945.   if (((unsigned)i) >= length()) error("invalid index");
  946.   return rep->s[i];
  947. }
  948.  
  949. inline char  String::elem (int i) const
  950.   if (((unsigned)i) >= length()) error("invalid index");
  951.   return rep->s[i];
  952. }
  953.  
  954. inline char  String::firstchar() const
  955.   return elem(0);
  956. }
  957.  
  958. inline char  String::lastchar() const
  959.   return elem(length() - 1);
  960. }
  961.  
  962. // searching
  963.  
  964. inline int String::index(char c, int startpos) const
  965. {
  966.   return search(startpos, length(), c);
  967. }
  968.  
  969. inline int String::index(const char* t, int startpos) const
  970. {   
  971.   return search(startpos, length(), t);
  972. }
  973.  
  974. inline int String::index(const String& y, int startpos) const
  975. {   
  976.   return search(startpos, length(), y.chars(), y.length());
  977. }
  978.  
  979. inline int String::index(const SubString& y, int startpos) const
  980. {   
  981.   return search(startpos, length(), y.chars(), y.length());
  982. }
  983.  
  984. inline int String::index(const Regex& r, int startpos) const
  985. {
  986.   int unused;  return r.search(chars(), length(), unused, startpos);
  987. }
  988.  
  989. inline int String::contains(char c) const
  990. {
  991.   return search(0, length(), c) >= 0;
  992. }
  993.  
  994. inline int String::contains(const char* t) const
  995. {   
  996.   return search(0, length(), t) >= 0;
  997. }
  998.  
  999. inline int String::contains(const String& y) const
  1000. {   
  1001.   return search(0, length(), y.chars(), y.length()) >= 0;
  1002. }
  1003.  
  1004. inline int String::contains(const SubString& y) const
  1005. {   
  1006.   return search(0, length(), y.chars(), y.length()) >= 0;
  1007. }
  1008.  
  1009. inline int String::contains(char c, int p) const
  1010. {
  1011.   return match(p, length(), 0, &c, 1) >= 0;
  1012. }
  1013.  
  1014. inline int String::contains(const char* t, int p) const
  1015. {
  1016.   return match(p, length(), 0, t) >= 0;
  1017. }
  1018.  
  1019. inline int String::contains(const String& y, int p) const
  1020. {
  1021.   return match(p, length(), 0, y.chars(), y.length()) >= 0;
  1022. }
  1023.  
  1024. inline int String::contains(const SubString& y, int p) const
  1025. {
  1026.   return match(p, length(), 0, y.chars(), y.length()) >= 0;
  1027. }
  1028.  
  1029. inline int String::contains(const Regex& r) const
  1030. {
  1031.   int unused;  return r.search(chars(), length(), unused, 0) >= 0;
  1032. }
  1033.  
  1034. inline int String::contains(const Regex& r, int p) const
  1035. {
  1036.   return r.match(chars(), length(), p) >= 0;
  1037. }
  1038.  
  1039.  
  1040. inline int String::matches(const SubString& y, int p) const
  1041. {
  1042.   return match(p, length(), 1, y.chars(), y.length()) >= 0;
  1043. }
  1044.  
  1045. inline int String::matches(const String& y, int p) const
  1046. {
  1047.   return match(p, length(), 1, y.chars(), y.length()) >= 0;
  1048. }
  1049.  
  1050. inline int String::matches(const char* t, int p) const
  1051. {
  1052.   return match(p, length(), 1, t) >= 0;
  1053. }
  1054.  
  1055. inline int String::matches(char c, int p) const
  1056. {
  1057.   return match(p, length(), 1, &c, 1) >= 0;
  1058. }
  1059.  
  1060. inline int String::matches(const Regex& r, int p) const
  1061. {
  1062.   int l = (p < 0)? -p : length() - p;
  1063.   return r.match(chars(), length(), p) == l;
  1064. }
  1065.  
  1066.  
  1067. inline int SubString::contains(const char* t) const
  1068. {   
  1069.   return S.search(pos, pos+len, t) >= 0;
  1070. }
  1071.  
  1072. inline int SubString::contains(const String& y) const
  1073. {   
  1074.   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
  1075. }
  1076.  
  1077. inline int SubString::contains(const SubString&  y) const
  1078. {   
  1079.   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
  1080. }
  1081.  
  1082. inline int SubString::contains(char c) const
  1083. {
  1084.   return S.search(pos, pos+len, c) >= 0;
  1085. }
  1086.  
  1087. inline int SubString::contains(const Regex& r) const
  1088. {
  1089.   int unused;  return r.search(chars(), len, unused, 0) >= 0;
  1090. }
  1091.  
  1092. inline int SubString::matches(const Regex& r) const
  1093. {
  1094.   return r.match(chars(), len, 0) == len;
  1095. }
  1096.  
  1097.  
  1098. inline int String::gsub(const String& pat, const String& r)
  1099. {
  1100.   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
  1101. }
  1102.  
  1103. inline int String::gsub(const SubString&  pat, const String& r)
  1104. {
  1105.   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
  1106. }
  1107.  
  1108. inline int String::gsub(const Regex& pat, const String& r)
  1109. {
  1110.   return _gsub(pat, r.chars(), r.length());
  1111. }
  1112.  
  1113. inline int String::gsub(const char* pat, const String& r)
  1114. {
  1115.   return _gsub(pat, -1, r.chars(), r.length());
  1116. }
  1117.  
  1118. inline int String::gsub(const char* pat, const char* r)
  1119. {
  1120.   return _gsub(pat, -1, r, -1);
  1121. }
  1122.  
  1123.  
  1124.  
  1125. inline  ostream& operator<<(ostream& s, const String& x)
  1126. {
  1127.    s << x.chars(); return s;
  1128. }
  1129.  
  1130. // a zillion comparison operators
  1131.  
  1132. inline int operator==(const String& x, const String& y) 
  1133. {
  1134.   return compare(x, y) == 0; 
  1135. }
  1136.  
  1137. inline int operator!=(const String& x, const String& y)
  1138. {
  1139.   return compare(x, y) != 0; 
  1140. }
  1141.  
  1142. inline int operator>(const String& x, const String& y)
  1143. {
  1144.   return compare(x, y) > 0; 
  1145. }
  1146.  
  1147. inline int operator>=(const String& x, const String& y)
  1148. {
  1149.   return compare(x, y) >= 0; 
  1150. }
  1151.  
  1152. inline int operator<(const String& x, const String& y)
  1153. {
  1154.   return compare(x, y) < 0; 
  1155. }
  1156.  
  1157. inline int operator<=(const String& x, const String& y)
  1158. {
  1159.   return compare(x, y) <= 0; 
  1160. }
  1161.  
  1162. inline int operator==(const String& x, const SubString&  y) 
  1163. {
  1164.   return compare(x, y) == 0; 
  1165. }
  1166.  
  1167. inline int operator!=(const String& x, const SubString&  y)
  1168. {
  1169.   return compare(x, y) != 0; 
  1170. }
  1171.  
  1172. inline int operator>(const String& x, const SubString&  y)      
  1173. {
  1174.   return compare(x, y) > 0; 
  1175. }
  1176.  
  1177. inline int operator>=(const String& x, const SubString&  y)
  1178. {
  1179.   return compare(x, y) >= 0; 
  1180. }
  1181.  
  1182. inline int operator<(const String& x, const SubString&  y) 
  1183. {
  1184.   return compare(x, y) < 0; 
  1185. }
  1186.  
  1187. inline int operator<=(const String& x, const SubString&  y)
  1188. {
  1189.   return compare(x, y) <= 0; 
  1190. }
  1191.  
  1192. inline int operator==(const String& x, const char* t) 
  1193. {
  1194.   return compare(x, t) == 0; 
  1195. }
  1196.  
  1197. inline int operator!=(const String& x, const char* t) 
  1198. {
  1199.   return compare(x, t) != 0; 
  1200. }
  1201.  
  1202. inline int operator>(const String& x, const char* t)  
  1203. {
  1204.   return compare(x, t) > 0; 
  1205. }
  1206.  
  1207. inline int operator>=(const String& x, const char* t) 
  1208. {
  1209.   return compare(x, t) >= 0; 
  1210. }
  1211.  
  1212. inline int operator<(const String& x, const char* t)  
  1213. {
  1214.   return compare(x, t) < 0; 
  1215. }
  1216.  
  1217. inline int operator<=(const String& x, const char* t) 
  1218. {
  1219.   return compare(x, t) <= 0; 
  1220. }
  1221.  
  1222. inline int operator==(const SubString& x, const String& y) 
  1223. {
  1224.   return compare(y, x) == 0; 
  1225. }
  1226.  
  1227. inline int operator!=(const SubString& x, const String& y)
  1228. {
  1229.   return compare(y, x) != 0;
  1230. }
  1231.  
  1232. inline int operator>(const SubString& x, const String& y)      
  1233. {
  1234.   return compare(y, x) < 0;
  1235. }
  1236.  
  1237. inline int operator>=(const SubString& x, const String& y)     
  1238. {
  1239.   return compare(y, x) <= 0;
  1240. }
  1241.  
  1242. inline int operator<(const SubString& x, const String& y)      
  1243. {
  1244.   return compare(y, x) > 0;
  1245. }
  1246.  
  1247. inline int operator<=(const SubString& x, const String& y)     
  1248. {
  1249.   return compare(y, x) >= 0;
  1250. }
  1251.  
  1252. inline int operator==(const SubString& x, const SubString&  y) 
  1253. {
  1254.   return compare(x, y) == 0; 
  1255. }
  1256.  
  1257. inline int operator!=(const SubString& x, const SubString&  y)
  1258. {
  1259.   return compare(x, y) != 0;
  1260. }
  1261.  
  1262. inline int operator>(const SubString& x, const SubString&  y)      
  1263. {
  1264.   return compare(x, y) > 0;
  1265. }
  1266.  
  1267. inline int operator>=(const SubString& x, const SubString&  y)
  1268. {
  1269.   return compare(x, y) >= 0;
  1270. }
  1271.  
  1272. inline int operator<(const SubString& x, const SubString&  y) 
  1273. {
  1274.   return compare(x, y) < 0;
  1275. }
  1276.  
  1277. inline int operator<=(const SubString& x, const SubString&  y)
  1278. {
  1279.   return compare(x, y) <= 0;
  1280. }
  1281.  
  1282. inline int operator==(const SubString& x, const char* t) 
  1283. {
  1284.   return compare(x, t) == 0; 
  1285. }
  1286.  
  1287. inline int operator!=(const SubString& x, const char* t) 
  1288. {
  1289.   return compare(x, t) != 0;
  1290. }
  1291.  
  1292. inline int operator>(const SubString& x, const char* t)  
  1293. {
  1294.   return compare(x, t) > 0; 
  1295. }
  1296.  
  1297. inline int operator>=(const SubString& x, const char* t) 
  1298. {
  1299.   return compare(x, t) >= 0; 
  1300. }
  1301.  
  1302. inline int operator<(const SubString& x, const char* t)  
  1303. {
  1304.   return compare(x, t) < 0; 
  1305. }
  1306.  
  1307. inline int operator<=(const SubString& x, const char* t) 
  1308. {
  1309.   return compare(x, t) <= 0; 
  1310. }
  1311.  
  1312.  
  1313. // a helper needed by at, before, etc.
  1314.  
  1315. inline SubString String::_substr(int first, int l)
  1316. {
  1317.   if (first < 0 || (unsigned)(first + l) > length() )
  1318.     return SubString(_nilString, 0, 0) ;
  1319.   else 
  1320.     return SubString(*this, first, l);
  1321. }
  1322.  
  1323. #endif
  1324.