home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C++ / Snippets / GNU String⁄Regex / GNUString.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-06  |  32.3 KB  |  988 lines  |  [TEXT/CWIE]

  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 "stream.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*, 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(StrRep*, StrRep*);
  47. StrRep*     Supcase(StrRep*, StrRep*);
  48. StrRep*     Sdowncase(StrRep*, StrRep*);
  49. StrRep*     Scapitalize(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(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.   void              operator =  (const String&     y);
  77.   void              operator =  (const SubString&  y);
  78.   void              operator =  (const char* t);
  79.   void              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.   void              operator =  (const String&     y);
  138.   void              operator =  (const char* y);
  139.   void              operator =  (char        c);
  140.   void              operator =  (const SubString&  y);
  141.  
  142. // concatenation
  143.  
  144.   void              operator += (const String&     y); 
  145.   void              operator += (const SubString&  y);
  146.   void              operator += (const char* t);
  147.   void              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 void String::operator =  (const String& y)
  489.   rep = Scopy(rep, y.rep);
  490. }
  491.  
  492. inline void String::operator=(const char* t)
  493. {
  494.   rep = Salloc(rep, t, -1, -1); 
  495. }
  496.  
  497. inline void String::operator=(const SubString&  y)
  498. {
  499.   rep = Salloc(rep, y.chars(), y.length(), y.length());
  500. }
  501.  
  502. inline void String::operator=(char c)
  503. {
  504.   rep = Salloc(rep, &c, 1, 1); 
  505. }
  506.  
  507.  
  508. inline void SubString::operator = (const char* ys)
  509. {
  510.   assign(0, ys);
  511. }
  512.  
  513. inline void SubString::operator = (char ch)
  514. {
  515.   assign(0, &ch, 1);
  516. }
  517.  
  518. inline void SubString::operator = (const String& y)
  519. {
  520.   assign(y.rep, y.chars(), y.length());
  521. }
  522.  
  523. inline void SubString::operator = (const SubString& y)
  524. {
  525.   assign(y.S.rep, y.chars(), y.length());
  526. }
  527.  
  528. // Zillions of cats...
  529.  
  530. void cat(const String& x, const String& y, String& r);
  531. void cat(const String& x, const SubString& y, String& r);
  532. void cat(const String& x, const char* y, String& r);
  533. void cat(const String& x, char y, String& r);
  534. void cat(const SubString& x, const String& y, String& r);
  535. void cat(const SubString& x, const SubString& y, String& r);
  536. void cat(const SubString& x, const char* y, String& r);
  537. void cat(const SubString& x, char y, String& r);
  538. void cat(const char* x, const String& y, String& r);
  539. void cat(const char* x, const SubString& y, String& r);
  540. void cat(const char* x, const char* y, String& r);
  541. void cat(const char* x, char y, String& r);
  542. void cat(const String& a, const String& x, const String& y, String& r);
  543. void cat(const String& a, const String& x, const SubString& y, String& r);
  544. void cat(const String& ine String operator + (const char* x, const SubString& y) 
  545. {
  546.   String r; cat(x, y, r); return r;
  547. }
  548.  
  549. String reverse(const String& x);
  550. String upcase(const String& x); 
  551. String downcase(const String& x);
  552. String capitalize(const String& x);
  553.  
  554. #endif
  555.  
  556. // prepend
  557.  
  558. inline void String::prepend(const String& y)
  559. {
  560.   rep = Sprepend(rep, y.chars(), y.length());
  561. }
  562.  
  563. inline void String::prepend(const char* y)
  564. {
  565.   rep = Sprepend(rep, y, -1); 
  566. }
  567.  
  568. inline void String::prepend(char y)
  569. {
  570.   rep = Sprepend(rep, &y, 1); 
  571. }
  572.  
  573. inline void String::prepend(const SubString& y)
  574. {
  575.   rep = Sprepend(rep, y.chars(), y.length());
  576. }
  577.  
  578. // misc transformations
  579.  
  580.  
  581. inline void String::reverse()
  582. {
  583.   rep = Sreverse(rep, rep);
  584. }
  585.  
  586.  
  587. inline void String::upcase()
  588. {
  589.   rep = Supcase(rep, rep);
  590. }
  591.  
  592.  
  593. inline void String::downcase()
  594. {
  595.   rep = Sdowncase(rep, rep);
  596. }
  597.  
  598.  
  599. inline void String::capitalize()
  600. {
  601.   rep = Scapitalize(rep, rep);
  602. }
  603.  
  604. // element extraction
  605.  
  606. inline char&  String::operator [] (int i) 
  607.   if (((unsigned)i) >= length()) error("invalid index");
  608.   return rep->s[i];
  609. }
  610.  
  611. inline char  String::elem (int i) const
  612.   if (((unsigned)i) >= length()) error("invalid index");
  613.   return rep->s[i];
  614. }
  615.  
  616. inline char  String::firstchar() const
  617.   return elem(0);
  618. }
  619.  
  620. inline char  String::lastchar() const
  621.   return elem(length() - 1);
  622. }
  623.  
  624. // searching
  625.  
  626. inline int String::index(char c, int startpos) const
  627. {
  628.   return search(startpos, length(), c);
  629. }
  630.  
  631. inline int String::index(const char* t, int startpos) const
  632. {   
  633.   return search(startpos, length(), t);
  634. }
  635.  
  636. inline int String::index(const String& y, int startpos) const
  637. {   
  638.   return search(startpos, length(), y.chars(), y.length());
  639. }
  640.  
  641. inline int String::index(const SubString& y, int startpos) const
  642. {   
  643.   return search(startpos, length(), y.chars(), y.length());
  644. }
  645.  
  646. inline int String::index(const Regex& r, int startpos) const
  647. {
  648.   int unused;  return r.search(chars(), length(), unused, startpos);
  649. }
  650.  
  651. inline int String::contains(char c) const
  652. {
  653.   return search(0, length(), c) >= 0;
  654. }
  655.  
  656. inline int String::contains(const char* t) const
  657. {   
  658.   return search(0, length(), t) >= 0;
  659. }
  660.  
  661. inline int String::contains(const String& y) const
  662. {   
  663.   return search(0, length(), y.chars(), y.length()) >= 0;
  664. }
  665.  
  666. inline int String::contains(const SubString& y) const
  667. {   
  668.   return search(0, length(), y.chars(), y.length()) >= 0;
  669. }
  670.  
  671. inline int String::contains(char c, int p) const
  672. {
  673.   return match(p, length(), 0, &c, 1) >= 0;
  674. }
  675.  
  676. inline int String::contains(const char* t, int p) const
  677. {
  678.   return match(p, length(), 0, t) >= 0;
  679. }
  680.  
  681. inline int String::contains(const String& y, int p) const
  682. {
  683.   return match(p, length(), 0, y.chars(), y.length()) >= 0;
  684. }
  685.  
  686. inline int String::contains(const SubString& y, int p) const
  687. {
  688.   return match(p, length(), 0, y.chars(), y.length()) >= 0;
  689. }
  690.  
  691. inline int String::contains(const Regex& r) const
  692. {
  693.   int unused;  return r.search(chars(), length(), unused, 0) >= 0;
  694. }
  695.  
  696. inline int String::contains(const Regex& r, int p) const
  697. {
  698.   return r.match(chars(), length(), p) >= 0;
  699. }
  700.  
  701.  
  702. inline int String::matches(const SubString& y, int p) const
  703. {
  704.   return match(p, length(), 1, y.chars(), y.length()) >= 0;
  705. }
  706.  
  707. inline int String::matches(const String& y, int p) const
  708. {
  709.   return match(p, length(), 1, y.chars(), y.length()) >= 0;
  710. }
  711.  
  712. inline int String::matches(const char* t, int p) const
  713. {
  714.   return match(p, length(), 1, t) >= 0;
  715. }
  716.  
  717. inline int String::matches(char c, int p) const
  718. {
  719.   return match(p, length(), 1, &c, 1) >= 0;
  720. }
  721.  
  722. inline int String::matches(const Regex& r, int p) const
  723. {
  724.   int l = (p < 0)? -p : length() - p;
  725.   return r.match(chars(), length(), p) == l;
  726. }
  727.  
  728.  
  729. inline int SubString::contains(const char* t) const
  730. {   
  731.   return S.search(pos, pos+len, t) >= 0;
  732. }
  733.  
  734. inline int SubString::contains(const String& y) const
  735. {   
  736.   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
  737. }
  738.  
  739. inline int SubString::contains(const SubString&  y) const
  740. {   
  741.   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
  742. }
  743.  
  744. inline int SubString::contains(char c) const
  745. {
  746.   return S.search(pos, pos+len, c) >= 0;
  747. }
  748.  
  749. inline int SubString::contains(const Regex& r) const
  750. {
  751.   int unused;  return r.search(chars(), len, unused, 0) >= 0;
  752. }
  753.  
  754. inline int SubString::matches(const Regex& r) const
  755. {
  756.   return r.match(chars(), len, 0) == len;
  757. }
  758.  
  759.  
  760. inline int String::gsub(const String& pat, const String& r)
  761. {
  762.   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
  763. }
  764.  
  765. inline int String::gsub(const SubString&  pat, const String& r)
  766. {
  767.   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
  768. }
  769.  
  770. inline int String::gsub(const Regex& pat, const String& r)
  771. {
  772.   return _gsub(pat, r.chars(), r.length());
  773. }
  774.  
  775. inline int String::gsub(const char* pat, const String& r)
  776. {
  777.   return _gsub(pat, -1, r.chars(), r.length());
  778. }
  779.  
  780. inline int String::gsub(const char* pat, const char* r)
  781. {
  782.   return _gsub(pat, -1, r, -1);
  783. }
  784.  
  785.  
  786.  
  787. ostream& operator<<(ostream& s, const String& x);
  788.  
  789. // a zillion comparison operators
  790.  
  791. inline int operator==(const String& x, const String& y) 
  792. {
  793.   return compare(x, y) == 0; 
  794. }
  795.  
  796. inline int operator!=(const String& x, const String& y)
  797. {
  798.   return compare(x, y) != 0; 
  799. }
  800.  
  801. inline int operator>(const String& x, const String& y)
  802. {
  803.   return compare(x, y) > 0; 
  804. }
  805.  
  806. inline int operator>=(const String& x, const String& y)
  807. {
  808.   return compare(x, y) >= 0; 
  809. }
  810.  
  811. inline int operator<(const String& x, const String& y)
  812. {
  813.   return compare(x, y) < 0; 
  814. }
  815.  
  816. inline int operator<=(const String& x, const String& y)
  817. {
  818.   return compare(x, y) <= 0; 
  819. }
  820.  
  821. inline int operator==(const String& x, const SubString&  y) 
  822. {
  823.   return compare(x, y) == 0; 
  824. }
  825.  
  826. inline int operator!=(const String& x, const SubString&  y)
  827. {
  828.   return compare(x, y) != 0; 
  829. }
  830.  
  831. inline int operator>(const String& x, const SubString&  y)      
  832. {
  833.   return compare(x, y) > 0; 
  834. }
  835.  
  836. inline int operator>=(const String& x, const SubString&  y)
  837. {
  838.   return compare(x, y) >= 0; 
  839. }
  840.  
  841. inline int operator<(const String& x, const SubString&  y) 
  842. {
  843.   return compare(x, y) < 0; 
  844. }
  845.  
  846. inline int operator<=(const String& x, const SubString&  y)
  847. {
  848.   return compare(x, y) <= 0; 
  849. }
  850.  
  851. inline int operator==(const String& x, const char* t) 
  852. {
  853.   return compare(x, t) == 0; 
  854. }
  855.  
  856. inline int operator!=(const String& x, const char* t) 
  857. {
  858.   return compare(x, t) != 0; 
  859. }
  860.  
  861. inline int operator>(const String& x, const char* t)  
  862. {
  863.   return compare(x, t) > 0; 
  864. }
  865.  
  866. inline int operator>=(const String& x, const char* t) 
  867. {
  868.   return compare(x, t) >= 0; 
  869. }
  870.  
  871. inline int operator<(const String& x, const char* t)  
  872. {
  873.   return compare(x, t) < 0; 
  874. }
  875.  
  876. inline int operator<=(const String& x, const char* t) 
  877. {
  878.   return compare(x, t) <= 0; 
  879. }
  880.  
  881. inline int operator==(const SubString& x, const String& y) 
  882. {
  883.   return compare(y, x) == 0; 
  884. }
  885.  
  886. inline int operator!=(const SubString& x, const String& y)
  887. {
  888.   return compare(y, x) != 0;
  889. }
  890.  
  891. inline int operator>(const SubString& x, const String& y)      
  892. {
  893.   return compare(y, x) < 0;
  894. }
  895.  
  896. inline int operator>=(const SubString& x, const String& y)     
  897. {
  898.   return compare(y, x) <= 0;
  899. }
  900.  
  901. inline int operator<(const SubString& x, const String& y)      
  902. {
  903.   return compare(y, x) > 0;
  904. }
  905.  
  906. inline int operator<=(const SubString& x, const String& y)     
  907. {
  908.   return compare(y, x) >= 0;
  909. }
  910.  
  911. inline int operator==(const SubString& x, const SubString&  y) 
  912. {
  913.   return compare(x, y) == 0; 
  914. }
  915.  
  916. inline int operator!=(const SubString& x, const SubString&  y)
  917. {
  918.   return compare(x, y) != 0;
  919. }
  920.  
  921. inline int operator>(const SubString& x, const SubString&  y)      
  922. {
  923.   return compare(x, y) > 0;
  924. }
  925.  
  926. inline int operator>=(const SubString& x, const SubString&  y)
  927. {
  928.   return compare(x, y) >= 0;
  929. }
  930.  
  931. inline int operator<(const SubString& x, const SubString&  y) 
  932. {
  933.   return compare(x, y) < 0;
  934. }
  935.  
  936. inline int operator<=(const SubString& x, const SubString&  y)
  937. {
  938.   return compare(x, y) <= 0;
  939. }
  940.  
  941. inline int operator==(const SubString& x, const char* t) 
  942. {
  943.   return compare(x, t) == 0; 
  944. }
  945.  
  946. inline int operator!=(const SubString& x, const char* t) 
  947. {
  948.   return compare(x, t) != 0;
  949. }
  950.  
  951. inline int operator>(const SubString& x, const char* t)  
  952. {
  953.   return compare(x, t) > 0; 
  954. }
  955.  
  956. inline int operator>=(const SubString& x, const char* t) 
  957. {
  958.   return compare(x, t) >= 0; 
  959. }
  960.  
  961. inline int operator<(const SubString& x, const char* t)  
  962. {
  963.   return compare(x, t) < 0; 
  964. }
  965.  
  966. inline int operator<=(const SubString& x, const char* t) 
  967. {
  968.   return compare(x, t) <= 0; 
  969. }
  970.  
  971.  
  972. // a helper needed by at, before, etc.
  973.  
  974. inline SubString String::_substr(int first, int l)
  975. {
  976.   if (first < 0 || (unsigned)(first + l) > length() )
  977.     return SubString(_nilString, 0, 0) ;
  978.   else 
  979.     return SubString(*this, first, l);
  980. }
  981.  
  982. #endif
  983.