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.h < prev    next >
C/C++ Source or Header  |  1996-10-12  |  19KB  |  575 lines

  1. // Main templates for the -*- C++ -*- string classes.
  2. // Copyright (C) 1994, 1995 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. #ifndef __BASTRING__
  29. #define __BASTRING__
  30.  
  31. #ifdef __GNUG__
  32. #pragma interface
  33. #endif
  34.  
  35. #include <std/stddef.h>
  36. #include <std/straits.h>
  37.  
  38. #if _G_USE_EXCEPTIONS
  39.  
  40. #include <stdexcept>
  41. #define OUTOFRANGE(cond) \
  42.   do { if (!(cond)) throw out_of_range (#cond); } while (0)
  43. #define LENGTHERROR(cond) \
  44.   do { if (!(cond)) throw length_error (#cond); } while (0)
  45.  
  46. #else
  47.  
  48. #include <cassert>
  49. #define OUTOFRANGE(cond) assert (!(cond))
  50. #define LENGTHERROR(cond) assert (!(cond))
  51.  
  52. #endif
  53.  
  54. extern "C++" {
  55. class istream; class ostream;
  56.  
  57. // Should be a nested class basic_string<charT, traits>::Rep, but nested
  58. // classes don't work well with templates in g++.
  59. template <class charT, class traits = string_char_traits<charT> >
  60. struct __bsrep {
  61.   typedef __bsrep Rep;
  62.  
  63.   size_t len, res, ref;
  64.   bool selfish;
  65.  
  66.   charT* data () { return reinterpret_cast<charT *>(this + 1); }
  67.   charT& operator[] (size_t s) { return data () [s]; }
  68.   charT* grab () { if (selfish) return clone (); ++ref; return data (); }
  69.   void release () { if (--ref == 0) delete this; }
  70.  
  71.   inline static void * operator new (size_t, size_t);
  72.   inline static Rep* create (size_t);
  73.   charT* clone ();
  74.  
  75.   inline void copy (size_t, const charT *, size_t);
  76.   inline void move (size_t, const charT *, size_t);
  77.   inline void set  (size_t, const charT,   size_t);
  78.  
  79. #if _G_ALLOC_CONTROL
  80.   // These function pointers allow you to modify the allocation policy used
  81.   // by the string classes.  By default they expand by powers of two, but
  82.   // this may be excessive for space-critical applications.
  83.  
  84.   // Returns true if ALLOCATED is too much larger than LENGTH
  85.   static bool (*excess_slop) (size_t length, size_t allocated);
  86.   inline static bool default_excess (size_t, size_t);
  87.  
  88.   // Returns a good amount of space to allocate for a string of length LENGTH
  89.   static size_t (*frob_size) (size_t length);
  90.   inline static size_t default_frob (size_t);
  91. #else
  92.   inline static bool excess_slop (size_t, size_t);
  93.   inline static size_t frob_size (size_t);
  94. #endif
  95.  
  96. private:
  97.   Rep &operator= (const Rep &);
  98. };
  99.  
  100. // #include <iterator.h>
  101.  
  102. template <class charT, class traits = string_char_traits<charT> >
  103. class basic_string
  104. {
  105. private:
  106.   typedef __bsrep<charT, traits> Rep;
  107.  
  108. public:
  109. // types:
  110.   typedef traits traits_type;
  111.   typedef charT value_type;
  112.   typedef size_t size_type;
  113.   typedef ptrdiff_t difference_type;
  114.   typedef charT& reference;
  115.   typedef const charT& const_reference;
  116.   typedef charT* pointer;
  117.   typedef const charT* const_pointer;
  118.   typedef pointer iterator;
  119.   typedef const_pointer const_iterator;
  120. #if 0
  121.   typedef reverse_iterator<iterator, value_type,
  122.                            reference, difference_type> reverse_iterator;
  123.   typedef reverse_iterator<const_iterator, value_type, const_reference,
  124.                            difference_type> const_reverse_iterator;
  125. #endif
  126.   static const size_type npos = static_cast<size_type>(-1);
  127.  
  128. private:
  129.   Rep *rep () const { return reinterpret_cast<Rep *>(dat) - 1; }
  130.   void repup (Rep *p) { rep ()->release (); dat = p->data (); }
  131.  
  132. public:
  133.   const charT* data () const
  134.     { return rep ()->data(); }
  135.   size_type length () const
  136.     { return rep ()->len; }
  137.   size_type size () const
  138.     { return rep ()->len; }
  139.   size_type capacity () const
  140.     { return rep ()->res; }
  141.   size_type max_size () const
  142.     { return npos - 1; }        // XXX
  143.   bool empty () const
  144.     { return size () == 0; }
  145.  
  146. // _lib.string.cons_ construct/copy/destroy:
  147.   basic_string& operator= (const basic_string& str)
  148.     {
  149.       if (&str != this) { rep ()->release (); dat = str.rep ()->grab (); }
  150.       return *this;
  151.     }
  152.  
  153.   explicit basic_string (): dat (nilRep.grab ()) { }
  154.   basic_string (const basic_string& str): dat (str.rep ()->grab ()) { }
  155.   basic_string (const basic_string& str, size_type pos, size_type n = npos)
  156.     : dat (nilRep.grab ()) { assign (str, pos, n); }
  157.   basic_string (const charT* s, size_type n)
  158.     : dat (nilRep.grab ()) { assign (s, n); }
  159.   basic_string (const charT* s)
  160.     : dat (nilRep.grab ()) { assign (s); }
  161.   basic_string (size_type n, charT c)
  162.     : dat (nilRep.grab ()) { assign (n, c); }
  163. #if 0
  164.   template<class InputIterator>
  165.     basic_string(InputIterator begin, InputIterator end,
  166.          Allocator& = Allocator());
  167. #endif
  168.  
  169.   ~basic_string ()
  170.     { rep ()->release (); }
  171.  
  172.   void swap (basic_string &s) { charT *d = dat; dat = s.dat; s.dat = d; }
  173.  
  174.   basic_string& append (const basic_string& str, size_type pos = 0,
  175.             size_type n = npos)
  176.     { return replace (length (), 0, str, pos, n); }
  177.   basic_string& append (const charT* s, size_type n)
  178.     { return replace (length (), 0, s, n); }
  179.   basic_string& append (const charT* s)
  180.     { return append (s, traits::length (s)); }
  181.   basic_string& append (size_type n, charT c)
  182.     { return replace (length (), 0, n, c); }
  183. #if 0
  184.   template<class InputIterator>
  185.     basic_string& append(InputIterator first, InputIterator last);
  186. #endif
  187.  
  188.   basic_string& assign (const basic_string& str, size_type pos = 0,
  189.             size_type n = npos)
  190.     { return replace (0, npos, str, pos, n); }
  191.   basic_string& assign (const charT* s, size_type n)
  192.     { return replace (0, npos, s, n); }
  193.   basic_string& assign (const charT* s)
  194.     { return assign (s, traits::length (s)); }
  195.   basic_string& assign (size_type n, charT c)
  196.     { return replace (0, npos, n, c); }
  197. #if 0
  198.   template<class InputIterator>
  199.     basic_string& assign(InputIterator first, InputIterator last);
  200. #endif
  201.  
  202.   basic_string& operator= (const charT* s)
  203.     { return assign (s); }
  204.   basic_string& operator= (charT c)
  205.     { return assign (1, c); }
  206.  
  207.   basic_string& operator+= (const basic_string& rhs)
  208.     { return append (rhs); }
  209.   basic_string& operator+= (const charT* s)
  210.     { return append (s); }
  211.   basic_string& operator+= (charT c)
  212.     { return append (1, c); }
  213.  
  214.   basic_string& insert (size_type pos1, const basic_string& str,
  215.             size_type pos2 = 0, size_type n = npos)
  216.     { return replace (pos1, 0, str, pos2, n); }
  217.   basic_string& insert (size_type pos, const charT* s, size_type n)
  218.     { return replace (pos, 0, s, n); }
  219.   basic_string& insert (size_type pos, const charT* s)
  220.     { return insert (pos, s, traits::length (s)); }
  221.   basic_string& insert (size_type pos, size_type n, charT c)
  222.     { return replace (pos, 0, n, c); }
  223.   iterator insert(iterator p, charT c)
  224.     { insert (p - begin (), 1, c); return p; }
  225.   iterator insert(iterator p, size_type n, charT c)
  226.     { insert (p - begin (), n, c); return p; }
  227. #if 0
  228.   template<class InputIterator>
  229.     void insert(iterator p, InputIterator first, InputIterator last);
  230. #endif
  231.  
  232.   basic_string& remove (size_type pos = 0, size_type n = npos)
  233.     { return replace (pos, n, 0, (charT)0); }
  234.   basic_string& remove (iterator pos)
  235.     { return replace (pos - begin (), 1, 0, (charT)0); }
  236.   basic_string& remove (iterator first, iterator last)
  237.     { return replace (first - begin (), last - first, 0, (charT)0); }
  238.  
  239.   basic_string& replace (size_type pos1, size_type n1, const basic_string& str,
  240.              size_type pos2 = 0, size_type n2 = npos);
  241.   basic_string& replace (size_type pos, size_type n1, const charT* s,
  242.              size_type n2);
  243.   basic_string& replace (size_type pos, size_type n1, const charT* s)
  244.     { return replace (pos, n1, s, traits::length (s)); }
  245.   basic_string& replace (size_type pos, size_type n1, size_type n2, charT c);
  246.   basic_string& replace (size_type pos, size_type n, charT c)
  247.     { return replace (pos, n, 1, c); }
  248.   basic_string& replace (iterator i1, iterator i2, const basic_string& str)
  249.     { return replace (i1 - begin (), i2 - i1, str); }
  250.   basic_string& replace (iterator i1, iterator i2, const charT* s, size_type n)
  251.     { return replace (i1 - begin (), i2 - i1, s, n); }
  252.   basic_string& replace (iterator i1, iterator i2, const charT* s)
  253.     { return replace (i1 - begin (), i2 - i1, s); }
  254.   basic_string& replace (iterator i1, iterator i2, size_type n, charT c)
  255.     { return replace (i1 - begin (), i2 - i1, n, c); }
  256. #if 0
  257.   template<class InputIterator>
  258.     basic_string& replace(iterator i1, iterator i2,
  259.               InputIterator j1, InputIterator j2);
  260. #endif
  261.  
  262. private:
  263.   static charT eos () { return traits::eos (); }
  264.   void unique () { if (rep ()->ref > 1) alloc (capacity (), true); }
  265.   void selfish () { unique (); rep ()->selfish = true; }
  266.  
  267. public:
  268.   charT operator[] (size_type pos) const
  269.     {
  270.       if (pos == length ())
  271.     return eos ();
  272.       return data ()[pos];
  273.     }
  274.  
  275.   reference operator[] (size_type pos)
  276.     { unique (); return (*rep ())[pos]; }
  277.  
  278.   reference at (size_type pos)
  279.     {
  280.       OUTOFRANGE (pos >= length ());
  281.       return (*this)[pos];
  282.     }
  283.   const_reference at (size_type pos) const
  284.     {
  285.       OUTOFRANGE (pos >= length ());
  286.       return data ()[pos];
  287.     }
  288.  
  289. private:
  290.   void terminate () const
  291.     { traits::assign ((*rep ())[length ()], eos ()); }
  292.  
  293. public:
  294.   const charT* c_str () const
  295.     { terminate (); return data (); }
  296.   void resize (size_type n, charT c);
  297.   void resize (size_type n)
  298.     { resize (n, eos ()); }
  299.   void reserve (size_type) { }
  300.  
  301.   size_type copy (charT* s, size_type n, size_type pos = 0);
  302.  
  303.   size_type find (const basic_string& str, size_type pos = 0) const
  304.     { return find (str.data(), pos, str.length()); }
  305.   size_type find (const charT* s, size_type pos, size_type n) const;
  306.   size_type find (const charT* s, size_type pos = 0) const
  307.     { return find (s, pos, traits::length (s)); }
  308.   size_type find (charT c, size_type pos = 0) const;
  309.  
  310.   size_type rfind (const basic_string& str, size_type pos = npos) const
  311.     { return rfind (str.data(), pos, str.length()); }
  312.   size_type rfind (const charT* s, size_type pos, size_type n) const;
  313.   size_type rfind (const charT* s, size_type pos = npos) const
  314.     { return rfind (s, pos, traits::length (s)); }
  315.   size_type rfind (charT c, size_type pos = npos) const;
  316.  
  317.   size_type find_first_of (const basic_string& str, size_type pos = 0) const
  318.     { return find_first_of (str.data(), pos, str.length()); }
  319.   size_type find_first_of (const charT* s, size_type pos, size_type n) const;
  320.   size_type find_first_of (const charT* s, size_type pos = 0) const
  321.     { return find_first_of (s, pos, traits::length (s)); }
  322.   size_type find_first_of (charT c, size_type pos = 0) const
  323.     { return find (c, pos); }
  324.  
  325.   size_type find_last_of (const basic_string& str, size_type pos = npos) const
  326.     { return find_last_of (str.data(), pos, str.length()); }
  327.   size_type find_last_of (const charT* s, size_type pos, size_type n) const;
  328.   size_type find_last_of (const charT* s, size_type pos = npos) const
  329.     { return find_last_of (s, pos, traits::length (s)); }
  330.   size_type find_last_of (charT c, size_type pos = npos) const
  331.     { return rfind (c, pos); }
  332.  
  333.   size_type find_first_not_of (const basic_string& str, size_type pos = 0) const
  334.     { return find_first_not_of (str.data(), pos, str.length()); }
  335.   size_type find_first_not_of (const charT* s, size_type pos, size_type n) const;
  336.   size_type find_first_not_of (const charT* s, size_type pos = 0) const
  337.     { return find_first_not_of (s, pos, traits::length (s)); }
  338.   size_type find_first_not_of (charT c, size_type pos = 0) const;
  339.  
  340.   size_type find_last_not_of (const basic_string& str, size_type pos = npos) const
  341.     { return find_last_not_of (str.data(), pos, str.length()); }
  342.   size_type find_last_not_of (const charT* s, size_type pos, size_type n) const;
  343.   size_type find_last_not_of (const charT* s, size_type pos = npos) const
  344.     { return find_last_not_of (s, pos, traits::length (s)); }
  345.   size_type find_last_not_of (charT c, size_type pos = npos) const;
  346.  
  347.   basic_string substr (size_type pos = 0, size_type n = npos) const
  348.     { return basic_string (*this, pos, n); }
  349.  
  350.   int compare (const basic_string& str, size_type pos = 0, size_type n = npos) const;
  351.   // There is no 'strncmp' equivalent for charT pointers.
  352.   int compare (const charT* s, size_type pos, size_type n) const;
  353.   int compare (const charT* s, size_type pos = 0) const
  354.     { return compare (s, pos, traits::length (s)); }
  355.  
  356.   iterator begin () { selfish (); return &(*this)[0]; }
  357.   iterator end () { selfish (); return &(*this)[length ()]; }
  358.   const_iterator begin () const { return &(*rep ())[0]; }
  359.   const_iterator end () const { return &(*rep ())[length ()]; }
  360.  
  361. #if 0
  362.   reverse_iterator       rbegin() { return reverse_iterator (end ()); }
  363.   const_reverse_iterator rbegin() const
  364.     { return const_reverse_iterator (end ()); }
  365.   reverse_iterator       rend() { return reverse_iterator (begin ()); }
  366.   const_reverse_iterator rend() const
  367.     { return const reverse_iterator (begin ()); }
  368. #endif
  369.  
  370. private:
  371.   void alloc (size_type size, bool save);
  372.   static size_type _find (const charT* ptr, charT c, size_type xpos, size_type len);
  373.   inline bool check_realloc (size_type s) const;
  374.  
  375.   static Rep nilRep;
  376.   charT *dat;
  377. };
  378.  
  379. template <class charT, class traits>
  380. inline basic_string <charT, traits>
  381. operator+ (const basic_string <charT, traits>& lhs,
  382.        const basic_string <charT, traits>& rhs)
  383. {
  384.   basic_string <charT, traits> str (lhs);
  385.   str.append (rhs);
  386.   return str;
  387. }
  388.  
  389. template <class charT, class traits>
  390. inline basic_string <charT, traits>
  391. operator+ (const charT* lhs, const basic_string <charT, traits>& rhs)
  392. {
  393.   basic_string <charT, traits> str (lhs);
  394.   str.append (rhs);
  395.   return str;
  396. }
  397.  
  398. template <class charT, class traits>
  399. inline basic_string <charT, traits>
  400. operator+ (charT lhs, const basic_string <charT, traits>& rhs)
  401. {
  402.   basic_string <charT, traits> str (1, lhs);
  403.   str.append (rhs);
  404.   return str;
  405. }
  406.  
  407. template <class charT, class traits>
  408. inline basic_string <charT, traits>
  409. operator+ (const basic_string <charT, traits>& lhs, const charT* rhs)
  410. {
  411.   basic_string <charT, traits> str (lhs);
  412.   str.append (rhs);
  413.   return str;
  414. }
  415.  
  416. template <class charT, class traits>
  417. inline basic_string <charT, traits>
  418. operator+ (const basic_string <charT, traits>& lhs, charT rhs)
  419. {
  420.   basic_string <charT, traits> str (lhs);
  421.   str.append (1, rhs);
  422.   return str;
  423. }
  424.  
  425. template <class charT, class traits>
  426. inline bool
  427. operator== (const basic_string <charT, traits>& lhs,
  428.         const basic_string <charT, traits>& rhs)
  429. {
  430.   return (lhs.compare (rhs) == 0);
  431. }
  432.  
  433. template <class charT, class traits>
  434. inline bool
  435. operator== (const charT* lhs, const basic_string <charT, traits>& rhs)
  436. {
  437.   return (rhs.compare (lhs) == 0);
  438. }
  439.  
  440. template <class charT, class traits>
  441. inline bool
  442. operator== (const basic_string <charT, traits>& lhs, const charT* rhs)
  443. {
  444.   return (lhs.compare (rhs) == 0);
  445. }
  446.  
  447. template <class charT, class traits>
  448. inline bool
  449. operator!= (const charT* lhs, const basic_string <charT, traits>& rhs)
  450. {
  451.   return (rhs.compare (lhs) != 0);
  452. }
  453.  
  454. template <class charT, class traits>
  455. inline bool
  456. operator!= (const basic_string <charT, traits>& lhs, const charT* rhs)
  457. {
  458.   return (lhs.compare (rhs) != 0);
  459. }
  460.  
  461. template <class charT, class traits>
  462. inline bool
  463. operator< (const basic_string <charT, traits>& lhs,
  464.         const basic_string <charT, traits>& rhs)
  465. {
  466.   return (lhs.compare (rhs) < 0);
  467. }
  468.  
  469. template <class charT, class traits>
  470. inline bool
  471. operator< (const charT* lhs, const basic_string <charT, traits>& rhs)
  472. {
  473.   return (rhs.compare (lhs) > 0);
  474. }
  475.  
  476. template <class charT, class traits>
  477. inline bool
  478. operator< (const basic_string <charT, traits>& lhs, const charT* rhs)
  479. {
  480.   return (lhs.compare (rhs) < 0);
  481. }
  482.  
  483. template <class charT, class traits>
  484. inline bool
  485. operator> (const charT* lhs, const basic_string <charT, traits>& rhs)
  486. {
  487.   return (rhs.compare (lhs) < 0);
  488. }
  489.  
  490. template <class charT, class traits>
  491. inline bool
  492. operator> (const basic_string <charT, traits>& lhs, const charT* rhs)
  493. {
  494.   return (lhs.compare (rhs) > 0);
  495. }
  496.  
  497. template <class charT, class traits>
  498. inline bool
  499. operator<= (const charT* lhs, const basic_string <charT, traits>& rhs)
  500. {
  501.   return (rhs.compare (lhs) >= 0);
  502. }
  503.  
  504. template <class charT, class traits>
  505. inline bool
  506. operator<= (const basic_string <charT, traits>& lhs, const charT* rhs)
  507. {
  508.   return (lhs.compare (rhs) <= 0);
  509. }
  510.  
  511. template <class charT, class traits>
  512. inline bool
  513. operator>= (const charT* lhs, const basic_string <charT, traits>& rhs)
  514. {
  515.   return (rhs.compare (lhs) <= 0);
  516. }
  517.  
  518. template <class charT, class traits>
  519. inline bool
  520. operator>= (const basic_string <charT, traits>& lhs, const charT* rhs)
  521. {
  522.   return (lhs.compare (rhs) >= 0);
  523. }
  524.  
  525. // Kludge this until g++ supports the new template overloading semantics.
  526. #if !defined(FUNCTION_H)
  527. template <class charT, class traits>
  528. inline bool
  529. operator!= (const basic_string <charT, traits>& lhs,
  530.         const basic_string <charT, traits>& rhs)
  531. {
  532.   return (lhs.compare (rhs) != 0);
  533. }
  534.  
  535. template <class charT, class traits>
  536. inline bool
  537. operator> (const basic_string <charT, traits>& lhs,
  538.        const basic_string <charT, traits>& rhs)
  539. {
  540.   return (lhs.compare (rhs) > 0);
  541. }
  542.  
  543. template <class charT, class traits>
  544. inline bool
  545. operator<= (const basic_string <charT, traits>& lhs,
  546.         const basic_string <charT, traits>& rhs)
  547. {
  548.   return (lhs.compare (rhs) <= 0);
  549. }
  550.  
  551. template <class charT, class traits>
  552. inline bool
  553. operator>= (const basic_string <charT, traits>& lhs,
  554.         const basic_string <charT, traits>& rhs)
  555. {
  556.   return (lhs.compare (rhs) >= 0);
  557. }
  558. #endif
  559.  
  560. class istream; class ostream;
  561. template <class charT, class traits> istream&
  562. operator>> (istream&, basic_string <charT, traits>&);
  563. template <class charT, class traits> ostream&
  564. operator<< (ostream&, const basic_string <charT, traits>&);
  565. template <class charT, class traits> istream&
  566. getline (istream&, basic_string <charT, traits>&, charT delim = '\n');
  567.  
  568. } // extern "C++"
  569.  
  570. #if !defined (_G_NO_EXTERN_TEMPLATES)
  571. #include <std/sinst.h>
  572. #endif
  573.  
  574. #endif
  575.