1f2ced752SOliver Tappe// Main templates for the -*- C++ -*- string classes.
2f2ced752SOliver Tappe// Copyright (C) 1994, 1995, 1999 Free Software Foundation
3f2ced752SOliver Tappe
4f2ced752SOliver Tappe// This file is part of the GNU ANSI C++ Library.  This library is free
5f2ced752SOliver Tappe// software; you can redistribute it and/or modify it under the
6f2ced752SOliver Tappe// terms of the GNU General Public License as published by the
7f2ced752SOliver Tappe// Free Software Foundation; either version 2, or (at your option)
8f2ced752SOliver Tappe// any later version.
9f2ced752SOliver Tappe
10f2ced752SOliver Tappe// This library is distributed in the hope that it will be useful,
11f2ced752SOliver Tappe// but WITHOUT ANY WARRANTY; without even the implied warranty of
12f2ced752SOliver Tappe// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13f2ced752SOliver Tappe// GNU General Public License for more details.
14f2ced752SOliver Tappe
15f2ced752SOliver Tappe// You should have received a copy of the GNU General Public License
16f2ced752SOliver Tappe// along with this library; see the file COPYING.  If not, write to the Free
17f2ced752SOliver Tappe// Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18f2ced752SOliver Tappe
19f2ced752SOliver Tappe// As a special exception, if you link this library with files
20f2ced752SOliver Tappe// compiled with a GNU compiler to produce an executable, this does not cause
21f2ced752SOliver Tappe// the resulting executable to be covered by the GNU General Public License.
22f2ced752SOliver Tappe// This exception does not however invalidate any other reasons why
23f2ced752SOliver Tappe// the executable file might be covered by the GNU General Public License.
24f2ced752SOliver Tappe
25f2ced752SOliver Tappe// Written by Jason Merrill based upon the specification by Takanori Adachi
26f2ced752SOliver Tappe// in ANSI X3J16/94-0013R2.
27f2ced752SOliver Tappe
28f2ced752SOliver Tappe#ifndef __BASTRING__
29f2ced752SOliver Tappe#define __BASTRING__
30f2ced752SOliver Tappe
31f2ced752SOliver Tappe#ifdef __GNUG__
32f2ced752SOliver Tappe#pragma interface
33f2ced752SOliver Tappe#endif
34f2ced752SOliver Tappe
35f2ced752SOliver Tappe#include <cstddef>
36f2ced752SOliver Tappe#include <std/straits.h>
37f2ced752SOliver Tappe
38f2ced752SOliver Tappe// NOTE : This does NOT conform to the draft standard and is likely to change
39f2ced752SOliver Tappe#include <alloc.h>
40f2ced752SOliver Tappe
412222d055SIngo Weinhold#ifdef __HAIKU__
422222d055SIngo Weinhold#	include <config/types.h>
432222d055SIngo Weinhold#endif
442222d055SIngo Weinhold
45f2ced752SOliver Tappeextern "C++" {
46f2ced752SOliver Tappeclass istream; class ostream;
47f2ced752SOliver Tappe
48f2ced752SOliver Tappe#include <iterator>
49f2ced752SOliver Tappe
50f2ced752SOliver Tappe#ifdef __STL_USE_EXCEPTIONS
51f2ced752SOliver Tappe
52f2ced752SOliver Tappeextern void __out_of_range (const char *);
53f2ced752SOliver Tappeextern void __length_error (const char *);
54f2ced752SOliver Tappe
55f2ced752SOliver Tappe#define OUTOFRANGE(cond) \
56f2ced752SOliver Tappe  do { if (cond) __out_of_range (#cond); } while (0)
57f2ced752SOliver Tappe#define LENGTHERROR(cond) \
58f2ced752SOliver Tappe  do { if (cond) __length_error (#cond); } while (0)
59f2ced752SOliver Tappe
60f2ced752SOliver Tappe#else
61f2ced752SOliver Tappe
62f2ced752SOliver Tappe#include <cassert>
63f2ced752SOliver Tappe#define OUTOFRANGE(cond) assert (!(cond))
64f2ced752SOliver Tappe#define LENGTHERROR(cond) assert (!(cond))
65f2ced752SOliver Tappe
66f2ced752SOliver Tappe#endif
67f2ced752SOliver Tappe
682222d055SIngo Weinhold#ifdef __HAIKU__
6973ad2473SPawel Dziepakextern "C" __haiku_int32 atomic_add(__haiku_int32* value,
702222d055SIngo Weinhold	__haiku_int32 addvalue);
712222d055SIngo Weinhold#endif	/* __HAIKU__ */
72f2ced752SOliver Tappe
73f2ced752SOliver Tappetemplate <class charT, class traits = string_char_traits<charT>,
74f2ced752SOliver Tappe	  class Allocator = alloc >
75f2ced752SOliver Tappeclass basic_string
76f2ced752SOliver Tappe{
77f2ced752SOliver Tappeprivate:
78f2ced752SOliver Tappe  struct Rep {
79f2ced752SOliver Tappe    size_t len, res, ref;
80f2ced752SOliver Tappe    bool selfish;
81f2ced752SOliver Tappe
82f2ced752SOliver Tappe    charT* data () { return reinterpret_cast<charT *>(this + 1); }
83f2ced752SOliver Tappe    charT& operator[] (size_t s) { return data () [s]; }
842222d055SIngo Weinhold#ifdef __HAIKU__
8573ad2473SPawel Dziepak    charT* grab () { if (selfish) return clone (); atomic_add((__haiku_int32*) &ref, 1); return data (); }
862222d055SIngo Weinhold    void release() { if (atomic_add((__haiku_int32*) &ref, -1) == 1) delete this; }
87f2ced752SOliver Tappe#else
88f2ced752SOliver Tappe    charT* grab () { if (selfish) return clone (); ++ref; return data (); }
89f2ced752SOliver Tappe#if defined __i486__ || defined __i586__ || defined __i686__
90f2ced752SOliver Tappe    void release ()
91f2ced752SOliver Tappe      {
92f2ced752SOliver Tappe	size_t __val;
93f2ced752SOliver Tappe	// This opcode exists as a .byte instead of as a mnemonic for the
942222d055SIngo Weinhold	// benefit of SCO OpenServer 5.  The system assembler (which is
952222d055SIngo Weinhold	// essentially required on this target) can't assemble xaddl in
96f2ced752SOliver Tappe	//COFF mode.
97f2ced752SOliver Tappe	asm (".byte 0xf0, 0x0f, 0xc1, 0x02" // lock; xaddl %eax, (%edx)
98f2ced752SOliver Tappe	    : "=a" (__val)
99f2ced752SOliver Tappe	    : "0" (-1), "m" (ref), "d" (&ref)
100f2ced752SOliver Tappe	    : "memory");
101f2ced752SOliver Tappe
102f2ced752SOliver Tappe	if (__val == 1)
103f2ced752SOliver Tappe	  delete this;
104f2ced752SOliver Tappe      }
105f2ced752SOliver Tappe#elif defined __sparcv9__
106f2ced752SOliver Tappe    void release ()
107f2ced752SOliver Tappe      {
108f2ced752SOliver Tappe	size_t __newval, __oldval = ref;
109f2ced752SOliver Tappe	do
110f2ced752SOliver Tappe	  {
111f2ced752SOliver Tappe	    __newval = __oldval - 1;
112f2ced752SOliver Tappe	    __asm__ ("cas	[%4], %2, %0"
113f2ced752SOliver Tappe		     : "=r" (__oldval), "=m" (ref)
114f2ced752SOliver Tappe		     : "r" (__oldval), "m" (ref), "r"(&(ref)), "0" (__newval));
115f2ced752SOliver Tappe	  }
116f2ced752SOliver Tappe	while (__newval != __oldval);
117f2ced752SOliver Tappe
118f2ced752SOliver Tappe	if (__oldval == 0)
119f2ced752SOliver Tappe	  delete this;
120f2ced752SOliver Tappe      }
121f2ced752SOliver Tappe#else
122f2ced752SOliver Tappe    void release () { if (--ref == 0) delete this; }
123f2ced752SOliver Tappe#endif
1242222d055SIngo Weinhold#endif /* __HAIKU__ */
125f2ced752SOliver Tappe    inline static void * operator new (size_t, size_t);
126f2ced752SOliver Tappe    inline static void operator delete (void *);
127f2ced752SOliver Tappe    inline static Rep* create (size_t);
128f2ced752SOliver Tappe    charT* clone ();
129f2ced752SOliver Tappe
130f2ced752SOliver Tappe    inline void copy (size_t, const charT *, size_t);
131f2ced752SOliver Tappe    inline void move (size_t, const charT *, size_t);
132f2ced752SOliver Tappe    inline void set  (size_t, const charT,   size_t);
133f2ced752SOliver Tappe
134f2ced752SOliver Tappe    inline static bool excess_slop (size_t, size_t);
135f2ced752SOliver Tappe    inline static size_t frob_size (size_t);
136f2ced752SOliver Tappe
137f2ced752SOliver Tappe  private:
138f2ced752SOliver Tappe    Rep &operator= (const Rep &);
139f2ced752SOliver Tappe  };
140f2ced752SOliver Tappe
141f2ced752SOliver Tappepublic:
142f2ced752SOliver Tappe// types:
143f2ced752SOliver Tappe  typedef	   traits		traits_type;
144f2ced752SOliver Tappe  typedef typename traits::char_type	value_type;
145f2ced752SOliver Tappe  typedef	   Allocator		allocator_type;
146f2ced752SOliver Tappe
147f2ced752SOliver Tappe  typedef size_t size_type;
148f2ced752SOliver Tappe  typedef ptrdiff_t difference_type;
149f2ced752SOliver Tappe  typedef charT& reference;
150f2ced752SOliver Tappe  typedef const charT& const_reference;
151f2ced752SOliver Tappe  typedef charT* pointer;
152f2ced752SOliver Tappe  typedef const charT* const_pointer;
153f2ced752SOliver Tappe  typedef pointer iterator;
154f2ced752SOliver Tappe  typedef const_pointer const_iterator;
155f2ced752SOliver Tappe  typedef ::reverse_iterator<iterator> reverse_iterator;
156f2ced752SOliver Tappe  typedef ::reverse_iterator<const_iterator> const_reverse_iterator;
157f2ced752SOliver Tappe  static const size_type npos = static_cast<size_type>(-1);
158f2ced752SOliver Tappe
159f2ced752SOliver Tappeprivate:
160f2ced752SOliver Tappe  Rep *rep () const { return reinterpret_cast<Rep *>(dat) - 1; }
161f2ced752SOliver Tappe  void repup (Rep *p) { rep ()->release (); dat = p->data (); }
162f2ced752SOliver Tappe
163f2ced752SOliver Tappepublic:
164f2ced752SOliver Tappe  const charT* data () const
165f2ced752SOliver Tappe    { return rep ()->data(); }
166f2ced752SOliver Tappe  size_type length () const
167f2ced752SOliver Tappe    { return rep ()->len; }
168f2ced752SOliver Tappe  size_type size () const
169f2ced752SOliver Tappe    { return rep ()->len; }
170f2ced752SOliver Tappe  size_type capacity () const
171f2ced752SOliver Tappe    { return rep ()->res; }
172f2ced752SOliver Tappe  size_type max_size () const
173f2ced752SOliver Tappe    { return (npos - 1)/sizeof (charT); }		// XXX
174f2ced752SOliver Tappe  bool empty () const
175f2ced752SOliver Tappe    { return size () == 0; }
176f2ced752SOliver Tappe
177f2ced752SOliver Tappe// _lib.string.cons_ construct/copy/destroy:
178f2ced752SOliver Tappe  basic_string& operator= (const basic_string& str)
179f2ced752SOliver Tappe    {
180f2ced752SOliver Tappe      if (&str != this) { rep ()->release (); dat = str.rep ()->grab (); }
181f2ced752SOliver Tappe      return *this;
182f2ced752SOliver Tappe    }
183f2ced752SOliver Tappe
184f2ced752SOliver Tappe  explicit basic_string (): dat (nilRep.grab ()) { }
185f2ced752SOliver Tappe  basic_string (const basic_string& _str): dat (_str.rep ()->grab ()) { }
186f2ced752SOliver Tappe  basic_string (const basic_string& _str, size_type pos, size_type n = npos)
187f2ced752SOliver Tappe    : dat (nilRep.grab ()) { assign (_str, pos, n); }
188f2ced752SOliver Tappe  basic_string (const charT* s, size_type n)
189f2ced752SOliver Tappe    : dat (nilRep.grab ()) { assign (s, n); }
190f2ced752SOliver Tappe  basic_string (const charT* s)
191f2ced752SOliver Tappe    : dat (nilRep.grab ()) { assign (s); }
192f2ced752SOliver Tappe  basic_string (size_type n, charT c)
193f2ced752SOliver Tappe    : dat (nilRep.grab ()) { assign (n, c); }
194f2ced752SOliver Tappe#ifdef __STL_MEMBER_TEMPLATES
195f2ced752SOliver Tappe  template<class InputIterator>
196f2ced752SOliver Tappe    basic_string(InputIterator __begin, InputIterator __end)
197f2ced752SOliver Tappe#else
198f2ced752SOliver Tappe  basic_string(const_iterator __begin, const_iterator __end)
199f2ced752SOliver Tappe#endif
200f2ced752SOliver Tappe    : dat (nilRep.grab ()) { assign (__begin, __end); }
201f2ced752SOliver Tappe
202f2ced752SOliver Tappe  ~basic_string ()
203f2ced752SOliver Tappe    { rep ()->release (); }
204f2ced752SOliver Tappe
205f2ced752SOliver Tappe  void swap (basic_string &s) { charT *d = dat; dat = s.dat; s.dat = d; }
206f2ced752SOliver Tappe
207f2ced752SOliver Tappe  basic_string& append (const basic_string& _str, size_type pos = 0,
208f2ced752SOliver Tappe			size_type n = npos)
209f2ced752SOliver Tappe    { return replace (length (), 0, _str, pos, n); }
210f2ced752SOliver Tappe  basic_string& append (const charT* s, size_type n)
211f2ced752SOliver Tappe    { return replace (length (), 0, s, n); }
212f2ced752SOliver Tappe  basic_string& append (const charT* s)
213f2ced752SOliver Tappe    { return append (s, traits::length (s)); }
214f2ced752SOliver Tappe  basic_string& append (size_type n, charT c)
215f2ced752SOliver Tappe    { return replace (length (), 0, n, c); }
216f2ced752SOliver Tappe#ifdef __STL_MEMBER_TEMPLATES
217f2ced752SOliver Tappe  template<class InputIterator>
218f2ced752SOliver Tappe    basic_string& append(InputIterator first, InputIterator last)
219f2ced752SOliver Tappe#else
220f2ced752SOliver Tappe  basic_string& append(const_iterator first, const_iterator last)
221f2ced752SOliver Tappe#endif
222f2ced752SOliver Tappe    { return replace (iend (), iend (), first, last); }
223f2ced752SOliver Tappe
224f2ced752SOliver Tappe  void push_back(charT __c)
225f2ced752SOliver Tappe  { append(1, __c); }
2262222d055SIngo Weinhold
227f2ced752SOliver Tappe  basic_string& assign (const basic_string& str, size_type pos = 0,
228f2ced752SOliver Tappe			size_type n = npos)
229f2ced752SOliver Tappe    { return replace (0, npos, str, pos, n); }
230f2ced752SOliver Tappe  basic_string& assign (const charT* s, size_type n)
231f2ced752SOliver Tappe    { return replace (0, npos, s, n); }
232f2ced752SOliver Tappe  basic_string& assign (const charT* s)
233f2ced752SOliver Tappe    { return assign (s, traits::length (s)); }
234f2ced752SOliver Tappe  basic_string& assign (size_type n, charT c)
235f2ced752SOliver Tappe    { return replace (0, npos, n, c); }
236f2ced752SOliver Tappe#ifdef __STL_MEMBER_TEMPLATES
237f2ced752SOliver Tappe  template<class InputIterator>
238f2ced752SOliver Tappe    basic_string& assign(InputIterator first, InputIterator last)
239f2ced752SOliver Tappe#else
240f2ced752SOliver Tappe  basic_string& assign(const_iterator first, const_iterator last)
241f2ced752SOliver Tappe#endif
242f2ced752SOliver Tappe    { return replace (ibegin (), iend (), first, last); }
243f2ced752SOliver Tappe
244f2ced752SOliver Tappe  basic_string& operator= (const charT* s)
245f2ced752SOliver Tappe    { return assign (s); }
246f2ced752SOliver Tappe  basic_string& operator= (charT c)
247f2ced752SOliver Tappe    { return assign (1, c); }
248f2ced752SOliver Tappe
249f2ced752SOliver Tappe  basic_string& operator+= (const basic_string& rhs)
250f2ced752SOliver Tappe    { return append (rhs); }
251f2ced752SOliver Tappe  basic_string& operator+= (const charT* s)
252f2ced752SOliver Tappe    { return append (s); }
253f2ced752SOliver Tappe  basic_string& operator+= (charT c)
254f2ced752SOliver Tappe    { return append (1, c); }
255f2ced752SOliver Tappe
256f2ced752SOliver Tappe  basic_string& insert (size_type pos1, const basic_string& str,
257f2ced752SOliver Tappe			size_type pos2 = 0, size_type n = npos)
258f2ced752SOliver Tappe    { return replace (pos1, 0, str, pos2, n); }
259f2ced752SOliver Tappe  basic_string& insert (size_type pos, const charT* s, size_type n)
260f2ced752SOliver Tappe    { return replace (pos, 0, s, n); }
261f2ced752SOliver Tappe  basic_string& insert (size_type pos, const charT* s)
262f2ced752SOliver Tappe    { return insert (pos, s, traits::length (s)); }
263f2ced752SOliver Tappe  basic_string& insert (size_type pos, size_type n, charT c)
264f2ced752SOliver Tappe    { return replace (pos, 0, n, c); }
265f2ced752SOliver Tappe  iterator insert(iterator p, charT c)
266f2ced752SOliver Tappe    { size_type __o = p - ibegin ();
267f2ced752SOliver Tappe      insert (p - ibegin (), 1, c); selfish ();
268f2ced752SOliver Tappe      return ibegin () + __o; }
269f2ced752SOliver Tappe  iterator insert(iterator p, size_type n, charT c)
270f2ced752SOliver Tappe    { size_type __o = p - ibegin ();
271f2ced752SOliver Tappe      insert (p - ibegin (), n, c); selfish ();
272f2ced752SOliver Tappe      return ibegin () + __o; }
273f2ced752SOliver Tappe#ifdef __STL_MEMBER_TEMPLATES
274f2ced752SOliver Tappe  template<class InputIterator>
275f2ced752SOliver Tappe    void insert(iterator p, InputIterator first, InputIterator last)
276f2ced752SOliver Tappe#else
277f2ced752SOliver Tappe  void insert(iterator p, const_iterator first, const_iterator last)
278f2ced752SOliver Tappe#endif
279f2ced752SOliver Tappe    { replace (p, p, first, last); }
280f2ced752SOliver Tappe
281f2ced752SOliver Tappe  basic_string& erase (size_type pos = 0, size_type n = npos)
282f2ced752SOliver Tappe    { return replace (pos, n, (size_type)0, (charT)0); }
283f2ced752SOliver Tappe  iterator erase(iterator p)
284f2ced752SOliver Tappe    { size_type __o = p - begin();
285f2ced752SOliver Tappe      replace (__o, 1, (size_type)0, (charT)0); selfish ();
286f2ced752SOliver Tappe      return ibegin() + __o; }
287f2ced752SOliver Tappe  iterator erase(iterator f, iterator l)
288f2ced752SOliver Tappe    { size_type __o = f - ibegin();
289f2ced752SOliver Tappe      replace (__o, l-f, (size_type)0, (charT)0);selfish ();
290f2ced752SOliver Tappe      return ibegin() + __o; }
291f2ced752SOliver Tappe
292481f986bSAxel Dörfler  void clear()
293481f986bSAxel Dörfler    { erase(begin(), end()); }
294f2ced752SOliver Tappe  basic_string& replace (size_type pos1, size_type n1, const basic_string& str,
295f2ced752SOliver Tappe			 size_type pos2 = 0, size_type n2 = npos);
296f2ced752SOliver Tappe  basic_string& replace (size_type pos, size_type n1, const charT* s,
297f2ced752SOliver Tappe			 size_type n2);
298f2ced752SOliver Tappe  basic_string& replace (size_type pos, size_type n1, const charT* s)
299f2ced752SOliver Tappe    { return replace (pos, n1, s, traits::length (s)); }
300f2ced752SOliver Tappe  basic_string& replace (size_type pos, size_type n1, size_type n2, charT c);
301f2ced752SOliver Tappe  basic_string& replace (size_type pos, size_type n, charT c)
302f2ced752SOliver Tappe    { return replace (pos, n, 1, c); }
303f2ced752SOliver Tappe  basic_string& replace (iterator i1, iterator i2, const basic_string& str)
304f2ced752SOliver Tappe    { return replace (i1 - ibegin (), i2 - i1, str); }
305f2ced752SOliver Tappe  basic_string& replace (iterator i1, iterator i2, const charT* s, size_type n)
306f2ced752SOliver Tappe    { return replace (i1 - ibegin (), i2 - i1, s, n); }
307f2ced752SOliver Tappe  basic_string& replace (iterator i1, iterator i2, const charT* s)
308f2ced752SOliver Tappe    { return replace (i1 - ibegin (), i2 - i1, s); }
309f2ced752SOliver Tappe  basic_string& replace (iterator i1, iterator i2, size_type n, charT c)
310f2ced752SOliver Tappe    { return replace (i1 - ibegin (), i2 - i1, n, c); }
311f2ced752SOliver Tappe#ifdef __STL_MEMBER_TEMPLATES
312f2ced752SOliver Tappe  template<class InputIterator>
313f2ced752SOliver Tappe    basic_string& replace(iterator i1, iterator i2,
314f2ced752SOliver Tappe			  InputIterator j1, InputIterator j2);
315f2ced752SOliver Tappe#else
316f2ced752SOliver Tappe  basic_string& replace(iterator i1, iterator i2,
317f2ced752SOliver Tappe			const_iterator j1, const_iterator j2);
318f2ced752SOliver Tappe#endif
319f2ced752SOliver Tappe
320f2ced752SOliver Tappeprivate:
321f2ced752SOliver Tappe  static charT eos () { return traits::eos (); }
322f2ced752SOliver Tappe  void unique () { if (rep ()->ref > 1) alloc (length (), true); }
323f2ced752SOliver Tappe  void selfish () { unique (); rep ()->selfish = true; }
324f2ced752SOliver Tappe
325f2ced752SOliver Tappepublic:
326f2ced752SOliver Tappe  charT operator[] (size_type pos) const
327f2ced752SOliver Tappe    {
328f2ced752SOliver Tappe      if (pos == length ())
329f2ced752SOliver Tappe	return eos ();
330f2ced752SOliver Tappe      return data ()[pos];
331f2ced752SOliver Tappe    }
332f2ced752SOliver Tappe
333f2ced752SOliver Tappe  reference operator[] (size_type pos)
334f2ced752SOliver Tappe    { selfish (); return (*rep ())[pos]; }
335f2ced752SOliver Tappe
336f2ced752SOliver Tappe  reference at (size_type pos)
337f2ced752SOliver Tappe    {
338f2ced752SOliver Tappe      OUTOFRANGE (pos >= length ());
339f2ced752SOliver Tappe      return (*this)[pos];
340f2ced752SOliver Tappe    }
341f2ced752SOliver Tappe  const_reference at (size_type pos) const
342f2ced752SOliver Tappe    {
343f2ced752SOliver Tappe      OUTOFRANGE (pos >= length ());
344f2ced752SOliver Tappe      return data ()[pos];
345f2ced752SOliver Tappe    }
346f2ced752SOliver Tappe
347f2ced752SOliver Tappeprivate:
348f2ced752SOliver Tappe  void terminate () const
349f2ced752SOliver Tappe    { traits::assign ((*rep ())[length ()], eos ()); }
350f2ced752SOliver Tappe
351f2ced752SOliver Tappepublic:
352f2ced752SOliver Tappe  const charT* c_str () const
353100db087SAdrien Destugues - PulkoMandy    {
354100db087SAdrien Destugues - PulkoMandy	  static const charT null_str[1] = {0};
355100db087SAdrien Destugues - PulkoMandy	  if (length () == 0) return null_str; terminate (); return data ();
356100db087SAdrien Destugues - PulkoMandy	}
357f2ced752SOliver Tappe  void resize (size_type n, charT c);
358f2ced752SOliver Tappe  void resize (size_type n)
359f2ced752SOliver Tappe    { resize (n, eos ()); }
360f2ced752SOliver Tappe  void reserve (size_type) { }
361f2ced752SOliver Tappe
362f2ced752SOliver Tappe  size_type copy (charT* s, size_type n, size_type pos = 0) const;
363f2ced752SOliver Tappe
364f2ced752SOliver Tappe  size_type find (const basic_string& str, size_type pos = 0) const
365f2ced752SOliver Tappe    { return find (str.data(), pos, str.length()); }
366f2ced752SOliver Tappe  size_type find (const charT* s, size_type pos, size_type n) const;
367f2ced752SOliver Tappe  size_type find (const charT* _s, size_type pos = 0) const
368f2ced752SOliver Tappe    { return find (_s, pos, traits::length (_s)); }
369f2ced752SOliver Tappe  size_type find (charT c, size_type pos = 0) const;
370f2ced752SOliver Tappe
371f2ced752SOliver Tappe  size_type rfind (const basic_string& str, size_type pos = npos) const
372f2ced752SOliver Tappe    { return rfind (str.data(), pos, str.length()); }
373f2ced752SOliver Tappe  size_type rfind (const charT* s, size_type pos, size_type n) const;
374f2ced752SOliver Tappe  size_type rfind (const charT* s, size_type pos = npos) const
375f2ced752SOliver Tappe    { return rfind (s, pos, traits::length (s)); }
376f2ced752SOliver Tappe  size_type rfind (charT c, size_type pos = npos) const;
377f2ced752SOliver Tappe
378f2ced752SOliver Tappe  size_type find_first_of (const basic_string& str, size_type pos = 0) const
379f2ced752SOliver Tappe    { return find_first_of (str.data(), pos, str.length()); }
380f2ced752SOliver Tappe  size_type find_first_of (const charT* s, size_type pos, size_type n) const;
381f2ced752SOliver Tappe  size_type find_first_of (const charT* s, size_type pos = 0) const
382f2ced752SOliver Tappe    { return find_first_of (s, pos, traits::length (s)); }
383f2ced752SOliver Tappe  size_type find_first_of (charT c, size_type pos = 0) const
384f2ced752SOliver Tappe    { return find (c, pos); }
385f2ced752SOliver Tappe
386f2ced752SOliver Tappe  size_type find_last_of (const basic_string& str, size_type pos = npos) const
387f2ced752SOliver Tappe    { return find_last_of (str.data(), pos, str.length()); }
388f2ced752SOliver Tappe  size_type find_last_of (const charT* s, size_type pos, size_type n) const;
389f2ced752SOliver Tappe  size_type find_last_of (const charT* s, size_type pos = npos) const
390f2ced752SOliver Tappe    { return find_last_of (s, pos, traits::length (s)); }
391f2ced752SOliver Tappe  size_type find_last_of (charT c, size_type pos = npos) const
392f2ced752SOliver Tappe    { return rfind (c, pos); }
393f2ced752SOliver Tappe
394f2ced752SOliver Tappe  size_type find_first_not_of (const basic_string& str, size_type pos = 0) const
395f2ced752SOliver Tappe    { return find_first_not_of (str.data(), pos, str.length()); }
396f2ced752SOliver Tappe  size_type find_first_not_of (const charT* s, size_type pos, size_type n) const;
397f2ced752SOliver Tappe  size_type find_first_not_of (const charT* s, size_type pos = 0) const
398f2ced752SOliver Tappe    { return find_first_not_of (s, pos, traits::length (s)); }
399f2ced752SOliver Tappe  size_type find_first_not_of (charT c, size_type pos = 0) const;
400f2ced752SOliver Tappe
401f2ced752SOliver Tappe  size_type find_last_not_of (const basic_string& str, size_type pos = npos) const
402f2ced752SOliver Tappe    { return find_last_not_of (str.data(), pos, str.length()); }
403f2ced752SOliver Tappe  size_type find_last_not_of (const charT* s, size_type pos, size_type n) const;
404f2ced752SOliver Tappe  size_type find_last_not_of (const charT* s, size_type pos = npos) const
405f2ced752SOliver Tappe    { return find_last_not_of (s, pos, traits::length (s)); }
406f2ced752SOliver Tappe  size_type find_last_not_of (charT c, size_type pos = npos) const;
407f2ced752SOliver Tappe
408f2ced752SOliver Tappe  basic_string substr (size_type pos = 0, size_type n = npos) const
409f2ced752SOliver Tappe    { return basic_string (*this, pos, n); }
410f2ced752SOliver Tappe
411837b1625SAdrien Destugues
412e1caa56bSAdrien Destugues  // BeOS bogus versions
413f2ced752SOliver Tappe  int compare (const charT* s, size_type pos, size_type n) const;
414e1caa56bSAdrien Destugues  int compare (const basic_string& str, size_type pos = 0, size_type n = npos) const;
415e1caa56bSAdrien Destugues  // There is no 'strncmp' equivalent for charT pointers.
416837b1625SAdrien Destugues
417e1caa56bSAdrien Destugues  // Correct std C++ prototypes
418e1caa56bSAdrien Destugues  int compare (size_type pos, size_type n, const basic_string& str) const
419e1caa56bSAdrien Destugues	{ return compare(str, pos, n); }
420837b1625SAdrien Destugues  int compare (size_type pos, size_type n, const charT* s) const
421837b1625SAdrien Destugues    { return compare(s, pos, n); }
4224e3137c0SAdrien Destugues  int compare (size_type pos, size_type n, const charT* s, size_type n2) const
423691e517bSAdrien Destugues    { if (n > n2) n = n2; return compare(s, pos, n); }
424f2ced752SOliver Tappe  int compare (const charT* s, size_type pos = 0) const
425f2ced752SOliver Tappe    { return compare (s, pos, traits::length (s)); }
426f2ced752SOliver Tappe
427f2ced752SOliver Tappe  iterator begin () { selfish (); return &(*this)[0]; }
428f2ced752SOliver Tappe  iterator end () { selfish (); return &(*this)[length ()]; }
429f2ced752SOliver Tappe
430f2ced752SOliver Tappeprivate:
431f2ced752SOliver Tappe  iterator ibegin () const { return &(*rep ())[0]; }
432f2ced752SOliver Tappe  iterator iend () const { return &(*rep ())[length ()]; }
433f2ced752SOliver Tappe
434f2ced752SOliver Tappepublic:
435f2ced752SOliver Tappe  const_iterator begin () const { return ibegin (); }
436f2ced752SOliver Tappe  const_iterator end () const { return iend (); }
437f2ced752SOliver Tappe
438f2ced752SOliver Tappe  reverse_iterator       rbegin() { return reverse_iterator (end ()); }
439f2ced752SOliver Tappe  const_reverse_iterator rbegin() const
440f2ced752SOliver Tappe    { return const_reverse_iterator (end ()); }
441f2ced752SOliver Tappe  reverse_iterator       rend() { return reverse_iterator (begin ()); }
442f2ced752SOliver Tappe  const_reverse_iterator rend() const
443f2ced752SOliver Tappe    { return const_reverse_iterator (begin ()); }
444f2ced752SOliver Tappe
445f2ced752SOliver Tappeprivate:
446f2ced752SOliver Tappe  void alloc (size_type size, bool save);
447f2ced752SOliver Tappe  static size_type _find (const charT* ptr, charT c, size_type xpos, size_type len);
448f2ced752SOliver Tappe  inline bool check_realloc (size_type s) const;
449f2ced752SOliver Tappe
450f2ced752SOliver Tappe  static Rep nilRep;
451f2ced752SOliver Tappe  charT *dat;
452f2ced752SOliver Tappe};
453f2ced752SOliver Tappe
454f2ced752SOliver Tappe#ifdef __STL_MEMBER_TEMPLATES
455f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator> template <class InputIterator>
456f2ced752SOliver Tappebasic_string <charT, traits, Allocator>& basic_string <charT, traits, Allocator>::
457f2ced752SOliver Tappereplace (iterator i1, iterator i2, InputIterator j1, InputIterator j2)
458f2ced752SOliver Tappe#else
459f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
460f2ced752SOliver Tappebasic_string <charT, traits, Allocator>& basic_string <charT, traits, Allocator>::
461f2ced752SOliver Tappereplace (iterator i1, iterator i2, const_iterator j1, const_iterator j2)
462f2ced752SOliver Tappe#endif
463f2ced752SOliver Tappe{
464f2ced752SOliver Tappe  const size_type len = length ();
465f2ced752SOliver Tappe  size_type pos = i1 - ibegin ();
466f2ced752SOliver Tappe  size_type n1 = i2 - i1;
467f2ced752SOliver Tappe  size_type n2 = j2 - j1;
468f2ced752SOliver Tappe
469f2ced752SOliver Tappe  OUTOFRANGE (pos > len);
470f2ced752SOliver Tappe  if (n1 > len - pos)
471f2ced752SOliver Tappe    n1 = len - pos;
472f2ced752SOliver Tappe  LENGTHERROR (len - n1 > max_size () - n2);
473f2ced752SOliver Tappe  size_t newlen = len - n1 + n2;
474f2ced752SOliver Tappe
475f2ced752SOliver Tappe  if (check_realloc (newlen))
476f2ced752SOliver Tappe    {
477f2ced752SOliver Tappe      Rep *p = Rep::create (newlen);
478f2ced752SOliver Tappe      p->copy (0, data (), pos);
479f2ced752SOliver Tappe      p->copy (pos + n2, data () + pos + n1, len - (pos + n1));
480f2ced752SOliver Tappe      for (; j1 != j2; ++j1, ++pos)
481f2ced752SOliver Tappe	traits::assign ((*p)[pos], *j1);
482f2ced752SOliver Tappe      repup (p);
483f2ced752SOliver Tappe    }
484f2ced752SOliver Tappe  else
485f2ced752SOliver Tappe    {
486f2ced752SOliver Tappe      rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1));
487f2ced752SOliver Tappe      for (; j1 != j2; ++j1, ++pos)
488f2ced752SOliver Tappe	traits::assign ((*rep ())[pos], *j1);
489f2ced752SOliver Tappe    }
490f2ced752SOliver Tappe  rep ()->len = newlen;
491f2ced752SOliver Tappe
492f2ced752SOliver Tappe  return *this;
493f2ced752SOliver Tappe}
494f2ced752SOliver Tappe
495f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
496f2ced752SOliver Tappeinline basic_string <charT, traits, Allocator>
497f2ced752SOliver Tappeoperator+ (const basic_string <charT, traits, Allocator>& lhs,
498f2ced752SOliver Tappe	   const basic_string <charT, traits, Allocator>& rhs)
499f2ced752SOliver Tappe{
500f2ced752SOliver Tappe  basic_string <charT, traits, Allocator> _str (lhs);
501f2ced752SOliver Tappe  _str.append (rhs);
502f2ced752SOliver Tappe  return _str;
503f2ced752SOliver Tappe}
504f2ced752SOliver Tappe
505f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
506f2ced752SOliver Tappeinline basic_string <charT, traits, Allocator>
507f2ced752SOliver Tappeoperator+ (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs)
508f2ced752SOliver Tappe{
509f2ced752SOliver Tappe  basic_string <charT, traits, Allocator> _str (lhs);
510f2ced752SOliver Tappe  _str.append (rhs);
511f2ced752SOliver Tappe  return _str;
512f2ced752SOliver Tappe}
513f2ced752SOliver Tappe
514f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
515f2ced752SOliver Tappeinline basic_string <charT, traits, Allocator>
516f2ced752SOliver Tappeoperator+ (charT lhs, const basic_string <charT, traits, Allocator>& rhs)
517f2ced752SOliver Tappe{
518f2ced752SOliver Tappe  basic_string <charT, traits, Allocator> _str (1, lhs);
519f2ced752SOliver Tappe  _str.append (rhs);
520f2ced752SOliver Tappe  return _str;
521f2ced752SOliver Tappe}
522f2ced752SOliver Tappe
523f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
524f2ced752SOliver Tappeinline basic_string <charT, traits, Allocator>
525f2ced752SOliver Tappeoperator+ (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs)
526f2ced752SOliver Tappe{
527f2ced752SOliver Tappe  basic_string <charT, traits, Allocator> _str (lhs);
528f2ced752SOliver Tappe  _str.append (rhs);
529f2ced752SOliver Tappe  return _str;
530f2ced752SOliver Tappe}
531f2ced752SOliver Tappe
532f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
533f2ced752SOliver Tappeinline basic_string <charT, traits, Allocator>
534f2ced752SOliver Tappeoperator+ (const basic_string <charT, traits, Allocator>& lhs, charT rhs)
535f2ced752SOliver Tappe{
536f2ced752SOliver Tappe  basic_string <charT, traits, Allocator> str (lhs);
537f2ced752SOliver Tappe  str.append (1, rhs);
538f2ced752SOliver Tappe  return str;
539f2ced752SOliver Tappe}
540f2ced752SOliver Tappe
541f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
542f2ced752SOliver Tappeinline bool
543f2ced752SOliver Tappeoperator== (const basic_string <charT, traits, Allocator>& lhs,
544f2ced752SOliver Tappe	    const basic_string <charT, traits, Allocator>& rhs)
545f2ced752SOliver Tappe{
546f2ced752SOliver Tappe  return (lhs.compare (rhs) == 0);
547f2ced752SOliver Tappe}
548f2ced752SOliver Tappe
549f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
550f2ced752SOliver Tappeinline bool
551f2ced752SOliver Tappeoperator== (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs)
552f2ced752SOliver Tappe{
553f2ced752SOliver Tappe  return (rhs.compare (lhs) == 0);
554f2ced752SOliver Tappe}
555f2ced752SOliver Tappe
556f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
557f2ced752SOliver Tappeinline bool
558f2ced752SOliver Tappeoperator== (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs)
559f2ced752SOliver Tappe{
560f2ced752SOliver Tappe  return (lhs.compare (rhs) == 0);
561f2ced752SOliver Tappe}
562f2ced752SOliver Tappe
563f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
564f2ced752SOliver Tappeinline bool
565f2ced752SOliver Tappeoperator!= (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs)
566f2ced752SOliver Tappe{
567f2ced752SOliver Tappe  return (rhs.compare (lhs) != 0);
568f2ced752SOliver Tappe}
569f2ced752SOliver Tappe
570f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
571f2ced752SOliver Tappeinline bool
572f2ced752SOliver Tappeoperator!= (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs)
573f2ced752SOliver Tappe{
574f2ced752SOliver Tappe  return (lhs.compare (rhs) != 0);
575f2ced752SOliver Tappe}
576f2ced752SOliver Tappe
577f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
578f2ced752SOliver Tappeinline bool
579f2ced752SOliver Tappeoperator< (const basic_string <charT, traits, Allocator>& lhs,
580f2ced752SOliver Tappe	    const basic_string <charT, traits, Allocator>& rhs)
581f2ced752SOliver Tappe{
582f2ced752SOliver Tappe  return (lhs.compare (rhs) < 0);
583f2ced752SOliver Tappe}
584f2ced752SOliver Tappe
585f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
586f2ced752SOliver Tappeinline bool
587f2ced752SOliver Tappeoperator< (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs)
588f2ced752SOliver Tappe{
589f2ced752SOliver Tappe  return (rhs.compare (lhs) > 0);
590f2ced752SOliver Tappe}
591f2ced752SOliver Tappe
592f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
593f2ced752SOliver Tappeinline bool
594f2ced752SOliver Tappeoperator< (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs)
595f2ced752SOliver Tappe{
596f2ced752SOliver Tappe  return (lhs.compare (rhs) < 0);
597f2ced752SOliver Tappe}
598f2ced752SOliver Tappe
599f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
600f2ced752SOliver Tappeinline bool
601f2ced752SOliver Tappeoperator> (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs)
602f2ced752SOliver Tappe{
603f2ced752SOliver Tappe  return (rhs.compare (lhs) < 0);
604f2ced752SOliver Tappe}
605f2ced752SOliver Tappe
606f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
607f2ced752SOliver Tappeinline bool
608f2ced752SOliver Tappeoperator> (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs)
609f2ced752SOliver Tappe{
610f2ced752SOliver Tappe  return (lhs.compare (rhs) > 0);
611f2ced752SOliver Tappe}
612f2ced752SOliver Tappe
613f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
614f2ced752SOliver Tappeinline bool
615f2ced752SOliver Tappeoperator<= (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs)
616f2ced752SOliver Tappe{
617f2ced752SOliver Tappe  return (rhs.compare (lhs) >= 0);
618f2ced752SOliver Tappe}
619f2ced752SOliver Tappe
620f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
621f2ced752SOliver Tappeinline bool
622f2ced752SOliver Tappeoperator<= (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs)
623f2ced752SOliver Tappe{
624f2ced752SOliver Tappe  return (lhs.compare (rhs) <= 0);
625f2ced752SOliver Tappe}
626f2ced752SOliver Tappe
627f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
628f2ced752SOliver Tappeinline bool
629f2ced752SOliver Tappeoperator>= (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs)
630f2ced752SOliver Tappe{
631f2ced752SOliver Tappe  return (rhs.compare (lhs) <= 0);
632f2ced752SOliver Tappe}
633f2ced752SOliver Tappe
634f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
635f2ced752SOliver Tappeinline bool
636f2ced752SOliver Tappeoperator>= (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs)
637f2ced752SOliver Tappe{
638f2ced752SOliver Tappe  return (lhs.compare (rhs) >= 0);
639f2ced752SOliver Tappe}
640f2ced752SOliver Tappe
641f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
642f2ced752SOliver Tappeinline bool
643f2ced752SOliver Tappeoperator!= (const basic_string <charT, traits, Allocator>& lhs,
644f2ced752SOliver Tappe	    const basic_string <charT, traits, Allocator>& rhs)
645f2ced752SOliver Tappe{
646f2ced752SOliver Tappe  return (lhs.compare (rhs) != 0);
647f2ced752SOliver Tappe}
648f2ced752SOliver Tappe
649f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
650f2ced752SOliver Tappeinline bool
651f2ced752SOliver Tappeoperator> (const basic_string <charT, traits, Allocator>& lhs,
652f2ced752SOliver Tappe	   const basic_string <charT, traits, Allocator>& rhs)
653f2ced752SOliver Tappe{
654f2ced752SOliver Tappe  return (lhs.compare (rhs) > 0);
655f2ced752SOliver Tappe}
656f2ced752SOliver Tappe
657f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
658f2ced752SOliver Tappeinline bool
659f2ced752SOliver Tappeoperator<= (const basic_string <charT, traits, Allocator>& lhs,
660f2ced752SOliver Tappe	    const basic_string <charT, traits, Allocator>& rhs)
661f2ced752SOliver Tappe{
662f2ced752SOliver Tappe  return (lhs.compare (rhs) <= 0);
663f2ced752SOliver Tappe}
664f2ced752SOliver Tappe
665f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator>
666f2ced752SOliver Tappeinline bool
667f2ced752SOliver Tappeoperator>= (const basic_string <charT, traits, Allocator>& lhs,
668f2ced752SOliver Tappe	    const basic_string <charT, traits, Allocator>& rhs)
669f2ced752SOliver Tappe{
670f2ced752SOliver Tappe  return (lhs.compare (rhs) >= 0);
671f2ced752SOliver Tappe}
672f2ced752SOliver Tappe
673f2ced752SOliver Tappeclass istream; class ostream;
674f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator> istream&
675f2ced752SOliver Tappeoperator>> (istream&, basic_string <charT, traits, Allocator>&);
676f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator> ostream&
677f2ced752SOliver Tappeoperator<< (ostream&, const basic_string <charT, traits, Allocator>&);
678f2ced752SOliver Tappetemplate <class charT, class traits, class Allocator> istream&
679f2ced752SOliver Tappegetline (istream&, basic_string <charT, traits, Allocator>&, charT delim = '\n');
680f2ced752SOliver Tappe
681f2ced752SOliver Tappe} // extern "C++"
682f2ced752SOliver Tappe
683f2ced752SOliver Tappe#include <std/bastring.cc>
684f2ced752SOliver Tappe
685f2ced752SOliver Tappe#endif
686