aboutsummaryrefslogtreecommitdiff
path: root/libstdc++/std/bastring.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++/std/bastring.cc')
-rw-r--r--libstdc++/std/bastring.cc514
1 files changed, 514 insertions, 0 deletions
diff --git a/libstdc++/std/bastring.cc b/libstdc++/std/bastring.cc
new file mode 100644
index 00000000000..155656ae5d0
--- /dev/null
+++ b/libstdc++/std/bastring.cc
@@ -0,0 +1,514 @@
+// Member templates for the -*- C++ -*- string classes.
+// Copyright (C) 1994 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Jason Merrill based upon the specification by Takanori Adachi
+// in ANSI X3J16/94-0013R2.
+
+#include <cstddef>
+#include <std/bastring.h>
+
+extern "C++" {
+template <class charT, class traits>
+inline void * basic_string <charT, traits>::Rep::
+operator new (size_t s, size_t extra)
+{
+ return ::operator new (s + extra * sizeof (charT));
+}
+
+template <class charT, class traits>
+inline size_t basic_string <charT, traits>::Rep::
+#if _G_ALLOC_CONTROL
+default_frob (size_t s)
+#else
+frob_size (size_t s)
+#endif
+{
+ size_t i = 16;
+ while (i < s) i *= 2;
+ return i;
+}
+
+template <class charT, class traits>
+inline basic_string <charT, traits>::Rep * basic_string <charT, traits>::Rep::
+create (size_t extra)
+{
+ extra = frob_size (extra + 1);
+ Rep *p = new (extra) Rep;
+ p->res = extra;
+ p->ref = 1;
+ p->selfish = false;
+ return p;
+}
+
+template <class charT, class traits>
+charT * basic_string <charT, traits>::Rep::
+clone ()
+{
+ Rep *p = Rep::create (len);
+ p->copy (0, data (), len);
+ p->len = len;
+ return p->data ();
+}
+
+template <class charT, class traits>
+inline bool basic_string <charT, traits>::Rep::
+#ifdef _G_ALLOC_CONTROL
+default_excess (size_t s, size_t r)
+#else
+excess_slop (size_t s, size_t r)
+#endif
+{
+ return 2 * (s <= 16 ? 16 : s) < r;
+}
+
+template <class charT, class traits>
+inline bool basic_string <charT, traits>::
+check_realloc (size_t s) const
+{
+ s += sizeof (charT);
+ return (rep ()->ref > 1
+ || s > capacity ()
+ || Rep::excess_slop (s, capacity ()));
+}
+
+template <class charT, class traits>
+void basic_string <charT, traits>::
+alloc (size_t size, bool save)
+{
+ if (! check_realloc (size))
+ return;
+
+ Rep *p = Rep::create (size);
+
+ if (save)
+ {
+ p->copy (0, data (), length ());
+ p->len = length ();
+ }
+ else
+ p->len = 0;
+
+ repup (p);
+}
+
+template <class charT, class traits>
+basic_string <charT, traits>& basic_string <charT, traits>::
+replace (size_t pos1, size_t n1,
+ const basic_string& str, size_t pos2, size_t n2)
+{
+ const size_t len2 = str.length ();
+
+ if (pos1 == 0 && n1 >= length () && pos2 == 0 && n2 >= len2)
+ return operator= (str);
+
+ OUTOFRANGE (pos2 > len2);
+
+ if (n2 > len2 - pos2)
+ n2 = len2 - pos2;
+
+ return replace (pos1, n1, str.data () + pos2, n2);
+}
+
+template <class charT, class traits>
+inline void basic_string <charT, traits>::Rep::
+copy (size_t pos, const charT *s, size_t n)
+{
+ if (n)
+ traits::copy (data () + pos, s, n);
+}
+
+template <class charT, class traits>
+inline void basic_string <charT, traits>::Rep::
+move (size_t pos, const charT *s, size_t n)
+{
+ if (n)
+ traits::move (data () + pos, s, n);
+}
+
+template <class charT, class traits>
+basic_string <charT, traits>& basic_string <charT, traits>::
+replace (size_t pos, size_t n1, const charT* s, size_t n2)
+{
+ const size_t len = length ();
+ OUTOFRANGE (pos > len);
+ if (n1 > len - pos)
+ n1 = len - pos;
+ LENGTHERROR (len - n1 > max_size () - n2);
+ size_t newlen = len - n1 + n2;
+
+ if (check_realloc (newlen))
+ {
+ Rep *p = Rep::create (newlen);
+ p->copy (0, data (), pos);
+ p->copy (pos + n2, data () + pos + n1, len - (pos + n1));
+ p->copy (pos, s, n2);
+ repup (p);
+ }
+ else
+ {
+ rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1));
+ rep ()->copy (pos, s, n2);
+ }
+ rep ()->len = newlen;
+
+ return *this;
+}
+
+template <class charT, class traits>
+inline void basic_string <charT, traits>::Rep::
+set (size_t pos, const charT c, size_t n)
+{
+ traits::set (data () + pos, c, n);
+}
+
+template <class charT, class traits>
+basic_string <charT, traits>& basic_string <charT, traits>::
+replace (size_t pos, size_t n1, size_t n2, charT c)
+{
+ const size_t len = length ();
+ OUTOFRANGE (pos > len);
+ if (n1 > len - pos)
+ n1 = len - pos;
+ LENGTHERROR (len - n1 > max_size () - n2);
+ size_t newlen = len - n1 + n2;
+
+ if (check_realloc (newlen))
+ {
+ Rep *p = Rep::create (newlen);
+ p->copy (0, data (), pos);
+ p->copy (pos + n2, data () + pos + n1, len - (pos + n1));
+ p->set (pos, c, n2);
+ repup (p);
+ }
+ else
+ {
+ rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1));
+ rep ()->set (pos, c, n2);
+ }
+ rep ()->len = newlen;
+
+ return *this;
+}
+
+template <class charT, class traits>
+void basic_string <charT, traits>::
+resize (size_t n, charT c)
+{
+ LENGTHERROR (n > max_size ());
+
+ if (n > length ())
+ append (n - length (), c);
+ else
+ remove (n);
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+copy (charT* s, size_t n, size_t pos)
+{
+ OUTOFRANGE (pos > length ());
+
+ if (n > length () - pos)
+ n = length () - pos;
+
+ traits::copy (s, data () + pos, n);
+ return n;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find (const charT* s, size_t pos, size_t n) const
+{
+ size_t xpos = pos;
+ for (; xpos + n <= length (); ++xpos)
+ if (traits::eq (data () [xpos], *s)
+ && traits::compare (data () + xpos, s, n) == 0)
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+inline size_t basic_string <charT, traits>::
+_find (const charT* ptr, charT c, size_t xpos, size_t len)
+{
+ for (; xpos < len; ++xpos)
+ if (traits::eq (ptr [xpos], c))
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find (charT c, size_t pos) const
+{
+ return _find (data (), c, pos, length ());
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+rfind (const charT* s, size_t pos, size_t n) const
+{
+ if (n > length ())
+ return npos;
+
+ size_t xpos = length () - n;
+ if (xpos > pos)
+ xpos = pos;
+
+ for (++xpos; xpos-- > 0; )
+ if (traits::eq (data () [xpos], *s)
+ && traits::compare (data () + xpos, s, n) == 0)
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+rfind (charT c, size_t pos) const
+{
+ if (1 > length ())
+ return npos;
+
+ size_t xpos = length () - 1;
+ if (xpos > pos)
+ xpos = pos;
+
+ for (++xpos; xpos-- > 0; )
+ if (traits::eq (data () [xpos], c))
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find_first_of (const charT* s, size_t pos, size_t n) const
+{
+ size_t xpos = pos;
+ for (; xpos < length (); ++xpos)
+ if (_find (s, data () [xpos], 0, n) != npos)
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find_last_of (const charT* s, size_t pos, size_t n) const
+{
+ size_t xpos = length () - 1;
+ if (xpos > pos)
+ xpos = pos;
+ for (; xpos; --xpos)
+ if (_find (s, data () [xpos], 0, n) != npos)
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find_first_not_of (const charT* s, size_t pos, size_t n) const
+{
+ size_t xpos = pos;
+ for (; xpos < length (); ++xpos)
+ if (_find (s, data () [xpos], 0, n) == npos)
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find_first_not_of (charT c, size_t pos) const
+{
+ size_t xpos = pos;
+ for (; xpos < length (); ++xpos)
+ if (traits::ne (data () [xpos], c))
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find_last_not_of (const charT* s, size_t pos, size_t n) const
+{
+ size_t xpos = length () - 1;
+ if (xpos > pos)
+ xpos = pos;
+ for (; xpos; --xpos)
+ if (_find (s, data () [xpos], 0, n) == npos)
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find_last_not_of (charT c, size_t pos) const
+{
+ size_t xpos = length () - 1;
+ if (xpos > pos)
+ xpos = pos;
+ for (; xpos; --xpos)
+ if (traits::ne (data () [xpos], c))
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+int basic_string <charT, traits>::
+compare (const basic_string& str, size_t pos, size_t n) const
+{
+ OUTOFRANGE (pos > length ());
+
+ size_t rlen = length () - pos;
+ if (rlen > n)
+ rlen = n;
+ if (rlen > str.length ())
+ rlen = str.length ();
+ int r = traits::compare (data () + pos, str.data (), rlen);
+ if (r != 0)
+ return r;
+ if (rlen == n)
+ return 0;
+ return (length () - pos) - str.length ();
+}
+
+template <class charT, class traits>
+int basic_string <charT, traits>::
+compare (const charT* s, size_t pos, size_t n) const
+{
+ OUTOFRANGE (pos > length ());
+
+ size_t rlen = length () - pos;
+ if (rlen > n)
+ rlen = n;
+ int r = traits::compare (data () + pos, s, rlen);
+ if (r != 0)
+ return r;
+ return (length () - pos) - n;
+}
+
+#include <iostream.h>
+
+template <class charT, class traits>
+istream &
+operator>> (istream &is, basic_string <charT, traits> &s)
+{
+ int w = is.width (0);
+ if (is.ipfx0 ())
+ {
+ register streambuf *sb = is.rdbuf ();
+ s.resize (0);
+ while (1)
+ {
+ int ch = sb->sbumpc ();
+ if (ch == EOF)
+ {
+ is.setstate (ios::eofbit);
+ break;
+ }
+ else if (traits::is_del (ch))
+ {
+ sb->sungetc ();
+ break;
+ }
+ s += ch;
+ if (--w == 1)
+ break;
+ }
+ }
+
+ is.isfx ();
+ if (s.length () == 0)
+ is.setstate (ios::failbit);
+
+ return is;
+}
+
+template <class charT, class traits>
+ostream &
+operator<< (ostream &o, const basic_string <charT, traits>& s)
+{
+ return o.write (s.data (), s.length ());
+}
+
+template <class charT, class traits>
+istream&
+getline (istream &is, basic_string <charT, traits>& s, charT delim)
+{
+ if (is.ipfx1 ())
+ {
+ _IO_size_t count = 0;
+ streambuf *sb = is.rdbuf ();
+ s.resize (0);
+
+ while (1)
+ {
+ int ch = sb->sbumpc ();
+ if (ch == EOF)
+ {
+ is.setstate (count == 0
+ ? (ios::failbit|ios::eofbit)
+ : ios::eofbit);
+ break;
+ }
+
+ ++count;
+
+ if (ch == delim)
+ break;
+
+ s += ch;
+
+ if (s.length () == s.npos - 1)
+ {
+ is.setstate (ios::failbit);
+ break;
+ }
+ }
+ }
+
+ // We need to be friends with istream to do this.
+ // is._gcount = count;
+ is.isfx ();
+
+ return is;
+}
+
+template <class charT, class traits>
+basic_string <charT, traits>::Rep
+basic_string<charT, traits>::nilRep = { 0, 0, 1 };
+
+template <class charT, class traits>
+const basic_string <charT, traits>::size_type
+basic_string <charT, traits>::npos;
+
+#ifdef _G_ALLOC_CONTROL
+template <class charT, class traits>
+bool (*basic_string <charT, traits>::Rep::excess_slop) (size_t, size_t)
+ = basic_string <charT, traits>::Rep::default_excess;
+
+template <class charT, class traits>
+size_t (*basic_string <charT, traits>::Rep::frob_size) (size_t)
+ = basic_string <charT, traits>::Rep::default_frob;
+#endif
+
+} // extern "C++"