home *** CD-ROM | disk | FTP | other *** search
/ Monster Disc 2: The Best of 1992 / MONSTER2.ISO / prog / djgpp / djdev107.a01 / CPLUSINC / _STRING.H next >
Encoding:
C/C++ Source or Header  |  1992-03-29  |  34.2 KB  |  1,251 lines

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