1 // This may look like C code, but it is really -*- C++ -*-
3 Copyright (C) 1988 Free Software Foundation
4 written by Doug Lea (dl@rocky.oswego.edu)
6 This file is part of GNU CC.
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.
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.
24 #if defined(SHORT_NAMES) || defined(VMS)
25 #define re_compile_pattern recmppat
26 #define re_pattern_buffer repatbuf
27 #define re_registers reregs
40 struct StrRep
// internal String representations
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
49 // primitive ops on StrReps -- nearly all String fns go through these.
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
*);
62 // These classes need to be defined in the order given
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
76 void assign(StrRep
*, const char*, int = -1);
77 SubString(String
& x
, int p
, int l
);
78 SubString(const SubString
& x
);
82 // Note there are no public constructors. SubStrings are always
83 // created via String operations
87 void operator = (const String
& y
);
88 void operator = (const SubString
& y
);
89 void operator = (const char* t
);
90 void operator = (char c
);
92 // return 1 if target appears anywhere in SubString; else 0
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;
100 // return 1 if target matches entire SubString
102 int matches(const Regex
& r
) const;
106 friend ostream
& operator<<(ostream
& s
, const SubString
& x
);
112 const char* chars() const;
121 friend class SubString
;
124 StrRep
* rep
; // Strings are pointers to their representations
126 // some helper functions
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);
137 // constructors & assignment
140 String(const String
& x
);
141 String(const SubString
& x
);
142 String(const char* t
);
143 String(const char* t
, int len
);
148 void operator = (const String
& y
);
149 void operator = (const char* y
);
150 void operator = (char c
);
151 void operator = (const SubString
& y
);
155 void operator += (const String
& y
);
156 void operator += (const SubString
& y
);
157 void operator += (const char* t
);
158 void operator += (char c
);
160 void prepend(const String
& y
);
161 void prepend(const SubString
& y
);
162 void prepend(const char* t
);
163 void prepend(char c
);
166 // procedural versions:
167 // concatenate first 2 args, store result in last arg
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
&);
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
&);
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
&);
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
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
&);
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
&);
215 // searching & matching
217 // return position of target in string or -1 for failure
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;
225 // return 1 if target appears anyhere in String; else 0
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;
233 // return 1 if target appears anywhere after position pos
234 // (or before, if pos is negative) in String; else 0
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;
242 // return 1 if target appears at position pos in String; else 0
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;
250 // return number of occurences of target in String
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;
257 // SubString extraction
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
263 SubString
at(int pos
, int len
);
264 SubString
operator () (int pos
, int len
); // synonym for at
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);
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);
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);
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);
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);
303 // delete len chars starting at pos
304 void del(int pos
, int len
);
306 // delete the first occurrence of target after startpos
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);
314 // global substitution: substitute all occurrences of pat with repl
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
);
322 // friends & utilities
324 // split string into array res at separators; return number of elements
326 friend int split(const String
& x
, String res
[], int maxn
,
328 friend int split(const String
& x
, String res
[], int maxn
,
331 friend String
common_prefix(const String
& x
, const String
& y
,
333 friend String
common_suffix(const String
& x
, const String
& y
,
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
);
339 // simple builtin transformations
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
);
346 // in-place versions of above
353 // element extraction
355 char& operator [] (int i
);
356 char elem(int i
) const;
357 char firstchar() const;
358 char lastchar() const;
362 operator const char*() const;
363 const char* chars() const;
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
);
372 friend int readline(istream
& s
, String
& x
,
373 char terminator
= '\n',
374 int discard_terminator
= 1);
381 // preallocate some space for String
382 void alloc(int newsize
);
384 // report current allocation (not length!)
386 int allocation() const;
389 volatile void error(const char* msg
) const;
394 typedef String StrTmp
; // for backward compatibility
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
406 extern StrRep _nilStrRep
;
407 extern String _nilString
;
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
);
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
);
459 #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
462 // status reports, needed before defining other things
464 inline int String::length() const { return rep
->len
; }
465 inline int String::empty() const { return rep
->len
== 0; }
466 inline const char* String::chars() const { return &(rep
->s
[0]); }
467 inline int String::allocation() const { return rep
->sz
; }
468 inline void String::alloc(int newsize
) { rep
= Sresize(rep
, newsize
); }
470 inline int SubString::length() const { return len
; }
471 inline int SubString::empty() const { return len
== 0; }
472 inline const char* SubString::chars() const { return &(S
.rep
->s
[pos
]); }
477 inline String::String()
478 : rep(&_nilStrRep
) {}
479 inline String::String(const String
& x
)
480 : rep(Scopy(0, x
.rep
)) {}
481 inline String::String(const char* t
)
482 : rep(Salloc(0, t
, -1, -1)) {}
483 inline String::String(const char* t
, int tlen
)
484 : rep(Salloc(0, t
, tlen
, tlen
)) {}
485 inline String::String(const SubString
& y
)
486 : rep(Salloc(0, y
.chars(), y
.length(), y
.length())) {}
487 inline String::String(char c
)
488 : rep(Salloc(0, &c
, 1, 1)) {}
490 inline String::~String() { if (rep
!= &_nilStrRep
) delete rep
; }
492 inline SubString::SubString(const SubString
& x
)
493 :S(x
.S
), pos(x
.pos
), len(x
.len
) {}
494 inline SubString::SubString(String
& x
, int first
, int l
)
495 :S(x
), pos(first
), len(l
) {}
497 inline SubString::~SubString() {}
501 inline void String::operator = (const String
& y
)
503 rep
= Scopy(rep
, y
.rep
);
506 inline void String::operator=(const char* t
)
508 rep
= Salloc(rep
, t
, -1, -1);
511 inline void String::operator=(const SubString
& y
)
513 rep
= Salloc(rep
, y
.chars(), y
.length(), y
.length());
516 inline void String::operator=(char c
)
518 rep
= Salloc(rep
, &c
, 1, 1);
522 inline void SubString::operator = (const char* ys
)
527 inline void SubString::operator = (char ch
)
532 inline void SubString::operator = (const String
& y
)
534 assign(y
.rep
, y
.chars(), y
.length());
537 inline void SubString::operator = (const SubString
& y
)
539 assign(y
.S
.rep
, y
.chars(), y
.length());
542 // Zillions of cats...
544 inline void cat(const String
& x
, const String
& y
, String
& r
)
546 r
.rep
= Scat(r
.rep
, x
.chars(), x
.length(), y
.chars(), y
.length());
549 inline void cat(const String
& x
, const SubString
& y
, String
& r
)
551 r
.rep
= Scat(r
.rep
, x
.chars(), x
.length(), y
.chars(), y
.length());
554 inline void cat(const String
& x
, const char* y
, String
& r
)
556 r
.rep
= Scat(r
.rep
, x
.chars(), x
.length(), y
, -1);
559 inline void cat(const String
& x
, char y
, String
& r
)
561 r
.rep
= Scat(r
.rep
, x
.chars(), x
.length(), &y
, 1);
564 inline void cat(const SubString
& x
, const String
& y
, String
& r
)
566 r
.rep
= Scat(r
.rep
, x
.chars(), x
.length(), y
.chars(), y
.length());
569 inline void cat(const SubString
& x
, const SubString
& y
, String
& r
)
571 r
.rep
= Scat(r
.rep
, x
.chars(), x
.length(), y
.chars(), y
.length());
574 inline void cat(const SubString
& x
, const char* y
, String
& r
)
576 r
.rep
= Scat(r
.rep
, x
.chars(), x
.length(), y
, -1);
579 inline void cat(const SubString
& x
, char y
, String
& r
)
581 r
.rep
= Scat(r
.rep
, x
.chars(), x
.length(), &y
, 1);
584 inline void cat(const char* x
, const String
& y
, String
& r
)
586 r
.rep
= Scat(r
.rep
, x
, -1, y
.chars(), y
.length());
589 inline void cat(const char* x
, const SubString
& y
, String
& r
)
591 r
.rep
= Scat(r
.rep
, x
, -1, y
.chars(), y
.length());
594 inline void cat(const char* x
, const char* y
, String
& r
)
596 r
.rep
= Scat(r
.rep
, x
, -1, y
, -1);
599 inline void cat(const char* x
, char y
, String
& r
)
601 r
.rep
= Scat(r
.rep
, x
, -1, &y
, 1);
604 inline void cat(const String
& a
, const String
& x
, const String
& y
, String
& r
)
606 r
.rep
= Scat(r
.rep
, a
.chars(), a
.length(), x
.chars(), x
.length(), y
.chars(), y
.length());
609 inline void cat(const String
& a
, const String
& x
, const SubString
& y
, String
& r
)
611 r
.rep
= Scat(r
.rep
, a
.chars(), a
.length(), x
.chars(), x
.length(), y
.chars(), y
.length());
614 inline void cat(const String
& a
, const String
& x
, const char* y
, String
& r
)
616 r
.rep
= Scat(r
.rep
, a
.chars(), a
.length(), x
.chars(), x
.length(), y
, -1);
619 inline void cat(const String
& a
, const String
& x
, char y
, String
& r
)
621 r
.rep
= Scat(r
.rep
, a
.chars(), a
.length(), x
.chars(), x
.length(), &y
, 1);
624 inline void cat(const String
& a
, const SubString
& x
, const String
& y
, String
& r
)
626 r
.rep
= Scat(r
.rep
, a
.chars(), a
.length(), x
.chars(), x
.length(), y
.chars(), y
.length());
629 inline void cat(const String
& a
, const SubString
& x
, const SubString
& y
, String
& r
)
631 r
.rep
= Scat(r
.rep
, a
.chars(), a
.length(), x
.chars(), x
.length(), y
.chars(), y
.length());
634 inline void cat(const String
& a
, const SubString
& x
, const char* y
, String
& r
)
636 r
.rep
= Scat(r
.rep
, a
.chars(), a
.length(), x
.chars(), x
.length(), y
, -1);
639 inline void cat(const String
& a
, const SubString
& x
, char y
, String
& r
)
641 r
.rep
= Scat(r
.rep
, a
.chars(), a
.length(), x
.chars(), x
.length(), &y
, 1);
644 inline void cat(const String
& a
, const char* x
, const String
& y
, String
& r
)
646 r
.rep
= Scat(r
.rep
, a
.chars(), a
.length(), x
, -1, y
.chars(), y
.length());
649 inline void cat(const String
& a
, const char* x
, const SubString
& y
, String
& r
)
651 r
.rep
= Scat(r
.rep
, a
.chars(), a
.length(), x
, -1, y
.chars(), y
.length());
654 inline void cat(const String
& a
, const char* x
, const char* y
, String
& r
)
656 r
.rep
= Scat(r
.rep
, a
.chars(), a
.length(), x
, -1, y
, -1);
659 inline void cat(const String
& a
, const char* x
, char y
, String
& r
)
661 r
.rep
= Scat(r
.rep
, a
.chars(), a
.length(), x
, -1, &y
, 1);
665 inline void cat(const char* a
, const String
& x
, const String
& y
, String
& r
)
667 r
.rep
= Scat(r
.rep
, a
, -1, x
.chars(), x
.length(), y
.chars(), y
.length());
670 inline void cat(const char* a
, const String
& x
, const SubString
& y
, String
& r
)
672 r
.rep
= Scat(r
.rep
, a
, -1, x
.chars(), x
.length(), y
.chars(), y
.length());
675 inline void cat(const char* a
, const String
& x
, const char* y
, String
& r
)
677 r
.rep
= Scat(r
.rep
, a
, -1, x
.chars(), x
.length(), y
, -1);
680 inline void cat(const char* a
, const String
& x
, char y
, String
& r
)
682 r
.rep
= Scat(r
.rep
, a
, -1, x
.chars(), x
.length(), &y
, 1);
685 inline void cat(const char* a
, const SubString
& x
, const String
& y
, String
& r
)
687 r
.rep
= Scat(r
.rep
, a
, -1, x
.chars(), x
.length(), y
.chars(), y
.length());
690 inline void cat(const char* a
, const SubString
& x
, const SubString
& y
, String
& r
)
692 r
.rep
= Scat(r
.rep
, a
, -1, x
.chars(), x
.length(), y
.chars(), y
.length());
695 inline void cat(const char* a
, const SubString
& x
, const char* y
, String
& r
)
697 r
.rep
= Scat(r
.rep
, a
, -1, x
.chars(), x
.length(), y
, -1);
700 inline void cat(const char* a
, const SubString
& x
, char y
, String
& r
)
702 r
.rep
= Scat(r
.rep
, a
, -1, x
.chars(), x
.length(), &y
, 1);
705 inline void cat(const char* a
, const char* x
, const String
& y
, String
& r
)
707 r
.rep
= Scat(r
.rep
, a
, -1, x
, -1, y
.chars(), y
.length());
710 inline void cat(const char* a
, const char* x
, const SubString
& y
, String
& r
)
712 r
.rep
= Scat(r
.rep
, a
, -1, x
, -1, y
.chars(), y
.length());
715 inline void cat(const char* a
, const char* x
, const char* y
, String
& r
)
717 r
.rep
= Scat(r
.rep
, a
, -1, x
, -1, y
, -1);
720 inline void cat(const char* a
, const char* x
, char y
, String
& r
)
722 r
.rep
= Scat(r
.rep
, a
, -1, x
, -1, &y
, 1);
728 inline void String::operator +=(const String
& y
)
730 cat(*this, y
, *this);
733 inline void String::operator +=(const SubString
& y
)
735 cat(*this, y
, *this);
738 inline void String::operator += (const char* y
)
740 cat(*this, y
, *this);
743 inline void String:: operator +=(char y
)
745 cat(*this, y
, *this);
748 // constructive concatenation
750 #if defined(__GNUG__) && !defined(NO_NRV)
752 inline String
operator + (const String
& x
, const String
& y
) return r
;
757 inline String
operator + (const String
& x
, const SubString
& y
) return r
;
762 inline String
operator + (const String
& x
, const char* y
) return r
;
767 inline String
operator + (const String
& x
, char y
) return r
;
772 inline String
operator + (const SubString
& x
, const String
& y
) return r
;
777 inline String
operator + (const SubString
& x
, const SubString
& y
) return r
;
782 inline String
operator + (const SubString
& x
, const char* y
) return r
;
787 inline String
operator + (const SubString
& x
, char y
) return r
;
792 inline String
operator + (const char* x
, const String
& y
) return r
;
797 inline String
operator + (const char* x
, const SubString
& y
) return r
;
802 inline String
reverse(const String
& x
) return r
;
804 r
.rep
= Sreverse(x
.rep
, r
.rep
);
807 inline String
upcase(const String
& x
) return r
;
809 r
.rep
= Supcase(x
.rep
, r
.rep
);
812 inline String
downcase(const String
& x
) return r
;
814 r
.rep
= Sdowncase(x
.rep
, r
.rep
);
817 inline String
capitalize(const String
& x
) return r
;
819 r
.rep
= Scapitalize(x
.rep
, r
.rep
);
824 inline String
operator + (const String
& x
, const String
& y
)
826 String r
; cat(x
, y
, r
); return r
;
829 inline String
operator + (const String
& x
, const SubString
& y
)
831 String r
; cat(x
, y
, r
); return r
;
834 inline String
operator + (const String
& x
, const char* y
)
836 String r
; cat(x
, y
, r
); return r
;
839 inline String
operator + (const String
& x
, char y
)
841 String r
; cat(x
, y
, r
); return r
;
844 inline String
operator + (const SubString
& x
, const String
& y
)
846 String r
; cat(x
, y
, r
); return r
;
849 inline String
operator + (const SubString
& x
, const SubString
& y
)
851 String r
; cat(x
, y
, r
); return r
;
854 inline String
operator + (const SubString
& x
, const char* y
)
856 String r
; cat(x
, y
, r
); return r
;
859 inline String
operator + (const SubString
& x
, char y
)
861 String r
; cat(x
, y
, r
); return r
;
864 inline String
operator + (const char* x
, const String
& y
)
866 String r
; cat(x
, y
, r
); return r
;
869 inline String
operator + (const char* x
, const SubString
& y
)
871 String r
; cat(x
, y
, r
); return r
;
874 inline String
reverse(const String
& x
)
876 String r
; r
.rep
= Sreverse(x
.rep
, r
.rep
); return r
;
879 inline String
upcase(const String
& x
)
881 String r
; r
.rep
= Supcase(x
.rep
, r
.rep
); return r
;
884 inline String
downcase(const String
& x
)
886 String r
; r
.rep
= Sdowncase(x
.rep
, r
.rep
); return r
;
889 inline String
capitalize(const String
& x
)
891 String r
; r
.rep
= Scapitalize(x
.rep
, r
.rep
); return r
;
898 inline void String::prepend(const String
& y
)
900 rep
= Sprepend(rep
, y
.chars(), y
.length());
903 inline void String::prepend(const char* y
)
905 rep
= Sprepend(rep
, y
, -1);
908 inline void String::prepend(char y
)
910 rep
= Sprepend(rep
, &y
, 1);
913 inline void String::prepend(const SubString
& y
)
915 rep
= Sprepend(rep
, y
.chars(), y
.length());
918 // misc transformations
921 inline void String::reverse()
923 rep
= Sreverse(rep
, rep
);
927 inline void String::upcase()
929 rep
= Supcase(rep
, rep
);
933 inline void String::downcase()
935 rep
= Sdowncase(rep
, rep
);
939 inline void String::capitalize()
941 rep
= Scapitalize(rep
, rep
);
944 // element extraction
946 inline char& String::operator [] (int i
)
948 if (((unsigned)i
) >= length()) error("invalid index");
952 inline char String::elem (int i
) const
954 if (((unsigned)i
) >= length()) error("invalid index");
958 inline char String::firstchar() const
963 inline char String::lastchar() const
965 return elem(length() - 1);
970 inline int String::index(char c
, int startpos
) const
972 return search(startpos
, length(), c
);
975 inline int String::index(const char* t
, int startpos
) const
977 return search(startpos
, length(), t
);
980 inline int String::index(const String
& y
, int startpos
) const
982 return search(startpos
, length(), y
.chars(), y
.length());
985 inline int String::index(const SubString
& y
, int startpos
) const
987 return search(startpos
, length(), y
.chars(), y
.length());
990 inline int String::index(const Regex
& r
, int startpos
) const
992 int unused
; return r
.search(chars(), length(), unused
, startpos
);
995 inline int String::contains(char c
) const
997 return search(0, length(), c
) >= 0;
1000 inline int String::contains(const char* t
) const
1002 return search(0, length(), t
) >= 0;
1005 inline int String::contains(const String
& y
) const
1007 return search(0, length(), y
.chars(), y
.length()) >= 0;
1010 inline int String::contains(const SubString
& y
) const
1012 return search(0, length(), y
.chars(), y
.length()) >= 0;
1015 inline int String::contains(char c
, int p
) const
1017 return match(p
, length(), 0, &c
, 1) >= 0;
1020 inline int String::contains(const char* t
, int p
) const
1022 return match(p
, length(), 0, t
) >= 0;
1025 inline int String::contains(const String
& y
, int p
) const
1027 return match(p
, length(), 0, y
.chars(), y
.length()) >= 0;
1030 inline int String::contains(const SubString
& y
, int p
) const
1032 return match(p
, length(), 0, y
.chars(), y
.length()) >= 0;
1035 inline int String::contains(const Regex
& r
) const
1037 int unused
; return r
.search(chars(), length(), unused
, 0) >= 0;
1040 inline int String::contains(const Regex
& r
, int p
) const
1042 return r
.match(chars(), length(), p
) >= 0;
1046 inline int String::matches(const SubString
& y
, int p
) const
1048 return match(p
, length(), 1, y
.chars(), y
.length()) >= 0;
1051 inline int String::matches(const String
& y
, int p
) const
1053 return match(p
, length(), 1, y
.chars(), y
.length()) >= 0;
1056 inline int String::matches(const char* t
, int p
) const
1058 return match(p
, length(), 1, t
) >= 0;
1061 inline int String::matches(char c
, int p
) const
1063 return match(p
, length(), 1, &c
, 1) >= 0;
1066 inline int String::matches(const Regex
& r
, int p
) const
1068 int l
= (p
< 0)? -p
: length() - p
;
1069 return r
.match(chars(), length(), p
) == l
;
1073 inline int SubString::contains(const char* t
) const
1075 return S
.search(pos
, pos
+len
, t
) >= 0;
1078 inline int SubString::contains(const String
& y
) const
1080 return S
.search(pos
, pos
+len
, y
.chars(), y
.length()) >= 0;
1083 inline int SubString::contains(const SubString
& y
) const
1085 return S
.search(pos
, pos
+len
, y
.chars(), y
.length()) >= 0;
1088 inline int SubString::contains(char c
) const
1090 return S
.search(pos
, pos
+len
, 0, c
) >= 0;
1093 inline int SubString::contains(const Regex
& r
) const
1095 int unused
; return r
.search(chars(), len
, unused
, 0) >= 0;
1098 inline int SubString::matches(const Regex
& r
) const
1100 return r
.match(chars(), len
, 0) == len
;
1104 inline int String::gsub(const String
& pat
, const String
& r
)
1106 return _gsub(pat
.chars(), pat
.length(), r
.chars(), r
.length());
1109 inline int String::gsub(const SubString
& pat
, const String
& r
)
1111 return _gsub(pat
.chars(), pat
.length(), r
.chars(), r
.length());
1114 inline int String::gsub(const Regex
& pat
, const String
& r
)
1116 return _gsub(pat
, r
.chars(), r
.length());
1119 inline int String::gsub(const char* pat
, const String
& r
)
1121 return _gsub(pat
, -1, r
.chars(), r
.length());
1124 inline int String::gsub(const char* pat
, const char* r
)
1126 return _gsub(pat
, -1, r
, -1);
1130 inline String::operator const char*() const
1132 return str(chars());
1135 inline ostream
& operator<<(ostream
& s
, const String
& x
)
1138 s
<< x
.chars(); return s
;
1140 s
.put(x
.chars()); return s
;
1145 // a zillion comparison operators
1147 inline int operator==(const String
& x
, const String
& y
)
1149 return compare(x
, y
) == 0;
1152 inline int operator!=(const String
& x
, const String
& y
)
1154 return compare(x
, y
) != 0;
1157 inline int operator>(const String
& x
, const String
& y
)
1159 return compare(x
, y
) > 0;
1162 inline int operator>=(const String
& x
, const String
& y
)
1164 return compare(x
, y
) >= 0;
1167 inline int operator<(const String
& x
, const String
& y
)
1169 return compare(x
, y
) < 0;
1172 inline int operator<=(const String
& x
, const String
& y
)
1174 return compare(x
, y
) <= 0;
1177 inline int operator==(const String
& x
, const SubString
& y
)
1179 return compare(x
, y
) == 0;
1182 inline int operator!=(const String
& x
, const SubString
& y
)
1184 return compare(x
, y
) != 0;
1187 inline int operator>(const String
& x
, const SubString
& y
)
1189 return compare(x
, y
) > 0;
1192 inline int operator>=(const String
& x
, const SubString
& y
)
1194 return compare(x
, y
) >= 0;
1197 inline int operator<(const String
& x
, const SubString
& y
)
1199 return compare(x
, y
) < 0;
1202 inline int operator<=(const String
& x
, const SubString
& y
)
1204 return compare(x
, y
) <= 0;
1207 inline int operator==(const String
& x
, const char* t
)
1209 return compare(x
, t
) == 0;
1212 inline int operator!=(const String
& x
, const char* t
)
1214 return compare(x
, t
) != 0;
1217 inline int operator>(const String
& x
, const char* t
)
1219 return compare(x
, t
) > 0;
1222 inline int operator>=(const String
& x
, const char* t
)
1224 return compare(x
, t
) >= 0;
1227 inline int operator<(const String
& x
, const char* t
)
1229 return compare(x
, t
) < 0;
1232 inline int operator<=(const String
& x
, const char* t
)
1234 return compare(x
, t
) <= 0;
1237 inline int operator==(const SubString
& x
, const String
& y
)
1239 return compare(y
, x
) == 0;
1242 inline int operator!=(const SubString
& x
, const String
& y
)
1244 return compare(y
, x
) != 0;
1247 inline int operator>(const SubString
& x
, const String
& y
)
1249 return compare(y
, x
) < 0;
1252 inline int operator>=(const SubString
& x
, const String
& y
)
1254 return compare(y
, x
) <= 0;
1257 inline int operator<(const SubString
& x
, const String
& y
)
1259 return compare(y
, x
) > 0;
1262 inline int operator<=(const SubString
& x
, const String
& y
)
1264 return compare(y
, x
) >= 0;
1267 inline int operator==(const SubString
& x
, const SubString
& y
)
1269 return compare(x
, y
) == 0;
1272 inline int operator!=(const SubString
& x
, const SubString
& y
)
1274 return compare(x
, y
) != 0;
1277 inline int operator>(const SubString
& x
, const SubString
& y
)
1279 return compare(x
, y
) > 0;
1282 inline int operator>=(const SubString
& x
, const SubString
& y
)
1284 return compare(x
, y
) >= 0;
1287 inline int operator<(const SubString
& x
, const SubString
& y
)
1289 return compare(x
, y
) < 0;
1292 inline int operator<=(const SubString
& x
, const SubString
& y
)
1294 return compare(x
, y
) <= 0;
1297 inline int operator==(const SubString
& x
, const char* t
)
1299 return compare(x
, t
) == 0;
1302 inline int operator!=(const SubString
& x
, const char* t
)
1304 return compare(x
, t
) != 0;
1307 inline int operator>(const SubString
& x
, const char* t
)
1309 return compare(x
, t
) > 0;
1312 inline int operator>=(const SubString
& x
, const char* t
)
1314 return compare(x
, t
) >= 0;
1317 inline int operator<(const SubString
& x
, const char* t
)
1319 return compare(x
, t
) < 0;
1322 inline int operator<=(const SubString
& x
, const char* t
)
1324 return compare(x
, t
) <= 0;
1328 // a helper needed by at, before, etc.
1330 inline SubString
String::_substr(int first
, int l
)
1332 if (first
< 0 || (unsigned)(first
+ l
) > length())
1333 return SubString(_nilString
, 0, 0) ;
1335 return SubString(*this, first
, l
);