home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / g__inc / xstring.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-23  |  35.7 KB  |  1,337 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. #if defined(SHORT_NAMES) || defined(VMS)
  20. #define re_compile_pattern    recmppat
  21. #define re_pattern_buffer    repatbuf
  22. #define re_registers        reregs
  23. #endif
  24.  
  25. #ifndef _String_h
  26. #ifdef __GNUG__
  27. #pragma once
  28. #pragma interface
  29. #endif
  30. #define _String_h 1
  31.  
  32. #include <stream.h>
  33. #include <xregex.h>
  34.  
  35. struct StrRep                     // internal String representations
  36. {
  37.   unsigned short    len;         // string length 
  38.   unsigned short    sz;          // allocated space
  39.   char              s[1];        // the string starts here 
  40.                                  // (at least 1 char for trailing null)
  41.                                  // allocated & expanded via non-public fcts
  42. };
  43.  
  44. // primitive ops on StrReps -- nearly all String fns go through these.
  45.  
  46. StrRep*     Salloc(StrRep*, const char*, int, int);
  47. StrRep*     Scopy(StrRep*, StrRep*);
  48. StrRep*     Sresize(StrRep*, int);
  49. StrRep*     Scat(StrRep*, const char*, int, const char*, int);
  50. StrRep*     Scat(StrRep*, const char*, int,const char*,int, const char*,int);
  51. StrRep*     Sprepend(StrRep*, const char*, int);
  52. StrRep*     Sreverse(StrRep*, StrRep*);
  53. StrRep*     Supcase(StrRep*, StrRep*);
  54. StrRep*     Sdowncase(StrRep*, StrRep*);
  55. StrRep*     Scapitalize(StrRep*, StrRep*);
  56.  
  57. // These classes need to be defined in the order given
  58.  
  59. class String;
  60. class SubString;
  61.  
  62. class SubString
  63. {
  64.   friend class      String;
  65. protected:
  66.  
  67.   String&           S;        // The String I'm a substring of
  68.   unsigned short    pos;      // starting position in S's rep
  69.   unsigned short    len;      // length of substring
  70.  
  71.   void              assign(StrRep*, const char*, int = -1);
  72.                     SubString(String& x, int p, int l);
  73.                     SubString(const SubString& x);
  74.  
  75. public:
  76.  
  77. // Note there are no public constructors. SubStrings are always
  78. // created via String operations
  79.  
  80.                    ~SubString();
  81.  
  82.   void              operator =  (const String&     y);
  83.   void              operator =  (const SubString&  y);
  84.   void              operator =  (const char* t);
  85.   void              operator =  (char        c);
  86.  
  87. // return 1 if target appears anywhere in SubString; else 0
  88.  
  89.   int               contains(char        c) const;
  90.   int               contains(const String&     y) const;
  91.   int               contains(const SubString&  y) const;
  92.   int               contains(const char* t) const;
  93.   int               contains(const Regex&       r) const;
  94.  
  95. // return 1 if target matches entire SubString
  96.  
  97.   int               matches(const Regex&  r) const;
  98.  
  99. // IO 
  100.  
  101.   friend ostream&   operator<<(ostream& s, const SubString& x);
  102.  
  103. // status
  104.  
  105.   int               length() const;
  106.   int               empty() const;
  107.   const char*       chars() const;
  108.  
  109.   int               OK() const; 
  110.  
  111. };
  112.  
  113.  
  114. class String
  115. {
  116.   friend class      SubString;
  117.  
  118. protected:
  119.   StrRep*           rep;   // Strings are pointers to their representations
  120.  
  121. // some helper functions
  122.  
  123.   int               search(int, int, const char*, int = -1) const;
  124.   int               search(int, int, char) const;
  125.   int               match(int, int, int, const char*, int = -1) const;
  126.   int               _gsub(const char*, int, const char* ,int);
  127.   int               _gsub(const Regex&, const char*, int);
  128.   SubString         _substr(int, int);
  129.  
  130. public:
  131.  
  132. // constructors & assignment
  133.  
  134.                     String();
  135.                     String(const String& x);
  136.                     String(const SubString&  x);
  137.                     String(const char* t);
  138.                     String(const char* t, int len);
  139.                     String(char c);
  140.  
  141.                     ~String();
  142.  
  143.   void              operator =  (const String&     y);
  144.   void              operator =  (const char* y);
  145.   void              operator =  (char        c);
  146.   void              operator =  (const SubString&  y);
  147.  
  148. // concatenation
  149.  
  150.   void              operator += (const String&     y); 
  151.   void              operator += (const SubString&  y);
  152.   void              operator += (const char* t);
  153.   void              operator += (char        c);
  154.  
  155.   void              prepend(const String&     y); 
  156.   void              prepend(const SubString&  y);
  157.   void              prepend(const char* t);
  158.   void              prepend(char        c);
  159.  
  160.  
  161. // procedural versions:
  162. // concatenate first 2 args, store result in last arg
  163.  
  164.   friend void     cat(const String&, const String&, String&);
  165.   friend void     cat(const String&, const SubString&, String&);
  166.   friend void     cat(const String&, const char*, String&);
  167.   friend void     cat(const String&, char, String&);
  168.  
  169.   friend void     cat(const SubString&, const String&, String&);
  170.   friend void     cat(const SubString&, const SubString&, String&);
  171.   friend void     cat(const SubString&, const char*, String&);
  172.   friend void     cat(const SubString&, char, String&);
  173.  
  174.   friend void     cat(const char*, const String&, String&);
  175.   friend void     cat(const char*, const SubString&, String&);
  176.   friend void     cat(const char*, const char*, String&);
  177.   friend void     cat(const char*, char, String&);
  178.  
  179. // double concatenation, by request. (yes, there are too many versions, 
  180. // but if one is supported, then the others should be too...)
  181. // Concatenate first 3 args, store in last arg
  182.  
  183.   friend void     cat(const String&,const String&, const String&,String&);
  184.   friend void     cat(const String&,const String&,const SubString&,String&);
  185.   friend void     cat(const String&,const String&, const char*, String&);
  186.   friend void     cat(const String&,const String&, char, String&);
  187.   friend void     cat(const String&,const SubString&,const String&,String&);
  188.   friend void     cat(const String&,const SubString&,const SubString&,String&);
  189.   friend void     cat(const String&,const SubString&, const char*, String&);
  190.   friend void     cat(const String&,const SubString&, char, String&);
  191.   friend void     cat(const String&,const char*, const String&,    String&);
  192.   friend void     cat(const String&,const char*, const SubString&, String&);
  193.   friend void     cat(const String&,const char*, const char*, String&);
  194.   friend void     cat(const String&,const char*, char, String&);
  195.  
  196.   friend void     cat(const char*, const String&, const String&,String&);
  197.   friend void     cat(const char*,const String&,const SubString&,String&);
  198.   friend void     cat(const char*,const String&, const char*, String&);
  199.   friend void     cat(const char*,const String&, char, String&);
  200.   friend void     cat(const char*,const SubString&,const String&,String&);
  201.   friend void     cat(const char*,const SubString&,const SubString&,String&);
  202.   friend void     cat(const char*,const SubString&, const char*, String&);
  203.   friend void     cat(const char*,const SubString&, char, String&);
  204.   friend void     cat(const char*,const char*, const String&,    String&);
  205.   friend void     cat(const char*,const char*, const SubString&, String&);
  206.   friend void     cat(const char*,const char*, const char*, String&);
  207.   friend void     cat(const char*,const char*, char, String&);
  208.  
  209.  
  210. // searching & matching
  211.  
  212. // return position of target in string or -1 for failure
  213.  
  214.   int               index(char        c, int startpos = 0) const;      
  215.   int               index(const String&     y, int startpos = 0) const;      
  216.   int               index(const SubString&  y, int startpos = 0) const;      
  217.   int               index(const char* t, int startpos = 0) const;  
  218.   int               index(const Regex&      r, int startpos = 0) const;       
  219.  
  220. // return 1 if target appears anyhere in String; else 0
  221.  
  222.   int               contains(char        c) const;
  223.   int               contains(const String&     y) const;
  224.   int               contains(const SubString&  y) const;
  225.   int               contains(const char* t) const;
  226.   int               contains(const Regex&      r) const;
  227.  
  228. // return 1 if target appears anywhere after position pos 
  229. // (or before, if pos is negative) in String; else 0
  230.  
  231.   int               contains(char        c, int pos) const;
  232.   int               contains(const String&     y, int pos) const;
  233.   int               contains(const SubString&  y, int pos) const;
  234.   int               contains(const char* t, int pos) const;
  235.   int               contains(const Regex&      r, int pos) const;
  236.  
  237. // return 1 if target appears at position pos in String; else 0
  238.  
  239.   int               matches(char        c, int pos = 0) const;
  240.   int               matches(const String&     y, int pos = 0) const;
  241.   int               matches(const SubString&  y, int pos = 0) const;
  242.   int               matches(const char* t, int pos = 0) const;
  243.   int               matches(const Regex&      r, int pos = 0) const;
  244.  
  245. //  return number of occurences of target in String
  246.  
  247.   int               freq(char        c) const; 
  248.   int               freq(const String&     y) const;
  249.   int               freq(const SubString&  y) const;
  250.   int               freq(const char* t) const;
  251.  
  252. // SubString extraction
  253.  
  254. // Note that you can't take a substring of a const String, since
  255. // this leaves open the possiblility of indirectly modifying the
  256. // String through the SubString
  257.  
  258.   SubString         at(int         pos, int len);
  259.   SubString         operator () (int         pos, int len); // synonym for at
  260.  
  261.   SubString         at(const String&     x, int startpos = 0); 
  262.   SubString         at(const SubString&  x, int startpos = 0); 
  263.   SubString         at(const char* t, int startpos = 0);
  264.   SubString         at(char        c, int startpos = 0);
  265.   SubString         at(const Regex&      r, int startpos = 0); 
  266.  
  267.   SubString         before(int          pos);
  268.   SubString         before(const String&      x, int startpos = 0);
  269.   SubString         before(const SubString&   x, int startpos = 0);
  270.   SubString         before(const char*  t, int startpos = 0);
  271.   SubString         before(char         c, int startpos = 0);
  272.   SubString         before(const Regex&       r, int startpos = 0);
  273.  
  274.   SubString         through(int          pos);
  275.   SubString         through(const String&      x, int startpos = 0);
  276.   SubString         through(const SubString&   x, int startpos = 0);
  277.   SubString         through(const char*  t, int startpos = 0);
  278.   SubString         through(char         c, int startpos = 0);
  279.   SubString         through(const Regex&       r, int startpos = 0);
  280.  
  281.   SubString         from(int          pos);
  282.   SubString         from(const String&      x, int startpos = 0);
  283.   SubString         from(const SubString&   x, int startpos = 0);
  284.   SubString         from(const char*  t, int startpos = 0);
  285.   SubString         from(char         c, int startpos = 0);
  286.   SubString         from(const Regex&       r, int startpos = 0);
  287.  
  288.   SubString         after(int         pos);
  289.   SubString         after(const String&     x, int startpos = 0);
  290.   SubString         after(const SubString&  x, int startpos = 0);
  291.   SubString         after(const char* t, int startpos = 0);
  292.   SubString         after(char        c, int startpos = 0);
  293.   SubString         after(const Regex&      r, int startpos = 0);
  294.  
  295.  
  296. // deletion
  297.  
  298. // delete len chars starting at pos
  299.   void              del(int         pos, int len);
  300.  
  301. // delete the first occurrence of target after startpos
  302.  
  303.   void              del(const String&     y, int startpos = 0);
  304.   void              del(const SubString&  y, int startpos = 0);
  305.   void              del(const char* t, int startpos = 0);
  306.   void              del(char        c, int startpos = 0);
  307.   void              del(const Regex&      r, int startpos = 0);
  308.  
  309. // global substitution: substitute all occurrences of pat with repl
  310.  
  311.   int               gsub(const String&     pat, const String&     repl);
  312.   int               gsub(const SubString&  pat, const String&     repl);
  313.   int               gsub(const char* pat, const String&     repl);
  314.   int               gsub(const char* pat, const char* repl);
  315.   int               gsub(const Regex&      pat, const String&     repl);
  316.  
  317. // friends & utilities
  318.  
  319. // split string into array res at separators; return number of elements
  320.  
  321.   friend int        split(const String& x, String res[], int maxn, 
  322.                           const String& sep);
  323.   friend int        split(const String& x, String res[], int maxn, 
  324.                           const Regex&  sep);
  325.  
  326.   friend String     common_prefix(const String& x, const String& y, 
  327.                                   int startpos = 0);
  328.   friend String     common_suffix(const String& x, const String& y, 
  329.                                   int startpos = -1);
  330.   friend String     replicate(char        c, int n);
  331.   friend String     replicate(const String&     y, int n);
  332.   friend String     join(String src[], int n, const String& sep);
  333.  
  334. // simple builtin transformations
  335.  
  336.   friend String     reverse(const String& x);
  337.   friend String     upcase(const String& x);
  338.   friend String     downcase(const String& x);
  339.   friend String     capitalize(const String& x);
  340.  
  341. // in-place versions of above
  342.  
  343.   void              reverse();
  344.   void              upcase();
  345.   void              downcase();
  346.   void              capitalize();
  347.  
  348. // element extraction
  349.  
  350.   char&             operator [] (int i);
  351.   char              elem(int i) const;
  352.   char              firstchar() const;
  353.   char              lastchar() const;
  354.  
  355. // conversion
  356.  
  357.                     operator const char*() const;
  358.   const char*       chars() const;
  359.  
  360.  
  361. // IO
  362.  
  363.   friend ostream&   operator<<(ostream& s, const String& x);
  364.   friend ostream&   operator<<(ostream& s, const SubString& x);
  365.   friend istream&   operator>>(istream& s, String& x);
  366.  
  367.   friend int        readline(istream& s, String& x, 
  368.                              char terminator = '\n',
  369.                              int discard_terminator = 1);
  370.  
  371. // status
  372.  
  373.   int               length() const;
  374.   int               empty() const;
  375.  
  376. // preallocate some space for String
  377.   void              alloc(int newsize);
  378.  
  379. // report current allocation (not length!)
  380.  
  381.   int               allocation() const;
  382.  
  383.  
  384.   volatile void     error(const char* msg) const;
  385.  
  386.   int               OK() const;
  387. };
  388.  
  389. typedef String StrTmp; // for backward compatibility
  390.  
  391. // other externs
  392.  
  393. int        compare(const String&    x, const String&     y);
  394. int        compare(const String&    x, const SubString&  y);
  395. int        compare(const String&    x, const char* y);
  396. int        compare(const SubString& x, const String&     y);
  397. int        compare(const SubString& x, const SubString&  y);
  398. int        compare(const SubString& x, const char* y);
  399. int        fcompare(const String&   x, const String&     y); // ignore case
  400.  
  401. extern StrRep  _nilStrRep;
  402. extern String _nilString;
  403.  
  404. // other inlines
  405.  
  406. String operator + (const String& x, const String& y);
  407. String operator + (const String& x, const SubString& y);
  408. String operator + (const String& x, const char* y);
  409. String operator + (const String& x, char y);
  410. String operator + (const SubString& x, const String& y);
  411. String operator + (const SubString& x, const SubString& y);
  412. String operator + (const SubString& x, const char* y);
  413. String operator + (const SubString& x, char y);
  414. String operator + (const char* x, const String& y);
  415. String operator + (const char* x, const SubString& y);
  416.  
  417. int operator==(const String& x, const String& y); 
  418. int operator!=(const String& x, const String& y);
  419. int operator> (const String& x, const String& y);
  420. int operator>=(const String& x, const String& y);
  421. int operator< (const String& x, const String& y);
  422. int operator<=(const String& x, const String& y);
  423. int operator==(const String& x, const SubString&  y);
  424. int operator!=(const String& x, const SubString&  y);
  425. int operator> (const String& x, const SubString&  y);
  426. int operator>=(const String& x, const SubString&  y);
  427. int operator< (const String& x, const SubString&  y);
  428. int operator<=(const String& x, const SubString&  y);
  429. int operator==(const String& x, const char* t);
  430. int operator!=(const String& x, const char* t);
  431. int operator> (const String& x, const char* t);
  432. int operator>=(const String& x, const char* t);
  433. int operator< (const String& x, const char* t);
  434. int operator<=(const String& x, const char* t);
  435. int operator==(const SubString& x, const String& y);
  436. int operator!=(const SubString& x, const String& y);
  437. int operator> (const SubString& x, const String& y);
  438. int operator>=(const SubString& x, const String& y);
  439. int operator< (const SubString& x, const String& y);
  440. int operator<=(const SubString& x, const String& y);
  441. int operator==(const SubString& x, const SubString&  y);
  442. int operator!=(const SubString& x, const SubString&  y);
  443. int operator> (const SubString& x, const SubString&  y);
  444. int operator>=(const SubString& x, const SubString&  y);
  445. int operator< (const SubString& x, const SubString&  y);
  446. int operator<=(const SubString& x, const SubString&  y);
  447. int operator==(const SubString& x, const char* t);
  448. int operator!=(const SubString& x, const char* t);
  449. int operator> (const SubString& x, const char* t);
  450. int operator>=(const SubString& x, const char* t);
  451. int operator< (const SubString& x, const char* t);
  452. int operator<=(const SubString& x, const char* t);
  453.  
  454. #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
  455.  
  456.  
  457. // status reports, needed before defining other things
  458.  
  459. inline int         String::length() const {  return rep->len; }
  460. inline int         String::empty() const { return rep->len == 0; }
  461. inline const char* String::chars() const { return &(rep->s[0]); }
  462. inline int         String::allocation() const { return rep->sz; }
  463. inline void        String::alloc(int newsize) { rep = Sresize(rep, newsize); }
  464.  
  465. inline int         SubString::length() const { return len; }
  466. inline int         SubString::empty() const { return len == 0; }
  467. inline const char* SubString::chars() const { return &(S.rep->s[pos]); }
  468.  
  469.  
  470. // constructors
  471.  
  472. inline String::String() 
  473.   : rep(&_nilStrRep) {}
  474. inline String::String(const String& x) 
  475.   : rep(Scopy(0, x.rep)) {}
  476. inline String::String(const char* t) 
  477.   : rep(Salloc(0, t, -1, -1)) {}
  478. inline String::String(const char* t, int tlen)
  479.   : rep(Salloc(0, t, tlen, tlen)) {}
  480. inline String::String(const SubString& y)
  481.   : rep(Salloc(0, y.chars(), y.length(), y.length())) {}
  482. inline String::String(char c) 
  483.   : rep(Salloc(0, &c, 1, 1)) {}
  484.  
  485. inline String::~String() { if (rep != &_nilStrRep) delete rep; }
  486.  
  487. inline SubString::SubString(const SubString& x)
  488.   :S(x.S), pos(x.pos), len(x.len) {}
  489. inline SubString::SubString(String& x, int first, int l)
  490.   :S(x), pos(first), len(l) {}
  491.  
  492. inline SubString::~SubString() {}
  493.  
  494. // assignment
  495.  
  496. inline void String::operator =  (const String& y)
  497.   rep = Scopy(rep, y.rep);
  498. }
  499.  
  500. inline void String::operator=(const char* t)
  501. {
  502.   rep = Salloc(rep, t, -1, -1); 
  503. }
  504.  
  505. inline void String::operator=(const SubString&  y)
  506. {
  507.   rep = Salloc(rep, y.chars(), y.length(), y.length());
  508. }
  509.  
  510. inline void String::operator=(char c)
  511. {
  512.   rep = Salloc(rep, &c, 1, 1); 
  513. }
  514.  
  515.  
  516. inline void SubString::operator = (const char* ys)
  517. {
  518.   assign(0, ys);
  519. }
  520.  
  521. inline void SubString::operator = (char ch)
  522. {
  523.   assign(0, &ch, 1);
  524. }
  525.  
  526. inline void SubString::operator = (const String& y)
  527. {
  528.   assign(y.rep, y.chars(), y.length());
  529. }
  530.  
  531. inline void SubString::operator = (const SubString& y)
  532. {
  533.   assign(y.S.rep, y.chars(), y.length());
  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 void String::operator +=(const String& y)
  723. {
  724.   cat(*this, y, *this);
  725. }
  726.  
  727. inline void String::operator +=(const SubString& y)
  728. {
  729.   cat(*this, y, *this);
  730. }
  731.  
  732. inline void String::operator += (const char* y)
  733. {
  734.   cat(*this, y, *this);
  735. }
  736.  
  737. inline void String:: operator +=(char y)
  738. {
  739.   cat(*this, y, *this);
  740. }
  741.  
  742. // constructive concatenation
  743.  
  744. #if defined(__GNUG__) && !defined(NO_NRV)
  745.  
  746. inline String operator + (const String& x, const String& y) return r;
  747. {
  748.   cat(x, y, r);
  749. }
  750.  
  751. inline String operator + (const String& x, const SubString& y) return r;
  752. {
  753.   cat(x, y, r);
  754. }
  755.  
  756. inline String operator + (const String& x, const char* y) return r;
  757. {
  758.   cat(x, y, r);
  759. }
  760.  
  761. inline String operator + (const String& x, char y) return r;
  762. {
  763.   cat(x, y, r);
  764. }
  765.  
  766. inline String operator + (const SubString& x, const String& y) return r;
  767. {
  768.   cat(x, y, r);
  769. }
  770.  
  771. inline String operator + (const SubString& x, const SubString& y) return r;
  772. {
  773.   cat(x, y, r);
  774. }
  775.  
  776. inline String operator + (const SubString& x, const char* y) return r;
  777. {
  778.   cat(x, y, r);
  779. }
  780.  
  781. inline String operator + (const SubString& x, char y) return r;
  782. {
  783.   cat(x, y, r);
  784. }
  785.  
  786. inline String operator + (const char* x, const String& y) return r;
  787. {
  788.   cat(x, y, r);
  789. }
  790.  
  791. inline String operator + (const char* x, const SubString& y) return r;
  792. {
  793.   cat(x, y, r);
  794. }
  795.  
  796. inline String reverse(const String& x) return r;
  797. {
  798.   r.rep = Sreverse(x.rep, r.rep);
  799. }
  800.  
  801. inline String upcase(const String& x) return r;
  802. {
  803.   r.rep = Supcase(x.rep, r.rep);
  804. }
  805.  
  806. inline String downcase(const String& x) return r;
  807. {
  808.   r.rep = Sdowncase(x.rep, r.rep);
  809. }
  810.  
  811. inline String capitalize(const String& x) return r;
  812. {
  813.   r.rep = Scapitalize(x.rep, r.rep);
  814. }
  815.  
  816. #else /* NO_NRV */
  817.  
  818. inline String operator + (const String& x, const String& y)
  819. {
  820.   String r;  cat(x, y, r);  return r;
  821. }
  822.  
  823. inline String operator + (const String& x, const SubString& y) 
  824. {
  825.   String r; cat(x, y, r); return r;
  826. }
  827.  
  828. inline String operator + (const String& x, const char* y) 
  829. {
  830.   String r; cat(x, y, r); return r;
  831. }
  832.  
  833. inline String operator + (const String& x, char y) 
  834. {
  835.   String r; cat(x, y, r); return r;
  836. }
  837.  
  838. inline String operator + (const SubString& x, const String& y) 
  839. {
  840.   String r; cat(x, y, r); return r;
  841. }
  842.  
  843. inline String operator + (const SubString& x, const SubString& y) 
  844. {
  845.   String r; cat(x, y, r); return r;
  846. }
  847.  
  848. inline String operator + (const SubString& x, const char* y) 
  849. {
  850.   String r; cat(x, y, r); return r;
  851. }
  852.  
  853. inline String operator + (const SubString& x, char y) 
  854. {
  855.   String r; cat(x, y, r); return r;
  856. }
  857.  
  858. inline String operator + (const char* x, const String& y) 
  859. {
  860.   String r; cat(x, y, r); return r;
  861. }
  862.  
  863. inline String operator + (const char* x, const SubString& y) 
  864. {
  865.   String r; cat(x, y, r); return r;
  866. }
  867.  
  868. inline String reverse(const String& x) 
  869. {
  870.   String r; r.rep = Sreverse(x.rep, r.rep); return r;
  871. }
  872.  
  873. inline String upcase(const String& x) 
  874. {
  875.   String r; r.rep = Supcase(x.rep, r.rep); return r;
  876. }
  877.  
  878. inline String downcase(const String& x) 
  879. {
  880.   String r; r.rep = Sdowncase(x.rep, r.rep); return r;
  881. }
  882.  
  883. inline String capitalize(const String& x) 
  884. {
  885.   String r; r.rep = Scapitalize(x.rep, r.rep); return r;
  886. }
  887.  
  888. #endif
  889.  
  890. // prepend
  891.  
  892. inline void String::prepend(const String& y)
  893. {
  894.   rep = Sprepend(rep, y.chars(), y.length());
  895. }
  896.  
  897. inline void String::prepend(const char* y)
  898. {
  899.   rep = Sprepend(rep, y, -1); 
  900. }
  901.  
  902. inline void String::prepend(char y)
  903. {
  904.   rep = Sprepend(rep, &y, 1); 
  905. }
  906.  
  907. inline void String::prepend(const SubString& y)
  908. {
  909.   rep = Sprepend(rep, y.chars(), y.length());
  910. }
  911.  
  912. // misc transformations
  913.  
  914.  
  915. inline void String::reverse()
  916. {
  917.   rep = Sreverse(rep, rep);
  918. }
  919.  
  920.  
  921. inline void String::upcase()
  922. {
  923.   rep = Supcase(rep, rep);
  924. }
  925.  
  926.  
  927. inline void String::downcase()
  928. {
  929.   rep = Sdowncase(rep, rep);
  930. }
  931.  
  932.  
  933. inline void String::capitalize()
  934. {
  935.   rep = Scapitalize(rep, rep);
  936. }
  937.  
  938. // element extraction
  939.  
  940. inline char&  String::operator [] (int i) 
  941.   if (((unsigned)i) >= length()) error("invalid index");
  942.   return rep->s[i];
  943. }
  944.  
  945. inline char  String::elem (int i) const
  946.   if (((unsigned)i) >= length()) error("invalid index");
  947.   return rep->s[i];
  948. }
  949.  
  950. inline char  String::firstchar() const
  951.   return elem(0);
  952. }
  953.  
  954. inline char  String::lastchar() const
  955.   return elem(length() - 1);
  956. }
  957.  
  958. // searching
  959.  
  960. inline int String::index(char c, int startpos) const
  961. {
  962.   return search(startpos, length(), c);
  963. }
  964.  
  965. inline int String::index(const char* t, int startpos) const
  966. {   
  967.   return search(startpos, length(), t);
  968. }
  969.  
  970. inline int String::index(const String& y, int startpos) const
  971. {   
  972.   return search(startpos, length(), y.chars(), y.length());
  973. }
  974.  
  975. inline int String::index(const SubString& y, int startpos) const
  976. {   
  977.   return search(startpos, length(), y.chars(), y.length());
  978. }
  979.  
  980. inline int String::index(const Regex& r, int startpos) const
  981. {
  982.   int unused;  return r.search(chars(), length(), unused, startpos);
  983. }
  984.  
  985. inline int String::contains(char c) const
  986. {
  987.   return search(0, length(), c) >= 0;
  988. }
  989.  
  990. inline int String::contains(const char* t) const
  991. {   
  992.   return search(0, length(), t) >= 0;
  993. }
  994.  
  995. inline int String::contains(const String& y) const
  996. {   
  997.   return search(0, length(), y.chars(), y.length()) >= 0;
  998. }
  999.  
  1000. inline int String::contains(const SubString& y) const
  1001. {   
  1002.   return search(0, length(), y.chars(), y.length()) >= 0;
  1003. }
  1004.  
  1005. inline int String::contains(char c, int p) const
  1006. {
  1007.   return match(p, length(), 0, &c, 1) >= 0;
  1008. }
  1009.  
  1010. inline int String::contains(const char* t, int p) const
  1011. {
  1012.   return match(p, length(), 0, t) >= 0;
  1013. }
  1014.  
  1015. inline int String::contains(const String& y, int p) const
  1016. {
  1017.   return match(p, length(), 0, y.chars(), y.length()) >= 0;
  1018. }
  1019.  
  1020. inline int String::contains(const SubString& y, int p) const
  1021. {
  1022.   return match(p, length(), 0, y.chars(), y.length()) >= 0;
  1023. }
  1024.  
  1025. inline int String::contains(const Regex& r) const
  1026. {
  1027.   int unused;  return r.search(chars(), length(), unused, 0) >= 0;
  1028. }
  1029.  
  1030. inline int String::contains(const Regex& r, int p) const
  1031. {
  1032.   return r.match(chars(), length(), p) >= 0;
  1033. }
  1034.  
  1035.  
  1036. inline int String::matches(const SubString& y, int p) const
  1037. {
  1038.   return match(p, length(), 1, y.chars(), y.length()) >= 0;
  1039. }
  1040.  
  1041. inline int String::matches(const String& y, int p) const
  1042. {
  1043.   return match(p, length(), 1, y.chars(), y.length()) >= 0;
  1044. }
  1045.  
  1046. inline int String::matches(const char* t, int p) const
  1047. {
  1048.   return match(p, length(), 1, t) >= 0;
  1049. }
  1050.  
  1051. inline int String::matches(char c, int p) const
  1052. {
  1053.   return match(p, length(), 1, &c, 1) >= 0;
  1054. }
  1055.  
  1056. inline int String::matches(const Regex& r, int p) const
  1057. {
  1058.   int l = (p < 0)? -p : length() - p;
  1059.   return r.match(chars(), length(), p) == l;
  1060. }
  1061.  
  1062.  
  1063. inline int SubString::contains(const char* t) const
  1064. {   
  1065.   return S.search(pos, pos+len, t) >= 0;
  1066. }
  1067.  
  1068. inline int SubString::contains(const String& y) const
  1069. {   
  1070.   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
  1071. }
  1072.  
  1073. inline int SubString::contains(const SubString&  y) const
  1074. {   
  1075.   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
  1076. }
  1077.  
  1078. inline int SubString::contains(char c) const
  1079. {
  1080.   return S.search(pos, pos+len, 0, c) >= 0;
  1081. }
  1082.  
  1083. inline int SubString::contains(const Regex& r) const
  1084. {
  1085.   int unused;  return r.search(chars(), len, unused, 0) >= 0;
  1086. }
  1087.  
  1088. inline int SubString::matches(const Regex& r) const
  1089. {
  1090.   return r.match(chars(), len, 0) == len;
  1091. }
  1092.  
  1093.  
  1094. inline int String::gsub(const String& pat, const String& r)
  1095. {
  1096.   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
  1097. }
  1098.  
  1099. inline int String::gsub(const SubString&  pat, const String& r)
  1100. {
  1101.   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
  1102. }
  1103.  
  1104. inline int String::gsub(const Regex& pat, const String& r)
  1105. {
  1106.   return _gsub(pat, r.chars(), r.length());
  1107. }
  1108.  
  1109. inline int String::gsub(const char* pat, const String& r)
  1110. {
  1111.   return _gsub(pat, -1, r.chars(), r.length());
  1112. }
  1113.  
  1114. inline int String::gsub(const char* pat, const char* r)
  1115. {
  1116.   return _gsub(pat, -1, r, -1);
  1117. }
  1118.  
  1119.  
  1120. inline String::operator const char*() const
  1121.   return str(chars());
  1122. }
  1123.  
  1124. inline  ostream& operator<<(ostream& s, const String& x)
  1125. {
  1126. #ifdef VMS
  1127.    s << x.chars(); return s;
  1128. #else
  1129.   s.put(x.chars()); return s;
  1130. #endif
  1131.  
  1132. }
  1133.  
  1134. // a zillion comparison operators
  1135.  
  1136. inline int operator==(const String& x, const String& y) 
  1137. {
  1138.   return compare(x, y) == 0; 
  1139. }
  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 SubString&  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 char* t) 
  1197. {
  1198.   return compare(x, t) == 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 SubString& x, const String& y) 
  1227. {
  1228.   return compare(y, x) == 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 SubString&  y) 
  1257. {
  1258.   return compare(x, y) == 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 char* t) 
  1287. {
  1288.   return compare(x, t) == 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.  
  1317. // a helper needed by at, before, etc.
  1318.  
  1319. inline SubString String::_substr(int first, int l)
  1320. {
  1321.   if (first < 0 || (unsigned)(first + l) > length()) 
  1322.     return SubString(_nilString, 0, 0) ;
  1323.   else 
  1324.     return SubString(*this, first, l);
  1325. }
  1326.  
  1327.  
  1328. #endif
  1329.  
  1330. #endif
  1331.