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