bastring.cc
上传用户:sichengcw
上传日期:2009-02-17
资源大小:202k
文件大小:13k
源码类别:

STL

开发平台:

Visual C++

  1. // Member templates for the -*- C++ -*- string classes.
  2. // Copyright (C) 1994 Free Software Foundation
  3. // This file is part of the GNU ANSI C++ Library.  This library is free
  4. // software; you can redistribute it and/or modify it under the
  5. // terms of the GNU General Public License as published by the
  6. // Free Software Foundation; either version 2, or (at your option)
  7. // any later version.
  8. // This library is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. // GNU General Public License for more details.
  12. // You should have received a copy of the GNU General Public License
  13. // along with this library; see the file COPYING.  If not, write to the Free
  14. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  15. // As a special exception, if you link this library with files
  16. // compiled with a GNU compiler to produce an executable, this does not cause
  17. // the resulting executable to be covered by the GNU General Public License.
  18. // This exception does not however invalidate any other reasons why
  19. // the executable file might be covered by the GNU General Public License.
  20. // Written by Jason Merrill based upon the specification by Takanori Adachi
  21. // in ANSI X3J16/94-0013R2.
  22. extern "C++" {
  23. template <class charT, class traits, class Allocator>
  24. inline void * basic_string <charT, traits, Allocator>::Rep::
  25. operator new (size_t s, size_t extra)
  26. {
  27.   return Allocator::allocate(s + extra * sizeof (charT));
  28. }
  29. template <class charT, class traits, class Allocator>
  30. inline void basic_string <charT, traits, Allocator>::Rep::
  31. operator delete (void * ptr)
  32. {
  33.   Allocator::deallocate(ptr, sizeof(Rep) +
  34. reinterpret_cast<Rep *>(ptr)->res *
  35. sizeof (charT)); 
  36. }
  37. template <class charT, class traits, class Allocator>
  38. inline size_t basic_string <charT, traits, Allocator>::Rep::
  39. frob_size (size_t s)
  40. {
  41.   size_t i = 16;
  42.   while (i < s) i *= 2;
  43.   return i;
  44. }
  45. template <class charT, class traits, class Allocator>
  46. inline basic_string <charT, traits, Allocator>::Rep *
  47. basic_string <charT, traits, Allocator>::Rep::
  48. create (size_t extra)
  49. {
  50.   extra = frob_size (extra + 1);
  51.   Rep *p = new (extra) Rep;
  52.   p->res = extra;
  53.   p->ref = 1;
  54.   p->selfish = false;
  55.   return p;
  56. }
  57. template <class charT, class traits, class Allocator>
  58. charT * basic_string <charT, traits, Allocator>::Rep::
  59. clone ()
  60. {
  61.   Rep *p = Rep::create (len);
  62.   p->copy (0, data (), len);
  63.   p->len = len;
  64.   return p->data ();
  65. }
  66. template <class charT, class traits, class Allocator>
  67. inline bool basic_string <charT, traits, Allocator>::Rep::
  68. excess_slop (size_t s, size_t r)
  69. {
  70.   return 2 * (s <= 16 ? 16 : s) < r;
  71. }
  72. template <class charT, class traits, class Allocator>
  73. inline bool basic_string <charT, traits, Allocator>::
  74. check_realloc (basic_string::size_type s) const
  75. {
  76.   s += sizeof (charT);
  77.   rep ()->selfish = false;
  78.   return (rep ()->ref > 1
  79.   || s > capacity ()
  80.   || Rep::excess_slop (s, capacity ()));
  81. }
  82. template <class charT, class traits, class Allocator>
  83. void basic_string <charT, traits, Allocator>::
  84. alloc (basic_string::size_type size, bool save)
  85. {
  86.   if (! check_realloc (size))
  87.     return;
  88.   Rep *p = Rep::create (size);
  89.   if (save)
  90.     {
  91.       p->copy (0, data (), length ());
  92.       p->len = length ();
  93.     }
  94.   else
  95.     p->len = 0;
  96.   repup (p);
  97. }
  98. template <class charT, class traits, class Allocator>
  99. basic_string <charT, traits, Allocator>&
  100. basic_string <charT, traits, Allocator>::
  101. replace (size_type pos1, size_type n1,
  102.  const basic_string& str, size_type pos2, size_type n2)
  103. {
  104.   const size_t len2 = str.length ();
  105.   if (pos1 == 0 && n1 >= length () && pos2 == 0 && n2 >= len2)
  106.     return operator= (str);
  107.   OUTOFRANGE (pos2 > len2);
  108.   if (n2 > len2 - pos2)
  109.     n2 = len2 - pos2;
  110.   return replace (pos1, n1, str.data () + pos2, n2);
  111. }
  112. template <class charT, class traits, class Allocator>
  113. inline void basic_string <charT, traits, Allocator>::Rep::
  114. copy (size_t pos, const charT *s, size_t n)
  115. {
  116.   if (n)
  117.     traits::copy (data () + pos, s, n);
  118. }
  119. template <class charT, class traits, class Allocator>
  120. inline void basic_string <charT, traits, Allocator>::Rep::
  121. move (size_t pos, const charT *s, size_t n)
  122. {
  123.   if (n)
  124.     traits::move (data () + pos, s, n);
  125. }
  126. template <class charT, class traits, class Allocator>
  127. basic_string <charT, traits, Allocator>&
  128. basic_string <charT, traits, Allocator>::
  129. replace (size_type pos, size_type n1, const charT* s, size_type n2)
  130. {
  131.   const size_type len = length ();
  132.   OUTOFRANGE (pos > len);
  133.   if (n1 > len - pos)
  134.     n1 = len - pos;
  135.   LENGTHERROR (len - n1 > max_size () - n2);
  136.   size_t newlen = len - n1 + n2;
  137.   if (check_realloc (newlen))
  138.     {
  139.       Rep *p = Rep::create (newlen);
  140.       p->copy (0, data (), pos);
  141.       p->copy (pos + n2, data () + pos + n1, len - (pos + n1));
  142.       p->copy (pos, s, n2);
  143.       repup (p);
  144.     }
  145.   else
  146.     {
  147.       rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1));
  148.       rep ()->copy (pos, s, n2);
  149.     }
  150.   rep ()->len = newlen;
  151.   return *this;
  152. }
  153. template <class charT, class traits, class Allocator>
  154. inline void basic_string <charT, traits, Allocator>::Rep::
  155. set (size_t pos, const charT c, size_t n)
  156. {
  157.   traits::set  (data () + pos, c, n);
  158. }
  159. template <class charT, class traits, class Allocator>
  160. basic_string <charT, traits, Allocator>& basic_string <charT, traits, Allocator>::
  161. replace (size_type pos, size_type n1, size_type n2, charT c)
  162. {
  163.   const size_t len = length ();
  164.   OUTOFRANGE (pos > len);
  165.   if (n1 > len - pos)
  166.     n1 = len - pos;
  167.   LENGTHERROR (len - n1 > max_size () - n2);
  168.   size_t newlen = len - n1 + n2;
  169.   if (check_realloc (newlen))
  170.     {
  171.       Rep *p = Rep::create (newlen);
  172.       p->copy (0, data (), pos);
  173.       p->copy (pos + n2, data () + pos + n1, len - (pos + n1));
  174.       p->set  (pos, c, n2);
  175.       repup (p);
  176.     }
  177.   else
  178.     {
  179.       rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1));
  180.       rep ()->set  (pos, c, n2);
  181.     }
  182.   rep ()->len = newlen;
  183.   return *this;
  184. }
  185. template <class charT, class traits, class Allocator>
  186. void basic_string <charT, traits, Allocator>::
  187. resize (size_type n, charT c)
  188. {
  189.   LENGTHERROR (n > max_size ());
  190.   if (n > length ())
  191.     append (n - length (), c);
  192.   else
  193.     erase (n);
  194. }
  195. template <class charT, class traits, class Allocator>
  196. basic_string <charT, traits, Allocator>::size_type
  197. basic_string <charT, traits, Allocator>::
  198. copy (charT* s, size_type n, size_type pos) const
  199. {
  200.   OUTOFRANGE (pos > length ());
  201.   if (n > length () - pos)
  202.     n = length () - pos;
  203.   traits::copy (s, data () + pos, n);
  204.   return n;
  205. }
  206. template <class charT, class traits, class Allocator>
  207. basic_string <charT, traits, Allocator>::size_type
  208. basic_string <charT, traits, Allocator>::
  209. find (const charT* s, size_type pos, size_type n) const
  210. {
  211.   size_t xpos = pos;
  212.   for (; xpos + n <= length (); ++xpos)
  213.     if (traits::eq (data () [xpos], *s)
  214. && traits::compare (data () + xpos, s, n) == 0)
  215.       return xpos;
  216.   return npos;
  217. }
  218. template <class charT, class traits, class Allocator>
  219. inline basic_string <charT, traits, Allocator>::size_type
  220. basic_string <charT, traits, Allocator>::
  221. _find (const charT* ptr, charT c, size_type xpos, size_type len)
  222. {
  223.   for (; xpos < len; ++xpos)
  224.     if (traits::eq (ptr [xpos], c))
  225.       return xpos;
  226.   return npos;
  227. }
  228. template <class charT, class traits, class Allocator>
  229. basic_string <charT, traits, Allocator>::size_type
  230. basic_string <charT, traits, Allocator>::
  231. find (charT c, size_type pos) const
  232. {
  233.   return _find (data (), c, pos, length ());
  234. }
  235. template <class charT, class traits, class Allocator>
  236. basic_string <charT, traits, Allocator>::size_type
  237. basic_string <charT, traits, Allocator>::
  238. rfind (const charT* s, size_type pos, size_type n) const
  239. {
  240.   if (n > length ())
  241.     return npos;
  242.   size_t xpos = length () - n;
  243.   if (xpos > pos)
  244.     xpos = pos;
  245.   for (++xpos; xpos-- > 0; )
  246.     if (traits::eq (data () [xpos], *s)
  247. && traits::compare (data () + xpos, s, n) == 0)
  248.       return xpos;
  249.   return npos;
  250. }
  251. template <class charT, class traits, class Allocator>
  252. basic_string <charT, traits, Allocator>::size_type
  253. basic_string <charT, traits, Allocator>::
  254. rfind (charT c, size_type pos) const
  255. {
  256.   if (1 > length ())
  257.     return npos;
  258.   size_t xpos = length () - 1;
  259.   if (xpos > pos)
  260.     xpos = pos;
  261.   for (++xpos; xpos-- > 0; )
  262.     if (traits::eq (data () [xpos], c))
  263.       return xpos;
  264.   return npos;
  265. }
  266. template <class charT, class traits, class Allocator>
  267. basic_string <charT, traits, Allocator>::size_type
  268. basic_string <charT, traits, Allocator>::
  269. find_first_of (const charT* s, size_type pos, size_type n) const
  270. {
  271.   size_t xpos = pos;
  272.   for (; xpos < length (); ++xpos)
  273.     if (_find (s, data () [xpos], 0, n) != npos)
  274.       return xpos;
  275.   return npos;
  276. }
  277. template <class charT, class traits, class Allocator>
  278. basic_string <charT, traits, Allocator>::size_type
  279. basic_string <charT, traits, Allocator>::
  280. find_last_of (const charT* s, size_type pos, size_type n) const
  281. {
  282.   if (length() == 0)
  283.     return npos;
  284.   size_t xpos = length () - 1;
  285.   if (xpos > pos)
  286.     xpos = pos;
  287.   for (++xpos; xpos-- > 0;)
  288.     if (_find (s, data () [xpos], 0, n) != npos)
  289.       return xpos;
  290.   return npos;
  291. }
  292. template <class charT, class traits, class Allocator>
  293. basic_string <charT, traits, Allocator>::size_type
  294. basic_string <charT, traits, Allocator>::
  295. find_first_not_of (const charT* s, size_type pos, size_type n) const
  296. {
  297.   size_t xpos = pos;
  298.   for (; xpos < length (); ++xpos)
  299.     if (_find (s, data () [xpos], 0, n) == npos)
  300.       return xpos;
  301.   return npos;
  302. }
  303. template <class charT, class traits, class Allocator>
  304. basic_string <charT, traits, Allocator>::size_type
  305. basic_string <charT, traits, Allocator>::
  306. find_first_not_of (charT c, size_type pos) const
  307. {
  308.   size_t xpos = pos;
  309.   for (; xpos < length (); ++xpos)
  310.     if (traits::ne (data () [xpos], c))
  311.       return xpos;
  312.   return npos;
  313. }
  314. template <class charT, class traits, class Allocator>
  315. basic_string <charT, traits, Allocator>::size_type
  316. basic_string <charT, traits, Allocator>::
  317. find_last_not_of (const charT* s, size_type pos, size_type n) const
  318. {
  319.   if (length() == 0)
  320.     return npos;
  321.   size_t xpos = length () - 1;
  322.   if (xpos > pos)
  323.     xpos = pos;
  324.   for (++xpos; xpos-- > 0;)
  325.     if (_find (s, data () [xpos], 0, n) == npos)
  326.       return xpos;
  327.   return npos;
  328. }
  329. template <class charT, class traits, class Allocator>
  330. basic_string <charT, traits, Allocator>::size_type
  331. basic_string <charT, traits, Allocator>::
  332. find_last_not_of (charT c, size_type pos) const
  333. {
  334.   if (length() == 0)
  335.     return npos;
  336.   size_t xpos = length () - 1;
  337.   if (xpos > pos)
  338.     xpos = pos;
  339.   for (++xpos; xpos-- > 0;)
  340.     if (traits::ne (data () [xpos], c))
  341.       return xpos;
  342.   return npos;
  343. }
  344. template <class charT, class traits, class Allocator>
  345. int basic_string <charT, traits, Allocator>::
  346. compare (const basic_string& str, size_type pos, size_type n) const
  347. {
  348.   OUTOFRANGE (pos > length ());
  349.   size_t rlen = length () - pos;
  350.   if (rlen > n)
  351.     rlen = n;
  352.   if (rlen > str.length ())
  353.     rlen = str.length ();
  354.   int r = traits::compare (data () + pos, str.data (), rlen);
  355.   if (r != 0)
  356.     return r;
  357.   if (rlen == n)
  358.     return 0;
  359.   return (length () - pos) - str.length ();
  360. }
  361. template <class charT, class traits, class Allocator>
  362. int basic_string <charT, traits, Allocator>::
  363. compare (const charT* s, size_type pos, size_type n) const
  364. {
  365.   OUTOFRANGE (pos > length ());
  366.   size_t rlen = length () - pos;
  367.   if (rlen > n)
  368.     rlen = n;
  369.   int r = traits::compare (data () + pos, s, rlen);
  370.   if (r != 0)
  371.     return r;
  372.   return (length () - pos) - n;
  373. }
  374. #include <iostream.h>
  375. template <class charT, class traits, class Allocator>
  376. istream &
  377. operator>> (istream &is, basic_string <charT, traits, Allocator> &s)
  378. {
  379.   int w = is.width (0);
  380.   if (is.ipfx0 ())
  381.     {
  382.       register streambuf *sb = is.rdbuf ();
  383.       s.resize (0);
  384.       while (1)
  385. {
  386.   int ch = sb->sbumpc ();
  387.   if (ch == EOF)
  388.     {
  389.       is.setstate (ios::eofbit);
  390.       break;
  391.     }
  392.   else if (traits::is_del (ch))
  393.     {
  394.       sb->sungetc ();
  395.       break;
  396.     }
  397.   s += ch;
  398.   if (--w == 1)
  399.     break;
  400. }
  401.     }
  402.   is.isfx ();
  403.   if (s.length () == 0)
  404.     is.setstate (ios::failbit);
  405.   return is;
  406. }
  407. template <class charT, class traits, class Allocator>
  408. ostream &
  409. operator<< (ostream &o, const basic_string <charT, traits, Allocator>& s)
  410. {
  411.   return o.write (s.data (), s.length ());
  412. }
  413. template <class charT, class traits, class Allocator>
  414. istream&
  415. getline (istream &is, basic_string <charT, traits, Allocator>& s, charT delim)
  416. {
  417.   if (is.ipfx1 ())
  418.     {
  419.       _IO_size_t count = 0;
  420.       streambuf *sb = is.rdbuf ();
  421.       s.resize (0);
  422.       while (1)
  423. {
  424.   int ch = sb->sbumpc ();
  425.   if (ch == EOF)
  426.     {
  427.       is.setstate (count == 0
  428.    ? (ios::failbit|ios::eofbit)
  429.    : ios::eofbit);
  430.       break;
  431.     }
  432.   ++count;
  433.   if (ch == delim)
  434.     break;
  435.   s += ch;
  436.   if (s.length () == s.npos - 1)
  437.     {
  438.       is.setstate (ios::failbit);
  439.       break;
  440.     }
  441. }
  442.     }
  443.   // We need to be friends with istream to do this.
  444.   // is._gcount = count;
  445.   is.isfx ();
  446.   return is;
  447. }
  448. template <class charT, class traits, class Allocator>
  449. basic_string <charT, traits, Allocator>::Rep
  450. basic_string<charT, traits, Allocator>::nilRep = { 0, 0, 1, false };
  451. template <class charT, class traits, class Allocator>
  452. const basic_string <charT, traits, Allocator>::size_type
  453. basic_string <charT, traits, Allocator>::npos;
  454. } // extern "C++"