xref: /386bsd/usr/src/lib/libg++/g++-include/String.h (revision a2142627)
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 <Regex.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 
length()464 inline int         String::length() const {  return rep->len; }
empty()465 inline int         String::empty() const { return rep->len == 0; }
chars()466 inline const char* String::chars() const { return &(rep->s[0]); }
allocation()467 inline int         String::allocation() const { return rep->sz; }
alloc(int newsize)468 inline void        String::alloc(int newsize) { rep = Sresize(rep, newsize); }
469 
length()470 inline int         SubString::length() const { return len; }
empty()471 inline int         SubString::empty() const { return len == 0; }
chars()472 inline const char* SubString::chars() const { return &(S.rep->s[pos]); }
473 
474 
475 // constructors
476 
String()477 inline String::String()
478   : rep(&_nilStrRep) {}
String(const String & x)479 inline String::String(const String& x)
480   : rep(Scopy(0, x.rep)) {}
String(const char * t)481 inline String::String(const char* t)
482   : rep(Salloc(0, t, -1, -1)) {}
String(const char * t,int tlen)483 inline String::String(const char* t, int tlen)
484   : rep(Salloc(0, t, tlen, tlen)) {}
String(const SubString & y)485 inline String::String(const SubString& y)
486   : rep(Salloc(0, y.chars(), y.length(), y.length())) {}
String(char c)487 inline String::String(char c)
488   : rep(Salloc(0, &c, 1, 1)) {}
489 
~String()490 inline String::~String() { if (rep != &_nilStrRep) delete rep; }
491 
SubString(const SubString & x)492 inline SubString::SubString(const SubString& x)
493   :S(x.S), pos(x.pos), len(x.len) {}
SubString(String & x,int first,int l)494 inline SubString::SubString(String& x, int first, int l)
495   :S(x), pos(first), len(l) {}
496 
~SubString()497 inline SubString::~SubString() {}
498 
499 // assignment
500 
501 inline void String::operator =  (const String& y)
502 {
503   rep = Scopy(rep, y.rep);
504 }
505 
506 inline void String::operator=(const char* t)
507 {
508   rep = Salloc(rep, t, -1, -1);
509 }
510 
511 inline void String::operator=(const SubString&  y)
512 {
513   rep = Salloc(rep, y.chars(), y.length(), y.length());
514 }
515 
516 inline void String::operator=(char c)
517 {
518   rep = Salloc(rep, &c, 1, 1);
519 }
520 
521 
522 inline void SubString::operator = (const char* ys)
523 {
524   assign(0, ys);
525 }
526 
527 inline void SubString::operator = (char ch)
528 {
529   assign(0, &ch, 1);
530 }
531 
532 inline void SubString::operator = (const String& y)
533 {
534   assign(y.rep, y.chars(), y.length());
535 }
536 
537 inline void SubString::operator = (const SubString& y)
538 {
539   assign(y.S.rep, y.chars(), y.length());
540 }
541 
542 // Zillions of cats...
543 
cat(const String & x,const String & y,String & r)544 inline void cat(const String& x, const String& y, String& r)
545 {
546   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
547 }
548 
cat(const String & x,const SubString & y,String & r)549 inline void cat(const String& x, const SubString& y, String& r)
550 {
551   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
552 }
553 
cat(const String & x,const char * y,String & r)554 inline void cat(const String& x, const char* y, String& r)
555 {
556   r.rep = Scat(r.rep, x.chars(), x.length(), y, -1);
557 }
558 
cat(const String & x,char y,String & r)559 inline void cat(const String& x, char y, String& r)
560 {
561   r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
562 }
563 
cat(const SubString & x,const String & y,String & r)564 inline void cat(const SubString& x, const String& y, String& r)
565 {
566   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
567 }
568 
cat(const SubString & x,const SubString & y,String & r)569 inline void cat(const SubString& x, const SubString& y, String& r)
570 {
571   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
572 }
573 
cat(const SubString & x,const char * y,String & r)574 inline void cat(const SubString& x, const char* y, String& r)
575 {
576   r.rep = Scat(r.rep, x.chars(), x.length(), y, -1);
577 }
578 
cat(const SubString & x,char y,String & r)579 inline void cat(const SubString& x, char y, String& r)
580 {
581   r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
582 }
583 
cat(const char * x,const String & y,String & r)584 inline void cat(const char* x, const String& y, String& r)
585 {
586   r.rep = Scat(r.rep, x, -1, y.chars(), y.length());
587 }
588 
cat(const char * x,const SubString & y,String & r)589 inline void cat(const char* x, const SubString& y, String& r)
590 {
591   r.rep = Scat(r.rep, x, -1, y.chars(), y.length());
592 }
593 
cat(const char * x,const char * y,String & r)594 inline void cat(const char* x, const char* y, String& r)
595 {
596   r.rep = Scat(r.rep, x, -1, y, -1);
597 }
598 
cat(const char * x,char y,String & r)599 inline void cat(const char* x, char y, String& r)
600 {
601   r.rep = Scat(r.rep, x, -1, &y, 1);
602 }
603 
cat(const String & a,const String & x,const String & y,String & r)604 inline void cat(const String& a, const String& x, const String& y, String& r)
605 {
606   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
607 }
608 
cat(const String & a,const String & x,const SubString & y,String & r)609 inline void cat(const String& a, const String& x, const SubString& y, String& r)
610 {
611   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
612 }
613 
cat(const String & a,const String & x,const char * y,String & r)614 inline void cat(const String& a, const String& x, const char* y, String& r)
615 {
616   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1);
617 }
618 
cat(const String & a,const String & x,char y,String & r)619 inline void cat(const String& a, const String& x, char y, String& r)
620 {
621   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1);
622 }
623 
cat(const String & a,const SubString & x,const String & y,String & r)624 inline void cat(const String& a, const SubString& x, const String& y, String& r)
625 {
626   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
627 }
628 
cat(const String & a,const SubString & x,const SubString & y,String & r)629 inline void cat(const String& a, const SubString& x, const SubString& y, String& r)
630 {
631   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
632 }
633 
cat(const String & a,const SubString & x,const char * y,String & r)634 inline void cat(const String& a, const SubString& x, const char* y, String& r)
635 {
636   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1);
637 }
638 
cat(const String & a,const SubString & x,char y,String & r)639 inline void cat(const String& a, const SubString& x, char y, String& r)
640 {
641   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1);
642 }
643 
cat(const String & a,const char * x,const String & y,String & r)644 inline void cat(const String& a, const char* x, const String& y, String& r)
645 {
646   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length());
647 }
648 
cat(const String & a,const char * x,const SubString & y,String & r)649 inline void cat(const String& a, const char* x, const SubString& y, String& r)
650 {
651   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length());
652 }
653 
cat(const String & a,const char * x,const char * y,String & r)654 inline void cat(const String& a, const char* x, const char* y, String& r)
655 {
656   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y, -1);
657 }
658 
cat(const String & a,const char * x,char y,String & r)659 inline void cat(const String& a, const char* x, char y, String& r)
660 {
661   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, &y, 1);
662 }
663 
664 
cat(const char * a,const String & x,const String & y,String & r)665 inline void cat(const char* a, const String& x, const String& y, String& r)
666 {
667   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
668 }
669 
cat(const char * a,const String & x,const SubString & y,String & r)670 inline void cat(const char* a, const String& x, const SubString& y, String& r)
671 {
672   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
673 }
674 
cat(const char * a,const String & x,const char * y,String & r)675 inline void cat(const char* a, const String& x, const char* y, String& r)
676 {
677   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1);
678 }
679 
cat(const char * a,const String & x,char y,String & r)680 inline void cat(const char* a, const String& x, char y, String& r)
681 {
682   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1);
683 }
684 
cat(const char * a,const SubString & x,const String & y,String & r)685 inline void cat(const char* a, const SubString& x, const String& y, String& r)
686 {
687   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
688 }
689 
cat(const char * a,const SubString & x,const SubString & y,String & r)690 inline void cat(const char* a, const SubString& x, const SubString& y, String& r)
691 {
692   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
693 }
694 
cat(const char * a,const SubString & x,const char * y,String & r)695 inline void cat(const char* a, const SubString& x, const char* y, String& r)
696 {
697   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1);
698 }
699 
cat(const char * a,const SubString & x,char y,String & r)700 inline void cat(const char* a, const SubString& x, char y, String& r)
701 {
702   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1);
703 }
704 
cat(const char * a,const char * x,const String & y,String & r)705 inline void cat(const char* a, const char* x, const String& y, String& r)
706 {
707   r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length());
708 }
709 
cat(const char * a,const char * x,const SubString & y,String & r)710 inline void cat(const char* a, const char* x, const SubString& y, String& r)
711 {
712   r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length());
713 }
714 
cat(const char * a,const char * x,const char * y,String & r)715 inline void cat(const char* a, const char* x, const char* y, String& r)
716 {
717   r.rep = Scat(r.rep, a, -1, x, -1, y, -1);
718 }
719 
cat(const char * a,const char * x,char y,String & r)720 inline void cat(const char* a, const char* x, char y, String& r)
721 {
722   r.rep = Scat(r.rep, a, -1, x, -1, &y, 1);
723 }
724 
725 
726 // operator versions
727 
728 inline void String::operator +=(const String& y)
729 {
730   cat(*this, y, *this);
731 }
732 
733 inline void String::operator +=(const SubString& y)
734 {
735   cat(*this, y, *this);
736 }
737 
738 inline void String::operator += (const char* y)
739 {
740   cat(*this, y, *this);
741 }
742 
743 inline void String:: operator +=(char y)
744 {
745   cat(*this, y, *this);
746 }
747 
748 // constructive concatenation
749 
750 #if defined(__GNUG__) && !defined(NO_NRV)
751 
752 inline String operator + (const String& x, const String& y) return r;
753 {
754   cat(x, y, r);
755 }
756 
757 inline String operator + (const String& x, const SubString& y) return r;
758 {
759   cat(x, y, r);
760 }
761 
762 inline String operator + (const String& x, const char* y) return r;
763 {
764   cat(x, y, r);
765 }
766 
767 inline String operator + (const String& x, char y) return r;
768 {
769   cat(x, y, r);
770 }
771 
772 inline String operator + (const SubString& x, const String& y) return r;
773 {
774   cat(x, y, r);
775 }
776 
777 inline String operator + (const SubString& x, const SubString& y) return r;
778 {
779   cat(x, y, r);
780 }
781 
782 inline String operator + (const SubString& x, const char* y) return r;
783 {
784   cat(x, y, r);
785 }
786 
787 inline String operator + (const SubString& x, char y) return r;
788 {
789   cat(x, y, r);
790 }
791 
792 inline String operator + (const char* x, const String& y) return r;
793 {
794   cat(x, y, r);
795 }
796 
797 inline String operator + (const char* x, const SubString& y) return r;
798 {
799   cat(x, y, r);
800 }
801 
802 inline String reverse(const String& x) return r;
803 {
804   r.rep = Sreverse(x.rep, r.rep);
805 }
806 
807 inline String upcase(const String& x) return r;
808 {
809   r.rep = Supcase(x.rep, r.rep);
810 }
811 
812 inline String downcase(const String& x) return r;
813 {
814   r.rep = Sdowncase(x.rep, r.rep);
815 }
816 
817 inline String capitalize(const String& x) return r;
818 {
819   r.rep = Scapitalize(x.rep, r.rep);
820 }
821 
822 #else /* NO_NRV */
823 
824 inline String operator + (const String& x, const String& y)
825 {
826   String r;  cat(x, y, r);  return r;
827 }
828 
829 inline String operator + (const String& x, const SubString& y)
830 {
831   String r; cat(x, y, r); return r;
832 }
833 
834 inline String operator + (const String& x, const char* y)
835 {
836   String r; cat(x, y, r); return r;
837 }
838 
839 inline String operator + (const String& x, char y)
840 {
841   String r; cat(x, y, r); return r;
842 }
843 
844 inline String operator + (const SubString& x, const String& y)
845 {
846   String r; cat(x, y, r); return r;
847 }
848 
849 inline String operator + (const SubString& x, const SubString& y)
850 {
851   String r; cat(x, y, r); return r;
852 }
853 
854 inline String operator + (const SubString& x, const char* y)
855 {
856   String r; cat(x, y, r); return r;
857 }
858 
859 inline String operator + (const SubString& x, char y)
860 {
861   String r; cat(x, y, r); return r;
862 }
863 
864 inline String operator + (const char* x, const String& y)
865 {
866   String r; cat(x, y, r); return r;
867 }
868 
869 inline String operator + (const char* x, const SubString& y)
870 {
871   String r; cat(x, y, r); return r;
872 }
873 
reverse(const String & x)874 inline String reverse(const String& x)
875 {
876   String r; r.rep = Sreverse(x.rep, r.rep); return r;
877 }
878 
upcase(const String & x)879 inline String upcase(const String& x)
880 {
881   String r; r.rep = Supcase(x.rep, r.rep); return r;
882 }
883 
downcase(const String & x)884 inline String downcase(const String& x)
885 {
886   String r; r.rep = Sdowncase(x.rep, r.rep); return r;
887 }
888 
capitalize(const String & x)889 inline String capitalize(const String& x)
890 {
891   String r; r.rep = Scapitalize(x.rep, r.rep); return r;
892 }
893 
894 #endif
895 
896 // prepend
897 
prepend(const String & y)898 inline void String::prepend(const String& y)
899 {
900   rep = Sprepend(rep, y.chars(), y.length());
901 }
902 
prepend(const char * y)903 inline void String::prepend(const char* y)
904 {
905   rep = Sprepend(rep, y, -1);
906 }
907 
prepend(char y)908 inline void String::prepend(char y)
909 {
910   rep = Sprepend(rep, &y, 1);
911 }
912 
prepend(const SubString & y)913 inline void String::prepend(const SubString& y)
914 {
915   rep = Sprepend(rep, y.chars(), y.length());
916 }
917 
918 // misc transformations
919 
920 
reverse()921 inline void String::reverse()
922 {
923   rep = Sreverse(rep, rep);
924 }
925 
926 
upcase()927 inline void String::upcase()
928 {
929   rep = Supcase(rep, rep);
930 }
931 
932 
downcase()933 inline void String::downcase()
934 {
935   rep = Sdowncase(rep, rep);
936 }
937 
938 
capitalize()939 inline void String::capitalize()
940 {
941   rep = Scapitalize(rep, rep);
942 }
943 
944 // element extraction
945 
946 inline char&  String::operator [] (int i)
947 {
948   if (((unsigned)i) >= length()) error("invalid index");
949   return rep->s[i];
950 }
951 
elem(int i)952 inline char  String::elem (int i) const
953 {
954   if (((unsigned)i) >= length()) error("invalid index");
955   return rep->s[i];
956 }
957 
firstchar()958 inline char  String::firstchar() const
959 {
960   return elem(0);
961 }
962 
lastchar()963 inline char  String::lastchar() const
964 {
965   return elem(length() - 1);
966 }
967 
968 // searching
969 
index(char c,int startpos)970 inline int String::index(char c, int startpos) const
971 {
972   return search(startpos, length(), c);
973 }
974 
index(const char * t,int startpos)975 inline int String::index(const char* t, int startpos) const
976 {
977   return search(startpos, length(), t);
978 }
979 
index(const String & y,int startpos)980 inline int String::index(const String& y, int startpos) const
981 {
982   return search(startpos, length(), y.chars(), y.length());
983 }
984 
index(const SubString & y,int startpos)985 inline int String::index(const SubString& y, int startpos) const
986 {
987   return search(startpos, length(), y.chars(), y.length());
988 }
989 
index(const Regex & r,int startpos)990 inline int String::index(const Regex& r, int startpos) const
991 {
992   int unused;  return r.search(chars(), length(), unused, startpos);
993 }
994 
contains(char c)995 inline int String::contains(char c) const
996 {
997   return search(0, length(), c) >= 0;
998 }
999 
contains(const char * t)1000 inline int String::contains(const char* t) const
1001 {
1002   return search(0, length(), t) >= 0;
1003 }
1004 
contains(const String & y)1005 inline int String::contains(const String& y) const
1006 {
1007   return search(0, length(), y.chars(), y.length()) >= 0;
1008 }
1009 
contains(const SubString & y)1010 inline int String::contains(const SubString& y) const
1011 {
1012   return search(0, length(), y.chars(), y.length()) >= 0;
1013 }
1014 
contains(char c,int p)1015 inline int String::contains(char c, int p) const
1016 {
1017   return match(p, length(), 0, &c, 1) >= 0;
1018 }
1019 
contains(const char * t,int p)1020 inline int String::contains(const char* t, int p) const
1021 {
1022   return match(p, length(), 0, t) >= 0;
1023 }
1024 
contains(const String & y,int p)1025 inline int String::contains(const String& y, int p) const
1026 {
1027   return match(p, length(), 0, y.chars(), y.length()) >= 0;
1028 }
1029 
contains(const SubString & y,int p)1030 inline int String::contains(const SubString& y, int p) const
1031 {
1032   return match(p, length(), 0, y.chars(), y.length()) >= 0;
1033 }
1034 
contains(const Regex & r)1035 inline int String::contains(const Regex& r) const
1036 {
1037   int unused;  return r.search(chars(), length(), unused, 0) >= 0;
1038 }
1039 
contains(const Regex & r,int p)1040 inline int String::contains(const Regex& r, int p) const
1041 {
1042   return r.match(chars(), length(), p) >= 0;
1043 }
1044 
1045 
matches(const SubString & y,int p)1046 inline int String::matches(const SubString& y, int p) const
1047 {
1048   return match(p, length(), 1, y.chars(), y.length()) >= 0;
1049 }
1050 
matches(const String & y,int p)1051 inline int String::matches(const String& y, int p) const
1052 {
1053   return match(p, length(), 1, y.chars(), y.length()) >= 0;
1054 }
1055 
matches(const char * t,int p)1056 inline int String::matches(const char* t, int p) const
1057 {
1058   return match(p, length(), 1, t) >= 0;
1059 }
1060 
matches(char c,int p)1061 inline int String::matches(char c, int p) const
1062 {
1063   return match(p, length(), 1, &c, 1) >= 0;
1064 }
1065 
matches(const Regex & r,int p)1066 inline int String::matches(const Regex& r, int p) const
1067 {
1068   int l = (p < 0)? -p : length() - p;
1069   return r.match(chars(), length(), p) == l;
1070 }
1071 
1072 
contains(const char * t)1073 inline int SubString::contains(const char* t) const
1074 {
1075   return S.search(pos, pos+len, t) >= 0;
1076 }
1077 
contains(const String & y)1078 inline int SubString::contains(const String& y) const
1079 {
1080   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
1081 }
1082 
contains(const SubString & y)1083 inline int SubString::contains(const SubString&  y) const
1084 {
1085   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
1086 }
1087 
contains(char c)1088 inline int SubString::contains(char c) const
1089 {
1090   return S.search(pos, pos+len, 0, c) >= 0;
1091 }
1092 
contains(const Regex & r)1093 inline int SubString::contains(const Regex& r) const
1094 {
1095   int unused;  return r.search(chars(), len, unused, 0) >= 0;
1096 }
1097 
matches(const Regex & r)1098 inline int SubString::matches(const Regex& r) const
1099 {
1100   return r.match(chars(), len, 0) == len;
1101 }
1102 
1103 
gsub(const String & pat,const String & r)1104 inline int String::gsub(const String& pat, const String& r)
1105 {
1106   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
1107 }
1108 
gsub(const SubString & pat,const String & r)1109 inline int String::gsub(const SubString&  pat, const String& r)
1110 {
1111   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
1112 }
1113 
gsub(const Regex & pat,const String & r)1114 inline int String::gsub(const Regex& pat, const String& r)
1115 {
1116   return _gsub(pat, r.chars(), r.length());
1117 }
1118 
gsub(const char * pat,const String & r)1119 inline int String::gsub(const char* pat, const String& r)
1120 {
1121   return _gsub(pat, -1, r.chars(), r.length());
1122 }
1123 
gsub(const char * pat,const char * r)1124 inline int String::gsub(const char* pat, const char* r)
1125 {
1126   return _gsub(pat, -1, r, -1);
1127 }
1128 
1129 
1130 inline String::operator const char*() const
1131 {
1132   return str(chars());
1133 }
1134 
1135 inline  ostream& operator<<(ostream& s, const String& x)
1136 {
1137 #ifdef VMS
1138    s << x.chars(); return s;
1139 #else
1140   s.put(x.chars()); return s;
1141 #endif
1142 
1143 }
1144 
1145 // a zillion comparison operators
1146 
1147 inline int operator==(const String& x, const String& y)
1148 {
1149   return compare(x, y) == 0;
1150 }
1151 
1152 inline int operator!=(const String& x, const String& y)
1153 {
1154   return compare(x, y) != 0;
1155 }
1156 
1157 inline int operator>(const String& x, const String& y)
1158 {
1159   return compare(x, y) > 0;
1160 }
1161 
1162 inline int operator>=(const String& x, const String& y)
1163 {
1164   return compare(x, y) >= 0;
1165 }
1166 
1167 inline int operator<(const String& x, const String& y)
1168 {
1169   return compare(x, y) < 0;
1170 }
1171 
1172 inline int operator<=(const String& x, const String& y)
1173 {
1174   return compare(x, y) <= 0;
1175 }
1176 
1177 inline int operator==(const String& x, const SubString&  y)
1178 {
1179   return compare(x, y) == 0;
1180 }
1181 
1182 inline int operator!=(const String& x, const SubString&  y)
1183 {
1184   return compare(x, y) != 0;
1185 }
1186 
1187 inline int operator>(const String& x, const SubString&  y)
1188 {
1189   return compare(x, y) > 0;
1190 }
1191 
1192 inline int operator>=(const String& x, const SubString&  y)
1193 {
1194   return compare(x, y) >= 0;
1195 }
1196 
1197 inline int operator<(const String& x, const SubString&  y)
1198 {
1199   return compare(x, y) < 0;
1200 }
1201 
1202 inline int operator<=(const String& x, const SubString&  y)
1203 {
1204   return compare(x, y) <= 0;
1205 }
1206 
1207 inline int operator==(const String& x, const char* t)
1208 {
1209   return compare(x, t) == 0;
1210 }
1211 
1212 inline int operator!=(const String& x, const char* t)
1213 {
1214   return compare(x, t) != 0;
1215 }
1216 
1217 inline int operator>(const String& x, const char* t)
1218 {
1219   return compare(x, t) > 0;
1220 }
1221 
1222 inline int operator>=(const String& x, const char* t)
1223 {
1224   return compare(x, t) >= 0;
1225 }
1226 
1227 inline int operator<(const String& x, const char* t)
1228 {
1229   return compare(x, t) < 0;
1230 }
1231 
1232 inline int operator<=(const String& x, const char* t)
1233 {
1234   return compare(x, t) <= 0;
1235 }
1236 
1237 inline int operator==(const SubString& x, const String& y)
1238 {
1239   return compare(y, x) == 0;
1240 }
1241 
1242 inline int operator!=(const SubString& x, const String& y)
1243 {
1244   return compare(y, x) != 0;
1245 }
1246 
1247 inline int operator>(const SubString& x, const String& y)
1248 {
1249   return compare(y, x) < 0;
1250 }
1251 
1252 inline int operator>=(const SubString& x, const String& y)
1253 {
1254   return compare(y, x) <= 0;
1255 }
1256 
1257 inline int operator<(const SubString& x, const String& y)
1258 {
1259   return compare(y, x) > 0;
1260 }
1261 
1262 inline int operator<=(const SubString& x, const String& y)
1263 {
1264   return compare(y, x) >= 0;
1265 }
1266 
1267 inline int operator==(const SubString& x, const SubString&  y)
1268 {
1269   return compare(x, y) == 0;
1270 }
1271 
1272 inline int operator!=(const SubString& x, const SubString&  y)
1273 {
1274   return compare(x, y) != 0;
1275 }
1276 
1277 inline int operator>(const SubString& x, const SubString&  y)
1278 {
1279   return compare(x, y) > 0;
1280 }
1281 
1282 inline int operator>=(const SubString& x, const SubString&  y)
1283 {
1284   return compare(x, y) >= 0;
1285 }
1286 
1287 inline int operator<(const SubString& x, const SubString&  y)
1288 {
1289   return compare(x, y) < 0;
1290 }
1291 
1292 inline int operator<=(const SubString& x, const SubString&  y)
1293 {
1294   return compare(x, y) <= 0;
1295 }
1296 
1297 inline int operator==(const SubString& x, const char* t)
1298 {
1299   return compare(x, t) == 0;
1300 }
1301 
1302 inline int operator!=(const SubString& x, const char* t)
1303 {
1304   return compare(x, t) != 0;
1305 }
1306 
1307 inline int operator>(const SubString& x, const char* t)
1308 {
1309   return compare(x, t) > 0;
1310 }
1311 
1312 inline int operator>=(const SubString& x, const char* t)
1313 {
1314   return compare(x, t) >= 0;
1315 }
1316 
1317 inline int operator<(const SubString& x, const char* t)
1318 {
1319   return compare(x, t) < 0;
1320 }
1321 
1322 inline int operator<=(const SubString& x, const char* t)
1323 {
1324   return compare(x, t) <= 0;
1325 }
1326 
1327 
1328 // a helper needed by at, before, etc.
1329 
_substr(int first,int l)1330 inline SubString String::_substr(int first, int l)
1331 {
1332   if (first < 0 || (unsigned)(first + l) > length())
1333     return SubString(_nilString, 0, 0) ;
1334   else
1335     return SubString(*this, first, l);
1336 }
1337 
1338 
1339 #endif
1340 
1341 #endif
1342