home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 mARCH / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / strclass.h < prev    next >
Text File  |  1998-11-26  |  61KB  |  2,176 lines

  1. // $Id: strclass.h,v 1.31 1998/11/26 09:31:22 zeller Exp $
  2. // A string class (based on `String' from GNU libg++-2.3)
  3.  
  4. // This may look like C code, but it is really -*- C++ -*-
  5. /* 
  6. Copyright (C) 1988 Free Software Foundation
  7.     written by Doug Lea (dl@rocky.oswego.edu)
  8.  
  9. This file is part of the GNU C++ Library.  This library is free
  10. software; you can redistribute it and/or modify it under the terms of
  11. the GNU Library General Public License as published by the Free
  12. Software Foundation; either version 2 of the License, or (at your
  13. option) any later version.  This library is distributed in the hope
  14. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  15. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  16. PURPOSE.  See the GNU Library General Public License for more details.
  17. You should have received a copy of the GNU Library General Public
  18. License along with this library; if not, write to the Free Software
  19. Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20. */
  21.  
  22. // Differences to GNU String class:
  23. // - class name is `string' instead of `String'
  24. // - string length is `unsigned int' instead of `short'
  25. // - extra constructor string::string(ostrstream&)
  26. // - extra assignment string::operator=(ostrstream&)
  27. // - output to stream issues *all* characters, including '\0'
  28. // - extra functions for `char *' provided (besides `const char *')
  29. // - `cat' with 4 arguments is not supported
  30.  
  31.  
  32. // Here's the libg++ documentation of Doug Lea, adapted for this class:
  33.  
  34. // The string class
  35. // ****************
  36. // 
  37. //    The `string' class is designed to extend GNU C++ to support string
  38. // processing capabilities similar to those in languages like Awk.  The
  39. // class provides facilities that ought to be convenient and efficient
  40. // enough to be useful replacements for `char*' based processing via the C
  41. // string library (i.e., `strcpy, strcmp,' etc.) in many applications.
  42. // Many details about string representations are described in the
  43. // Representation section.
  44. // 
  45. //    A separate `subString' class supports substring extraction and
  46. // modification operations. This is implemented in a way that user
  47. // programs never directly construct or represent subStrings, which are
  48. // only used indirectly via string operations.
  49. // 
  50. //    Another separate class, `regex' is also used indirectly via string
  51. // operations in support of regular expression searching, matching, and the
  52. // like.  The regex class is based entirely on the GNU Emacs regex
  53. // functions.  *See Syntax of Regular Expressions: (emacs.info)regexps,
  54. // for a full explanation of regular expression syntax.  (For
  55. // implementation details, see the internal documentation in files
  56. // `rxclass.h' and `rxclass.C'.)
  57. // 
  58. // Constructors
  59. // ============
  60. // 
  61. //    Strings are initialized and assigned as in the following examples:
  62. // 
  63. // `string x;  string y = 0; string z = "";'
  64. //      Set x, y, and z to the nil string. Note that either 0 or "" may
  65. //      always be used to refer to the nil string.
  66. // 
  67. // `string x = "Hello"; string y("Hello");'
  68. //      Set x and y to a copy of the string "Hello".
  69. // 
  70. // `string x = 'A'; string y('A');'
  71. //      Set x and y to the string value "A"
  72. // 
  73. // `string u = x; string v(x);'
  74. //      Set u and v to the same string as string x
  75. // 
  76. // `string u = x.at(1,4); string v(x.at(1,4));'
  77. //      Set u and v to the length 4 substring of x starting at position 1
  78. //      (counting indexes from 0).
  79. // 
  80. // `string x("abc", 2);'
  81. //      Sets x to "ab", i.e., the first 2 characters of "abc".
  82. // 
  83. // `string x = dec(20);'
  84. //      Sets x to "20". As here, strings may be initialized or assigned
  85. //      the results of any `char*' function.
  86. // 
  87. //    There are no directly accessible forms for declaring subString
  88. // variables.
  89. // 
  90. //    The declaration `regex r("[a-zA-Z_][a-zA-Z0-9_]*");' creates a
  91. // compiled regular expression suitable for use in string operations
  92. // described below. (In this case, one that matches any C++ identifier).
  93. // The first argument may also be a string.  Be careful in distinguishing
  94. // the role of backslashes in quoted GNU C++ char* constants versus those
  95. // in regexes. For example, a regex that matches either one or more tabs
  96. // or all strings beginning with "ba" and ending with any number of
  97. // occurrences of "na" could be declared as `regex r =
  98. // "\\(\t+\\)\\|\\(ba\\(na\\)*\\)"' Note that only one backslash is needed
  99. // to signify the tab, but two are needed for the parenthesization and
  100. // virgule, since the GNU C++ lexical analyzer decodes and strips
  101. // backslashes before they are seen by regex.
  102. //
  103. //    As a convenience, several regexes are predefined and usable in any
  104. // program. Here are their declarations from `rxclass.h'.
  105. // 
  106. //      extern regex rxwhite;      // = "[ \n\t]+"
  107. //      extern regex rxint;        // = "-?[0-9]+"
  108. //      extern regex rxdouble;     // = "-?\\(\\([0-9]+\\.[0-9]*\\)\\|
  109. //                                 //    \\([0-9]+\\)\\|
  110. //                                 //    \\(\\.[0-9]+\\)\\)
  111. //                                 //    \\([eE][---+]?[0-9]+\\)?"
  112. //      extern regex rxalpha;      // = "[A-Za-z]+"
  113. //      extern regex rxlowercase;  // = "[a-z]+"
  114. //      extern regex rxuppercase;  // = "[A-Z]+"
  115. //      extern regex rxalphanum;   // = "[0-9A-Za-z]+"
  116. //      extern regex rxidentifier; // = "[A-Za-z_][A-Za-z0-9_]*"
  117. // 
  118. // Examples
  119. // ========
  120. // 
  121. //    Most `string' class capabilities are best shown via example.  The
  122. // examples below use the following declarations.
  123. // 
  124. //          string x = "Hello";
  125. //          string y = "world";
  126. //          string n = "123";
  127. //          string z;
  128. //          char*  s = ",";
  129. //          string lft, mid, rgt;
  130. //          regex  r = "e[a-z]*o";
  131. //          regex  r2("/[a-z]*/");
  132. //          char   c;
  133. //          int    i, pos, len;
  134. //          double f;
  135. //          string words[10];
  136. //          words[0] = "a";
  137. //          words[1] = "b";
  138. //          words[2] = "c";
  139. // 
  140. // Comparing, Searching and Matching
  141. // =================================
  142. // 
  143. //    The usual lexicographic relational operators (`==, !=, <, <=, >, >=')
  144. // are defined. A functional form `compare(string, string)' is also
  145. // provided, as is `fcompare(string, string)', which compares strings
  146. // without regard for upper vs. lower case.
  147. // 
  148. //    All other matching and searching operations are based on some form
  149. // of the (non-public) `match' and `search' functions.  `match' and
  150. // `search' differ in that `match' attempts to match only at the given
  151. // starting position, while `search' starts at the position, and then
  152. // proceeds left or right looking for a match.  As seen in the following
  153. // examples, the second optional `startpos' argument to functions using
  154. // `match' and `search' specifies the starting position of the search: If
  155. // non-negative, it results in a left-to-right search starting at position
  156. // `startpos', and if negative, a right-to-left search starting at
  157. // position `x.length() + startpos'. In all cases, the index returned is
  158. // that of the beginning of the match, or -1 if there is no match.
  159. // 
  160. //    Three string functions serve as front ends to `search' and `match'.
  161. // `index' performs a search, returning the index, `matches' performs a
  162. // match, returning nonzero (actually, the length of the match) on success,
  163. // and `contains' is a boolean function performing either a search or
  164. // match, depending on whether an index argument is provided:
  165. // 
  166. // `x.index("lo")'
  167. //      returns the zero-based index of the leftmost occurrence of
  168. //      substring "lo" (3, in this case).  The argument may be a string,
  169. //      subString, char, char*, or regex.
  170. // 
  171. // `x.index("l", 2)'
  172. //      returns the index of the first of the leftmost occurrence of "l"
  173. //      found starting the search at position x[2], or 2 in this case.
  174. // 
  175. // `x.index("l", -1)'
  176. //      returns the index of the rightmost occurrence of "l", or 3 here.
  177. // 
  178. // `x.index("l", -3)'
  179. //      returns the index of the rightmost occurrence of "l" found by
  180. //      starting the search at the 3rd to the last position of x,
  181. //      returning 2 in this case.
  182. // 
  183. // `pos = r.search("leo", 3, len, 0)'
  184. //      returns the index of r in the `char*' string of length 3, starting
  185. //      at position 0, also placing the  length of the match in reference
  186. //      parameter len.
  187. // 
  188. // `x.contains("He")'
  189. //      returns nonzero if the string x contains the substring "He". The
  190. //      argument may be a string, subString, char, char*, or regex.
  191. // 
  192. // `x.contains("el", 1)'
  193. //      returns nonzero if x contains the substring "el" at position 1.
  194. //      As in this example, the second argument to `contains', if present,
  195. //      means to match the substring only at that position, and not to
  196. //      search elsewhere in the string.
  197. // 
  198. // `x.contains(rxwhite);'
  199. //      returns nonzero if x contains any whitespace (space, tab, or
  200. //      newline). Recall that `rxwhite' is a global whitespace regex.
  201. // 
  202. // `x.matches("lo", 3)'
  203. //      returns nonzero if x starting at position 3 exactly matches "lo",
  204. //      with no trailing characters (as it does in this example).
  205. // 
  206. // `x.matches(r)'
  207. //      returns nonzero if string x as a whole matches regex r.
  208. // 
  209. // `int f = x.freq("l")'
  210. //      returns the number of distinct, nonoverlapping matches to the
  211. //      argument (2 in this case).
  212. // 
  213. // Substring extraction
  214. // ====================
  215. // 
  216. //    Substrings may be extracted via the `at', `before', `through',
  217. // `from', and `after' functions.  These behave as either lvalues or
  218. // rvalues.
  219. // 
  220. // `z = x.at(2, 3)'
  221. //      sets string z to be equal to the length 3 substring of string x
  222. //      starting at zero-based position 2, setting z to "llo" in this
  223. //      case. A nil string is returned if the arguments don't make sense.
  224. // 
  225. // `x.at(2, 2) = "r"'
  226. //      Sets what was in positions 2 to 3 of x to "r", setting x to "Hero"
  227. //      in this case. As indicated here, substring assignments may be of
  228. //      different lengths.
  229. // 
  230. // `x.at("He") = "je";'
  231. //      x("He") is the substring of x that matches the first occurrence of
  232. //      it's argument. The substitution sets x to "jello". If "He" did not
  233. //      occur, the substring would be nil, and the assignment would have
  234. //      no effect.
  235. // 
  236. // `x.at("l", -1) = "i";'
  237. //      replaces the rightmost occurrence of "l" with "i", setting x to
  238. //      "Helio".
  239. // 
  240. // `z = x.at(r)'
  241. //      sets string z to the first match in x of regex r, or "ello" in this
  242. //      case. A nil string is returned if there is no match.
  243. // 
  244. // `z = x.before("o")'
  245. //      sets z to the part of x to the left of the first occurrence of
  246. //      "o", or "Hell" in this case. The argument may also be a string,
  247. //      subString, or regex.  (If there is no match, z is set to "".)
  248. // 
  249. // `x.before("ll") = "Bri";'
  250. //      sets the part of x to the left of "ll" to "Bri", setting x to
  251. //      "Brillo".
  252. // 
  253. // `z = x.before(2)'
  254. //      sets z to the part of x to the left of x[2], or "He" in this case.
  255. // 
  256. // `z = x.after("Hel")'
  257. //      sets z to the part of x to the right of "Hel", or "lo" in this
  258. //      case.
  259. // 
  260. // `z = x.through("el")'
  261. //      sets z to the part of x up and including "el", or "Hel" in this
  262. //      case.
  263. // 
  264. // `z = x.from("el")'
  265. //      sets z to the part of x from "el" to the end, or "ello" in this
  266. //      case.
  267. // 
  268. // `x.after("Hel") = "p";'
  269. //      sets x to "Help";
  270. // 
  271. // `z = x.after(3)'
  272. //      sets z to the part of x to the right of x[3] or "o" in this case.
  273. // 
  274. // `z = "  ab c"; z = z.after(rxwhite)'
  275. //      sets z to the part of its old string to the right of the first
  276. //      group of whitespace, setting z to "ab c"; Use gsub(below) to strip
  277. //      out multiple occurrences of whitespace or any pattern.
  278. // 
  279. // `x[0] = 'J';'
  280. //      sets the first element of x to 'J'. x[i] returns a reference to
  281. //      the ith element of x, or triggers an error if i is out of range.
  282. // 
  283. // `common_prefix(x, "Help")'
  284. //      returns the string containing the common prefix of the two strings
  285. //      or "Hel" in this case.
  286. // 
  287. // `common_suffix(x, "to")'
  288. //      returns the string containing the common suffix of the two strings
  289. //      or "o" in this case.
  290. // 
  291. // Concatenation
  292. // =============
  293. // 
  294. // `z = x + s + ' ' + y.at("w") + y.after("w") + ".";'
  295. //      sets z to "Hello, world."
  296. // 
  297. // `x += y;'
  298. //      sets x to "Helloworld"
  299. // 
  300. // `cat(x, y, z)'
  301. //      A faster way to say z = x + y.
  302. // 
  303. // `y.prepend(x);'
  304. //      A faster way to say y = x + y.
  305. // 
  306. // `z = replicate(x, 3);'
  307. //      sets z to "HelloHelloHello".
  308. // 
  309. // `z = join(words, 3, "/")'
  310. //      sets z to the concatenation of the first 3 strings in string array
  311. //      words, each separated by "/", setting z to "a/b/c" in this case.
  312. //      The last argument may be "" or 0, indicating no separation.
  313. // 
  314. // Other manipulations
  315. // ===================
  316. // 
  317. // `z = "this string has five words"; i = split(z, words, 10, rxwhite);'
  318. //      sets up to 10 elements of string array words to the parts of z
  319. //      separated by whitespace, and returns the number of parts actually
  320. //      encountered (5 in this case). Here, words[0] = "this", words[1] =
  321. //      "string", etc.  The last argument may be any of the usual.  If
  322. //      there is no match, all of z ends up in words[0]. The words array
  323. //      is *not* dynamically created by split.
  324. // 
  325. // `int nmatches x.gsub("l","ll")'
  326. //      substitutes all original occurrences of "l" with "ll", setting x
  327. //      to "Hellllo". The first argument may be any of the usual,
  328. //      including regex.  If the second argument is "" or 0, all
  329. //      occurrences are deleted. gsub returns the number of matches that
  330. //      were replaced.
  331. // 
  332. // `z = x + y;  z.del("loworl");'
  333. //      deletes the leftmost occurrence of "loworl" in z, setting z to
  334. //      "Held".
  335. // 
  336. // `z = reverse(x)'
  337. //      sets z to the reverse of x, or "olleH".
  338. // 
  339. // `z = upcase(x)'
  340. //      sets z to x, with all letters set to uppercase, setting z to
  341. //      "HELLO"
  342. // 
  343. // `z = downcase(x)'
  344. //      sets z to x, with all letters set to lowercase, setting z to
  345. //      "hello"
  346. // 
  347. // `z = capitalize(x)'
  348. //      sets z to x, with the first letter of each word set to uppercase,
  349. //      and all others to lowercase, setting z to "Hello"
  350. // 
  351. // `x.reverse(), x.upcase(), x.downcase(), x.capitalize()'
  352. //      in-place, self-modifying versions of the above.
  353. // 
  354. // Reading, Writing and Conversion
  355. // ===============================
  356. // 
  357. // `cout << x'
  358. //      writes out x.
  359. // 
  360. // `cout << x.at(2, 3)'
  361. //      writes out the substring "llo".
  362. // 
  363. // `cin >> x'
  364. //      reads a whitespace-bounded string into x.
  365. // 
  366. // `x.length()'
  367. //      returns the length of string x (5, in this case).
  368. // 
  369. // `s = (const char*)x'
  370. // `s = x.chars()'
  371. //      can be used to extract the `char*' char array. This coercion is
  372. //      useful for sending a string as an argument to any function
  373. //      expecting a `const char*' argument (like `atoi', and
  374. //      `File::open'). This operator must be used with care, since the
  375. //      conversion returns a pointer to `string' internals without copying
  376. //      the characters: The resulting `(char *)' is only valid until the
  377. //      next string operation,  and you must not modify it.  (The
  378. //      conversion is defined to return a const value so that GNU C++ will
  379. //      produce warning and/or error messages if changes are attempted.)
  380. //
  381. //
  382. // Special stuff
  383. // =============
  384. // 
  385. // A string S can be put into `consuming' mode by invoking
  386. // 
  387. //     s.consuming(true)
  388. // 
  389. // While in `consuming' mode, the (physical) location of S does not change;
  390. // the only assignment operations allowed are assignments of substrings
  391. // at the end of S, as in
  392. // 
  393. //     s = s.from(...); s = s.after(...)
  394. //
  395. // Furthermore, pointers to S stay constant; it is safe to refer to an
  396. // earlier value of S via a pointer:
  397. //
  398. //     char *s0 = s;
  399. //     s = s.after(...);;
  400. //     // S0 still points to original S here
  401. // 
  402. // This feature is used in DDD to speed up several loops.
  403.  
  404.  
  405. #ifndef _ICE_strclass_h
  406. #define _ICE_strclass_h
  407.  
  408. #ifdef __GNUG__
  409. #pragma interface
  410. #endif
  411.  
  412. #include <iostream.h>
  413. #include <strstream.h>
  414. #include "rxclass.h"
  415. #include "config.h"
  416. #include "bool.h"
  417. #include "assert.h"
  418.  
  419. #ifndef STRING_CHECK_CONSUME
  420. #define STRING_CHECK_CONSUME 0
  421. #endif
  422.  
  423. // Internal string representations
  424. struct strRep
  425. {
  426.     unsigned int len;        // String length
  427.     unsigned int allocated;     // Allocated space
  428.     char *s;            // Start of string; points into
  429.                 // MEM[0]..MEM[ALLOCATED - 1]
  430.     char mem[1];                // Start of memory
  431.                     // (at least 1 char for trailing null)
  432.                 // Allocated & expanded via non-public fcts
  433. };
  434.  
  435. // Primitive ops on strReps -- nearly all string fns go through these.
  436.  
  437. strRep* string_Salloc(strRep*, const char*, int, int);
  438. strRep* string_Scopy(strRep*, strRep*);
  439. strRep* string_Scat(strRep*, const char*, int, const char*, int);
  440. strRep* string_Scat(strRep*, const char*, int,
  441.             const char*,int, const char*,int);
  442. strRep* string_Sprepend(strRep*, const char*, int);
  443. strRep* string_Sreverse(strRep*, strRep*);
  444. strRep* string_Supcase(strRep*, strRep*);
  445. strRep* string_Sdowncase(strRep*, strRep*);
  446. strRep* string_Scapitalize(strRep*, strRep*);
  447.  
  448.  
  449. // These classes need to be defined in the order given
  450.  
  451. class string;
  452. class subString;
  453.  
  454. class subString
  455. {
  456.     friend class string;
  457.  
  458. protected:
  459.  
  460.     string& S;            // The string I'm a subString of
  461.     unsigned int pos;        // Starting position in S's rep
  462.     unsigned int len;        // Length of subString
  463.  
  464.     void assign(strRep*, const char*, int = -1);
  465.     subString(string& x, int p, int l);
  466.     subString(const string& x, int p, int l);
  467.  
  468. public:
  469.     // Note there are no public constructors. subStrings are always
  470.     // created via string operations
  471.     
  472.     // This one should be protected, but KCC keeps complaining about this
  473.     subString(const subString& x);
  474.     ~subString();
  475.  
  476.     subString& operator = (const string& y);
  477.     subString& operator = (const subString& y);
  478.     subString& operator = (const char* t);
  479.     subString& operator = (char* t);
  480.     subString& operator = (char c);
  481.  
  482.     // Return true iff target appears anywhere in subString
  483.     bool contains(char c) const;
  484.     bool contains(const string& y) const;
  485.     bool contains(const subString& y) const;
  486.     bool contains(const char* t) const;
  487.     bool contains(char* t) const;
  488.     bool contains(const regex& r) const;
  489.  
  490.     // Return true iff target matches entire subString
  491.     bool matches(const regex& r) const;
  492.  
  493.     // I/O 
  494.     friend inline ostream& operator<<(ostream& s, const subString& x);
  495.  
  496.     // Status
  497.     unsigned int length() const;
  498.     int empty() const;
  499.     const char* chars() const;
  500.  
  501.     bool OK() const; 
  502. };
  503.  
  504.  
  505. class string
  506. {
  507.     friend class subString;
  508.  
  509. protected:
  510.     strRep* rep;     // Strings are pointers to their representations
  511. #if STRING_CHECK_CONSUME
  512.     bool consume;     // If true, check that we're only consuming
  513. #endif
  514.  
  515.     // Some helper functions
  516.     int search(int, int, const char*, int = -1) const;
  517.     int search(int, int, char) const;
  518.     int match(int, int, int, const char*, int = -1) const;
  519.     int _gsub(const char*, int, const char* ,int);
  520.     int _gsub(const regex&, const char*, int);
  521.     subString _substr(int, int);
  522.     const subString _substr(int, int) const;
  523.  
  524. private:
  525.     // Don't get constructed or assigned from int
  526.     string(int) : rep(0)
  527. #if STRING_CHECK_CONSUME
  528.     , consume(false)
  529. #endif
  530.     { 
  531.     error("init from int");
  532.     }
  533.     string& operator = (int)             { error("int assign"); return *this; }
  534.  
  535. public:
  536.     // Constructors and assignment
  537.     string();
  538.     string(const string& x);
  539.     string(const subString&  x);
  540.     string(const char* t);
  541.     string(const char* t, int len);
  542.     string(char c);
  543.     string(ostrstream& os); // should be const
  544.  
  545.     ~string();
  546.  
  547.     void consuming(bool set);
  548.     bool consuming() const;
  549.  
  550.     string& operator = (const string& y);
  551.     string& operator = (const char* y);
  552.     string& operator = (char* y);
  553.     string& operator = (char c);
  554.     string& operator = (const subString& y);
  555.     string& operator = (ostrstream& os);
  556.  
  557.     // Concatenation
  558.     string& operator += (const string& y); 
  559.     string& operator += (const subString& y);
  560.     string& operator += (const char* t);
  561.     string& operator += (char* t);
  562.     string& operator += (char c);
  563.  
  564.     string& prepend(const string& y); 
  565.     string& prepend(const subString& y);
  566.     string& prepend(const char* t);
  567.     string& prepend(char* t);
  568.     string& prepend(char c);
  569.  
  570.  
  571.     // Procedural versions:
  572.     // Concatenate first 2 args, store result in last arg
  573.     friend inline void cat(const string&, const string&, string&);
  574.     friend inline void cat(const string&, const subString&, string&);
  575.     friend inline void cat(const string&, const char*, string&);
  576.     friend inline void cat(const string&, char*, string&);
  577.     friend inline void cat(const string&, char, string&);
  578.  
  579.     friend inline void cat(const subString&, const string&, string&);
  580.     friend inline void cat(const subString&, const subString&, string&);
  581.     friend inline void cat(const subString&, const char*, string&);
  582.     friend inline void cat(const subString&, char*, string&);
  583.     friend inline void cat(const subString&, char, string&);
  584.  
  585.     friend inline void cat(const char*, const string&, string&);
  586.     friend inline void cat(const char*, const subString&, string&);
  587.     friend inline void cat(const char*, const char*, string&);
  588.     friend inline void cat(const char*, char*, string&);
  589.     friend inline void cat(const char*, char, string&);
  590.  
  591.     friend inline void cat(char*, const string&, string&);
  592.     friend inline void cat(char*, const subString&, string&);
  593.     friend inline void cat(char*, const char*, string&);
  594.     friend inline void cat(char*, char*, string&);
  595.     friend inline void cat(char*, char, string&);
  596.  
  597.     friend inline void cat(char, const string&, string&);
  598.     friend inline void cat(char, const subString&, string&);
  599.     friend inline void cat(char, const char*, string&);
  600.     friend inline void cat(char, char*, string&);
  601.     friend inline void cat(char, char, string&);
  602.  
  603.  
  604.     // Searching & matching
  605.  
  606.     // Return position of target in string or -1 for failure
  607.     int index(char c, int startpos = 0) const;      
  608.     int index(const string& y, int startpos = 0) const;      
  609.     int index(const subString&  y, int startpos = 0) const;      
  610.     int index(const char* t, int startpos = 0) const;  
  611.     int index(char* t, int startpos = 0) const;  
  612.     int index(const regex& r, int startpos = 0) const;       
  613.  
  614.     // Return 1 if target appears anyhere in string; else 0
  615.     bool contains(char c) const;
  616.     bool contains(const string& y) const;
  617.     bool contains(const subString& y) const;
  618.     bool contains(const char* t) const;
  619.     bool contains(char* t) const;
  620.     bool contains(const regex& r) const;
  621.  
  622.     // Return 1 if target appears anywhere after position pos 
  623.     // (or before, if pos is negative) in string; else 0
  624.     bool contains(char c, int pos) const;
  625.     bool contains(const string& y, int pos) const;
  626.     bool contains(const subString& y, int pos) const;
  627.     bool contains(const char* t, int pos) const;
  628.     bool contains(char* t, int pos) const;
  629.     bool contains(const regex& r, int pos) const;
  630.  
  631.     // Return 1 if target appears at position pos in string; else 0
  632.     bool matches(char c, int pos = 0) const;
  633.     bool matches(const string& y, int pos = 0) const;
  634.     bool matches(const subString& y, int pos = 0) const;
  635.     bool matches(const char* t, int pos = 0) const;
  636.     bool matches(char* t, int pos = 0) const;
  637.     bool matches(const regex& r, int pos = 0) const;
  638.  
  639.     // Return number of occurences of target in string
  640.     int freq(char c) const; 
  641.     int freq(const string& y) const;
  642.     int freq(const subString& y) const;
  643.     int freq(const char* t) const;
  644.     int freq(char* t) const;
  645.  
  646.     // subString extraction
  647.  
  648.     // Note that you can't take a subString of a const string, since
  649.     // this leaves open the possiblility of indirectly modifying the
  650.     // string through the subString
  651.     subString at(int pos, int len);
  652.     subString operator() (int pos, int len); // synonym for at
  653.  
  654.     subString at(const string& x, int startpos = 0); 
  655.     subString at(const subString&  x, int startpos = 0); 
  656.     subString at(const char* t, int startpos = 0);
  657.     subString at(char* t, int startpos = 0);
  658.     subString at(char c, int startpos = 0);
  659.     subString at(const regex& r, int startpos = 0); 
  660.  
  661.     subString before(int pos);
  662.     subString before(const string& x, int startpos = 0);
  663.     subString before(const subString&   x, int startpos = 0);
  664.     subString before(const char* t, int startpos = 0);
  665.     subString before(char* t, int startpos = 0);
  666.     subString before(char c, int startpos = 0);
  667.     subString before(const regex& r, int startpos = 0);
  668.  
  669.     subString through(int pos);
  670.     subString through(const string& x, int startpos = 0);
  671.     subString through(const subString& x, int startpos = 0);
  672.     subString through(const char* t, int startpos = 0);
  673.     subString through(char* t, int startpos = 0);
  674.     subString through(char c, int startpos = 0);
  675.     subString through(const regex& r, int startpos = 0);
  676.  
  677.     subString from(int pos);
  678.     subString from(const string& x, int startpos = 0);
  679.     subString from(const subString& x, int startpos = 0);
  680.     subString from(const char* t, int startpos = 0);
  681.     subString from(char* t, int startpos = 0);
  682.     subString from(char c, int startpos = 0);
  683.     subString from(const regex& r, int startpos = 0);
  684.  
  685.     subString after(int pos);
  686.     subString after(const string& x, int startpos = 0);
  687.     subString after(const subString& x, int startpos = 0);
  688.     subString after(const char* t, int startpos = 0);
  689.     subString after(char* t, int startpos = 0);
  690.     subString after(char c, int startpos = 0);
  691.     subString after(const regex& r, int startpos = 0);
  692.  
  693.     // Const versions
  694.     const subString at(int pos, int len) const;
  695.     const subString operator() (int pos, int len) const; // synonym for at
  696.  
  697.     const subString at(const string& x, int startpos = 0) const;
  698.     const subString at(const subString&  x, int startpos = 0) const;
  699.     const subString at(const char* t, int startpos = 0) const;
  700.     const subString at(char* t, int startpos = 0) const;
  701.     const subString at(char c, int startpos = 0) const;
  702.     const subString at(const regex& r, int startpos = 0) const;
  703.  
  704.     const subString before(int pos) const;
  705.     const subString before(const string& x, int startpos = 0) const;
  706.     const subString before(const subString&   x, int startpos = 0) const;
  707.     const subString before(const char* t, int startpos = 0) const;
  708.     const subString before(char* t, int startpos = 0) const;
  709.     const subString before(char c, int startpos = 0) const;
  710.     const subString before(const regex& r, int startpos = 0) const;
  711.  
  712.     const subString through(int pos) const;
  713.     const subString through(const string& x, int startpos = 0) const;
  714.     const subString through(const subString& x, int startpos = 0) const;
  715.     const subString through(const char* t, int startpos = 0) const;
  716.     const subString through(char* t, int startpos = 0) const;
  717.     const subString through(char c, int startpos = 0) const;
  718.     const subString through(const regex& r, int startpos = 0) const;
  719.  
  720.     const subString from(int pos) const;
  721.     const subString from(const string& x, int startpos = 0) const;
  722.     const subString from(const subString& x, int startpos = 0) const;
  723.     const subString from(const char* t, int startpos = 0) const;
  724.     const subString from(char* t, int startpos = 0) const;
  725.     const subString from(char c, int startpos = 0) const;
  726.     const subString from(const regex& r, int startpos = 0) const;
  727.  
  728.     const subString after(int pos) const;
  729.     const subString after(const string& x, int startpos = 0) const;
  730.     const subString after(const subString& x, int startpos = 0) const;
  731.     const subString after(const char* t, int startpos = 0) const;
  732.     const subString after(char* t, int startpos = 0) const;
  733.     const subString after(char c, int startpos = 0) const;
  734.     const subString after(const regex& r, int startpos = 0) const;
  735.  
  736.  
  737.     // Deletion
  738.  
  739.     // Delete len chars starting at pos
  740.     void del(int pos, int len);
  741.  
  742.     // Delete the first occurrence of target after startpos
  743.     void del(const string& y, int startpos = 0);
  744.     void del(const subString& y, int startpos = 0);
  745.     void del(const char* t, int startpos = 0);
  746.     void del(char* t, int startpos = 0);
  747.     void del(char c, int startpos = 0);
  748.     void del(const regex& r, int startpos = 0);
  749.  
  750.     // Global substitution: substitute all occurrences of PAT with REPL
  751.     int gsub(const string& pat, const string& repl);
  752.     int gsub(const subString& pat, const string& repl);
  753.     int gsub(const char* pat, const string& repl);
  754.     int gsub(const char* pat, const char* repl);
  755.     int gsub(const char* pat, char* repl);
  756.     int gsub(char* pat, const string& repl);
  757.     int gsub(char* pat, const char* repl);
  758.     int gsub(char* pat, char* repl);
  759.     int gsub(const regex& pat, const string& repl);
  760.  
  761.     // Friends & utilities
  762.     // Split string into array RES at SEPARATORS; return number of elements
  763.     friend int split(const string& x, string *res, int maxn, 
  764.              const string& sep);
  765.     friend int split(const string& x, string *res, int maxn, 
  766.              const regex& sep);
  767.  
  768.     friend string common_prefix(const string& x, const string& y, 
  769.                 int startpos = 0);
  770.     friend string common_suffix(const string& x, const string& y, 
  771.                 int startpos = -1);
  772.     // friend string replicate(char c, int n);
  773.     friend string replicate(const string& y, int n);
  774.     friend string join(string *src, int n, const string& sep);
  775.  
  776.     // Simple builtin transformations
  777.     friend inline string reverse(const string& x);
  778.     friend inline string upcase(const string& x);
  779.     friend inline string downcase(const string& x);
  780.     friend inline string capitalize(const string& x);
  781.  
  782.     // In-place versions of above
  783.     void reverse();
  784.     void upcase();
  785.     void downcase();
  786.     void capitalize();
  787.  
  788.     // Element extraction
  789.     // Some C++ compilers cannot properly disambiguate here,
  790.     // so we supply prototypes for all integral types.
  791.  
  792.     char& operator [] (char i);
  793.     char& operator [] (short i);
  794.     char& operator [] (unsigned short i);
  795.     char& operator [] (int i);
  796.     char& operator [] (unsigned int i);
  797.     char& operator [] (long i);
  798.     char& operator [] (unsigned long i);
  799.  
  800.     char operator [] (char i) const;
  801.     char operator [] (unsigned short i) const;
  802.     char operator [] (short i) const;
  803.     char operator [] (int i) const;
  804.     char operator [] (unsigned int i) const;
  805.     char operator [] (long i) const;
  806.     char operator [] (unsigned long i) const;
  807.  
  808.     char elem(int i) const;
  809.     char firstchar() const;
  810.     char lastchar() const;
  811.  
  812.     // Conversion
  813.     operator const char*() const;
  814.     operator char*() const;
  815.     const char* chars() const;
  816.  
  817.  
  818.     // I/O
  819.     friend inline ostream& operator<<(ostream& s, const string& x);
  820.     friend inline ostream& operator<<(ostream& s, const subString& x);
  821.     friend istream& operator>>(istream& s, string& x);
  822.  
  823.     friend int readline(istream& s, string& x, 
  824.             char terminator = '\n',
  825.             int discard_terminator = 1);
  826.  
  827.     // Status
  828.     unsigned int length() const;
  829.     int empty() const;
  830.  
  831.     // Preallocate some space for string
  832.     void alloc(int newsize);
  833.  
  834.     // Report current allocation (not length!)
  835.     int allocation() const;
  836.  
  837.     void error(const char* msg) const;
  838.  
  839.     bool OK() const;
  840. };
  841.  
  842. #if 0
  843. typedef string strTmp; // for backward compatibility
  844. #endif
  845.  
  846. // Other externs
  847.  
  848. int compare(const string& x,    const string& y);
  849. int compare(const string& x,    const subString& y);
  850. int compare(const string& x,    const char* y);
  851. int compare(const subString& x, const string& y);
  852. int compare(const subString& x, const subString& y);
  853. int compare(const subString& x, const char* y);
  854. int compare(const char *x,      const string& y);
  855. int compare(const char *x,      const subString& y);
  856.  
  857. int fcompare(const string& x, const string& y); // ignore case
  858.  
  859. extern strRep  _nilstrRep;
  860. extern string _nilstring;
  861.  
  862. // Status reports, needed before defining other things
  863.  
  864. inline unsigned int string::length() const {  return rep->len; }
  865. inline int          string::empty() const { return rep->len == 0; }
  866. inline const char*  string::chars() const { return rep->s; }
  867. inline int          string::allocation() const { return rep->allocated; }
  868.  
  869. inline unsigned int subString::length() const { return len; }
  870. inline int          subString::empty() const { return len == 0; }
  871. inline const char*  subString::chars() const { return S.rep->s + pos; }
  872.  
  873. // Resources
  874. inline void string::consuming(bool set)
  875. {
  876. #if STRING_CHECK_CONSUME
  877.     consume = set;
  878. #else
  879.     (void) set;
  880. #endif
  881. }
  882.  
  883. inline bool string::consuming() const
  884. {
  885. #if STRING_CHECK_CONSUME
  886.     return consume;
  887. #else
  888.     return false;
  889. #endif
  890. }
  891.  
  892. // Constructors
  893. inline string::string() 
  894.   : rep(&_nilstrRep)
  895. #if STRING_CHECK_CONSUME
  896.     , consume(false) 
  897. #endif
  898.   {}
  899.  
  900. inline string::string(const string& x)
  901.   : rep(string_Scopy(0, x.rep))
  902. #if STRING_CHECK_CONSUME
  903.     , consume(false) 
  904. #endif
  905.   {}
  906.  
  907. inline string::string(const char* t) 
  908.   : rep(string_Salloc(0, t, -1, -1))
  909. #if STRING_CHECK_CONSUME
  910.     , consume(false) 
  911. #endif
  912.   {}
  913.  
  914. inline string::string(const char* t, int tlen)
  915.   : rep(string_Salloc(0, t, tlen, tlen))
  916. #if STRING_CHECK_CONSUME
  917.     , consume(false) 
  918. #endif
  919.   {}
  920.  
  921. inline string::string(const subString& y)
  922.   : rep(string_Salloc(0, y.chars(), y.length(), y.length()))
  923. #if STRING_CHECK_CONSUME
  924.     , consume(false) 
  925. #endif
  926.   {}
  927.  
  928. inline string::string(char c) 
  929.   : rep(string_Salloc(0, &c, 1, 1))
  930. #if STRING_CHECK_CONSUME
  931.     , consume(false) 
  932. #endif
  933.   {}
  934.  
  935.  
  936. // For HAVE_PLACEMENT_NEW, if using placement new, use operator
  937. // delete instead of vector delete.
  938. // 
  939. // According to Robert Wiegand <wiegand@kong.gsfc.nasa.gov>, Purify
  940. // was flagging this and it does result in undefined behavior.
  941. inline void string_DeleteRep(strRep *rep)
  942. {
  943. #if HAVE_PLACEMENT_NEW
  944.     operator delete(rep);
  945. #else
  946.     delete[] (char *) rep;
  947. #endif
  948. }
  949.  
  950. inline string::~string()
  951. {
  952.     if (rep != &_nilstrRep) string_DeleteRep(rep);
  953. }
  954.  
  955. inline subString::subString(const subString& x)
  956.   :S(x.S), pos(x.pos), len(x.len) {}
  957. inline subString::subString(string& x, int first, int l)
  958.   :S(x), pos(first), len(l) {}
  959. inline subString::subString(const string& x, int first, int l)
  960.   :S((string &)x), pos(first), len(l) {}
  961.  
  962. inline subString::~subString() {}
  963.  
  964. // String Assignment
  965.  
  966. inline string& string::operator = (const string& y)
  967. {
  968.     assert(!consuming());
  969.     rep = string_Scopy(rep, y.rep); return *this;
  970. }
  971.  
  972. inline string& string::operator = (const char* t)
  973. {
  974.     if (t >= rep->s && t < rep->s + rep->len)
  975.     {
  976.     // Assignment of self-substring
  977.     int len = t - rep->s;
  978.     rep->len -= len;
  979.     rep->s = (char *)t;
  980.     }
  981.     else if (t >= &(rep->mem[0]) && t < rep->s)
  982.     {
  983.     // Assignment of older base mem
  984.     int len = (rep->s - t);
  985.     rep->len += len;
  986.     rep->s = (char *)t;
  987.     }
  988.     else
  989.     {
  990.     assert(!consuming());
  991.     rep = string_Salloc(rep, t, -1, -1);
  992.     }
  993.     return *this;
  994. }
  995.  
  996. inline string& string::operator = (char *t)
  997. {
  998.     return operator = ((const char *)t);
  999. }
  1000.  
  1001. inline string& string::operator = (const subString&  y)
  1002. {
  1003.     if (y.chars() >= &(rep->mem[0]) && 
  1004.     y.chars() < &(rep->mem[0]) + rep->allocated)
  1005.     {
  1006.     // Assignment of self-substring
  1007.     rep->s   = (char *)y.chars();
  1008.     rep->len = y.length();
  1009.     rep->s[rep->len] = '\0';
  1010.     }
  1011.     else
  1012.     {
  1013.     assert(!consuming());
  1014.     rep = string_Salloc(rep, y.chars(), y.length(), y.length());
  1015.     }
  1016.     return *this;
  1017. }
  1018.  
  1019. inline string& string::operator = (char c)
  1020. {
  1021.     assert(!consuming());
  1022.     rep = string_Salloc(rep, &c, 1, 1); return *this;
  1023. }
  1024.  
  1025. inline string& string::operator = (ostrstream& os)
  1026. {
  1027.     assert(!consuming());
  1028.  
  1029. #if HAVE_FROZEN_OSTRSTREAM
  1030.     // No need to freeze the stream, since the string is copied right away
  1031.     int frozen = os.frozen();
  1032. #endif
  1033.  
  1034.     const char *str = os.str();
  1035. #if OSTRSTREAM_PCOUNT_BROKEN
  1036.     // In the SGI C++ I/O library, accessing os.str() *increases*
  1037.     // os.pcount() by 1.  We could compensate this in a
  1038.     // machine-independent way by fetching pcount() before str(), but
  1039.     // this will cause trouble when os is assigned the next time.
  1040.     rep = string_Salloc(rep, str, os.pcount() - 1, os.pcount() - 1);
  1041. #else
  1042.     rep = string_Salloc(rep, str, os.pcount(), os.pcount());
  1043. #endif
  1044.  
  1045. #if HAVE_FROZEN_OSTRSTREAM
  1046.     os.freeze(frozen);
  1047. #endif
  1048.     return *this;
  1049. }
  1050.  
  1051. inline string::string(ostrstream& os)
  1052.     : rep(&_nilstrRep)
  1053. #if STRING_CHECK_CONSUME
  1054.     , consume(false) 
  1055. #endif
  1056. {
  1057.     operator=(os);
  1058. }
  1059.  
  1060.  
  1061. // Substring assignments
  1062.  
  1063. inline subString& subString::operator = (const char* ys)
  1064. {
  1065.     assign(0, ys); return *this;
  1066. }
  1067.  
  1068. inline subString& subString::operator = (char* ys)
  1069. {
  1070.     assign(0, ys); return *this;
  1071. }
  1072.  
  1073. inline subString& subString::operator = (char ch)
  1074. {
  1075.     assign(0, &ch, 1); return *this;
  1076. }
  1077.  
  1078. inline subString& subString::operator = (const string& y)
  1079. {
  1080.     assign(y.rep, y.chars(), y.length()); return *this;
  1081. }
  1082.  
  1083. inline subString& subString::operator = (const subString& y)
  1084. {
  1085.     assign(y.S.rep, y.chars(), y.length()); return *this;
  1086. }
  1087.  
  1088. // Zillions of cats...
  1089.  
  1090. inline void cat(const string& x, const string& y, string& r)
  1091. {
  1092.     assert(!r.consuming());
  1093.     r.rep = string_Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  1094. }
  1095.  
  1096. inline void cat(const string& x, const subString& y, string& r)
  1097. {
  1098.     assert(!r.consuming());
  1099.     r.rep = string_Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  1100. }
  1101.  
  1102. inline void cat(const string& x, const char* y, string& r)
  1103. {
  1104.     assert(!r.consuming());
  1105.     r.rep = string_Scat(r.rep, x.chars(), x.length(), y, -1);
  1106. }
  1107.  
  1108. inline void cat(const string& x, char* y, string& r)
  1109. {
  1110.     assert(!r.consuming());
  1111.     r.rep = string_Scat(r.rep, x.chars(), x.length(), y, -1);
  1112. }
  1113.  
  1114. inline void cat(const string& x, char y, string& r)
  1115. {
  1116.     assert(!r.consuming());
  1117.     r.rep = string_Scat(r.rep, x.chars(), x.length(), &y, 1);
  1118. }
  1119.  
  1120. inline void cat(const subString& x, const string& y, string& r)
  1121. {
  1122.     assert(!r.consuming());
  1123.     r.rep = string_Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  1124. }
  1125.  
  1126. inline void cat(const subString& x, const subString& y, string& r)
  1127. {
  1128.     assert(!r.consuming());
  1129.     r.rep = string_Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
  1130. }
  1131.  
  1132. inline void cat(const subString& x, const char* y, string& r)
  1133. {
  1134.     assert(!r.consuming());
  1135.     r.rep = string_Scat(r.rep, x.chars(), x.length(), y, -1);
  1136. }
  1137.  
  1138. inline void cat(const subString& x, char* y, string& r)
  1139. {
  1140.     assert(!r.consuming());
  1141.     r.rep = string_Scat(r.rep, x.chars(), x.length(), y, -1);
  1142. }
  1143.  
  1144. inline void cat(const subString& x, char y, string& r)
  1145. {
  1146.     assert(!r.consuming());
  1147.     r.rep = string_Scat(r.rep, x.chars(), x.length(), &y, 1);
  1148. }
  1149.  
  1150. inline void cat(const char* x, const string& y, string& r)
  1151. {
  1152.     assert(!r.consuming());
  1153.     r.rep = string_Scat(r.rep, x, -1, y.chars(), y.length());
  1154. }
  1155.  
  1156. inline void cat(const char* x, const subString& y, string& r)
  1157. {
  1158.     assert(!r.consuming());
  1159.     r.rep = string_Scat(r.rep, x, -1, y.chars(), y.length());
  1160. }
  1161.  
  1162. inline void cat(const char* x, const char* y, string& r)
  1163. {
  1164.     assert(!r.consuming());
  1165.     r.rep = string_Scat(r.rep, x, -1, y, -1);
  1166. }
  1167.  
  1168. inline void cat(const char* x, char* y, string& r)
  1169. {
  1170.     assert(!r.consuming());
  1171.     r.rep = string_Scat(r.rep, x, -1, y, -1);
  1172. }
  1173.  
  1174. inline void cat(const char* x, char y, string& r)
  1175. {
  1176.     assert(!r.consuming());
  1177.     r.rep = string_Scat(r.rep, x, -1, &y, 1);
  1178. }
  1179.  
  1180. inline void cat(char* x, const string& y, string& r)
  1181. {
  1182.     assert(!r.consuming());
  1183.     r.rep = string_Scat(r.rep, x, -1, y.chars(), y.length());
  1184. }
  1185.  
  1186. inline void cat(char* x, const subString& y, string& r)
  1187. {
  1188.     assert(!r.consuming());
  1189.     r.rep = string_Scat(r.rep, x, -1, y.chars(), y.length());
  1190. }
  1191.  
  1192. inline void cat(char* x, const char* y, string& r)
  1193. {
  1194.     assert(!r.consuming());
  1195.     r.rep = string_Scat(r.rep, x, -1, y, -1);
  1196. }
  1197.  
  1198. inline void cat(char* x, char* y, string& r)
  1199. {
  1200.     assert(!r.consuming());
  1201.     r.rep = string_Scat(r.rep, x, -1, y, -1);
  1202. }
  1203.  
  1204. inline void cat(char* x, char y, string& r)
  1205. {
  1206.     assert(!r.consuming());
  1207.     r.rep = string_Scat(r.rep, x, -1, &y, 1);
  1208. }
  1209.  
  1210. inline void cat(char x, const string& y, string& r)
  1211. {
  1212.     assert(!r.consuming());
  1213.     r.rep = string_Scat(r.rep, &x, 1, y.chars(), y.length());
  1214. }
  1215.  
  1216. inline void cat(char x, const subString& y, string& r)
  1217. {
  1218.     assert(!r.consuming());
  1219.     r.rep = string_Scat(r.rep, &x, 1, y.chars(), y.length());
  1220. }
  1221.  
  1222. inline void cat(char x, const char* y, string& r)
  1223. {
  1224.     assert(!r.consuming());
  1225.     r.rep = string_Scat(r.rep, &x, 1, y, -1);
  1226. }
  1227.  
  1228. inline void cat(char x, char* y, string& r)
  1229. {
  1230.     assert(!r.consuming());
  1231.     r.rep = string_Scat(r.rep, &x, 1, y, -1);
  1232. }
  1233.  
  1234. inline void cat(char x, char y, string& r)
  1235. {
  1236.     assert(!r.consuming());
  1237.     r.rep = string_Scat(r.rep, &x, 1, &y, 1);
  1238. }
  1239.  
  1240.  
  1241. // Operator versions
  1242. inline string& string::operator += (const string& y)
  1243. {
  1244.     cat(*this, y, *this); return *this;
  1245. }
  1246.  
  1247. inline string& string::operator += (const subString& y)
  1248. {
  1249.     cat(*this, y, *this); return *this;
  1250. }
  1251.  
  1252. inline string& string::operator += (const char* y)
  1253. {
  1254.     cat(*this, y, *this); return *this;
  1255. }
  1256.  
  1257. inline string& string::operator += (char* y)
  1258. {
  1259.     cat(*this, y, *this); return *this;
  1260. }
  1261.  
  1262. inline string& string:: operator +=(char y)
  1263. {
  1264.     cat(*this, y, *this); return *this;
  1265. }
  1266.  
  1267. // Constructive concatenation
  1268. #if HAVE_NAMED_RETURN_VALUES
  1269.  
  1270. inline string operator + (const string& x, const string& y) return r;
  1271. {
  1272.     cat(x, y, r);
  1273. }
  1274.  
  1275. inline string operator + (const string& x, const subString& y) return r;
  1276. {
  1277.     cat(x, y, r);
  1278. }
  1279.  
  1280. inline string operator + (const string& x, const char* y) return r;
  1281. {
  1282.     cat(x, y, r);
  1283. }
  1284.  
  1285. inline string operator + (const string& x, char* y) return r;
  1286. {
  1287.     cat(x, y, r);
  1288. }
  1289.  
  1290. inline string operator + (const string& x, char y) return r;
  1291. {
  1292.     cat(x, y, r);
  1293. }
  1294.  
  1295. inline string operator + (const subString& x, const string& y) return r;
  1296. {
  1297.     cat(x, y, r);
  1298. }
  1299.  
  1300. inline string operator + (const subString& x, const subString& y) return r;
  1301. {
  1302.     cat(x, y, r);
  1303. }
  1304.  
  1305. inline string operator + (const subString& x, const char* y) return r;
  1306. {
  1307.     cat(x, y, r);
  1308. }
  1309.  
  1310. inline string operator + (const subString& x, char* y) return r;
  1311. {
  1312.     cat(x, y, r);
  1313. }
  1314.  
  1315. inline string operator + (const subString& x, char y) return r;
  1316. {
  1317.     cat(x, y, r);
  1318. }
  1319.  
  1320. inline string operator + (const char* x, const string& y) return r;
  1321. {
  1322.     cat(x, y, r);
  1323. }
  1324.  
  1325. inline string operator + (const char* x, const subString& y) return r;
  1326. {
  1327.     cat(x, y, r);
  1328. }
  1329.  
  1330. inline string operator + (char* x, const string& y) return r;
  1331. {
  1332.     cat(x, y, r);
  1333. }
  1334.  
  1335. inline string operator + (char* x, const subString& y) return r;
  1336. {
  1337.     cat(x, y, r);
  1338. }
  1339.  
  1340. inline string operator + (char x, const string& y) return r;
  1341. {
  1342.     cat(x, y, r);
  1343. }
  1344.  
  1345. inline string operator + (char x, const subString& y) return r;
  1346. {
  1347.     cat(x, y, r);
  1348. }
  1349.  
  1350. inline string reverse(const string& x) return r;
  1351. {
  1352.     r.rep = string_Sreverse(x.rep, r.rep);
  1353. }
  1354.  
  1355. inline string upcase(const string& x) return r;
  1356. {
  1357.     r.rep = string_Supcase(x.rep, r.rep);
  1358. }
  1359.  
  1360. inline string downcase(const string& x) return r;
  1361. {
  1362.     r.rep = string_Sdowncase(x.rep, r.rep);
  1363. }
  1364.  
  1365. inline string capitalize(const string& x) return r;
  1366. {
  1367.     r.rep = string_Scapitalize(x.rep, r.rep);
  1368. }
  1369.  
  1370. #else /* ! defined(NAMED_RETURN_VALUES) */
  1371.  
  1372. inline string operator + (const string& x, const string& y)
  1373. {
  1374.     string r;  cat(x, y, r);  return r;
  1375. }
  1376.  
  1377. inline string operator + (const string& x, const subString& y) 
  1378. {
  1379.     string r; cat(x, y, r); return r;
  1380. }
  1381.  
  1382. inline string operator + (const string& x, const char* y) 
  1383. {
  1384.     string r; cat(x, y, r); return r;
  1385. }
  1386.  
  1387. inline string operator + (const string& x, char* y) 
  1388. {
  1389.     string r; cat(x, y, r); return r;
  1390. }
  1391.  
  1392. inline string operator + (const string& x, char y) 
  1393. {
  1394.     string r; cat(x, y, r); return r;
  1395. }
  1396.  
  1397. inline string operator + (const subString& x, const string& y) 
  1398. {
  1399.     string r; cat(x, y, r); return r;
  1400. }
  1401.  
  1402. inline string operator + (const subString& x, const subString& y) 
  1403. {
  1404.     string r; cat(x, y, r); return r;
  1405. }
  1406.  
  1407. inline string operator + (const subString& x, const char* y) 
  1408. {
  1409.     string r; cat(x, y, r); return r;
  1410. }
  1411.  
  1412. inline string operator + (const subString& x, char* y) 
  1413. {
  1414.     string r; cat(x, y, r); return r;
  1415. }
  1416.  
  1417. inline string operator + (const subString& x, char y) 
  1418. {
  1419.     string r; cat(x, y, r); return r;
  1420. }
  1421.  
  1422. inline string operator + (const char* x, const string& y) 
  1423. {
  1424.     string r; cat(x, y, r); return r;
  1425. }
  1426.  
  1427. inline string operator + (const char* x, const subString& y) 
  1428. {
  1429.     string r; cat(x, y, r); return r;
  1430. }
  1431.  
  1432. inline string operator + (char* x, const string& y) 
  1433. {
  1434.     string r; cat(x, y, r); return r;
  1435. }
  1436.  
  1437. inline string operator + (char* x, const subString& y) 
  1438. {
  1439.     string r; cat(x, y, r); return r;
  1440. }
  1441.  
  1442. inline string operator + (char x, const string& y) 
  1443. {
  1444.     string r; cat(x, y, r); return r;
  1445. }
  1446.  
  1447. inline string operator + (char x, const subString& y) 
  1448. {
  1449.     string r; cat(x, y, r); return r;
  1450. }
  1451.  
  1452. inline string reverse(const string& x) 
  1453. {
  1454.     string r; r.rep = string_Sreverse(x.rep, r.rep); return r;
  1455. }
  1456.  
  1457. inline string upcase(const string& x) 
  1458. {
  1459.     string r; r.rep = string_Supcase(x.rep, r.rep); return r;
  1460. }
  1461.  
  1462. inline string downcase(const string& x) 
  1463. {
  1464.     string r; r.rep = string_Sdowncase(x.rep, r.rep); return r;
  1465. }
  1466.  
  1467. inline string capitalize(const string& x) 
  1468. {
  1469.     string r; r.rep = string_Scapitalize(x.rep, r.rep); return r;
  1470. }
  1471.  
  1472. #endif /* ! defined(NAMED_RETURN_VALUES) */
  1473.  
  1474. // prepend
  1475.  
  1476. inline string& string::prepend(const string& y)
  1477. {
  1478.     assert(!consuming());
  1479.     rep = string_Sprepend(rep, y.chars(), y.length()); return *this;
  1480. }
  1481.  
  1482. inline string& string::prepend(const char* y)
  1483. {
  1484.     assert(!consuming());
  1485.     rep = string_Sprepend(rep, y, -1); return *this;
  1486. }
  1487.  
  1488. inline string& string::prepend(char* y)
  1489. {
  1490.     assert(!consuming());
  1491.     rep = string_Sprepend(rep, y, -1); return *this;
  1492. }
  1493.  
  1494. inline string& string::prepend(char y)
  1495. {
  1496.     assert(!consuming());
  1497.     rep = string_Sprepend(rep, &y, 1); return *this;
  1498. }
  1499.  
  1500. inline string& string::prepend(const subString& y)
  1501. {
  1502.     assert(!consuming());
  1503.     rep = string_Sprepend(rep, y.chars(), y.length());return *this;
  1504. }
  1505.  
  1506.  
  1507. // Misc transformations
  1508.  
  1509. inline void string::reverse()
  1510. {
  1511.     assert(!consuming());
  1512.     rep = string_Sreverse(rep, rep);
  1513. }
  1514.  
  1515. inline void string::upcase()
  1516. {
  1517.     assert(!consuming());
  1518.     rep = string_Supcase(rep, rep);
  1519. }
  1520.  
  1521. inline void string::downcase()
  1522. {
  1523.     assert(!consuming());
  1524.     rep = string_Sdowncase(rep, rep);
  1525. }
  1526.  
  1527. inline void string::capitalize()
  1528. {
  1529.     assert(!consuming());
  1530.     rep = string_Scapitalize(rep, rep);
  1531. }
  1532.  
  1533.  
  1534. // Element extraction
  1535.  
  1536. inline char&  string::operator [] (unsigned int i) 
  1537. {
  1538. #ifndef NDEBUG
  1539.     if (i >= length()) error("invalid index");
  1540. #endif
  1541.     return rep->s[i];
  1542. }
  1543.  
  1544. inline char string::operator [] (unsigned int i) const
  1545. #ifndef NDEBUG
  1546.     if (i >= length()) error("invalid index");
  1547. #endif
  1548.     return rep->s[i];
  1549. }
  1550.  
  1551. inline char& string::operator [] (int i) 
  1552. {
  1553.     return string::operator [] ((unsigned int) i);
  1554. }
  1555.  
  1556. inline char string::operator [] (int i) const
  1557. {
  1558.     return string::operator [] ((unsigned int) i);
  1559. }
  1560.  
  1561. inline char& string::operator [] (char i) 
  1562. {
  1563.     return string::operator [] ((unsigned int) i);
  1564. }
  1565.  
  1566. inline char string::operator [] (char i) const
  1567. {
  1568.     return string::operator [] ((unsigned int) i);
  1569. }
  1570.  
  1571. inline char& string::operator [] (short i) 
  1572. {
  1573.     return string::operator [] ((unsigned int) i);
  1574. }
  1575.  
  1576. inline char string::operator [] (short i) const
  1577. {
  1578.     return string::operator [] ((unsigned int) i);
  1579. }
  1580.  
  1581. inline char& string::operator [] (unsigned short i) 
  1582. {
  1583.     return string::operator [] ((unsigned int) i);
  1584. }
  1585.  
  1586. inline char string::operator [] (unsigned short i) const
  1587. {
  1588.     return string::operator [] ((unsigned int) i);
  1589. }
  1590.  
  1591. inline char& string::operator [] (long i) 
  1592. {
  1593.     return string::operator [] ((unsigned int) i);
  1594. }
  1595.  
  1596. inline char string::operator [] (long i) const
  1597. {
  1598.     return string::operator [] ((unsigned int) i);
  1599. }
  1600.  
  1601. inline char& string::operator [] (unsigned long i) 
  1602. {
  1603.     return string::operator [] ((unsigned int) i);
  1604. }
  1605.  
  1606. inline char string::operator [] (unsigned long i) const
  1607. {
  1608.     return string::operator [] ((unsigned int) i);
  1609. }
  1610.  
  1611. inline char string::elem (int i) const
  1612. #ifndef NDEBUG
  1613.     if (((unsigned)i) >= length()) error("invalid index");
  1614. #endif
  1615.     return rep->s[i];
  1616. }
  1617.  
  1618. inline char string::firstchar() const
  1619.     return elem(0);
  1620. }
  1621.  
  1622. inline char string::lastchar() const
  1623.     return elem(length() - 1);
  1624. }
  1625.  
  1626. // Searching
  1627.  
  1628. inline int string::index(char c, int startpos) const
  1629. {
  1630.     return search(startpos, length(), c);
  1631. }
  1632.  
  1633. inline int string::index(const char* t, int startpos) const
  1634. {   
  1635.     return search(startpos, length(), t);
  1636. }
  1637.  
  1638. inline int string::index(char* t, int startpos) const
  1639. {   
  1640.     return search(startpos, length(), t);
  1641. }
  1642.  
  1643. inline int string::index(const string& y, int startpos) const
  1644. {   
  1645.     return search(startpos, length(), y.chars(), y.length());
  1646. }
  1647.  
  1648. inline int string::index(const subString& y, int startpos) const
  1649. {   
  1650.     return search(startpos, length(), y.chars(), y.length());
  1651. }
  1652.  
  1653. inline int string::index(const regex& r, int startpos) const
  1654. {
  1655.     int unused;  return r.search(chars(), length(), unused, startpos);
  1656. }
  1657.  
  1658. inline bool string::contains(char c) const
  1659. {
  1660.     return search(0, length(), c) >= 0;
  1661. }
  1662.  
  1663. inline bool string::contains(const char* t) const
  1664. {   
  1665.     return search(0, length(), t) >= 0;
  1666. }
  1667.  
  1668. inline bool string::contains(char* t) const
  1669. {   
  1670.     return search(0, length(), t) >= 0;
  1671. }
  1672.  
  1673. inline bool string::contains(const string& y) const
  1674. {   
  1675.     return search(0, length(), y.chars(), y.length()) >= 0;
  1676. }
  1677.  
  1678. inline bool string::contains(const subString& y) const
  1679. {   
  1680.     return search(0, length(), y.chars(), y.length()) >= 0;
  1681. }
  1682.  
  1683. inline bool string::contains(char c, int p) const
  1684. {
  1685.     return match(p, length(), 0, &c, 1) >= 0;
  1686. }
  1687.  
  1688. inline bool string::contains(const char* t, int p) const
  1689. {
  1690.     return match(p, length(), 0, t) >= 0;
  1691. }
  1692.  
  1693. inline bool string::contains(char* t, int p) const
  1694. {
  1695.     return match(p, length(), 0, t) >= 0;
  1696. }
  1697.  
  1698. inline bool string::contains(const string& y, int p) const
  1699. {
  1700.     return match(p, length(), 0, y.chars(), y.length()) >= 0;
  1701. }
  1702.  
  1703. inline bool string::contains(const subString& y, int p) const
  1704. {
  1705.     return match(p, length(), 0, y.chars(), y.length()) >= 0;
  1706. }
  1707.  
  1708. inline bool string::contains(const regex& r) const
  1709. {
  1710.     int unused;  return r.search(chars(), length(), unused, 0) >= 0;
  1711. }
  1712.  
  1713. inline bool string::contains(const regex& r, int p) const
  1714. {
  1715.     return r.match(chars(), length(), p) >= 0;
  1716. }
  1717.  
  1718.  
  1719. inline bool string::matches(const subString& y, int p) const
  1720. {
  1721.     return match(p, length(), 1, y.chars(), y.length()) >= 0;
  1722. }
  1723.  
  1724. inline bool string::matches(const string& y, int p) const
  1725. {
  1726.     return match(p, length(), 1, y.chars(), y.length()) >= 0;
  1727. }
  1728.  
  1729. inline bool string::matches(const char* t, int p) const
  1730. {
  1731.     return match(p, length(), 1, t) >= 0;
  1732. }
  1733.  
  1734. inline bool string::matches(char* t, int p) const
  1735. {
  1736.     return match(p, length(), 1, t) >= 0;
  1737. }
  1738.  
  1739. inline bool string::matches(char c, int p) const
  1740. {
  1741.     return match(p, length(), 1, &c, 1) >= 0;
  1742. }
  1743.  
  1744. inline bool string::matches(const regex& r, int p) const
  1745. {
  1746.     int l = (p < 0)? -p : length() - p;
  1747.     return r.match(chars(), length(), p) == l;
  1748. }
  1749.  
  1750.  
  1751. inline bool subString::contains(const char* t) const
  1752. {   
  1753.     return S.search(pos, pos+len, t) >= 0;
  1754. }
  1755.  
  1756. inline bool subString::contains(char* t) const
  1757. {   
  1758.     return S.search(pos, pos+len, t) >= 0;
  1759. }
  1760.  
  1761. inline bool subString::contains(const string& y) const
  1762. {   
  1763.     return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
  1764. }
  1765.  
  1766. inline bool subString::contains(const subString&  y) const
  1767. {   
  1768.     return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
  1769. }
  1770.  
  1771. inline bool subString::contains(char c) const
  1772. {
  1773.     return S.search(pos, pos+len, 0, c) >= 0;
  1774. }
  1775.  
  1776. inline bool subString::contains(const regex& r) const
  1777. {
  1778.     int unused;  return r.search(chars(), len, unused, 0) >= 0;
  1779. }
  1780.  
  1781. inline bool subString::matches(const regex& r) const
  1782. {
  1783.     return unsigned(r.match(chars(), len, 0)) == len;
  1784. }
  1785.  
  1786.  
  1787. inline int string::gsub(const string& pat, const string& r)
  1788. {
  1789.     return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
  1790. }
  1791.  
  1792. inline int string::gsub(const subString&  pat, const string& r)
  1793. {
  1794.     return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
  1795. }
  1796.  
  1797. inline int string::gsub(const regex& pat, const string& r)
  1798. {
  1799.     return _gsub(pat, r.chars(), r.length());
  1800. }
  1801.  
  1802. inline int string::gsub(const char* pat, const string& r)
  1803. {
  1804.     return _gsub(pat, -1, r.chars(), r.length());
  1805. }
  1806.  
  1807. inline int string::gsub(char* pat, const string& r)
  1808. {
  1809.     return _gsub(pat, -1, r.chars(), r.length());
  1810. }
  1811.  
  1812. inline int string::gsub(const char* pat, const char* r)
  1813. {
  1814.     return _gsub(pat, -1, r, -1);
  1815. }
  1816.  
  1817. inline int string::gsub(const char* pat, char* r)
  1818. {
  1819.     return _gsub(pat, -1, r, -1);
  1820. }
  1821.  
  1822. inline int string::gsub(char* pat, const char* r)
  1823. {
  1824.     return _gsub(pat, -1, r, -1);
  1825. }
  1826.  
  1827. inline int string::gsub(char* pat, char* r)
  1828. {
  1829.     return _gsub(pat, -1, r, -1);
  1830. }
  1831.  
  1832.  
  1833. // `char *' => `const char *' wrappers
  1834.  
  1835. inline subString string::after(char* t, int startpos)
  1836. {
  1837.     return after((const char *)t, startpos);
  1838. }
  1839.  
  1840. inline subString string::at(char* t, int startpos)
  1841. {
  1842.     return at((const char *)t, startpos);
  1843. }
  1844.  
  1845. inline subString string::before(char* t, int startpos)
  1846. {
  1847.     return before((const char *)t, startpos);
  1848. }
  1849.  
  1850. inline void string::del(char* t, int startpos)
  1851. {
  1852.     del((const char *)t, startpos);
  1853. }
  1854.  
  1855. inline int string::freq(char* t) const
  1856. {
  1857.     return freq((const char *)t);
  1858. }
  1859.  
  1860. inline subString string::from(char* t, int startpos)
  1861. {
  1862.     return from((const char *)t, startpos);
  1863. }
  1864.  
  1865. inline subString string::through(char* t, int startpos)
  1866. {
  1867.     return through((const char *)t, startpos);
  1868. }
  1869.  
  1870. inline int compare(const subString& x, char* y)
  1871. {
  1872.     return compare(x, (const char*)y);
  1873. }
  1874.  
  1875. inline int compare(const string& x, char* y)
  1876. {
  1877.     return compare(x, (const char*)y);
  1878. }
  1879.  
  1880. inline int compare(char *x, const subString& y)
  1881. {
  1882.     return compare((const char*)x, y);
  1883. }
  1884.  
  1885. inline int compare(char *x, const string& y)
  1886. {
  1887.     return compare((const char*)x, y);
  1888. }
  1889.  
  1890. inline int compare(const string& x, char y)
  1891. {
  1892.     return x.length() == 1 ? *x.chars() - y : x.length() - 1;
  1893. }
  1894.  
  1895. inline int compare(char x, const string& y)
  1896. {
  1897.     return -compare(y, x);
  1898. }
  1899.  
  1900. inline int compare(const subString& x, char y)
  1901. {
  1902.     return x.length() == 1 ? *x.chars() - y : x.length() - 1;
  1903. }
  1904.  
  1905. inline int compare(char x, const subString& y)
  1906. {
  1907.     return -compare(y, x);
  1908. }
  1909.  
  1910. // Const wrappers
  1911. inline const subString string::at(int pos, int len) const
  1912. {
  1913.     return ((string *)this)->at(pos, len);
  1914. }
  1915.  
  1916. inline const subString string::operator() (int pos, int len) const
  1917. {
  1918.     return ((string *)this)->operator()(pos, len);
  1919. }
  1920.  
  1921. inline const subString string::at(const string& x, int startpos) const
  1922. {
  1923.     return ((string *)this)->at(x, startpos);
  1924. }
  1925.  
  1926. inline const subString string::at(const subString&  x, int startpos) const
  1927. {
  1928.     return ((string *)this)->at(x, startpos);
  1929. }
  1930.  
  1931. inline const subString string::at(const char* t, int startpos) const
  1932. {
  1933.     return ((string *)this)->at(t, startpos);
  1934. }
  1935.  
  1936. inline const subString string::at(char* t, int startpos) const
  1937. {
  1938.     return ((string *)this)->at(t, startpos);
  1939. }
  1940.  
  1941. inline const subString string::at(char c, int startpos) const
  1942. {
  1943.     return ((string *)this)->at(c, startpos);
  1944. }
  1945.  
  1946. inline const subString string::at(const regex& r, int startpos) const
  1947. {
  1948.     return ((string *)this)->at(r, startpos);
  1949. }
  1950.  
  1951.  
  1952. inline const subString string::before(int pos) const
  1953. {
  1954.     return ((string *)this)->before(pos);
  1955. }
  1956.  
  1957. inline const subString string::before(const string& x, int startpos) const
  1958. {
  1959.     return ((string *)this)->before(x, startpos);
  1960. }
  1961.  
  1962. inline const subString string::before(const subString& x, int startpos) 
  1963.     const
  1964. {
  1965.     return ((string *)this)->before(x, startpos);
  1966. }
  1967.  
  1968. inline const subString string::before(const char* t, int startpos) const
  1969. {
  1970.     return ((string *)this)->before(t, startpos);
  1971. }
  1972.  
  1973. inline const subString string::before(char* t, int startpos) const
  1974. {
  1975.     return ((string *)this)->before(t, startpos);
  1976. }
  1977.  
  1978. inline const subString string::before(char c, int startpos) const
  1979. {
  1980.     return ((string *)this)->before(c, startpos);
  1981. }
  1982.  
  1983. inline const subString string::before(const regex& r, int startpos) const
  1984. {
  1985.     return ((string *)this)->before(r, startpos);
  1986. }
  1987.  
  1988.  
  1989. inline const subString string::through(int pos) const
  1990. {
  1991.     return ((string *)this)->through(pos);
  1992. }
  1993.  
  1994. inline const subString string::through(const string& x, int startpos) const
  1995. {
  1996.     return ((string *)this)->through(x, startpos);
  1997. }
  1998.  
  1999. inline const subString string::through(const subString& x, int startpos) 
  2000.     const
  2001. {
  2002.     return ((string *)this)->through(x, startpos);
  2003. }
  2004.  
  2005. inline const subString string::through(const char* t, int startpos) const
  2006. {
  2007.     return ((string *)this)->through(t, startpos);
  2008. }
  2009.  
  2010. inline const subString string::through(char* t, int startpos) const
  2011. {
  2012.     return ((string *)this)->through(t, startpos);
  2013. }
  2014.  
  2015. inline const subString string::through(char c, int startpos) const
  2016. {
  2017.     return ((string *)this)->through(c, startpos);
  2018. }
  2019.  
  2020. inline const subString string::through(const regex& r, int startpos) const
  2021. {
  2022.     return ((string *)this)->through(r, startpos);
  2023. }
  2024.  
  2025.  
  2026. inline const subString string::from(int pos) const
  2027. {
  2028.     return ((string *)this)->from(pos);
  2029. }
  2030.  
  2031. inline const subString string::from(const string& x, int startpos) const
  2032. {
  2033.     return ((string *)this)->from(x, startpos);
  2034. }
  2035.  
  2036. inline const subString string::from(const subString& x, int startpos) const
  2037. {
  2038.     return ((string *)this)->from(x, startpos);
  2039. }
  2040.  
  2041. inline const subString string::from(const char* t, int startpos) const
  2042. {
  2043.     return ((string *)this)->from(t, startpos);
  2044. }
  2045.  
  2046. inline const subString string::from(char* t, int startpos) const
  2047. {
  2048.     return ((string *)this)->from(t, startpos);
  2049. }
  2050.  
  2051. inline const subString string::from(char c, int startpos) const
  2052. {
  2053.     return ((string *)this)->from(c, startpos);
  2054. }
  2055.  
  2056. inline const subString string::from(const regex& r, int startpos) const
  2057. {
  2058.     return ((string *)this)->from(r, startpos);
  2059. }
  2060.  
  2061.  
  2062. inline const subString string::after(int pos) const
  2063. {
  2064.     return ((string *)this)->after(pos);
  2065. }
  2066.  
  2067. inline const subString string::after(const string& x, int startpos) const
  2068. {
  2069.     return ((string *)this)->after(x, startpos);
  2070. }
  2071.  
  2072. inline const subString string::after(const subString& x, int startpos) 
  2073.     const
  2074. {
  2075.     return ((string *)this)->after(x, startpos);
  2076. }
  2077.  
  2078. inline const subString string::after(const char* t, int startpos) const
  2079. {
  2080.     return ((string *)this)->after(t, startpos);
  2081. }
  2082.  
  2083. inline const subString string::after(char* t, int startpos) const
  2084. {
  2085.     return ((string *)this)->after(t, startpos);
  2086. }
  2087.  
  2088. inline const subString string::after(char c, int startpos) const
  2089. {
  2090.     return ((string *)this)->after(c, startpos);
  2091. }
  2092.  
  2093. inline const subString string::after(const regex& r, int startpos) const
  2094. {
  2095.     return ((string *)this)->after(r, startpos);
  2096. }
  2097.  
  2098.  
  2099.  
  2100.  
  2101. // I/O
  2102.  
  2103. inline ostream& operator<<(ostream& s, const string& x)
  2104. {
  2105.     s.write(x.chars(), x.length()); return s;
  2106. }
  2107.  
  2108. inline ostream& operator<<(ostream& s, const subString& x)
  2109.     s.write(x.chars(), x.length()); return s;
  2110. }
  2111.  
  2112. // A zillion comparison operators - for every combination of char,
  2113. // char *, const char *, string, and subString.
  2114. #define string_COMPARE(op, t1, t2) \
  2115. inline int operator op(t1 x, t2 y) \
  2116. { \
  2117.     return compare(x, y) op 0; \
  2118. }
  2119.  
  2120. #define string_COMPARE_ALL(t1, t2) \
  2121. string_COMPARE(==, t1, t2) \
  2122. string_COMPARE(!=, t1, t2) \
  2123. string_COMPARE(<,  t1, t2) \
  2124. string_COMPARE(>,  t1, t2) \
  2125. string_COMPARE(<=, t1, t2) \
  2126. string_COMPARE(>=, t1, t2)
  2127.  
  2128. string_COMPARE_ALL(const string&, const string&)
  2129. string_COMPARE_ALL(const string&, const subString&)
  2130. string_COMPARE_ALL(const string&, const char *)
  2131. string_COMPARE_ALL(const string&, char *)
  2132. string_COMPARE_ALL(const string&, char)
  2133.  
  2134. string_COMPARE_ALL(const subString&, const string&)
  2135. string_COMPARE_ALL(const subString&, const subString&)
  2136. string_COMPARE_ALL(const subString&, const char *)
  2137. string_COMPARE_ALL(const subString&, char *)
  2138. string_COMPARE_ALL(const subString&, char)
  2139.  
  2140. string_COMPARE_ALL(const char *, const string&)
  2141. string_COMPARE_ALL(const char *, const subString&)
  2142.  
  2143. string_COMPARE_ALL(char *, const string&)
  2144. string_COMPARE_ALL(char *, const subString&)
  2145.  
  2146. string_COMPARE_ALL(char, const string&)
  2147. string_COMPARE_ALL(char, const subString&)
  2148.  
  2149. #undef string_COMPARE
  2150. #undef string_COMPARE_ALL
  2151.  
  2152. // A helper needed by at, before, etc.
  2153. inline subString string::_substr(int first, int l)
  2154. {
  2155.     if (first < 0 || (unsigned)(first + l) > length())
  2156.     return subString(_nilstring, 0, 0);
  2157.     else 
  2158.     return subString(*this, first, l);
  2159. }
  2160.  
  2161. inline const subString string::_substr(int first, int l) const
  2162. {
  2163.     if (first < 0 || (unsigned)(first + l) > length())
  2164.     return subString(_nilstring, 0, 0);
  2165.     else 
  2166.     return subString(*this, first, l);
  2167. }
  2168.  
  2169. #endif // _ICE_strclass_h
  2170. // DON'T ADD ANYTHING BEHIND THIS #endif
  2171.