Install msysDVLPR-1.0.0-alpha-1
[msysgit.git] / include / g++-3 / std / bastring.cc
blobf86f6d30157c602fb5c30ced6fa93cba1acafc09
1 // Member templates for the -*- C++ -*- string classes.
2 // Copyright (C) 1994, 1999 Free Software Foundation
4 // This file is part of the GNU ANSI C++ Library. This library is free
5 // software; you can redistribute it and/or modify it under the
6 // terms of the GNU General Public License as published by the
7 // Free Software Foundation; either version 2, or (at your option)
8 // any later version.
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this library; see the file COPYING. If not, write to the Free
17 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 // As a special exception, if you link this library with files
20 // compiled with a GNU compiler to produce an executable, this does not cause
21 // the resulting executable to be covered by the GNU General Public License.
22 // This exception does not however invalidate any other reasons why
23 // the executable file might be covered by the GNU General Public License.
25 // Written by Jason Merrill based upon the specification by Takanori Adachi
26 // in ANSI X3J16/94-0013R2.
28 extern "C++" {
29 template <class charT, class traits, class Allocator>
30 inline void * basic_string <charT, traits, Allocator>::Rep::
31 operator new (size_t s, size_t extra)
33 return Allocator::allocate(s + extra * sizeof (charT));
36 template <class charT, class traits, class Allocator>
37 inline void basic_string <charT, traits, Allocator>::Rep::
38 operator delete (void * ptr)
40 Allocator::deallocate(ptr, sizeof(Rep) +
41 reinterpret_cast<Rep *>(ptr)->res *
42 sizeof (charT));
45 template <class charT, class traits, class Allocator>
46 inline size_t basic_string <charT, traits, Allocator>::Rep::
47 frob_size (size_t s)
49 size_t i = 16;
50 while (i < s) i *= 2;
51 return i;
54 template <class charT, class traits, class Allocator>
55 inline basic_string <charT, traits, Allocator>::Rep *
56 basic_string <charT, traits, Allocator>::Rep::
57 create (size_t extra)
59 extra = frob_size (extra + 1);
60 Rep *p = new (extra) Rep;
61 p->res = extra;
62 p->ref = 1;
63 p->selfish = false;
64 return p;
67 template <class charT, class traits, class Allocator>
68 charT * basic_string <charT, traits, Allocator>::Rep::
69 clone ()
71 Rep *p = Rep::create (len);
72 p->copy (0, data (), len);
73 p->len = len;
74 return p->data ();
77 template <class charT, class traits, class Allocator>
78 inline bool basic_string <charT, traits, Allocator>::Rep::
79 excess_slop (size_t s, size_t r)
81 return 2 * (s <= 16 ? 16 : s) < r;
84 template <class charT, class traits, class Allocator>
85 inline bool basic_string <charT, traits, Allocator>::
86 check_realloc (basic_string::size_type s) const
88 s += sizeof (charT);
89 rep ()->selfish = false;
90 return (rep ()->ref > 1
91 || s > capacity ()
92 || Rep::excess_slop (s, capacity ()));
95 template <class charT, class traits, class Allocator>
96 void basic_string <charT, traits, Allocator>::
97 alloc (basic_string::size_type __size, bool __save)
99 if (! check_realloc (__size))
100 return;
102 Rep *p = Rep::create (__size);
104 if (__save)
106 p->copy (0, data (), length ());
107 p->len = length ();
109 else
110 p->len = 0;
112 repup (p);
115 template <class charT, class traits, class Allocator>
116 basic_string <charT, traits, Allocator>&
117 basic_string <charT, traits, Allocator>::
118 replace (size_type pos1, size_type n1,
119 const basic_string& str, size_type pos2, size_type n2)
121 const size_t len2 = str.length ();
123 if (pos1 == 0 && n1 >= length () && pos2 == 0 && n2 >= len2)
124 return operator= (str);
126 OUTOFRANGE (pos2 > len2);
128 if (n2 > len2 - pos2)
129 n2 = len2 - pos2;
131 return replace (pos1, n1, str.data () + pos2, n2);
134 template <class charT, class traits, class Allocator>
135 inline void basic_string <charT, traits, Allocator>::Rep::
136 copy (size_t pos, const charT *s, size_t n)
138 if (n)
139 traits::copy (data () + pos, s, n);
142 template <class charT, class traits, class Allocator>
143 inline void basic_string <charT, traits, Allocator>::Rep::
144 move (size_t pos, const charT *s, size_t n)
146 if (n)
147 traits::move (data () + pos, s, n);
150 template <class charT, class traits, class Allocator>
151 basic_string <charT, traits, Allocator>&
152 basic_string <charT, traits, Allocator>::
153 replace (size_type pos, size_type n1, const charT* s, size_type n2)
155 const size_type len = length ();
156 OUTOFRANGE (pos > len);
157 if (n1 > len - pos)
158 n1 = len - pos;
159 LENGTHERROR (len - n1 > max_size () - n2);
160 size_t newlen = len - n1 + n2;
162 if (check_realloc (newlen))
164 Rep *p = Rep::create (newlen);
165 p->copy (0, data (), pos);
166 p->copy (pos + n2, data () + pos + n1, len - (pos + n1));
167 p->copy (pos, s, n2);
168 repup (p);
170 else
172 rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1));
173 rep ()->copy (pos, s, n2);
175 rep ()->len = newlen;
177 return *this;
180 template <class charT, class traits, class Allocator>
181 inline void basic_string <charT, traits, Allocator>::Rep::
182 set (size_t pos, const charT c, size_t n)
184 traits::set (data () + pos, c, n);
187 template <class charT, class traits, class Allocator>
188 basic_string <charT, traits, Allocator>& basic_string <charT, traits, Allocator>::
189 replace (size_type pos, size_type n1, size_type n2, charT c)
191 const size_t len = length ();
192 OUTOFRANGE (pos > len);
193 if (n1 > len - pos)
194 n1 = len - pos;
195 LENGTHERROR (len - n1 > max_size () - n2);
196 size_t newlen = len - n1 + n2;
198 if (check_realloc (newlen))
200 Rep *p = Rep::create (newlen);
201 p->copy (0, data (), pos);
202 p->copy (pos + n2, data () + pos + n1, len - (pos + n1));
203 p->set (pos, c, n2);
204 repup (p);
206 else
208 rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1));
209 rep ()->set (pos, c, n2);
211 rep ()->len = newlen;
213 return *this;
216 template <class charT, class traits, class Allocator>
217 void basic_string <charT, traits, Allocator>::
218 resize (size_type n, charT c)
220 LENGTHERROR (n > max_size ());
222 if (n > length ())
223 append (n - length (), c);
224 else
225 erase (n);
228 template <class charT, class traits, class Allocator>
229 basic_string <charT, traits, Allocator>::size_type
230 basic_string <charT, traits, Allocator>::
231 copy (charT* s, size_type n, size_type pos) const
233 OUTOFRANGE (pos > length ());
235 if (n > length () - pos)
236 n = length () - pos;
238 traits::copy (s, data () + pos, n);
239 return n;
242 template <class charT, class traits, class Allocator>
243 basic_string <charT, traits, Allocator>::size_type
244 basic_string <charT, traits, Allocator>::
245 find (const charT* s, size_type pos, size_type n) const
247 size_t xpos = pos;
248 for (; xpos + n <= length (); ++xpos)
249 if (traits::eq (data () [xpos], *s)
250 && traits::compare (data () + xpos, s, n) == 0)
251 return xpos;
252 return npos;
255 template <class charT, class traits, class Allocator>
256 inline basic_string <charT, traits, Allocator>::size_type
257 basic_string <charT, traits, Allocator>::
258 _find (const charT* ptr, charT c, size_type xpos, size_type len)
260 for (; xpos < len; ++xpos)
261 if (traits::eq (ptr [xpos], c))
262 return xpos;
263 return npos;
266 template <class charT, class traits, class Allocator>
267 basic_string <charT, traits, Allocator>::size_type
268 basic_string <charT, traits, Allocator>::
269 find (charT c, size_type pos) const
271 return _find (data (), c, pos, length ());
274 template <class charT, class traits, class Allocator>
275 basic_string <charT, traits, Allocator>::size_type
276 basic_string <charT, traits, Allocator>::
277 rfind (const charT* s, size_type pos, size_type n) const
279 if (n > length ())
280 return npos;
282 size_t xpos = length () - n;
283 if (xpos > pos)
284 xpos = pos;
286 for (++xpos; xpos-- > 0; )
287 if (traits::eq (data () [xpos], *s)
288 && traits::compare (data () + xpos, s, n) == 0)
289 return xpos;
290 return npos;
293 template <class charT, class traits, class Allocator>
294 basic_string <charT, traits, Allocator>::size_type
295 basic_string <charT, traits, Allocator>::
296 rfind (charT c, size_type pos) const
298 if (1 > length ())
299 return npos;
301 size_t xpos = length () - 1;
302 if (xpos > pos)
303 xpos = pos;
305 for (++xpos; xpos-- > 0; )
306 if (traits::eq (data () [xpos], c))
307 return xpos;
308 return npos;
311 template <class charT, class traits, class Allocator>
312 basic_string <charT, traits, Allocator>::size_type
313 basic_string <charT, traits, Allocator>::
314 find_first_of (const charT* s, size_type pos, size_type n) const
316 size_t xpos = pos;
317 for (; xpos < length (); ++xpos)
318 if (_find (s, data () [xpos], 0, n) != npos)
319 return xpos;
320 return npos;
323 template <class charT, class traits, class Allocator>
324 basic_string <charT, traits, Allocator>::size_type
325 basic_string <charT, traits, Allocator>::
326 find_last_of (const charT* s, size_type pos, size_type n) const
328 if (length() == 0)
329 return npos;
330 size_t xpos = length () - 1;
331 if (xpos > pos)
332 xpos = pos;
333 for (++xpos; xpos-- > 0;)
334 if (_find (s, data () [xpos], 0, n) != npos)
335 return xpos;
336 return npos;
339 template <class charT, class traits, class Allocator>
340 basic_string <charT, traits, Allocator>::size_type
341 basic_string <charT, traits, Allocator>::
342 find_first_not_of (const charT* s, size_type pos, size_type n) const
344 size_t xpos = pos;
345 for (; xpos < length (); ++xpos)
346 if (_find (s, data () [xpos], 0, n) == npos)
347 return xpos;
348 return npos;
351 template <class charT, class traits, class Allocator>
352 basic_string <charT, traits, Allocator>::size_type
353 basic_string <charT, traits, Allocator>::
354 find_first_not_of (charT c, size_type pos) const
356 size_t xpos = pos;
357 for (; xpos < length (); ++xpos)
358 if (traits::ne (data () [xpos], c))
359 return xpos;
360 return npos;
363 template <class charT, class traits, class Allocator>
364 basic_string <charT, traits, Allocator>::size_type
365 basic_string <charT, traits, Allocator>::
366 find_last_not_of (const charT* s, size_type pos, size_type n) const
368 if (length() == 0)
369 return npos;
370 size_t xpos = length () - 1;
371 if (xpos > pos)
372 xpos = pos;
373 for (++xpos; xpos-- > 0;)
374 if (_find (s, data () [xpos], 0, n) == npos)
375 return xpos;
376 return npos;
379 template <class charT, class traits, class Allocator>
380 basic_string <charT, traits, Allocator>::size_type
381 basic_string <charT, traits, Allocator>::
382 find_last_not_of (charT c, size_type pos) const
384 if (length() == 0)
385 return npos;
386 size_t xpos = length () - 1;
387 if (xpos > pos)
388 xpos = pos;
389 for (++xpos; xpos-- > 0;)
390 if (traits::ne (data () [xpos], c))
391 return xpos;
392 return npos;
395 template <class charT, class traits, class Allocator>
396 int basic_string <charT, traits, Allocator>::
397 compare (const basic_string& str, size_type pos, size_type n) const
399 OUTOFRANGE (pos > length ());
401 size_t rlen = length () - pos;
402 if (rlen > n)
403 rlen = n;
404 if (rlen > str.length ())
405 rlen = str.length ();
406 int r = traits::compare (data () + pos, str.data (), rlen);
407 if (r != 0)
408 return r;
409 if (rlen == n)
410 return 0;
411 return (length () - pos) - str.length ();
414 template <class charT, class traits, class Allocator>
415 int basic_string <charT, traits, Allocator>::
416 compare (const charT* s, size_type pos, size_type n) const
418 OUTOFRANGE (pos > length ());
420 size_t rlen = length () - pos;
421 if (rlen > n)
422 rlen = n;
423 int r = traits::compare (data () + pos, s, rlen);
424 if (r != 0)
425 return r;
426 return (length () - pos) - n;
429 #include <iostream.h>
431 template <class charT, class traits, class Allocator>
432 istream &
433 operator>> (istream &is, basic_string <charT, traits, Allocator> &s)
435 int w = is.width (0);
436 if (is.ipfx0 ())
438 register streambuf *sb = is.rdbuf ();
439 s.resize (0);
440 while (1)
442 int ch = sb->sbumpc ();
443 if (ch == EOF)
445 is.setstate (ios::eofbit);
446 break;
448 else if (traits::is_del (ch))
450 sb->sungetc ();
451 break;
453 s += static_cast<charT> (ch);
454 if (--w == 1)
455 break;
459 is.isfx ();
460 if (s.length () == 0)
461 is.setstate (ios::failbit);
463 return is;
466 template <class charT, class traits, class Allocator>
467 ostream &
468 operator<< (ostream &o, const basic_string <charT, traits, Allocator>& s)
470 return o.write (s.data (), s.length ());
473 template <class charT, class traits, class Allocator>
474 istream&
475 getline (istream &is, basic_string <charT, traits, Allocator>& s, charT delim)
477 if (is.ipfx1 ())
479 _IO_size_t count = 0;
480 streambuf *sb = is.rdbuf ();
481 s.resize (0);
483 while (1)
485 int ch = sb->sbumpc ();
486 if (ch == EOF)
488 is.setstate (count == 0
489 ? (ios::failbit|ios::eofbit)
490 : ios::eofbit);
491 break;
494 ++count;
496 if (ch == delim)
497 break;
499 s += static_cast<charT> (ch);
501 if (s.length () == s.npos - 1)
503 is.setstate (ios::failbit);
504 break;
509 // We need to be friends with istream to do this.
510 // is._gcount = count;
511 is.isfx ();
513 return is;
516 template <class charT, class traits, class Allocator>
517 basic_string <charT, traits, Allocator>::Rep
518 basic_string<charT, traits, Allocator>::nilRep = { 0, 0, 1, false };
520 template <class charT, class traits, class Allocator>
521 const basic_string <charT, traits, Allocator>::size_type
522 basic_string <charT, traits, Allocator>::npos;
524 } // extern "C++"