diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-08-21 22:57:35 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-08-21 22:57:35 +0000 |
commit | 28e9041cc224267271fbcd8db22bea115912365b (patch) | |
tree | a3b19970338bdae580faff126a716e1d5520400c /libstdc++/std/bastring.cc | |
parent | 5000a677980ebfb439f5349c5e269f7447dbab41 (diff) | |
download | gcc-28e9041cc224267271fbcd8db22bea115912365b.tar.gz |
Initial revision
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@14877 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++/std/bastring.cc')
-rw-r--r-- | libstdc++/std/bastring.cc | 514 |
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++" |