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