home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / libg++-2.7.1-bin.lha / lib / g++-include / std / bastring.cc next >
C/C++ Source or Header  |  1996-10-12  |  11KB  |  484 lines

  1. // Member templates for the -*- C++ -*- string classes.
  2. // Copyright (C) 1994 Free Software Foundation
  3.  
  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.
  9.  
  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.
  14.  
  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.
  18.  
  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.
  24.  
  25. // Written by Jason Merrill based upon the specification by Takanori Adachi
  26. // in ANSI X3J16/94-0013R2.
  27.  
  28. #include <std/stddef.h>
  29. #include <std/bastring.h>
  30.  
  31. extern "C++" {
  32. template <class charT, class traits>
  33. inline void * __bsrep <charT, traits>::
  34. operator new (size_t s, size_t extra)
  35. {
  36.   return ::operator new (s + extra * sizeof (charT));
  37. }
  38.  
  39. template <class charT, class traits>
  40. inline size_t __bsrep <charT, traits>::
  41. #if _G_ALLOC_CONTROL
  42. default_frob (size_t s)
  43. #else
  44. frob_size (size_t s)
  45. #endif
  46. {
  47.   size_t i = 16;
  48.   while (i < s) i *= 2;
  49.   return i;
  50. }
  51.  
  52. template <class charT, class traits>
  53. inline __bsrep <charT, traits> * __bsrep <charT, traits>::
  54. create (size_t extra)
  55. {
  56.   extra = frob_size (extra + 1);
  57.   Rep *p = new (extra) Rep;
  58.   p->res = extra;
  59.   p->ref = 1;
  60.   p->selfish = false;
  61.   return p;
  62. }
  63.  
  64. template <class charT, class traits>
  65. charT * __bsrep <charT, traits>::
  66. clone ()
  67. {
  68.   Rep *p = Rep::create (len);
  69.   p->copy (0, data (), len);
  70.   p->len = len;
  71.   return p->data ();
  72. }
  73.  
  74. template <class charT, class traits>
  75. inline bool __bsrep <charT, traits>::
  76. #ifdef _G_ALLOC_CONTROL
  77. default_excess (size_t s, size_t r)
  78. #else
  79. excess_slop (size_t s, size_t r)
  80. #endif
  81. {
  82.   return 2 * (s <= 16 ? 16 : s) < r;
  83. }
  84.  
  85. template <class charT, class traits>
  86. inline bool basic_string <charT, traits>::
  87. check_realloc (size_t s) const
  88. {
  89.   ++s;
  90.   return (rep ()->ref > 1
  91.       || s > capacity ()
  92.       || Rep::excess_slop (s, capacity ()));
  93. }
  94.  
  95. template <class charT, class traits>
  96. void basic_string <charT, traits>::
  97. alloc (size_t size, bool save)
  98. {
  99.   if (! check_realloc (size))
  100.     return;
  101.  
  102.   Rep *p = Rep::create (size);
  103.  
  104.   if (save)
  105.     {
  106.       p->copy (0, data (), length ());
  107.       p->len = length ();
  108.     }
  109.   else
  110.     p->len = 0;
  111.  
  112.   repup (p);
  113. }
  114.  
  115. template <class charT, class traits>
  116. basic_string <charT, traits>& basic_string <charT, traits>::
  117. replace (size_t pos1, size_t n1,
  118.      const basic_string& str, size_t pos2, size_t n2)
  119. {
  120.   const size_t len2 = str.length ();
  121.  
  122.   if (pos1 == 0 && n1 >= length () && pos2 == 0 && n2 >= len2)
  123.     return operator= (str);
  124.  
  125.   OUTOFRANGE (pos2 > len2);
  126.  
  127.   if (n2 > len2 - pos2)
  128.     n2 = len2 - pos2;
  129.  
  130.   return replace (pos1, n1, str.data () + pos2, n2);
  131. }
  132.  
  133. template <class charT, class traits>
  134. inline void __bsrep <charT, traits>::
  135. copy (size_t pos, const charT *s, size_t n)
  136. {
  137.   if (n)
  138.     traits::copy (data () + pos, s, n);
  139. }
  140.  
  141. template <class charT, class traits>
  142. inline void __bsrep <charT, traits>::
  143. move (size_t pos, const charT *s, size_t n)
  144. {
  145.   if (n)
  146.     traits::move (data () + pos, s, n);
  147. }
  148.  
  149. template <class charT, class traits>
  150. basic_string <charT, traits>& basic_string <charT, traits>::
  151. replace (size_t pos, size_t n1, const charT* s, size_t n2)
  152. {
  153.   const size_t len = length ();
  154.   OUTOFRANGE (pos > len);
  155.   if (n1 > len - pos)
  156.     n1 = len - pos;
  157.   LENGTHERROR (len - n1 >= npos - n2);
  158.   size_t newlen = len - n1 + n2;
  159.  
  160.   if (check_realloc (newlen))
  161.     {
  162.       Rep *p = Rep::create (newlen);
  163.       p->copy (0, data (), pos);
  164.       p->copy (pos + n2, data () + pos + n1, len - (pos + n1));
  165.       p->copy (pos, s, n2);
  166.       repup (p);
  167.     }
  168.   else
  169.     {
  170.       rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1));
  171.       rep ()->copy (pos, s, n2);
  172.     }
  173.   rep ()->len = newlen;
  174.  
  175.   return *this;
  176. }
  177.  
  178. template <class charT, class traits>
  179. inline void __bsrep <charT, traits>::
  180. set (size_t pos, const charT c, size_t n)
  181. {
  182.   traits::set  (data () + pos, c, n);
  183. }
  184.  
  185. template <class charT, class traits>
  186. basic_string <charT, traits>& basic_string <charT, traits>::
  187. replace (size_t pos, size_t n1, size_t n2, charT c)
  188. {
  189.   const size_t len = length ();
  190.   OUTOFRANGE (pos > len);
  191.   if (n1 > len - pos)
  192.     n1 = len - pos;
  193.   LENGTHERROR (len - n1 >= npos - n2);
  194.   size_t newlen = len - n1 + n2;
  195.  
  196.   if (check_realloc (newlen))
  197.     {
  198.       Rep *p = Rep::create (newlen);
  199.       p->copy (0, data (), pos);
  200.       p->copy (pos + n2, data () + pos + n1, len - (pos + n1));
  201.       p->set  (pos, c, n2);
  202.       repup (p);
  203.     }
  204.   else
  205.     {
  206.       rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1));
  207.       rep ()->set  (pos, c, n2);
  208.     }
  209.   rep ()->len = newlen;
  210.  
  211.   return *this;
  212. }
  213.  
  214. template <class charT, class traits>
  215. void basic_string <charT, traits>::
  216. resize (size_t n, charT c)
  217. {
  218.   LENGTHERROR (n == npos);
  219.  
  220.   if (n > length ())
  221.     append (n - length (), c);
  222.   else
  223.     remove (n);
  224. }
  225.  
  226. template <class charT, class traits>
  227. size_t basic_string <charT, traits>::
  228. copy (charT* s, size_t n, size_t pos)
  229. {
  230.   OUTOFRANGE (pos > length ());
  231.  
  232.   if (n > length () - pos)
  233.     n = length () - pos;
  234.  
  235.   traits::copy (s, data () + pos, n);
  236.   return n;
  237. }
  238.  
  239. template <class charT, class traits>
  240. size_t basic_string <charT, traits>::
  241. find (const charT* s, size_t pos, size_t n) const
  242. {
  243.   size_t xpos = pos;
  244.   for (; xpos + n <= length (); ++xpos)
  245.     if (traits::eq (data () [xpos], *s)
  246.     && traits::compare (data () + xpos, s, n) == 0)
  247.       return xpos;
  248.   return npos;
  249. }
  250.  
  251. template <class charT, class traits>
  252. inline size_t basic_string <charT, traits>::
  253. _find (const charT* ptr, charT c, size_t xpos, size_t len)
  254. {
  255.   for (; xpos < len; ++xpos)
  256.     if (traits::eq (ptr [xpos], c))
  257.       return xpos;
  258.   return npos;
  259. }
  260.  
  261. template <class charT, class traits>
  262. size_t basic_string <charT, traits>::
  263. find (charT c, size_t pos) const
  264. {
  265.   return _find (data (), c, pos, length ());
  266. }
  267.  
  268. template <class charT, class traits>
  269. size_t basic_string <charT, traits>::
  270. rfind (const charT* s, size_t pos, size_t n) const
  271. {
  272.   size_t xpos = length () - n;
  273.   if (xpos > pos)
  274.     xpos = pos;
  275.  
  276.   for (++xpos; xpos-- > 0; )
  277.     if (traits::eq (data () [xpos], *s)
  278.     && traits::compare (data () + xpos, s, n) == 0)
  279.       return xpos;
  280.   return npos;
  281. }
  282.  
  283. template <class charT, class traits>
  284. size_t basic_string <charT, traits>::
  285. rfind (charT c, size_t pos) const
  286. {
  287.   size_t xpos = length () - 1;
  288.   if (xpos > pos)
  289.     xpos = pos;
  290.  
  291.   for (++xpos; xpos-- > 0; )
  292.     if (traits::eq (data () [xpos], c))
  293.       return xpos;
  294.   return npos;
  295. }
  296.  
  297. template <class charT, class traits>
  298. size_t basic_string <charT, traits>::
  299. find_first_of (const charT* s, size_t pos, size_t n) const
  300. {
  301.   size_t xpos = pos;
  302.   for (; xpos < length (); ++xpos)
  303.     if (_find (s, data () [xpos], 0, n) != npos)
  304.       return xpos;
  305.   return npos;
  306. }
  307.  
  308. template <class charT, class traits>
  309. size_t basic_string <charT, traits>::
  310. find_last_of (const charT* s, size_t pos, size_t n) const
  311. {
  312.   size_t xpos = length ();
  313.   for (; xpos-- > pos; )
  314.     if (_find (s, data () [xpos], 0, n) != npos)
  315.       return xpos;
  316.   return npos;
  317. }
  318.  
  319. template <class charT, class traits>
  320. size_t basic_string <charT, traits>::
  321. find_first_not_of (const charT* s, size_t pos, size_t n) const
  322. {
  323.   size_t xpos = pos;
  324.   for (; xpos < length (); ++xpos)
  325.     if (_find (s, data () [xpos], 0, n) == npos)
  326.       return xpos;
  327.   return npos;
  328. }
  329.  
  330. template <class charT, class traits>
  331. size_t basic_string <charT, traits>::
  332. find_first_not_of (charT c, size_t pos) const
  333. {
  334.   size_t xpos = pos;
  335.   for (; xpos < length (); ++xpos)
  336.     if (traits::ne (data () [xpos], c))
  337.       return xpos;
  338.   return npos;
  339. }
  340.  
  341. template <class charT, class traits>
  342. size_t basic_string <charT, traits>::
  343. find_last_not_of (const charT* s, size_t pos, size_t n) const
  344. {
  345.   size_t xpos = length ();
  346.   for (; xpos-- > pos; )
  347.     if (_find (s, data () [xpos], 0, n) == npos)
  348.       return xpos;
  349.   return npos;
  350. }
  351.  
  352. template <class charT, class traits>
  353. size_t basic_string <charT, traits>::
  354. find_last_not_of (charT c, size_t pos) const
  355. {
  356.   size_t xpos = length ();
  357.   for (; xpos-- > pos; )
  358.     if (traits::ne (data () [xpos], c))
  359.       return xpos;
  360.   return npos;
  361. }
  362.  
  363. template <class charT, class traits>
  364. int basic_string <charT, traits>::
  365. compare (const basic_string& str, size_t pos, size_t n) const
  366. {
  367.   OUTOFRANGE (pos > length ());
  368.  
  369.   size_t rlen = length () - pos;
  370.   if (rlen > n)
  371.     rlen = n;
  372.   if (rlen > str.length ())
  373.     rlen = str.length ();
  374.   int r = traits::compare (data () + pos, str.data (), rlen);
  375.   if (r != 0)
  376.     return r;
  377.   if (rlen == n)
  378.     return 0;
  379.   return (length () - pos) - str.length ();
  380. }
  381.  
  382. template <class charT, class traits>
  383. int basic_string <charT, traits>::
  384. compare (const charT* s, size_t pos, size_t n) const
  385. {
  386.   OUTOFRANGE (pos > length ());
  387.  
  388.   size_t rlen = length () - pos;
  389.   if (rlen > n)
  390.     rlen = n;
  391.   int r = traits::compare (data () + pos, s, rlen);
  392.   if (r != 0)
  393.     return r;
  394.   return (length () - pos) - n;
  395. }
  396.  
  397. #include <iostream.h>
  398.  
  399. template <class charT, class traits>
  400. istream &
  401. operator>> (istream &is, basic_string <charT, traits> &s)
  402. {
  403.   int w = is.width (0);
  404.   if (is.ipfx0 ())
  405.     {
  406.       register streambuf *sb = is.rdbuf ();
  407.       s.resize (0);
  408.       while (1)
  409.     {
  410.       int ch = sb->sbumpc ();
  411.       if (ch == EOF)
  412.         {
  413.           is.setstate (ios::eofbit);
  414.           break;
  415.         }
  416.       else if (traits::is_del (ch))
  417.         {
  418.           sb->sungetc ();
  419.           break;
  420.         }
  421.       s += ch;
  422.       if (--w == 1)
  423.         break;
  424.     }
  425.     }
  426.  
  427.   is.isfx ();
  428.   if (s.length () == 0)
  429.     is.setstate (ios::failbit);
  430.  
  431.   return is;
  432. }
  433.  
  434. template <class charT, class traits>
  435. ostream &
  436. operator<< (ostream &o, const basic_string <charT, traits>& s)
  437. {
  438.   return o.write (s.data (), s.length ());
  439. }
  440.  
  441. template <class charT, class traits>
  442. istream&
  443. getline (istream &is, basic_string <charT, traits>& s, charT delim)
  444. {
  445.   if (is.ipfx1 ())
  446.     {
  447.       _IO_size_t count = 0;
  448.       streambuf *sb = is.rdbuf ();
  449.       s.resize (0);
  450.  
  451.       while (1)
  452.     {
  453.       int ch = sb->sbumpc ();
  454.       if (ch == EOF)
  455.         {
  456.           is.setstate (count == 0
  457.                ? (ios::failbit|ios::eofbit)
  458.                : ios::eofbit);
  459.           break;
  460.         }
  461.  
  462.       ++count;
  463.  
  464.       if (ch == delim)
  465.         break;
  466.  
  467.       s += ch;
  468.  
  469.       if (s.length () == s.npos - 1)
  470.         {
  471.           is.setstate (ios::failbit);
  472.           break;
  473.         }
  474.     }
  475.     }
  476.  
  477.   // We need to be friends with istream to do this.
  478.   // is._gcount = count;
  479.   is.isfx ();
  480.  
  481.   return is;
  482. }
  483. } // extern "C++"
  484.