Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

MNString.h

Go to the documentation of this file.
00001 // This may look like C code, but it is really -*- C++ -*- 00002 /* 00003 Copyright (C) 1988 Free Software Foundation 00004 written by Doug Lea (dl@rocky.oswego.edu) 00005 00006 This file is part of the GNU C++ Library. This library is free 00007 software; you can redistribute it and/or modify it under the terms of 00008 the GNU Library General Public License as published by the Free 00009 Software Foundation; either version 2 of the License, or (at your 00010 option) any later version. This library is distributed in the hope 00011 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00012 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00013 PURPOSE. See the GNU Library General Public License for more details. 00014 You should have received a copy of the GNU Library General Public 00015 License along with this library; if not, write to the Free Software 00016 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00024 00025 #include <config.h> 00026 00027 #ifndef _MNString_h 00028 #define _MNString_h 1 00029 00030 #include <string> 00031 00032 #include "mnstream.h" 00033 #include "MNRegex.h" 00034 00035 using std::string; 00036 00037 #undef OK 00038 00039 /* 00040 * The original string class uses the GCC extension called 'named 00041 * return values'. This concept may be known from Pascal. The 00042 * advantage is that optimizer can allocate storage for the return 00043 * value before actually calling the function, thus potentially 00044 * saving one constructor and one destructor call in the function. 00045 * This is not ANCI C++ and the following define disables it. 00046 */ 00047 #define _G_NO_NRV 00048 00051 struct MNStrRep // internal MNString representations 00052 { 00053 unsigned short len; // string length 00054 unsigned short sz; // allocated space 00055 char s[1]; // the string starts here 00056 // (at least 1 char for trailing null) 00057 // allocated & expanded via non-public fcts 00058 }; 00059 00062 // primitive ops on MNStrReps -- nearly all MNString fns go through these. 00063 00064 MNStrRep* Salloc(MNStrRep*, const char*, int, int); 00065 MNStrRep* Scopy(MNStrRep*, const MNStrRep*); 00066 MNStrRep* Scat(MNStrRep*, const char*, int, const char*, int); 00067 MNStrRep* Scat(MNStrRep*, const char*, int,const char*,int, const char*,int); 00068 MNStrRep* Sprepend(MNStrRep*, const char*, int); 00069 MNStrRep* Sreverse(const MNStrRep*, MNStrRep*); 00070 MNStrRep* Supcase(const MNStrRep*, MNStrRep*); 00071 MNStrRep* Sdowncase(const MNStrRep*, MNStrRep*); 00072 MNStrRep* Scapitalize(const MNStrRep*, MNStrRep*); 00074 00075 // These classes need to be defined in the order given 00076 00077 class MNString; 00078 class MNSubString; 00079 00082 class MNSubString 00083 { 00084 friend class MNString; 00085 protected: 00086 00087 MNString& S; // The MNString I'm a substring of 00088 unsigned short pos; // starting position in S's rep 00089 unsigned short len; // length of substring 00090 00091 void assign(const MNStrRep*, const char*, int = -1); 00092 public: 00093 MNSubString(MNString& x, int p, int l); 00094 MNSubString(const MNSubString& x); 00095 00096 public: 00097 00098 // Note there are no public constructors. MNSubStrings are always 00099 // created via MNString operations 00100 00101 ~MNSubString(); 00102 00103 MNSubString& operator = (const MNString& y); 00104 MNSubString& operator = (const MNSubString& y); 00105 MNSubString& operator = (const char* t); 00106 MNSubString& operator = (char c); 00107 00108 // return 1 if target appears anywhere in MNSubString; else 0 00109 00110 int contains(char c) const; 00111 int contains(const MNString& y) const; 00112 int contains(const MNSubString& y) const; 00113 int contains(const char* t) const; 00114 int contains(const MNRegex& r) const; 00115 00116 // return 1 if target matches entire MNSubString 00117 00118 int matches(const MNRegex& r) const; 00119 00120 // IO 00121 00122 friend std::ostream& operator<<(std::ostream& s, const MNSubString& x); 00123 00124 // status 00125 00126 unsigned int length() const; 00127 int empty() const; 00128 const char* chars() const; 00129 00130 int OK() const; 00131 00132 }; 00133 00134 00143 class MNString 00144 { 00145 friend class MNSubString; 00146 00147 protected: 00148 MNStrRep* rep; // MNStrings are pointers to their representations 00149 00150 // some helper functions 00151 00152 int search(int, int, const char*, int = -1) const; 00153 int search(int, int, char) const; 00154 int match(int, int, int, const char*, int = -1) const; 00155 int _gsub(const char*, int, const char* ,int); 00156 int _gsub(const MNRegex&, const char*, int); 00157 MNSubString _substr(int, int); 00158 00159 public: 00160 00161 // constructors & assignment 00162 00163 MNString(); 00164 MNString(const MNString& x); 00165 MNString(const MNSubString& x); 00166 MNString(const char* t); 00167 MNString(const string t); 00168 MNString(const char* t, int len); 00169 MNString(char c); 00170 private: 00171 /* And some forbidden constructors. These would 00172 * be helpful for reading and assigning characters 00173 * to strings, but they are too dangerous because 00174 * of their implicit typecast to char 00175 */ 00176 MNString(unsigned int c); 00177 MNString( signed int c); 00178 MNString(unsigned long c); 00179 MNString( signed long c); 00180 00181 public: 00182 ~MNString(); 00183 00184 MNString& operator = (const MNString& y); 00185 MNString& operator = (const char* y); 00186 MNString& operator = (char c); 00187 MNString& operator = (const MNSubString& y); 00188 MNString& operator = (const string y); 00189 00190 // concatenation 00191 00192 MNString& operator += (const MNString& y); 00193 MNString& operator += (const MNSubString& y); 00194 MNString& operator += (const char* t); 00195 MNString& operator += (char c); 00196 00197 void prepend(const MNString& y); 00198 void prepend(const MNSubString& y); 00199 void prepend(const char* t); 00200 void prepend(char c); 00201 00202 00203 // procedural versions: 00204 // concatenate first 2 args, store result in last arg 00205 00206 friend inline void cat(const MNString&, const MNString&, MNString&); 00207 friend inline void cat(const MNString&, const MNSubString&, MNString&); 00208 friend inline void cat(const MNString&, const char*, MNString&); 00209 friend inline void cat(const MNString&, char, MNString&); 00210 00211 friend inline void cat(const MNSubString&, const MNString&, MNString&); 00212 friend inline void cat(const MNSubString&, const MNSubString&, MNString&); 00213 friend inline void cat(const MNSubString&, const char*, MNString&); 00214 friend inline void cat(const MNSubString&, char, MNString&); 00215 00216 friend inline void cat(const char*, const MNString&, MNString&); 00217 friend inline void cat(const char*, const MNSubString&, MNString&); 00218 friend inline void cat(const char*, const char*, MNString&); 00219 friend inline void cat(const char*, char, MNString&); 00220 00221 // double concatenation, by request. (yes, there are too many versions, 00222 // but if one is supported, then the others should be too...) 00223 // Concatenate first 3 args, store in last arg 00224 00225 friend inline void cat(const MNString&,const MNString&, const MNString&,MNString&); 00226 friend inline void cat(const MNString&,const MNString&,const MNSubString&,MNString&); 00227 friend inline void cat(const MNString&,const MNString&, const char*, MNString&); 00228 friend inline void cat(const MNString&,const MNString&, char, MNString&); 00229 friend inline void cat(const MNString&,const MNSubString&,const MNString&,MNString&); 00230 inline friend void cat(const MNString&,const MNSubString&,const MNSubString&,MNString&); 00231 friend inline void cat(const MNString&,const MNSubString&, const char*, MNString&); 00232 friend inline void cat(const MNString&,const MNSubString&, char, MNString&); 00233 friend inline void cat(const MNString&,const char*, const MNString&, MNString&); 00234 friend inline void cat(const MNString&,const char*, const MNSubString&, MNString&); 00235 friend inline void cat(const MNString&,const char*, const char*, MNString&); 00236 friend inline void cat(const MNString&,const char*, char, MNString&); 00237 00238 friend inline void cat(const char*, const MNString&, const MNString&,MNString&); 00239 friend inline void cat(const char*,const MNString&,const MNSubString&,MNString&); 00240 friend inline void cat(const char*,const MNString&, const char*, MNString&); 00241 friend inline void cat(const char*,const MNString&, char, MNString&); 00242 friend inline void cat(const char*,const MNSubString&,const MNString&,MNString&); 00243 friend inline void cat(const char*,const MNSubString&,const MNSubString&,MNString&); 00244 friend inline void cat(const char*,const MNSubString&, const char*, MNString&); 00245 friend inline void cat(const char*,const MNSubString&, char, MNString&); 00246 friend inline void cat(const char*,const char*, const MNString&, MNString&); 00247 friend inline void cat(const char*,const char*, const MNSubString&, MNString&); 00248 friend inline void cat(const char*,const char*, const char*, MNString&); 00249 friend inline void cat(const char*,const char*, char, MNString&); 00250 00251 00252 // searching & matching 00253 00254 // return position of target in string or -1 for failure 00255 00256 int index(char c, int startpos = 0) const; 00257 int index(const MNString& y, int startpos = 0) const; 00258 int index(const MNSubString& y, int startpos = 0) const; 00259 int index(const char* t, int startpos = 0) const; 00260 int index(const MNRegex& r, int startpos = 0) const; 00261 00262 // return 1 if target appears anyhere in MNString; else 0 00263 00264 int contains(char c) const; 00265 int contains(const MNString& y) const; 00266 int contains(const MNSubString& y) const; 00267 int contains(const char* t) const; 00268 int contains(const MNRegex& r) const; 00269 00270 // return 1 if target appears anywhere after position pos 00271 // (or before, if pos is negative) in MNString; else 0 00272 00273 int contains(char c, int pos) const; 00274 int contains(const MNString& y, int pos) const; 00275 int contains(const MNSubString& y, int pos) const; 00276 int contains(const char* t, int pos) const; 00277 int contains(const MNRegex& r, int pos) const; 00278 00279 // return 1 if target appears at position pos in MNString; else 0 00280 00281 int matches(char c, int pos = 0) const; 00282 int matches(const MNString& y, int pos = 0) const; 00283 int matches(const MNSubString& y, int pos = 0) const; 00284 int matches(const char* t, int pos = 0) const; 00285 int matches(const MNRegex& r, int pos = 0) const; 00286 00287 // return number of occurences of target in MNString 00288 00289 int freq(char c) const; 00290 int freq(const MNString& y) const; 00291 int freq(const MNSubString& y) const; 00292 int freq(const char* t) const; 00293 00294 // MNSubString extraction 00295 00301 MNSubString at(int pos, int len); 00302 MNSubString operator () (int pos, int len); // synonym for at 00303 00304 MNSubString at(const MNString& x, int startpos = 0); 00305 MNSubString at(const MNSubString& x, int startpos = 0); 00306 MNSubString at(const char* t, int startpos = 0); 00307 MNSubString at(char c, int startpos = 0); 00308 MNSubString at(const MNRegex& r, int startpos = 0); 00310 00313 MNSubString before(int pos); 00314 MNSubString before(const MNString& x, int startpos = 0); 00315 MNSubString before(const MNSubString& x, int startpos = 0); 00316 MNSubString before(const char* t, int startpos = 0); 00317 MNSubString before(char c, int startpos = 0); 00318 MNSubString before(const MNRegex& r, int startpos = 0); 00320 00323 MNSubString through(int pos); 00324 MNSubString through(const MNString& x, int startpos = 0); 00325 MNSubString through(const MNSubString& x, int startpos = 0); 00326 MNSubString through(const char* t, int startpos = 0); 00327 MNSubString through(char c, int startpos = 0); 00328 MNSubString through(const MNRegex& r, int startpos = 0); 00330 00333 MNSubString from(int pos); 00334 MNSubString from(const MNString& x, int startpos = 0); 00335 MNSubString from(const MNSubString& x, int startpos = 0); 00336 MNSubString from(const char* t, int startpos = 0); 00337 MNSubString from(char c, int startpos = 0); 00338 MNSubString from(const MNRegex& r, int startpos = 0); 00340 00343 MNSubString after(int pos); 00344 MNSubString after(const MNString& x, int startpos = 0); 00345 MNSubString after(const MNSubString& x, int startpos = 0); 00346 MNSubString after(const char* t, int startpos = 0); 00347 MNSubString after(char c, int startpos = 0); 00348 MNSubString after(const MNRegex& r, int startpos = 0); 00350 00351 // deletion 00352 00353 // delete len chars starting at pos 00354 void del(int pos, int len); 00355 00356 // delete the first occurrence of target after startpos 00357 00358 void del(const MNString& y, int startpos = 0); 00359 void del(const MNSubString& y, int startpos = 0); 00360 void del(const char* t, int startpos = 0); 00361 void del(char c, int startpos = 0); 00362 void del(const MNRegex& r, int startpos = 0); 00363 00364 // global substitution: substitute all occurrences of pat with repl 00365 00366 int gsub(const MNString& pat, const MNString& repl); 00367 int gsub(const MNSubString& pat, const MNString& repl); 00368 int gsub(const char* pat, const MNString& repl); 00369 int gsub(const char* pat, const char* repl); 00370 int gsub(const MNRegex& pat, const MNString& repl); 00371 00372 // friends & utilities 00373 00374 // split string into array res at separators; return number of elements 00375 00376 friend int split(const MNString& x, MNString res[], int maxn, 00377 const MNString& sep); 00378 friend int split(const MNString& x, MNString res[], int maxn, 00379 const MNRegex& sep); 00380 00381 friend MNString common_prefix(const MNString& x, const MNString& y, 00382 int startpos = 0); 00383 friend MNString common_suffix(const MNString& x, const MNString& y, 00384 int startpos = -1); 00385 friend MNString replicate(char c, int n); 00386 friend MNString replicate(const MNString& y, int n); 00387 friend MNString join(MNString src[], int n, const MNString& sep); 00388 00389 // simple builtin transformations 00390 00391 friend inline MNString reverse(const MNString& x); 00392 friend inline MNString upcase(const MNString& x); 00393 friend inline MNString downcase(const MNString& x); 00394 friend inline MNString capitalize(const MNString& x); 00395 00396 // in-place versions of above 00397 00398 void reverse(); 00399 void upcase(); 00400 void downcase(); 00401 void capitalize(); 00402 00403 // element extraction 00404 00405 char& operator [] (int i); 00406 const char& operator [] (int i) const; 00407 char elem(int i) const; 00408 char firstchar() const; 00409 char lastchar() const; 00410 00411 // conversion 00412 00413 operator const char*() const; 00414 const char* chars() const; 00415 00416 00417 // IO 00418 friend inline std::ostream& operator<<(std::ostream& s, const MNString& x); 00419 friend std::ostream& operator<<(std::ostream& s, const MNSubString& x); 00420 friend std::istream& operator>>(std::istream& s, MNString& x); 00421 00422 friend int readline(std::istream& s, MNString& x, 00423 char terminator = '\n', 00424 int discard_terminator = 1); 00425 00426 // status 00427 00428 unsigned int length() const; 00429 int empty() const; 00430 00431 // preallocate some space for MNString 00432 void alloc(int newsize); 00433 00434 // report current allocation (not length!) 00435 00436 int allocation() const; 00437 00438 00439 void error(const char* msg) const; 00440 00441 int OK() const; 00442 }; 00443 00446 typedef MNString StrTmp; // for backward compatibility 00447 00448 // other externs 00449 00450 int compare(const MNString& x, const MNString& y); 00451 int compare(const MNString& x, const MNSubString& y); 00452 int compare(const MNString& x, const char* y); 00453 int compare(const MNSubString& x, const MNString& y); 00454 int compare(const MNSubString& x, const MNSubString& y); 00455 int compare(const MNSubString& x, const char* y); 00456 int fcompare(const MNString& x, const MNString& y); // ignore case 00458 00459 extern MNStrRep _nilMNStrRep; 00460 extern MNString _nilMNString; 00461 00462 // status reports, needed before defining other things 00463 00464 inline unsigned int MNString::length() const { return rep->len; } 00465 inline int MNString::empty() const { return rep->len == 0; } 00466 inline const char* MNString::chars() const { return &(rep->s[0]); } 00467 inline int MNString::allocation() const { return rep->sz; } 00468 00469 inline unsigned int MNSubString::length() const { return len; } 00470 inline int MNSubString::empty() const { return len == 0; } 00471 inline const char* MNSubString::chars() const { return &(S.rep->s[pos]); } 00472 00473 inline MNString::MNString() 00474 : rep(&_nilMNStrRep) {} 00475 inline MNString::MNString(const MNString& x) 00476 : rep(Scopy(0, x.rep)) {} 00477 inline MNString::MNString(const char* t) 00478 : rep(Salloc(0, t, -1, -1)) {} 00479 inline MNString::MNString(const string t) 00480 : rep(Salloc(0, t.c_str(), -1, -1)) {} 00481 inline MNString::MNString(const char* t, int tlen) 00482 : rep(Salloc(0, t, tlen, tlen)) {} 00483 inline MNString::MNString(const MNSubString& y) 00484 : rep(Salloc(0, y.chars(), y.length(), y.length())) {} 00485 inline MNString::MNString(char c) 00486 : rep(Salloc(0, &c, 1, 1)) {} 00487 00488 inline MNString::~MNString() { if (rep != &_nilMNStrRep) delete rep; } 00489 00490 inline MNSubString::MNSubString(const MNSubString& x) 00491 :S(x.S), pos(x.pos), len(x.len) {} 00492 inline MNSubString::MNSubString(MNString& x, int first, int l) 00493 :S(x), pos(first), len(l) {} 00494 00495 inline MNSubString::~MNSubString() {} 00496 00497 inline MNString& MNString::operator = (const MNString& y) 00498 { 00499 rep = Scopy(rep, y.rep); 00500 return *this; 00501 } 00502 00503 inline MNString& MNString::operator=(const char* t) 00504 { 00505 rep = Salloc(rep, t, -1, -1); 00506 return *this; 00507 } 00508 00509 inline MNString& MNString::operator=(const string t) 00510 { 00511 rep = Salloc(rep, t.c_str(), -1, -1); 00512 return *this; 00513 } 00514 00515 inline MNString& MNString::operator=(const MNSubString& y) 00516 { 00517 rep = Salloc(rep, y.chars(), y.length(), y.length()); 00518 return *this; 00519 } 00520 00521 inline MNString& MNString::operator=(char c) 00522 { 00523 rep = Salloc(rep, &c, 1, 1); 00524 return *this; 00525 } 00526 00527 inline MNSubString& MNSubString::operator = (const char* ys) 00528 { 00529 assign(0, ys); 00530 return *this; 00531 } 00532 00533 inline MNSubString& MNSubString::operator = (char ch) 00534 { 00535 assign(0, &ch, 1); 00536 return *this; 00537 } 00538 00539 inline MNSubString& MNSubString::operator = (const MNString& y) 00540 { 00541 assign(y.rep, y.chars(), y.length()); 00542 return *this; 00543 } 00544 00545 inline MNSubString& MNSubString::operator = (const MNSubString& y) 00546 { 00547 assign(y.S.rep, y.chars(), y.length()); 00548 return *this; 00549 } 00550 00553 // Zillions of cats... 00554 00556 inline void cat(const MNString& x, const MNString& y, MNString& r) 00557 { 00558 r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length()); 00559 } 00560 00562 inline void cat(const MNString& x, const MNSubString& y, MNString& r) 00563 { 00564 r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length()); 00565 } 00566 00568 inline void cat(const MNString& x, const char* y, MNString& r) 00569 { 00570 r.rep = Scat(r.rep, x.chars(), x.length(), y, -1); 00571 } 00572 00574 inline void cat(const MNString& x, char y, MNString& r) 00575 { 00576 r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1); 00577 } 00578 00580 inline void cat(const MNSubString& x, const MNString& y, MNString& r) 00581 { 00582 r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length()); 00583 } 00584 00586 inline void cat(const MNSubString& x, const MNSubString& y, MNString& r) 00587 { 00588 r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length()); 00589 } 00590 00592 inline void cat(const MNSubString& x, const char* y, MNString& r) 00593 { 00594 r.rep = Scat(r.rep, x.chars(), x.length(), y, -1); 00595 } 00596 00598 inline void cat(const MNSubString& x, char y, MNString& r) 00599 { 00600 r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1); 00601 } 00602 00604 inline void cat(const char* x, const MNString& y, MNString& r) 00605 { 00606 r.rep = Scat(r.rep, x, -1, y.chars(), y.length()); 00607 } 00608 00610 inline void cat(const char* x, const MNSubString& y, MNString& r) 00611 { 00612 r.rep = Scat(r.rep, x, -1, y.chars(), y.length()); 00613 } 00614 00616 inline void cat(const char* x, const char* y, MNString& r) 00617 { 00618 r.rep = Scat(r.rep, x, -1, y, -1); 00619 } 00620 00622 inline void cat(const char* x, char y, MNString& r) 00623 { 00624 r.rep = Scat(r.rep, x, -1, &y, 1); 00625 } 00626 00628 inline void cat(const MNString& a, const MNString& x, const MNString& y, MNString& r) 00629 { 00630 r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length()); 00631 } 00632 00634 inline void cat(const MNString& a, const MNString& x, const MNSubString& y, MNString& r) 00635 { 00636 r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length()); 00637 } 00638 00640 inline void cat(const MNString& a, const MNString& x, const char* y, MNString& r) 00641 { 00642 r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1); 00643 } 00644 00646 inline void cat(const MNString& a, const MNString& x, char y, MNString& r) 00647 { 00648 r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1); 00649 } 00650 00652 inline void cat(const MNString& a, const MNSubString& x, const MNString& y, MNString& r) 00653 { 00654 r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length()); 00655 } 00656 00658 inline void cat(const MNString& a, const MNSubString& x, const MNSubString& y, MNString& r) 00659 { 00660 r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length()); 00661 } 00662 00664 inline void cat(const MNString& a, const MNSubString& x, const char* y, MNString& r) 00665 { 00666 r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1); 00667 } 00668 00670 inline void cat(const MNString& a, const MNSubString& x, char y, MNString& r) 00671 { 00672 r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1); 00673 } 00674 00676 inline void cat(const MNString& a, const char* x, const MNString& y, MNString& r) 00677 { 00678 r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length()); 00679 } 00680 00682 inline void cat(const MNString& a, const char* x, const MNSubString& y, MNString& r) 00683 { 00684 r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length()); 00685 } 00686 00688 inline void cat(const MNString& a, const char* x, const char* y, MNString& r) 00689 { 00690 r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y, -1); 00691 } 00692 00694 inline void cat(const MNString& a, const char* x, char y, MNString& r) 00695 { 00696 r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, &y, 1); 00697 } 00698 00700 inline void cat(const char* a, const MNString& x, const MNString& y, MNString& r) 00701 { 00702 r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length()); 00703 } 00704 00706 inline void cat(const char* a, const MNString& x, const MNSubString& y, MNString& r) 00707 { 00708 r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length()); 00709 } 00710 00712 inline void cat(const char* a, const MNString& x, const char* y, MNString& r) 00713 { 00714 r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1); 00715 } 00716 00718 inline void cat(const char* a, const MNString& x, char y, MNString& r) 00719 { 00720 r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1); 00721 } 00722 00724 inline void cat(const char* a, const MNSubString& x, const MNString& y, MNString& r) 00725 { 00726 r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length()); 00727 } 00728 00730 inline void cat(const char* a, const MNSubString& x, const MNSubString& y, MNString& r) 00731 { 00732 r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length()); 00733 } 00734 00736 inline void cat(const char* a, const MNSubString& x, const char* y, MNString& r) 00737 { 00738 r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1); 00739 } 00740 00742 inline void cat(const char* a, const MNSubString& x, char y, MNString& r) 00743 { 00744 r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1); 00745 } 00746 00748 inline void cat(const char* a, const char* x, const MNString& y, MNString& r) 00749 { 00750 r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length()); 00751 } 00752 00754 inline void cat(const char* a, const char* x, const MNSubString& y, MNString& r) 00755 { 00756 r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length()); 00757 } 00758 00760 inline void cat(const char* a, const char* x, const char* y, MNString& r) 00761 { 00762 r.rep = Scat(r.rep, a, -1, x, -1, y, -1); 00763 } 00764 00766 inline void cat(const char* a, const char* x, char y, MNString& r) 00767 { 00768 r.rep = Scat(r.rep, a, -1, x, -1, &y, 1); 00769 } 00771 00772 inline MNString& MNString::operator +=(const MNString& y) 00773 { 00774 cat(*this, y, *this); 00775 return *this; 00776 } 00777 00778 inline MNString& MNString::operator +=(const MNSubString& y) 00779 { 00780 cat(*this, y, *this); 00781 return *this; 00782 } 00783 00784 inline MNString& MNString::operator += (const char* y) 00785 { 00786 cat(*this, y, *this); 00787 return *this; 00788 } 00789 00790 inline MNString& MNString:: operator +=(char y) 00791 { 00792 cat(*this, y, *this); 00793 return *this; 00794 } 00795 00798 // constructive concatenation 00799 00800 #if defined(__GNUG__) && !defined(_G_NO_NRV) 00801 00802 inline MNString operator + (const MNString& x, const MNString& y) return r; 00803 { 00804 cat(x, y, r); 00805 } 00806 00807 inline MNString operator + (const MNString& x, const MNSubString& y) return r; 00808 { 00809 cat(x, y, r); 00810 } 00811 00812 inline MNString operator + (const MNString& x, const char* y) return r; 00813 { 00814 cat(x, y, r); 00815 } 00816 00817 inline MNString operator + (const MNString& x, char y) return r; 00818 { 00819 cat(x, y, r); 00820 } 00821 00822 inline MNString operator + (const MNSubString& x, const MNString& y) return r; 00823 { 00824 cat(x, y, r); 00825 } 00826 00827 inline MNString operator + (const MNSubString& x, const MNSubString& y) return r; 00828 { 00829 cat(x, y, r); 00830 } 00831 00832 inline MNString operator + (const MNSubString& x, const char* y) return r; 00833 { 00834 cat(x, y, r); 00835 } 00836 00837 inline MNString operator + (const MNSubString& x, char y) return r; 00838 { 00839 cat(x, y, r); 00840 } 00841 00842 inline MNString operator + (const char* x, const MNString& y) return r; 00843 { 00844 cat(x, y, r); 00845 } 00846 00847 inline MNString operator + (const char* x, const MNSubString& y) return r; 00848 { 00849 cat(x, y, r); 00850 } 00851 00852 inline MNString reverse(const MNString& x) return r; 00853 { 00854 r.rep = Sreverse(x.rep, r.rep); 00855 } 00856 00857 inline MNString upcase(const MNString& x) return r; 00858 { 00859 r.rep = Supcase(x.rep, r.rep); 00860 } 00861 00862 inline MNString downcase(const MNString& x) return r; 00863 { 00864 r.rep = Sdowncase(x.rep, r.rep); 00865 } 00866 00867 inline MNString capitalize(const MNString& x) return r; 00868 { 00869 r.rep = Scapitalize(x.rep, r.rep); 00870 } 00871 00872 #else /* NO_NRV */ 00873 00874 inline MNString operator + (const MNString& x, const MNString& y) 00875 { 00876 MNString r; cat(x, y, r); return r; 00877 } 00878 00879 inline MNString operator + (const MNString& x, const MNSubString& y) 00880 { 00881 MNString r; cat(x, y, r); return r; 00882 } 00883 00884 inline MNString operator + (const MNString& x, const char* y) 00885 { 00886 MNString r; cat(x, y, r); return r; 00887 } 00888 00889 inline MNString operator + (const MNString& x, char y) 00890 { 00891 MNString r; cat(x, y, r); return r; 00892 } 00893 00894 inline MNString operator + (const MNSubString& x, const MNString& y) 00895 { 00896 MNString r; cat(x, y, r); return r; 00897 } 00898 00899 inline MNString operator + (const MNSubString& x, const MNSubString& y) 00900 { 00901 MNString r; cat(x, y, r); return r; 00902 } 00903 00904 inline MNString operator + (const MNSubString& x, const char* y) 00905 { 00906 MNString r; cat(x, y, r); return r; 00907 } 00908 00909 inline MNString operator + (const MNSubString& x, char y) 00910 { 00911 MNString r; cat(x, y, r); return r; 00912 } 00913 00914 inline MNString operator + (const char* x, const MNString& y) 00915 { 00916 MNString r; cat(x, y, r); return r; 00917 } 00918 00919 inline MNString operator + (const char* x, const MNSubString& y) 00920 { 00921 MNString r; cat(x, y, r); return r; 00922 } 00923 00924 inline MNString reverse(const MNString& x) 00925 { 00926 MNString r; r.rep = Sreverse(x.rep, r.rep); return r; 00927 } 00928 00929 inline MNString upcase(const MNString& x) 00930 { 00931 MNString r; r.rep = Supcase(x.rep, r.rep); return r; 00932 } 00933 00934 inline MNString downcase(const MNString& x) 00935 { 00936 MNString r; r.rep = Sdowncase(x.rep, r.rep); return r; 00937 } 00938 00939 inline MNString capitalize(const MNString& x) 00940 { 00941 MNString r; r.rep = Scapitalize(x.rep, r.rep); return r; 00942 } 00943 00944 #endif 00945 00946 00947 // prepend 00948 00949 inline void MNString::prepend(const MNString& y) 00950 { 00951 rep = Sprepend(rep, y.chars(), y.length()); 00952 } 00953 00954 inline void MNString::prepend(const char* y) 00955 { 00956 rep = Sprepend(rep, y, -1); 00957 } 00958 00959 inline void MNString::prepend(char y) 00960 { 00961 rep = Sprepend(rep, &y, 1); 00962 } 00963 00964 inline void MNString::prepend(const MNSubString& y) 00965 { 00966 rep = Sprepend(rep, y.chars(), y.length()); 00967 } 00968 00969 // misc transformations 00970 00971 00972 inline void MNString::reverse() 00973 { 00974 rep = Sreverse(rep, rep); 00975 } 00976 00977 00978 inline void MNString::upcase() 00979 { 00980 rep = Supcase(rep, rep); 00981 } 00982 00983 00984 inline void MNString::downcase() 00985 { 00986 rep = Sdowncase(rep, rep); 00987 } 00988 00989 00990 inline void MNString::capitalize() 00991 { 00992 rep = Scapitalize(rep, rep); 00993 } 00994 00995 // element extraction 00996 00997 inline char& MNString::operator [] (int i) 00998 { 00999 if (((unsigned)i) >= length()) error("invalid index"); 01000 return rep->s[i]; 01001 } 01002 01003 inline const char& MNString::operator [] (int i) const 01004 { 01005 if (((unsigned)i) >= length()) error("invalid index"); 01006 return rep->s[i]; 01007 } 01008 01009 inline char MNString::elem (int i) const 01010 { 01011 if (((unsigned)i) >= length()) error("invalid index"); 01012 return rep->s[i]; 01013 } 01014 01015 inline char MNString::firstchar() const 01016 { 01017 return elem(0); 01018 } 01019 01020 inline char MNString::lastchar() const 01021 { 01022 return elem(length() - 1); 01023 } 01024 01025 // searching 01026 01027 inline int MNString::index(char c, int startpos) const 01028 { 01029 return search(startpos, length(), c); 01030 } 01031 01032 inline int MNString::index(const char* t, int startpos) const 01033 { 01034 return search(startpos, length(), t); 01035 } 01036 01037 inline int MNString::index(const MNString& y, int startpos) const 01038 { 01039 return search(startpos, length(), y.chars(), y.length()); 01040 } 01041 01042 inline int MNString::index(const MNSubString& y, int startpos) const 01043 { 01044 return search(startpos, length(), y.chars(), y.length()); 01045 } 01046 01047 inline int MNString::index(const MNRegex& r, int startpos) const 01048 { 01049 int unused; return r.search(chars(), length(), unused, startpos); 01050 } 01051 01052 inline int MNString::contains(char c) const 01053 { 01054 return search(0, length(), c) >= 0; 01055 } 01056 01057 inline int MNString::contains(const char* t) const 01058 { 01059 return search(0, length(), t) >= 0; 01060 } 01061 01062 inline int MNString::contains(const MNString& y) const 01063 { 01064 return search(0, length(), y.chars(), y.length()) >= 0; 01065 } 01066 01067 inline int MNString::contains(const MNSubString& y) const 01068 { 01069 return search(0, length(), y.chars(), y.length()) >= 0; 01070 } 01071 01072 inline int MNString::contains(char c, int p) const 01073 { 01074 return match(p, length(), 0, &c, 1) >= 0; 01075 } 01076 01077 inline int MNString::contains(const char* t, int p) const 01078 { 01079 return match(p, length(), 0, t) >= 0; 01080 } 01081 01082 inline int MNString::contains(const MNString& y, int p) const 01083 { 01084 return match(p, length(), 0, y.chars(), y.length()) >= 0; 01085 } 01086 01087 inline int MNString::contains(const MNSubString& y, int p) const 01088 { 01089 return match(p, length(), 0, y.chars(), y.length()) >= 0; 01090 } 01091 01092 inline int MNString::contains(const MNRegex& r) const 01093 { 01094 int unused; return r.search(chars(), length(), unused, 0) >= 0; 01095 } 01096 01097 inline int MNString::contains(const MNRegex& r, int p) const 01098 { 01099 return r.match(chars(), length(), p) >= 0; 01100 } 01101 01102 01103 inline int MNString::matches(const MNSubString& y, int p) const 01104 { 01105 return match(p, length(), 1, y.chars(), y.length()) >= 0; 01106 } 01107 01108 inline int MNString::matches(const MNString& y, int p) const 01109 { 01110 return match(p, length(), 1, y.chars(), y.length()) >= 0; 01111 } 01112 01113 inline int MNString::matches(const char* t, int p) const 01114 { 01115 return match(p, length(), 1, t) >= 0; 01116 } 01117 01118 inline int MNString::matches(char c, int p) const 01119 { 01120 return match(p, length(), 1, &c, 1) >= 0; 01121 } 01122 01123 inline int MNString::matches(const MNRegex& r, int p) const 01124 { 01125 int l = (p < 0)? -p : length() - p; 01126 return r.match(chars(), length(), p) == l; 01127 } 01128 01129 01130 inline int MNSubString::contains(const char* t) const 01131 { 01132 return S.search(pos, pos+len, t) >= 0; 01133 } 01134 01135 inline int MNSubString::contains(const MNString& y) const 01136 { 01137 return S.search(pos, pos+len, y.chars(), y.length()) >= 0; 01138 } 01139 01140 inline int MNSubString::contains(const MNSubString& y) const 01141 { 01142 return S.search(pos, pos+len, y.chars(), y.length()) >= 0; 01143 } 01144 01145 inline int MNSubString::contains(char c) const 01146 { 01147 return S.search(pos, pos+len, c) >= 0; 01148 } 01149 01150 inline int MNSubString::contains(const MNRegex& r) const 01151 { 01152 int unused; return r.search(chars(), len, unused, 0) >= 0; 01153 } 01154 01155 inline int MNSubString::matches(const MNRegex& r) const 01156 { 01157 return r.match(chars(), len, 0) == len; 01158 } 01159 01160 01161 inline int MNString::gsub(const MNString& pat, const MNString& r) 01162 { 01163 return _gsub(pat.chars(), pat.length(), r.chars(), r.length()); 01164 } 01165 01166 inline int MNString::gsub(const MNSubString& pat, const MNString& r) 01167 { 01168 return _gsub(pat.chars(), pat.length(), r.chars(), r.length()); 01169 } 01170 01171 inline int MNString::gsub(const MNRegex& pat, const MNString& r) 01172 { 01173 return _gsub(pat, r.chars(), r.length()); 01174 } 01175 01176 inline int MNString::gsub(const char* pat, const MNString& r) 01177 { 01178 return _gsub(pat, -1, r.chars(), r.length()); 01179 } 01180 01181 inline int MNString::gsub(const char* pat, const char* r) 01182 { 01183 return _gsub(pat, -1, r, -1); 01184 } 01185 01186 01189 inline std::ostream& operator<<(std::ostream& s, const MNString& x) 01190 { 01191 s << x.chars(); return s; 01192 } 01193 01194 // a zillion comparison operators 01195 01196 inline int operator==(const MNString& x, const MNString& y) 01197 { 01198 return compare(x, y) == 0; 01199 } 01200 01201 inline int operator!=(const MNString& x, const MNString& y) 01202 { 01203 return compare(x, y) != 0; 01204 } 01205 01206 inline int operator>(const MNString& x, const MNString& y) 01207 { 01208 return compare(x, y) > 0; 01209 } 01210 01211 inline int operator>=(const MNString& x, const MNString& y) 01212 { 01213 return compare(x, y) >= 0; 01214 } 01215 01216 inline int operator<(const MNString& x, const MNString& y) 01217 { 01218 return compare(x, y) < 0; 01219 } 01220 01221 inline int operator<=(const MNString& x, const MNString& y) 01222 { 01223 return compare(x, y) <= 0; 01224 } 01225 01226 inline int operator==(const MNString& x, const MNSubString& y) 01227 { 01228 return compare(x, y) == 0; 01229 } 01230 01231 inline int operator!=(const MNString& x, const MNSubString& y) 01232 { 01233 return compare(x, y) != 0; 01234 } 01235 01236 inline int operator>(const MNString& x, const MNSubString& y) 01237 { 01238 return compare(x, y) > 0; 01239 } 01240 01241 inline int operator>=(const MNString& x, const MNSubString& y) 01242 { 01243 return compare(x, y) >= 0; 01244 } 01245 01246 inline int operator<(const MNString& x, const MNSubString& y) 01247 { 01248 return compare(x, y) < 0; 01249 } 01250 01251 inline int operator<=(const MNString& x, const MNSubString& y) 01252 { 01253 return compare(x, y) <= 0; 01254 } 01255 01256 inline int operator==(const MNString& x, const char* t) 01257 { 01258 return compare(x, t) == 0; 01259 } 01260 01261 inline int operator!=(const MNString& x, const char* t) 01262 { 01263 return compare(x, t) != 0; 01264 } 01265 01266 inline int operator>(const MNString& x, const char* t) 01267 { 01268 return compare(x, t) > 0; 01269 } 01270 01271 inline int operator>=(const MNString& x, const char* t) 01272 { 01273 return compare(x, t) >= 0; 01274 } 01275 01276 inline int operator<(const MNString& x, const char* t) 01277 { 01278 return compare(x, t) < 0; 01279 } 01280 01281 inline int operator<=(const MNString& x, const char* t) 01282 { 01283 return compare(x, t) <= 0; 01284 } 01285 01286 inline int operator==(const MNSubString& x, const MNString& y) 01287 { 01288 return compare(y, x) == 0; 01289 } 01290 01291 inline int operator!=(const MNSubString& x, const MNString& y) 01292 { 01293 return compare(y, x) != 0; 01294 } 01295 01296 inline int operator>(const MNSubString& x, const MNString& y) 01297 { 01298 return compare(y, x) < 0; 01299 } 01300 01301 inline int operator>=(const MNSubString& x, const MNString& y) 01302 { 01303 return compare(y, x) <= 0; 01304 } 01305 01306 inline int operator<(const MNSubString& x, const MNString& y) 01307 { 01308 return compare(y, x) > 0; 01309 } 01310 01311 inline int operator<=(const MNSubString& x, const MNString& y) 01312 { 01313 return compare(y, x) >= 0; 01314 } 01315 01316 inline int operator==(const MNSubString& x, const MNSubString& y) 01317 { 01318 return compare(x, y) == 0; 01319 } 01320 01321 inline int operator!=(const MNSubString& x, const MNSubString& y) 01322 { 01323 return compare(x, y) != 0; 01324 } 01325 01326 inline int operator>(const MNSubString& x, const MNSubString& y) 01327 { 01328 return compare(x, y) > 0; 01329 } 01330 01331 inline int operator>=(const MNSubString& x, const MNSubString& y) 01332 { 01333 return compare(x, y) >= 0; 01334 } 01335 01336 inline int operator<(const MNSubString& x, const MNSubString& y) 01337 { 01338 return compare(x, y) < 0; 01339 } 01340 01341 inline int operator<=(const MNSubString& x, const MNSubString& y) 01342 { 01343 return compare(x, y) <= 0; 01344 } 01345 01346 inline int operator==(const MNSubString& x, const char* t) 01347 { 01348 return compare(x, t) == 0; 01349 } 01350 01351 inline int operator!=(const MNSubString& x, const char* t) 01352 { 01353 return compare(x, t) != 0; 01354 } 01355 01356 inline int operator>(const MNSubString& x, const char* t) 01357 { 01358 return compare(x, t) > 0; 01359 } 01360 01361 inline int operator>=(const MNSubString& x, const char* t) 01362 { 01363 return compare(x, t) >= 0; 01364 } 01365 01366 inline int operator<(const MNSubString& x, const char* t) 01367 { 01368 return compare(x, t) < 0; 01369 } 01370 01371 inline int operator<=(const MNSubString& x, const char* t) 01372 { 01373 return compare(x, t) <= 0; 01374 } 01376 01377 // a helper needed by at, before, etc. 01378 01379 inline MNSubString MNString::_substr(int first, int l) 01380 { 01381 if (first < 0 || (unsigned)(first + l) > length() ) 01382 return MNSubString(_nilMNString, 0, 0) ; 01383 else 01384 return MNSubString(*this, first, l); 01385 } 01386 01387 #endif 01388

Generated on Sun Mar 6 13:35:49 2005 for Komssys by doxygen 1.3.8