Add diclaimer of copyright to _osname() manual page.
[unix-history] / gnu / lib / libg++ / g++-include / String.h
CommitLineData
15637ed4
RG
1// This may look like C code, but it is really -*- C++ -*-
2/*
3Copyright (C) 1988 Free Software Foundation
4 written by Doug Lea (dl@rocky.oswego.edu)
5
6This file is part of GNU CC.
7
8GNU CC is distributed in the hope that it will be useful,
9but WITHOUT ANY WARRANTY. No author or distributor
10accepts responsibility to anyone for the consequences of using it
11or for whether it serves any particular purpose or works at all,
12unless he says so in writing. Refer to the GNU CC General Public
13License for full details.
14
15Everyone is granted permission to copy, modify and redistribute
16GNU CC, but only under the conditions described in the
17GNU CC General Public License. A copy of this license is
18supposed to have been given to you along with GNU CC so you
19can know your rights and responsibilities. It should be in a
20file named COPYING. Among other things, the copyright notice
21and 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
40struct 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
51StrRep* Salloc(StrRep*, const char*, int, int);
52StrRep* Scopy(StrRep*, StrRep*);
53StrRep* Sresize(StrRep*, int);
54StrRep* Scat(StrRep*, const char*, int, const char*, int);
55StrRep* Scat(StrRep*, const char*, int,const char*,int, const char*,int);
56StrRep* Sprepend(StrRep*, const char*, int);
57StrRep* Sreverse(StrRep*, StrRep*);
58StrRep* Supcase(StrRep*, StrRep*);
59StrRep* Sdowncase(StrRep*, StrRep*);
60StrRep* Scapitalize(StrRep*, StrRep*);
61
62// These classes need to be defined in the order given
63
64class String;
65class SubString;
66
67class SubString
68{
69 friend class String;
70protected:
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
80public:
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
119class String
120{
121 friend class SubString;
122
123protected:
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
135public:
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
394typedef String StrTmp; // for backward compatibility
395
396// other externs
397
398int compare(const String& x, const String& y);
399int compare(const String& x, const SubString& y);
400int compare(const String& x, const char* y);
401int compare(const SubString& x, const String& y);
402int compare(const SubString& x, const SubString& y);
403int compare(const SubString& x, const char* y);
404int fcompare(const String& x, const String& y); // ignore case
405
406extern StrRep _nilStrRep;
407extern String _nilString;
408
409// other inlines
410
411String operator + (const String& x, const String& y);
412String operator + (const String& x, const SubString& y);
413String operator + (const String& x, const char* y);
414String operator + (const String& x, char y);
415String operator + (const SubString& x, const String& y);
416String operator + (const SubString& x, const SubString& y);
417String operator + (const SubString& x, const char* y);
418String operator + (const SubString& x, char y);
419String operator + (const char* x, const String& y);
420String operator + (const char* x, const SubString& y);
421
422int operator==(const String& x, const String& y);
423int operator!=(const String& x, const String& y);
424int operator> (const String& x, const String& y);
425int operator>=(const String& x, const String& y);
426int operator< (const String& x, const String& y);
427int operator<=(const String& x, const String& y);
428int operator==(const String& x, const SubString& y);
429int operator!=(const String& x, const SubString& y);
430int operator> (const String& x, const SubString& y);
431int operator>=(const String& x, const SubString& y);
432int operator< (const String& x, const SubString& y);
433int operator<=(const String& x, const SubString& y);
434int operator==(const String& x, const char* t);
435int operator!=(const String& x, const char* t);
436int operator> (const String& x, const char* t);
437int operator>=(const String& x, const char* t);
438int operator< (const String& x, const char* t);
439int operator<=(const String& x, const char* t);
440int operator==(const SubString& x, const String& y);
441int operator!=(const SubString& x, const String& y);
442int operator> (const SubString& x, const String& y);
443int operator>=(const SubString& x, const String& y);
444int operator< (const SubString& x, const String& y);
445int operator<=(const SubString& x, const String& y);
446int operator==(const SubString& x, const SubString& y);
447int operator!=(const SubString& x, const SubString& y);
448int operator> (const SubString& x, const SubString& y);
449int operator>=(const SubString& x, const SubString& y);
450int operator< (const SubString& x, const SubString& y);
451int operator<=(const SubString& x, const SubString& y);
452int operator==(const SubString& x, const char* t);
453int operator!=(const SubString& x, const char* t);
454int operator> (const SubString& x, const char* t);
455int operator>=(const SubString& x, const char* t);
456int operator< (const SubString& x, const char* t);
457int 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
464inline int String::length() const { return rep->len; }
465inline int String::empty() const { return rep->len == 0; }
466inline const char* String::chars() const { return &(rep->s[0]); }
467inline int String::allocation() const { return rep->sz; }
468inline void String::alloc(int newsize) { rep = Sresize(rep, newsize); }
469
470inline int SubString::length() const { return len; }
471inline int SubString::empty() const { return len == 0; }
472inline const char* SubString::chars() const { return &(S.rep->s[pos]); }
473
474
475// constructors
476
477inline String::String()
478 : rep(&_nilStrRep) {}
479inline String::String(const String& x)
480 : rep(Scopy(0, x.rep)) {}
481inline String::String(const char* t)
482 : rep(Salloc(0, t, -1, -1)) {}
483inline String::String(const char* t, int tlen)
484 : rep(Salloc(0, t, tlen, tlen)) {}
485inline String::String(const SubString& y)
486 : rep(Salloc(0, y.chars(), y.length(), y.length())) {}
487inline String::String(char c)
488 : rep(Salloc(0, &c, 1, 1)) {}
489
490inline String::~String() { if (rep != &_nilStrRep) delete rep; }
491
492inline SubString::SubString(const SubString& x)
493 :S(x.S), pos(x.pos), len(x.len) {}
494inline SubString::SubString(String& x, int first, int l)
495 :S(x), pos(first), len(l) {}
496
497inline SubString::~SubString() {}
498
499// assignment
500
501inline void String::operator = (const String& y)
502{
503 rep = Scopy(rep, y.rep);
504}
505
506inline void String::operator=(const char* t)
507{
508 rep = Salloc(rep, t, -1, -1);
509}
510
511inline void String::operator=(const SubString& y)
512{
513 rep = Salloc(rep, y.chars(), y.length(), y.length());
514}
515
516inline void String::operator=(char c)
517{
518 rep = Salloc(rep, &c, 1, 1);
519}
520
521
522inline void SubString::operator = (const char* ys)
523{
524 assign(0, ys);
525}
526
527inline void SubString::operator = (char ch)
528{
529 assign(0, &ch, 1);
530}
531
532inline void SubString::operator = (const String& y)
533{
534 assign(y.rep, y.chars(), y.length());
535}
536
537inline void SubString::operator = (const SubString& y)
538{
539 assign(y.S.rep, y.chars(), y.length());
540}
541
542// Zillions of cats...
543
544inline 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
549inline 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
554inline 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
559inline void cat(const String& x, char y, String& r)
560{
561 r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
562}
563
564inline 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
569inline 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
574inline 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
579inline void cat(const SubString& x, char y, String& r)
580{
581 r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
582}
583
584inline 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
589inline 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
594inline void cat(const char* x, const char* y, String& r)
595{
596 r.rep = Scat(r.rep, x, -1, y, -1);
597}
598
599inline void cat(const char* x, char y, String& r)
600{
601 r.rep = Scat(r.rep, x, -1, &y, 1);
602}
603
604inline 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
609inline 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
614inline 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
619inline 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
624inline 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
629inline 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
634inline 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
639inline 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
644inline 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
649inline 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
654inline 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
659inline 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
665inline 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
670inline 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
675inline 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
680inline 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
685inline 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
690inline 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
695inline 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
700inline 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
705inline 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
710inline 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
715inline 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
720inline 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
728inline void String::operator +=(const String& y)
729{
730 cat(*this, y, *this);
731}
732
733inline void String::operator +=(const SubString& y)
734{
735 cat(*this, y, *this);
736}
737
738inline void String::operator += (const char* y)
739{
740 cat(*this, y, *this);
741}
742
743inline 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
752inline String operator + (const String& x, const String& y) return r;
753{
754 cat(x, y, r);
755}
756
757inline String operator + (const String& x, const SubString& y) return r;
758{
759 cat(x, y, r);
760}
761
762inline String operator + (const String& x, const char* y) return r;
763{
764 cat(x, y, r);
765}
766
767inline String operator + (const String& x, char y) return r;
768{
769 cat(x, y, r);
770}
771
772inline String operator + (const SubString& x, const String& y) return r;
773{
774 cat(x, y, r);
775}
776
777inline String operator + (const SubString& x, const SubString& y) return r;
778{
779 cat(x, y, r);
780}
781
782inline String operator + (const SubString& x, const char* y) return r;
783{
784 cat(x, y, r);
785}
786
787inline String operator + (const SubString& x, char y) return r;
788{
789 cat(x, y, r);
790}
791
792inline String operator + (const char* x, const String& y) return r;
793{
794 cat(x, y, r);
795}
796
797inline String operator + (const char* x, const SubString& y) return r;
798{
799 cat(x, y, r);
800}
801
802inline String reverse(const String& x) return r;
803{
804 r.rep = Sreverse(x.rep, r.rep);
805}
806
807inline String upcase(const String& x) return r;
808{
809 r.rep = Supcase(x.rep, r.rep);
810}
811
812inline String downcase(const String& x) return r;
813{
814 r.rep = Sdowncase(x.rep, r.rep);
815}
816
817inline String capitalize(const String& x) return r;
818{
819 r.rep = Scapitalize(x.rep, r.rep);
820}
821
822#else /* NO_NRV */
823
824inline String operator + (const String& x, const String& y)
825{
826 String r; cat(x, y, r); return r;
827}
828
829inline String operator + (const String& x, const SubString& y)
830{
831 String r; cat(x, y, r); return r;
832}
833
834inline String operator + (const String& x, const char* y)
835{
836 String r; cat(x, y, r); return r;
837}
838
839inline String operator + (const String& x, char y)
840{
841 String r; cat(x, y, r); return r;
842}
843
844inline String operator + (const SubString& x, const String& y)
845{
846 String r; cat(x, y, r); return r;
847}
848
849inline String operator + (const SubString& x, const SubString& y)
850{
851 String r; cat(x, y, r); return r;
852}
853
854inline String operator + (const SubString& x, const char* y)
855{
856 String r; cat(x, y, r); return r;
857}
858
859inline String operator + (const SubString& x, char y)
860{
861 String r; cat(x, y, r); return r;
862}
863
864inline String operator + (const char* x, const String& y)
865{
866 String r; cat(x, y, r); return r;
867}
868
869inline String operator + (const char* x, const SubString& y)
870{
871 String r; cat(x, y, r); return r;
872}
873
874inline String reverse(const String& x)
875{
876 String r; r.rep = Sreverse(x.rep, r.rep); return r;
877}
878
879inline String upcase(const String& x)
880{
881 String r; r.rep = Supcase(x.rep, r.rep); return r;
882}
883
884inline String downcase(const String& x)
885{
886 String r; r.rep = Sdowncase(x.rep, r.rep); return r;
887}
888
889inline 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
898inline void String::prepend(const String& y)
899{
900 rep = Sprepend(rep, y.chars(), y.length());
901}
902
903inline void String::prepend(const char* y)
904{
905 rep = Sprepend(rep, y, -1);
906}
907
908inline void String::prepend(char y)
909{
910 rep = Sprepend(rep, &y, 1);
911}
912
913inline void String::prepend(const SubString& y)
914{
915 rep = Sprepend(rep, y.chars(), y.length());
916}
917
918// misc transformations
919
920
921inline void String::reverse()
922{
923 rep = Sreverse(rep, rep);
924}
925
926
927inline void String::upcase()
928{
929 rep = Supcase(rep, rep);
930}
931
932
933inline void String::downcase()
934{
935 rep = Sdowncase(rep, rep);
936}
937
938
939inline void String::capitalize()
940{
941 rep = Scapitalize(rep, rep);
942}
943
944// element extraction
945
946inline char& String::operator [] (int i)
947{
948 if (((unsigned)i) >= length()) error("invalid index");
949 return rep->s[i];
950}
951
952inline char String::elem (int i) const
953{
954 if (((unsigned)i) >= length()) error("invalid index");
955 return rep->s[i];
956}
957
958inline char String::firstchar() const
959{
960 return elem(0);
961}
962
963inline char String::lastchar() const
964{
965 return elem(length() - 1);
966}
967
968// searching
969
970inline int String::index(char c, int startpos) const
971{
972 return search(startpos, length(), c);
973}
974
975inline int String::index(const char* t, int startpos) const
976{
977 return search(startpos, length(), t);
978}
979
980inline int String::index(const String& y, int startpos) const
981{
982 return search(startpos, length(), y.chars(), y.length());
983}
984
985inline int String::index(const SubString& y, int startpos) const
986{
987 return search(startpos, length(), y.chars(), y.length());
988}
989
990inline int String::index(const Regex& r, int startpos) const
991{
992 int unused; return r.search(chars(), length(), unused, startpos);
993}
994
995inline int String::contains(char c) const
996{
997 return search(0, length(), c) >= 0;
998}
999
1000inline int String::contains(const char* t) const
1001{
1002 return search(0, length(), t) >= 0;
1003}
1004
1005inline int String::contains(const String& y) const
1006{
1007 return search(0, length(), y.chars(), y.length()) >= 0;
1008}
1009
1010inline int String::contains(const SubString& y) const
1011{
1012 return search(0, length(), y.chars(), y.length()) >= 0;
1013}
1014
1015inline int String::contains(char c, int p) const
1016{
1017 return match(p, length(), 0, &c, 1) >= 0;
1018}
1019
1020inline int String::contains(const char* t, int p) const
1021{
1022 return match(p, length(), 0, t) >= 0;
1023}
1024
1025inline int String::contains(const String& y, int p) const
1026{
1027 return match(p, length(), 0, y.chars(), y.length()) >= 0;
1028}
1029
1030inline int String::contains(const SubString& y, int p) const
1031{
1032 return match(p, length(), 0, y.chars(), y.length()) >= 0;
1033}
1034
1035inline int String::contains(const Regex& r) const
1036{
1037 int unused; return r.search(chars(), length(), unused, 0) >= 0;
1038}
1039
1040inline int String::contains(const Regex& r, int p) const
1041{
1042 return r.match(chars(), length(), p) >= 0;
1043}
1044
1045
1046inline int String::matches(const SubString& y, int p) const
1047{
1048 return match(p, length(), 1, y.chars(), y.length()) >= 0;
1049}
1050
1051inline int String::matches(const String& y, int p) const
1052{
1053 return match(p, length(), 1, y.chars(), y.length()) >= 0;
1054}
1055
1056inline int String::matches(const char* t, int p) const
1057{
1058 return match(p, length(), 1, t) >= 0;
1059}
1060
1061inline int String::matches(char c, int p) const
1062{
1063 return match(p, length(), 1, &c, 1) >= 0;
1064}
1065
1066inline 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
1073inline int SubString::contains(const char* t) const
1074{
1075 return S.search(pos, pos+len, t) >= 0;
1076}
1077
1078inline int SubString::contains(const String& y) const
1079{
1080 return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
1081}
1082
1083inline int SubString::contains(const SubString& y) const
1084{
1085 return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
1086}
1087
1088inline int SubString::contains(char c) const
1089{
1090 return S.search(pos, pos+len, 0, c) >= 0;
1091}
1092
1093inline int SubString::contains(const Regex& r) const
1094{
1095 int unused; return r.search(chars(), len, unused, 0) >= 0;
1096}
1097
1098inline int SubString::matches(const Regex& r) const
1099{
1100 return r.match(chars(), len, 0) == len;
1101}
1102
1103
1104inline int String::gsub(const String& pat, const String& r)
1105{
1106 return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
1107}
1108
1109inline int String::gsub(const SubString& pat, const String& r)
1110{
1111 return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
1112}
1113
1114inline int String::gsub(const Regex& pat, const String& r)
1115{
1116 return _gsub(pat, r.chars(), r.length());
1117}
1118
1119inline int String::gsub(const char* pat, const String& r)
1120{
1121 return _gsub(pat, -1, r.chars(), r.length());
1122}
1123
1124inline int String::gsub(const char* pat, const char* r)
1125{
1126 return _gsub(pat, -1, r, -1);
1127}
1128
1129
1130inline String::operator const char*() const
1131{
1132 return str(chars());
1133}
1134
1135inline 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
1147inline int operator==(const String& x, const String& y)
1148{
1149 return compare(x, y) == 0;
1150}
1151
1152inline int operator!=(const String& x, const String& y)
1153{
1154 return compare(x, y) != 0;
1155}
1156
1157inline int operator>(const String& x, const String& y)
1158{
1159 return compare(x, y) > 0;
1160}
1161
1162inline int operator>=(const String& x, const String& y)
1163{
1164 return compare(x, y) >= 0;
1165}
1166
1167inline int operator<(const String& x, const String& y)
1168{
1169 return compare(x, y) < 0;
1170}
1171
1172inline int operator<=(const String& x, const String& y)
1173{
1174 return compare(x, y) <= 0;
1175}
1176
1177inline int operator==(const String& x, const SubString& y)
1178{
1179 return compare(x, y) == 0;
1180}
1181
1182inline int operator!=(const String& x, const SubString& y)
1183{
1184 return compare(x, y) != 0;
1185}
1186
1187inline int operator>(const String& x, const SubString& y)
1188{
1189 return compare(x, y) > 0;
1190}
1191
1192inline int operator>=(const String& x, const SubString& y)
1193{
1194 return compare(x, y) >= 0;
1195}
1196
1197inline int operator<(const String& x, const SubString& y)
1198{
1199 return compare(x, y) < 0;
1200}
1201
1202inline int operator<=(const String& x, const SubString& y)
1203{
1204 return compare(x, y) <= 0;
1205}
1206
1207inline int operator==(const String& x, const char* t)
1208{
1209 return compare(x, t) == 0;
1210}
1211
1212inline int operator!=(const String& x, const char* t)
1213{
1214 return compare(x, t) != 0;
1215}
1216
1217inline int operator>(const String& x, const char* t)
1218{
1219 return compare(x, t) > 0;
1220}
1221
1222inline int operator>=(const String& x, const char* t)
1223{
1224 return compare(x, t) >= 0;
1225}
1226
1227inline int operator<(const String& x, const char* t)
1228{
1229 return compare(x, t) < 0;
1230}
1231
1232inline int operator<=(const String& x, const char* t)
1233{
1234 return compare(x, t) <= 0;
1235}
1236
1237inline int operator==(const SubString& x, const String& y)
1238{
1239 return compare(y, x) == 0;
1240}
1241
1242inline int operator!=(const SubString& x, const String& y)
1243{
1244 return compare(y, x) != 0;
1245}
1246
1247inline int operator>(const SubString& x, const String& y)
1248{
1249 return compare(y, x) < 0;
1250}
1251
1252inline int operator>=(const SubString& x, const String& y)
1253{
1254 return compare(y, x) <= 0;
1255}
1256
1257inline int operator<(const SubString& x, const String& y)
1258{
1259 return compare(y, x) > 0;
1260}
1261
1262inline int operator<=(const SubString& x, const String& y)
1263{
1264 return compare(y, x) >= 0;
1265}
1266
1267inline int operator==(const SubString& x, const SubString& y)
1268{
1269 return compare(x, y) == 0;
1270}
1271
1272inline int operator!=(const SubString& x, const SubString& y)
1273{
1274 return compare(x, y) != 0;
1275}
1276
1277inline int operator>(const SubString& x, const SubString& y)
1278{
1279 return compare(x, y) > 0;
1280}
1281
1282inline int operator>=(const SubString& x, const SubString& y)
1283{
1284 return compare(x, y) >= 0;
1285}
1286
1287inline int operator<(const SubString& x, const SubString& y)
1288{
1289 return compare(x, y) < 0;
1290}
1291
1292inline int operator<=(const SubString& x, const SubString& y)
1293{
1294 return compare(x, y) <= 0;
1295}
1296
1297inline int operator==(const SubString& x, const char* t)
1298{
1299 return compare(x, t) == 0;
1300}
1301
1302inline int operator!=(const SubString& x, const char* t)
1303{
1304 return compare(x, t) != 0;
1305}
1306
1307inline int operator>(const SubString& x, const char* t)
1308{
1309 return compare(x, t) > 0;
1310}
1311
1312inline int operator>=(const SubString& x, const char* t)
1313{
1314 return compare(x, t) >= 0;
1315}
1316
1317inline int operator<(const SubString& x, const char* t)
1318{
1319 return compare(x, t) < 0;
1320}
1321
1322inline 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
1330inline 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