src/Utility/bstring.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 // This is a locally modified version of Modena's old bstring class,
00012 // attempting to make it as standard-compliant as possible.
00013 
00027 #ifndef  __cplusplus
00028 #error Must use C++ for BSTRING.H
00029 #endif
00030 
00031 #ifndef BSTRING_H
00032 #define BSTRING_H
00033 
00034 // include files
00035 #ifdef IPPL_USE_STANDARD_HEADERS
00036 #include <iostream>
00037 using namespace std;
00038 #else
00039 #include <iostream.h>
00040 #endif
00041 
00042 #include <ctype.h>
00043 #include <string.h>
00044 #include <stddef.h>
00045 #include <stdlib.h>
00046 
00047 
00048 
00049 // bool.h
00050 // a typedef is less sweeping than a #define for "bool"
00051 #ifndef __BOOL_DEFINED
00052 #define true 1
00053 #define false 0
00054 typedef int bool;
00055 #endif
00056 
00057 
00058 // bc4const 
00059 
00060 #ifdef __BC4_STL
00061 #define __BC401_STL
00062 #endif
00063 
00064 #ifdef __BC401_STL
00065 #define __BC401_const 
00066 #else
00067 #define __BC401_const const
00068 #endif
00069 
00070 // bndchk.h
00071 #ifdef BOUNDS_CHECK
00072 void check_bounds
00073         (       int index, 
00074                 int container_size, 
00075                 int lineno,
00076                 char *filename  );
00077 #endif
00078 
00079 // mexcept.h
00080 
00081 #define _THROW_NONE
00082 #define _THROW_DOMAIN
00083 #define _THROW_INVALIDARG
00084 #define _THROW_LENGTH
00085 #define _THROW_OUTRANGE
00086 #define _THROW_RANGE
00087 #define _THROW_OVERFLOW
00088 #define _THROW_ALLOC
00089 #define _THROW_CAST
00090 #define _THROW_TYPEID
00091 #define _THROW_ALLOC_LENGTH
00092 #define _THROW_ALLOC_OUTRANGE
00093 #define _THROW_LENGTH_OUTRANGE
00094 #define _THROW_ALLOC_LENGTH_OUTRANGE
00095 
00096 #ifdef _SGITHREADS
00097 #ifndef MUTEX_H
00098 #include <mutex.h>
00099 #define MUTEX_H
00100 #endif
00101 #endif
00102 
00103 const size_t NPOS  = (size_t)(-1);
00104 
00105 enum capacity { default_size, reserve };
00106 
00107 template<class charT>
00108 struct  string_char_baggage {
00109 
00110     typedef charT char_type;
00111 
00112     //
00113     // for users to acquire the basic character type
00114     //
00115     // constraints functions
00116     //
00117     static void
00118     assign (char_type& c1, const char_type& c2) _THROW_NONE
00119     {
00120         c1 = c2;
00121     }
00122     static bool
00123     eq (const char_type& c1, const char_type& c2) _THROW_NONE
00124     {
00125         return (c1 == c2);
00126     }
00127     static bool
00128     ne (const char_type& c1, const char_type& c2) _THROW_NONE
00129     {
00130         return !(c1 == c2);
00131     }
00132     static bool
00133     lt (const char_type& c1, const char_type& c2) _THROW_NONE
00134     {
00135         return (c1 < c2);
00136     }
00137     static char_type
00138     eos () _THROW_NONE
00139     {
00140         return char_type();     // the null character
00141     }
00142     static istream&
00143     char_in (istream& is, char_type& c) _THROW_NONE
00144     {
00145         return is >> c;        // extractor for a char_type object
00146     }
00147     static ostream&
00148     char_out (ostream& os, char_type c) _THROW_NONE
00149     {
00150         return os << c;        // inserter for a char_type object
00151     }
00152     static bool
00153     is_del (char_type c) _THROW_NONE
00154     {
00155         // characteristic function for delimiters of char_type
00156         return isspace(c);
00157     }
00158 
00159     //
00160     // speed-up functions
00161     //
00162     static int
00163     compare (const char_type* s1, const char_type* s2, size_t n) _THROW_NONE
00164     {
00165         for (size_t i = 0; i < n; ++i, ++s1, ++s2)
00166             if (ne(*s1, *s2))
00167             {
00168                 return lt(*s1, *s2) ? -1 : 1;
00169             }
00170         return 0;
00171     }
00172     static size_t
00173     length (const char_type* s) _THROW_NONE
00174     {
00175         size_t l = 0;
00176         while (ne(*s++, eos()))
00177             ++l;
00178         return l;
00179     }
00180     static char_type*
00181     copy (char_type* s1, const char_type* s2, size_t n) _THROW_NONE
00182     {
00183         char_type* s = s1;
00184         for (size_t i = 0; i < n; ++i)
00185             assign(*++s1, *++s2);
00186         return s;
00187     }
00188 };
00189 
00190 struct string_char_baggage<char> {
00191 
00192     typedef char char_type;
00193 
00194     //
00195     // constraint member functions
00196     //
00197     static void
00198     assign (char_type& c1, const char_type& c2) _THROW_NONE
00199     {
00200         c1 = c2;
00201     }
00202     static bool
00203     eq (const char_type& c1, const char_type& c2) _THROW_NONE
00204     {
00205         return (c1 == c2);
00206     }
00207     static bool
00208     ne (const char_type& c1, const char_type& c2) _THROW_NONE
00209     {
00210         return (c1 != c2);
00211     }
00212     static bool
00213     lt (const char_type& c1, const char_type& c2) _THROW_NONE
00214     {
00215         return (c1 < c2);
00216     }
00217     static char_type
00218     eos () _THROW_NONE
00219     {
00220         return 0;     // the null character
00221     }
00222     static istream&
00223     char_in (istream& is, char_type& c) _THROW_NONE
00224     {
00225        // extractor for a char_type object
00226        // return is >> c;        // this does not work
00227        is.get(c);
00228        return is;
00229     }
00230     static ostream&
00231     char_out (ostream& os, char_type c) _THROW_NONE
00232     {
00233         return os << c;        // inserter for a char_type object
00234     }
00235     static bool
00236     is_del (char_type c) _THROW_NONE
00237     {
00238         // characteristic function for delimiters of char_type
00239         return isspace(c);
00240     }
00241 
00242     //
00243     // speed-up functions
00244     //
00245     static int
00246     compare (const char_type* s1, const char_type* s2, size_t n) _THROW_NONE
00247     {
00248         return memcmp(s1, s2, n);
00249     }
00250     static size_t
00251     length (const char_type* s) _THROW_NONE
00252     {
00253           return strlen(s);
00254     }
00255     static char_type*
00256     copy (char_type* s1, const char_type* s2, size_t n) _THROW_NONE
00257     {
00258         memcpy(s1, s2, n);
00259         return s1+n;
00260     }
00261 };
00262 
00263 /*
00264 struct string_char_baggage<wchar_t> {
00265 
00266     typedef wchar_t char_type;
00267 
00268     static void
00269     assign (char_type& c1, const char_type& c2) _THROW_NONE
00270     {
00271         c1 = c2;
00272     }
00273     static bool
00274     eq (const char_type& c1, const char_type& c2) _THROW_NONE
00275     {
00276         return (c1 == c2);
00277     }
00278     static bool
00279     ne (const char_type& c1, const char_type& c2) _THROW_NONE
00280     {
00281         return (c1 != c2);
00282     }
00283     static bool
00284     lt (const char_type& c1, const char_type& c2) _THROW_NONE
00285     {
00286         return (c1 < c2);
00287     }
00288     static char_type
00289     eos () _THROW_NONE
00290     {
00291         return 0;     // the null character
00292     }
00293     static istream&
00294     char_in (istream& is, char_type& c) _THROW_NONE
00295     {
00296         return is >> c;        // extractor for a char_type object
00297     }
00298     static ostream&
00299     char_out (ostream& os, char_type c) _THROW_NONE
00300     {
00301         return os << c;        // inserter for a char_type object
00302     }
00303     static bool
00304     is_del (char_type c) _THROW_NONE
00305     {
00306         // characteristic function for delimiters of char_type
00307         // using templatized locale::isspace function
00308         return isspace(c);
00309     }
00310 
00311     //
00312     // speed-up functions
00313     //
00314     static int
00315     compare (const char_type* s1, const char_type* s2, size_t n) _THROW_NONE
00316     {
00317         return wmemcmp(s1, s2, n);
00318     }
00319     static size_t
00320     length (const char_type* s) _THROW_NONE
00321     {
00322         return wcslen(s);
00323         // May use Koshida's overloaded MSE function strlen(s)
00324     }
00325     static char_type*
00326     copy (char_type* s1, const char_type* s2, size_t n) _THROW_NONE
00327     {
00328         return (char_type*)wmemcpy(s1, s2, n);
00329     }
00330 };
00331 */
00332 
00333 template <class charT>
00334 class basic_string;
00335 
00336 template <class charT>
00337 class basic_string_ref {
00338 
00339 //
00340 // friend class declaration
00341 //
00342 friend class basic_string<charT>;
00343 
00344 //
00345 // typedef declarations
00346 //
00347 typedef  string_char_baggage<charT>  baggage_type;
00348 
00349 //
00350 // private data members
00351 //
00352     charT*   ptr;
00353     size_t   len;
00354     size_t   res;
00355 
00356 #ifdef __MMULTITHREAD
00357     mutex_arith<size_t, mutex>   count;   // reference count
00358 #else
00359     size_t                       count;   // reference count
00360 #endif
00361 
00362 //
00363 // private constructors and destructors
00364 //
00365     basic_string_ref () _THROW_NONE ;
00366 
00367     basic_string_ref (size_t size, capacity cap) _THROW_ALLOC_LENGTH ;
00368 
00369     basic_string_ref (const basic_string<charT>& str, size_t pos , size_t rlen)
00370                       _THROW_ALLOC ;
00371 
00372     basic_string_ref (const charT* s, size_t rlen, size_t rres) _THROW_ALLOC ;
00373 
00374     basic_string_ref (const charT* s, size_t n) _THROW_ALLOC_LENGTH ;
00375 
00376     basic_string_ref (const charT* s) _THROW_ALLOC ;
00377 
00378     basic_string_ref (charT c, size_t rep) _THROW_ALLOC_LENGTH ;
00379 
00380     basic_string_ref (const vector<charT>& vec) _THROW_ALLOC_LENGTH ;
00381 
00382     ~basic_string_ref () _THROW_NONE ;
00383 
00384     inline void
00385     delete_ptr () _THROW_NONE ;
00386 
00387     inline static
00388     charT
00389     eos () _THROW_NONE ;
00390 
00391     inline static
00392     void
00393     throwlength () _THROW_LENGTH;
00394 
00395     inline static
00396     void
00397     throwrange () _THROW_OUTRANGE;
00398 
00399 };
00400 
00401 template<class charT>
00402 class basic_string {
00403 
00404 private:
00405 
00406 //
00407 // typedef declaration
00408 //
00409     typedef basic_string_ref<charT>   reference_class;
00410     typedef basic_string_ref<charT>*  reference_pointer;
00411 
00412 //
00413 // data member
00414 //
00415     charT*             c_str_ptr;
00416     reference_pointer  reference;
00417 
00418 //
00419 // private member functions
00420 //
00421     inline charT*
00422     point () _THROW_NONE ;
00423 
00424     inline size_t&
00425     len () _THROW_NONE ;
00426 
00427     inline size_t
00428     ref_count () const _THROW_NONE ;
00429     
00430     inline static
00431     charT
00432     eos () _THROW_NONE ;
00433 
00434     void
00435     assign_str (const charT* s, size_t slen) _THROW_ALLOC_LENGTH ;
00436 
00437     void
00438     append_str (const charT* s, size_t slen) _THROW_ALLOC_LENGTH ;
00439 
00440     void
00441     insert_str (size_t pos, const charT* s, size_t slen) 
00442                 _THROW_ALLOC_LENGTH_OUTRANGE ;
00443 
00444     void
00445     replace_str (size_t xlen, size_t pos, const charT* s, size_t slen) 
00446                  _THROW_ALLOC_LENGTH_OUTRANGE ;
00447 
00448     int
00449     compare_str (size_t pos, const charT* str, size_t slen, size_t strlen) 
00450                  const _THROW_OUTRANGE ;
00451 
00452     size_t
00453     find_str (const charT* s, size_t pos, size_t len) const _THROW_NONE ;
00454 
00455     size_t
00456     rfind_str (const charT* s, size_t pos, size_t len) const _THROW_NONE ;
00457 
00458     size_t
00459     find_first_of_str (const charT* s, size_t pos, size_t len) const 
00460                       _THROW_NONE ;
00461 
00462     size_t
00463     find_last_of_str (const charT* s, size_t pos, size_t len) const 
00464                      _THROW_NONE ;
00465 
00466     size_t
00467     find_first_not_of_str (const charT* s, size_t pos, size_t len) const 
00468                           _THROW_NONE ;
00469 
00470     size_t
00471     find_last_not_of_str (const charT* s, size_t pos, size_t len) const 
00472                          _THROW_NONE ;
00473 
00474 
00475 protected:
00476 
00477     basic_string (const charT* s, size_t rlen, size_t xlen) _THROW_ALLOC_LENGTH;
00478 
00479     inline void
00480     delete_ref () _THROW_NONE ;
00481 
00482 public:
00483 
00484     typedef  charT                       char_type;
00485     typedef  string_char_baggage<charT>  baggage_type;
00486 
00487     basic_string () _THROW_ALLOC ;
00488 
00489     basic_string (size_t size, capacity cap) _THROW_ALLOC_LENGTH ;
00490 
00491     basic_string (const basic_string<charT>& str, size_t pos = 0, size_t n = NPOS)
00492                   _THROW_ALLOC_OUTRANGE ;
00493 
00494     basic_string (const charT* s, size_t n) _THROW_ALLOC_LENGTH ;
00495 
00496     basic_string (const charT* s) _THROW_ALLOC ;
00497 
00498     basic_string (charT c, size_t rep = 1) _THROW_ALLOC_LENGTH ;
00499 
00500     basic_string (const vector<charT>& vec) _THROW_ALLOC_LENGTH ;
00501 
00502     ~basic_string () _THROW_NONE ;
00503 
00504     basic_string<charT>&
00505     operator= (const basic_string<charT>& str) _THROW_ALLOC ;
00506 
00507     basic_string<charT>&
00508     operator= (const charT* s) _THROW_ALLOC ;
00509 
00510     basic_string<charT>&
00511     operator= (charT c) _THROW_ALLOC ;
00512 
00513     basic_string<charT>&
00514     operator+= (const basic_string<charT>& rhs) _THROW_ALLOC_LENGTH ;
00515 
00516     basic_string<charT>&
00517     operator+= (const charT* s) _THROW_ALLOC_LENGTH ;
00518 
00519     basic_string<charT>&
00520     operator+= (charT c) _THROW_ALLOC_LENGTH ;
00521 
00522     operator vector<charT> () const _THROW_ALLOC { 
00523         return vector<charT> (data(), data()+length());
00524         }
00525 
00526     basic_string<charT>&
00527     append (const basic_string<charT>& str, size_t pos = 0, size_t n = NPOS)
00528             _THROW_ALLOC_LENGTH_OUTRANGE ;
00529 
00530     basic_string<charT>&
00531     append (const charT* s, size_t n) _THROW_ALLOC_LENGTH ;
00532 
00533     basic_string<charT>&
00534     append (const charT* s) _THROW_ALLOC_LENGTH ;
00535 
00536     basic_string<charT>&
00537     append (charT c, size_t rep = 1) _THROW_ALLOC_LENGTH ;
00538 
00539     basic_string<charT>&
00540     assign (const basic_string<charT>& str, size_t pos = 0, size_t n = NPOS)
00541             _THROW_ALLOC_LENGTH_OUTRANGE ;
00542 
00543     basic_string<charT>&
00544     assign (const charT* s, size_t n) _THROW_ALLOC_LENGTH ;
00545 
00546     basic_string<charT>&
00547     assign (const charT* s) _THROW_ALLOC_LENGTH ;
00548 
00549     basic_string<charT>&
00550     assign (charT c, size_t rep = 1) _THROW_ALLOC_LENGTH ;
00551 
00552     basic_string<charT>&
00553     insert (size_t pos1, const basic_string<charT>& str, size_t pos2 = 0,
00554             size_t n = NPOS) _THROW_ALLOC_LENGTH_OUTRANGE ;
00555 
00556     basic_string<charT>&
00557     insert (size_t pos, const charT* s, size_t n) _THROW_ALLOC_LENGTH_OUTRANGE ;
00558 
00559     basic_string<charT>&
00560     insert (size_t pos, const charT* s) _THROW_ALLOC_LENGTH_OUTRANGE ;
00561 
00562     basic_string<charT>&
00563     insert (size_t pos, charT c, size_t rep = 1) _THROW_ALLOC_LENGTH_OUTRANGE ;
00564 
00565     basic_string<charT>&
00566     erase (size_t pos = 0, size_t n = NPOS) _THROW_ALLOC_OUTRANGE ;
00567 
00568     basic_string<charT>&
00569     replace (size_t pos1, size_t n1, const basic_string<charT>& str, size_t pos2 = 0,
00570              size_t n2 = NPOS) _THROW_ALLOC_LENGTH_OUTRANGE ;
00571 
00572     basic_string<charT>&
00573     replace (size_t pos, size_t n1, const charT* s, size_t n2)
00574              _THROW_ALLOC_LENGTH_OUTRANGE ;
00575 
00576     basic_string<charT>&
00577     replace (size_t pos, size_t n1, const charT* s)
00578              _THROW_ALLOC_LENGTH_OUTRANGE ;
00579 
00580     basic_string<charT>&
00581     replace (size_t pos, size_t n, charT c, size_t rep = 1)
00582              _THROW_ALLOC_LENGTH_OUTRANGE ;
00583 
00584     inline charT
00585     at (size_t pos) const _THROW_OUTRANGE ;
00586 
00587     void
00588     put_at (size_t pos, charT c) _THROW_ALLOC_OUTRANGE ;
00589 
00590     inline charT
00591     operator[] (size_t pos) const _THROW_NONE ;
00592 
00593     charT&
00594     operator[] (size_t pos) _THROW_ALLOC_OUTRANGE ;
00595 
00596     const charT*
00597     c_str () const _THROW_ALLOC ;
00598 
00599     inline const charT*
00600     data () const _THROW_NONE ;
00601 
00602     inline size_t
00603     length () const _THROW_NONE ;
00604 
00605     void
00606     resize (size_t n, charT c) _THROW_ALLOC_LENGTH ;
00607 
00608     void
00609     resize (size_t n) _THROW_ALLOC_LENGTH ;
00610 
00611     inline size_t
00612     reserve () const _THROW_NONE ;
00613 
00614     void
00615     reserve (size_t res_arg) _THROW_ALLOC_LENGTH ;
00616 
00617     size_t
00618     copy (charT* s, size_t n, size_t pos = 0) const _THROW_OUTRANGE ;
00619 
00620     size_t
00621     find (const basic_string<charT>& str, size_t pos = 0) const _THROW_NONE ;
00622 
00623     size_t
00624     find (const charT* s, size_t pos, size_t n) const _THROW_NONE ;
00625 
00626     size_t
00627     find (const charT* s, size_t pos = 0) const _THROW_NONE ;
00628 
00629     size_t
00630     find (charT c, size_t pos = 0) const _THROW_NONE ;
00631 
00632     size_t
00633     rfind (const basic_string<charT>& str, size_t pos = NPOS) const _THROW_NONE ;
00634 
00635     size_t
00636     rfind (const charT* s, size_t pos, size_t n) const _THROW_NONE ;
00637 
00638     size_t
00639     rfind (const charT* s, size_t pos = NPOS) const _THROW_NONE ;
00640 
00641     size_t
00642     rfind (charT c, size_t pos = NPOS) const _THROW_NONE ;
00643 
00644     size_t
00645     find_first_of (const basic_string<charT>& str, size_t pos = 0) const _THROW_NONE ;
00646 
00647     size_t
00648     find_first_of (const charT* s, size_t pos, size_t n) const _THROW_NONE ;
00649 
00650     size_t
00651     find_first_of (const charT* s, size_t pos = 0) const _THROW_NONE ;
00652 
00653     size_t
00654     find_first_of (charT c, size_t pos = 0) const _THROW_NONE ;
00655 
00656 
00657     size_t
00658     find_last_of (const basic_string<charT>& str, size_t pos = NPOS) const
00659                   _THROW_NONE ;
00660 
00661     size_t
00662     find_last_of (const charT* s, size_t pos, size_t n) const _THROW_NONE ;
00663 
00664     size_t
00665     find_last_of (const charT* s, size_t pos = NPOS) const _THROW_NONE ;
00666 
00667     size_t
00668     find_last_of (charT c, size_t pos = NPOS) const _THROW_NONE ;
00669 
00670     size_t
00671     find_first_not_of (const basic_string<charT>& str, size_t pos = 0) const
00672                        _THROW_NONE ;
00673 
00674     size_t
00675     find_first_not_of (const charT* s, size_t pos, size_t n) const _THROW_NONE ;
00676 
00677     size_t
00678     find_first_not_of (const charT* s, size_t pos = 0) const _THROW_NONE ;
00679 
00680     size_t
00681     find_first_not_of (charT c, size_t pos = 0) const _THROW_NONE ;
00682 
00683     size_t
00684     find_last_not_of (const basic_string<charT>& str, size_t pos = NPOS) const
00685                       _THROW_NONE ;
00686 
00687     size_t
00688     find_last_not_of (const charT* s, size_t pos, size_t n) const _THROW_NONE ;
00689 
00690     size_t
00691     find_last_not_of (const charT* s, size_t pos = NPOS) const _THROW_NONE ;
00692 
00693     size_t
00694     find_last_not_of (charT c, size_t pos = NPOS) const _THROW_NONE ;
00695 
00696     basic_string<charT>
00697     substr (size_t pos = 0,  size_t n = NPOS) const _THROW_ALLOC_OUTRANGE ;
00698 
00699     int
00700     compare (const basic_string<charT>& str, size_t pos = 0, size_t n = NPOS) const
00701              _THROW_OUTRANGE ;
00702 
00703     int
00704     compare (const charT* s, size_t pos, size_t n) const
00705              _THROW_LENGTH_OUTRANGE ;
00706 
00707     int
00708     compare (const charT* s, size_t pos = 0) const _THROW_OUTRANGE ;
00709 
00710     int
00711     compare (charT c, size_t pos = 0, size_t rep = 1) const 
00712              _THROW_LENGTH_OUTRANGE ;
00713 
00714     friend
00715     ostream&
00716     operator<< (ostream& o, const basic_string<charT>& s) _THROW_NONE ;
00717 
00718     friend
00719     istream&
00720     operator>> (istream& i, basic_string<charT>& s) _THROW_ALLOC_LENGTH ;
00721 
00722     friend
00723     basic_string<charT>
00724     operator+ (const basic_string<charT>& lhs, const basic_string<charT>& rhs)
00725     _THROW_ALLOC_LENGTH ;
00726 
00727     friend
00728     basic_string<charT>
00729     operator+ (const charT* lhs, const basic_string<charT>& rhs)
00730     _THROW_ALLOC_LENGTH ;
00731 
00732     friend
00733     basic_string<charT>
00734     operator+ (charT lhs, const basic_string<charT>& rhs) _THROW_ALLOC_LENGTH ;
00735 
00736     friend
00737     basic_string<charT>
00738     operator+ (const basic_string<charT>& lhs, const charT* rhs)
00739     _THROW_ALLOC_LENGTH ;
00740 
00741     friend
00742     basic_string<charT>
00743     operator+ (const basic_string<charT>& lhs, charT rhs) _THROW_ALLOC_LENGTH ;
00744 
00745 };
00746 
00747 template <class charT>
00748 inline void
00749 basic_string_ref<charT>::delete_ptr () _THROW_NONE
00750 {
00751     if (res)
00752     {
00753         delete[] ptr;
00754         res = 0;
00755         ptr = 0;
00756     }
00757 }
00758 
00759 template <class charT>
00760 inline void
00761 basic_string_ref<charT>::throwlength ()  _THROW_LENGTH
00762 {
00763 #ifdef  __MEXCEPT
00764    throw   length_error("Length exception occurred");
00765 #else
00766    cout << "Length exception occurred" << endl;
00767    exit(1);
00768 #endif
00769 }
00770 
00771 template <class charT>
00772 inline void
00773 basic_string_ref<charT>::throwrange () _THROW_OUTRANGE
00774 {
00775 #ifdef  __MEXCEPT
00776    throw   out_of_range("Out of range exception occurred");
00777 #else
00778    cout << "Out of range exception occurred" << endl;
00779    exit(1);
00780 #endif
00781 }
00782 
00783 template <class charT>
00784 inline void
00785 basic_string<charT>::delete_ref () _THROW_NONE
00786 {
00787     --(reference->count);
00788     if (!(reference->count))
00789        delete reference;
00790 }
00791 
00792 template <class charT>
00793 inline size_t
00794 basic_string<charT>::ref_count () const _THROW_NONE
00795 {
00796     return reference->count;
00797 }
00798 
00799 template <class charT>
00800 inline const charT*
00801 basic_string<charT>::data () const _THROW_NONE
00802 {
00803     return (length() ? reference->ptr : 0);
00804 }
00805 
00806 template <class charT>
00807 inline charT*
00808 basic_string<charT>::point () _THROW_NONE
00809 {
00810     return reference->ptr;
00811 }
00812 
00813 template <class charT>
00814 inline size_t&
00815 basic_string<charT>::len () _THROW_NONE
00816 {
00817     return reference->len;
00818 }
00819 
00820 template <class charT>
00821 inline size_t
00822 basic_string<charT>::length () const _THROW_NONE
00823 {
00824     return reference->len;
00825 }
00826 
00827 template <class charT>
00828 inline size_t
00829 basic_string<charT>::reserve () const _THROW_NONE
00830 {
00831     return reference->res;
00832 }
00833 
00834 template <class charT>
00835 inline charT
00836 basic_string<charT>::at (size_t pos) const _THROW_OUTRANGE
00837 {
00838     if (pos >= length())
00839     {
00840         reference_class::throwrange();
00841     }
00842     return *(data()+pos);
00843 }
00844 
00845 template <class charT>
00846 inline charT
00847 basic_string<charT>::operator[] (size_t pos) const _THROW_NONE
00848 {
00849     if (pos < length())
00850         return *(data()+pos);
00851     else
00852         return 0;
00853 }
00854 
00855 template <class charT>
00856 inline bool
00857 operator== (const basic_string<charT>& lhs, const basic_string<charT>& rhs)
00858             _THROW_NONE
00859 {
00860     return !(lhs.compare(rhs));
00861 }
00862 
00863 template <class charT>
00864 inline bool
00865 operator== (const charT* lhs, const basic_string<charT>& rhs) _THROW_NONE
00866 {
00867     return !(rhs.compare(lhs));
00868 }
00869 
00870 template <class charT>
00871 inline bool
00872 operator== (charT lhs, const basic_string<charT>& rhs) _THROW_NONE
00873 {
00874     return !(rhs.compare(lhs));
00875 }
00876 
00877 template <class charT>
00878 inline bool
00879 operator== (const basic_string<charT>& lhs, const charT* rhs) _THROW_NONE
00880 {
00881     return !(lhs.compare(rhs));
00882 }
00883 
00884 template <class charT>
00885 inline bool
00886 operator== (const basic_string<charT>& lhs, charT rhs) _THROW_NONE
00887 {
00888     return !(lhs.compare(rhs));
00889 }
00890 
00891 #ifdef __MNONDEF
00892 template <class charT>
00893 inline bool
00894 operator!= (const basic_string<charT>& lhs, const basic_string<charT>& rhs)
00895             _THROW_NONE
00896 {
00897     return lhs.compare(rhs);
00898 }
00899 #endif
00900 
00901 template <class charT>
00902 inline bool
00903 operator!= (const charT* lhs, const basic_string<charT>& rhs) _THROW_NONE
00904 {
00905     return rhs.compare(lhs);
00906 }
00907 
00908 template <class charT>
00909 inline bool
00910 operator!= (charT lhs, const basic_string<charT>& rhs) _THROW_NONE
00911 {
00912     return rhs.compare(lhs);
00913 }
00914 
00915 template <class charT>
00916 inline bool
00917 operator!= (const basic_string<charT>& lhs, const charT* rhs) _THROW_NONE
00918 {
00919     return lhs.compare(rhs);
00920 }
00921 
00922 template <class charT>
00923 inline bool
00924 operator!= (const basic_string<charT>& lhs, charT rhs) _THROW_NONE
00925 {
00926     return lhs.compare(rhs);
00927 }
00928 
00929 template <class charT>
00930 inline bool
00931 operator< (const basic_string<charT>& lhs, const basic_string<charT>& rhs)
00932            _THROW_NONE
00933 {
00934     if (lhs.compare(rhs) < 0)
00935         return true;
00936     else
00937         return false;
00938 }
00939 
00940 template <class charT>
00941 inline bool
00942 operator< (const charT* lhs, const basic_string<charT>& rhs) _THROW_NONE
00943 {
00944     if (rhs.compare(lhs) > 0)
00945         return true;
00946     else
00947         return false;
00948 }
00949 
00950 template <class charT>
00951 inline bool
00952 operator< (charT lhs, const basic_string<charT>& rhs) _THROW_NONE
00953 {
00954     if (rhs.compare(lhs) > 0)
00955         return true;
00956     else
00957         return false;
00958 }
00959 
00960 template <class charT>
00961 inline bool
00962 operator< (const basic_string<charT>& lhs, const charT* rhs) _THROW_NONE
00963 {
00964     if (lhs.compare(rhs) < 0)
00965         return true;
00966     else
00967         return false;
00968 }
00969 
00970 template <class charT>
00971 inline bool
00972 operator< (const basic_string<charT>& lhs, charT rhs) _THROW_NONE
00973 {
00974     if (lhs.compare(rhs) < 0)
00975         return true;
00976     else
00977         return false;
00978 }
00979 
00980 #ifdef  __MNONDEF
00981 template <class charT>
00982 inline bool
00983 operator> (const basic_string<charT>& lhs, const basic_string<charT>& rhs)
00984            _THROW_NONE
00985 {
00986     return (rhs < lhs);
00987 }
00988 #endif
00989 
00990 template <class charT>
00991 inline bool
00992 operator> (const charT* lhs, const basic_string<charT>& rhs) _THROW_NONE
00993 {
00994     return (rhs < lhs);
00995 }
00996 
00997 template <class charT>
00998 inline bool
00999 operator> (charT lhs, const basic_string<charT>& rhs) _THROW_NONE
01000 {
01001     return (rhs < lhs);
01002 }
01003 
01004 template <class charT>
01005 inline bool
01006 operator> (const basic_string<charT>& lhs, const charT* rhs) _THROW_NONE
01007 {
01008     return (rhs < lhs);
01009 }
01010 
01011 template <class charT>
01012 inline bool
01013 operator> (const basic_string<charT>& lhs, charT rhs) _THROW_NONE
01014 {
01015     return (rhs < lhs);
01016 }
01017 
01018 #ifdef  __MNONDEF
01019 template <class charT>
01020 inline bool
01021 operator>= (const basic_string<charT>& lhs, const basic_string<charT>& rhs)
01022             _THROW_NONE
01023 {
01024     return !(lhs < rhs);
01025 }
01026 #endif
01027 
01028 template <class charT>
01029 inline bool
01030 operator>= (const charT* lhs, const basic_string<charT>& rhs) _THROW_NONE
01031 {
01032     return !(lhs < rhs);
01033 }
01034 
01035 template <class charT>
01036 inline bool
01037 operator>= (charT lhs, const basic_string<charT>& rhs) _THROW_NONE
01038 {
01039     return !(lhs < rhs);
01040 }
01041 
01042 template <class charT>
01043 inline bool
01044 operator>= (const basic_string<charT>& lhs, const charT* rhs) _THROW_NONE
01045 {
01046     return !(lhs < rhs);
01047 }
01048 
01049 template <class charT>
01050 inline bool
01051 operator>= (const basic_string<charT>& lhs, charT rhs) _THROW_NONE
01052 {
01053     return !(lhs < rhs);
01054 }
01055 
01056 #ifdef  __MNONDEF
01057 template <class charT>
01058 inline bool
01059 operator<= (const basic_string<charT>& lhs, const basic_string<charT>& rhs)
01060             _THROW_NONE
01061 {
01062     return !(rhs < lhs);
01063 }
01064 #endif
01065 
01066 template <class charT>
01067 inline bool
01068 operator<= (const charT* lhs, const basic_string<charT>& rhs) _THROW_NONE
01069 {
01070     return !(rhs < lhs);
01071 }
01072 
01073 template <class charT>
01074 inline bool
01075 operator<= (charT lhs, const basic_string<charT>& rhs) _THROW_NONE
01076 {
01077     return !(rhs < lhs);
01078 }
01079 
01080 template <class charT>
01081 inline bool
01082 operator<= (const basic_string<charT>& lhs, const charT* rhs) _THROW_NONE
01083 {
01084     return !(rhs < lhs);
01085 }
01086 
01087 template <class charT>
01088 inline bool
01089 operator<= (const basic_string<charT>& lhs, charT rhs) _THROW_NONE
01090 {
01091     return !(rhs < lhs);
01092 }
01093 
01094 // definitions : can be in a .c file
01095 //
01096 
01097 template <class charT>
01098 charT
01099 basic_string_ref<charT>::eos () _THROW_NONE
01100 {
01101     return baggage_type::eos();
01102 }
01103 
01104 template <class charT>
01105 basic_string_ref<charT>::basic_string_ref () _THROW_NONE
01106 {
01107      res = len = 0;
01108      ptr = 0;
01109      count = 1;
01110 }
01111 
01112 template <class charT>
01113 basic_string_ref<charT>::basic_string_ref (size_t size, capacity cap)
01114                                            _THROW_ALLOC_LENGTH
01115 {
01116     if (cap == ::reserve)
01117     {
01118        len = 0;
01119        res = size;
01120        ptr = new charT [res];
01121     }
01122     else if ((cap == ::default_size) && (size != NPOS))
01123     {
01124        res = len = size;
01125        if (res)
01126        {
01127           ptr = new charT [res];
01128           for (size_t position = 0; position < len; ++position)
01129               baggage_type::assign (*(ptr+position), eos());
01130        }
01131        else
01132           ptr = 0;
01133     }
01134     else
01135     {
01136        throwlength();
01137     }
01138     count = 1;
01139 }
01140 
01141 template <class charT>
01142 basic_string_ref<charT>::basic_string_ref (const basic_string<charT>& str,
01143                                            size_t pos, size_t rlen) _THROW_ALLOC
01144 {
01145     res = len = rlen;
01146     if (res)
01147     {
01148        ptr = new charT [res];
01149        baggage_type::copy (ptr, str.data()+pos, len);
01150     }
01151     else
01152        ptr = 0;
01153     count = 1;
01154 }
01155 
01156 template <class charT>
01157 basic_string_ref<charT>::basic_string_ref (const charT* s, size_t rlen,
01158                                            size_t rres) _THROW_ALLOC
01159 {
01160     res = rres;
01161     len = rlen;
01162     if (res)
01163     {
01164        ptr = new charT [res];
01165        if (len)
01166           baggage_type::copy (ptr, s, len);
01167     }
01168     else
01169        ptr = 0;
01170     count = 1;
01171 }
01172 
01173 template <class charT>
01174 basic_string_ref<charT>::basic_string_ref (const charT* s, size_t n)
01175                                            _THROW_ALLOC_LENGTH
01176 {
01177     if (n == NPOS)
01178     {
01179        throwlength();
01180     }
01181     res = len = n;
01182     if (res)
01183     {
01184        ptr = new charT [res];
01185        baggage_type::copy (ptr, s, len);
01186     }
01187     else
01188        ptr = 0;
01189     count = 1;
01190 }
01191 
01192 template <class charT>
01193 basic_string_ref<charT>::basic_string_ref (const charT* s) _THROW_ALLOC
01194 {
01195     res = len = baggage_type::length(s);
01196     if (res)
01197     {
01198        ptr = new charT [res];
01199        baggage_type::copy (ptr, s, len);
01200     }
01201     else
01202        ptr = 0;
01203     count = 1;
01204 }
01205 
01206 template <class charT>
01207 basic_string_ref<charT>::basic_string_ref (charT c, size_t rep)
01208                                            _THROW_ALLOC_LENGTH
01209 {
01210     if (rep == NPOS)
01211     {
01212        throwlength();
01213     }
01214     res = len = rep;
01215     if (res)
01216     {
01217        ptr = new charT [res];
01218        for (size_t  position = 0; position < len; ++position)
01219             baggage_type::assign (*(ptr+position), c);
01220     }
01221     else
01222        ptr = 0;
01223     count = 1;
01224 }
01225 
01226 template <class charT>
01227 basic_string_ref<charT>::basic_string_ref (const vector<charT>& vec)
01228                                            _THROW_ALLOC_LENGTH
01229 {
01230     size_t  n = vec.size();
01231     if (n == NPOS)
01232     {
01233         throwlength();
01234     }
01235     res = len = n;
01236     if (res)
01237     {
01238        ptr = new charT [res];
01239        baggage_type::copy (ptr, vec.begin(), len);
01240     }
01241     else
01242        ptr = 0;
01243     count = 1;
01244 }
01245 
01246 template <class charT>
01247 basic_string_ref<charT>::~basic_string_ref () _THROW_NONE
01248 {
01249     delete_ptr();
01250 }
01251 
01252 template <class charT>
01253 charT
01254 basic_string<charT>::eos () _THROW_NONE
01255 {
01256     return baggage_type::eos();
01257 }
01258 
01259 template <class charT>
01260 void
01261 basic_string<charT>::assign_str (const charT* s, size_t slen)
01262                                  _THROW_ALLOC_LENGTH
01263 {
01264     if (slen == NPOS)
01265     {
01266         reference_class::throwlength();
01267     }
01268     if ((ref_count() > 1) || (slen && (reserve() < slen)))
01269     {
01270         reference_pointer tmp;
01271         tmp = new basic_string_ref<charT> (s, slen);
01272         delete_ref();
01273         reference = tmp;
01274     }
01275     else if (slen)
01276     {
01277         baggage_type::copy (point(), s, slen);
01278     }
01279     reference->len = slen;
01280 }
01281 
01282 template <class charT>
01283 void
01284 basic_string<charT>::append_str (const charT* s, size_t slen)
01285                                  _THROW_ALLOC_LENGTH
01286 {
01287     if (length() >= (NPOS-slen))
01288     {
01289         reference_class::throwlength();
01290     }
01291     if ((ref_count() > 1) || (slen > (reserve()-length())))
01292     {
01293         reference_pointer tmp;
01294         tmp = new basic_string_ref<charT> (data(), length(), length()+slen);
01295         delete_ref();
01296         reference = tmp;
01297     }
01298     if (slen)
01299         baggage_type::copy (point()+length(), s, slen);
01300     reference->len += slen;
01301 }
01302 
01303 template <class charT>
01304 void
01305 basic_string<charT>::insert_str (size_t pos, const charT* s, size_t slen)
01306                                  _THROW_ALLOC_LENGTH_OUTRANGE
01307 {
01308     if (pos > length())
01309     {
01310         reference_class::throwrange();
01311     }
01312     if (length() >= (NPOS-slen))
01313     {
01314         reference_class::throwlength();
01315     }
01316     if ((ref_count() > 1) || (slen > (reserve()-length())))
01317     {
01318         reference_pointer tmp;
01319         tmp = new basic_string_ref<charT> (data(), pos, length()+slen);
01320         baggage_type::copy (tmp->ptr+pos+slen, data()+pos, length()-pos);
01321         tmp->len = length();
01322         delete_ref();
01323         reference = tmp;
01324     }
01325     else
01326     {
01327         for (size_t count = length()-pos; count > 0; --count)
01328              baggage_type::assign (*(point()+pos+slen+count-1),
01329                                    *(data()+pos+count-1));
01330     }
01331     if (slen)
01332         baggage_type::copy (point()+pos, s, slen);
01333     reference->len += slen;
01334 }
01335 
01336 template <class charT>
01337 void
01338 basic_string<charT>::replace_str (size_t xlen, size_t pos, const charT* s,
01339                      size_t slen) _THROW_ALLOC_LENGTH_OUTRANGE
01340 {
01341     if (pos > length())
01342     {
01343         reference_class::throwrange();
01344     }
01345     if ((length()-xlen) >= (NPOS-slen))
01346     {
01347         reference_class::throwlength();
01348     }
01349     if ((ref_count() > 1) || (reserve() < (length()+slen-xlen)))
01350     {
01351         reference_pointer tmp;
01352         tmp = new basic_string_ref<charT> (data(), pos, length()+slen-xlen);
01353         baggage_type::copy (tmp->ptr+pos+slen, data()+pos+xlen,
01354                             length()-pos-xlen);
01355         tmp->len = length();
01356         delete_ref();
01357         reference = tmp;
01358     }
01359     else 
01360     {
01361         if (slen < xlen)
01362             baggage_type::copy (point()+pos+slen, data()+pos+xlen,
01363                                 length()-pos-xlen);
01364         else
01365         {
01366             for (size_t count = length()-pos-xlen; count > 0; --count)
01367                 baggage_type::assign (*(point()+pos+slen+count-1),
01368                                       *(data()+pos+xlen+count-1));
01369         }
01370     }
01371     if (slen)
01372         baggage_type::copy (point()+pos, s, slen);
01373     reference->len += (slen-xlen);
01374 }
01375 
01376 template <class charT>
01377 int
01378 basic_string<charT>::compare_str (size_t pos, const charT* str, size_t slen,
01379                      size_t strlen) const _THROW_OUTRANGE
01380 {
01381     if (pos > length())
01382     {
01383         reference_class::throwrange();
01384     }
01385     size_t rlen = (slen > strlen ) ?  strlen  : slen;
01386     int result;
01387     if (!length())
01388         return str ? (eos()- *str) : eos();
01389     result =  baggage_type::compare (data()+pos, str, rlen);
01390     return result ? result : (length()-pos-strlen);
01391 }
01392 
01393 template <class charT>
01394 size_t
01395 basic_string<charT>::find_str (const charT* s, size_t pos, size_t len) 
01396                                const _THROW_NONE
01397 {
01398     size_t  count = pos;
01399     size_t  shift;
01400     size_t  place;
01401     if ((length() == 0) || (len == 0))
01402         return NPOS;
01403     while (len <= (length()-count))
01404     {
01405         for (place = 0; place < len; ++place)
01406         {
01407             if (baggage_type::ne(*(s+len-1-place), *(data()+count+(len-1-place))))
01408                 break;
01409         }
01410         if (place == len)
01411             return count;
01412         shift = find(*(s+len-1-place), count+(len-place));
01413         if (shift == NPOS)
01414             return NPOS;
01415         count = shift-(len-place-1);
01416     }
01417     return NPOS;
01418 }
01419 
01420 template <class charT>
01421 size_t
01422 basic_string<charT>::rfind_str (const charT* s, size_t pos, size_t len) 
01423                                 const _THROW_NONE
01424 {
01425     size_t  count = (pos < (length()-len)) ? (pos+1) : (length()-len);
01426     size_t  shift;
01427     size_t  place;    
01428     if ((length() < len) || (len == 0))
01429         return NPOS;
01430     while (count > 0)
01431     {
01432         for (place = 0; place < len; ++place)
01433         {
01434             if (baggage_type::ne(*(s+len-1-place), *(data()+count+(len-place)-2)))
01435                 break;
01436         }
01437         if (place == len)
01438             return count-1;
01439         shift = rfind(*(s+len-1-place), count+(len-place)-3);
01440         if (shift == NPOS)
01441             return NPOS;
01442         count = shift+place-len+2;
01443     }
01444     return NPOS;
01445 
01446 }
01447 
01448 template <class charT>
01449 size_t
01450 basic_string<charT>::find_first_of_str (const charT* s, size_t pos, size_t len) 
01451                                         const _THROW_NONE
01452 {
01453     size_t temp;
01454     size_t count  = pos;
01455     size_t result = NPOS;
01456     while (count < length())
01457     {
01458         temp = 0;
01459         while ((temp < len) && baggage_type::ne(*(data()+count), *(s+temp)))
01460             ++temp;
01461         if (temp != len)
01462             break;
01463         ++count;
01464     }
01465     temp = (count >= length()) ? NPOS : count;
01466     return ((result > temp) ? temp : result);
01467 }
01468 
01469 template <class charT>
01470 size_t
01471 basic_string<charT>::find_last_of_str (const charT* s, size_t pos, size_t len) 
01472                                        const _THROW_NONE
01473 {
01474     size_t temp = 0;
01475     size_t count = (pos < length()) ? (pos+1) : length();
01476     if (length())
01477     {
01478        while (count > 0)
01479        {
01480            temp = 0;
01481            --count;
01482            while ((temp != len) && baggage_type::ne(*(data()+count), *(s+temp)))
01483                ++temp;
01484            if (temp != len)
01485                break;
01486        }
01487     }
01488     return ((temp != len) && length()) ? count : NPOS;
01489 }
01490 
01491 template <class charT>
01492 size_t
01493 basic_string<charT>::find_first_not_of_str (const charT* s, size_t pos,
01494                      size_t len) const _THROW_NONE
01495 {
01496     size_t count = pos;
01497     while (count < length())
01498     {
01499         size_t temp  = 0;
01500         while (temp < len)
01501         {
01502             if (baggage_type::eq(*(data()+count), *(s+temp)))
01503                 break;
01504             ++temp;
01505         }
01506         if (temp == len)
01507             break;
01508         ++count;
01509     }
01510     return  ((count >= length()) ? NPOS : count);
01511 }
01512 
01513 template <class charT>
01514 size_t
01515 basic_string<charT>::find_last_not_of_str (const charT* s, size_t pos,
01516                      size_t len) const _THROW_NONE
01517 {
01518     size_t temp = 0;
01519     size_t count = (pos < length()) ? (pos+1) : length();
01520 
01521     if (length())
01522     {
01523         while (count > 0)
01524         {
01525            temp = 0;
01526            while (temp != len)
01527            {
01528                if (baggage_type::eq(*(data()+count-1), *(s+temp)))
01529                    break;
01530                ++temp;
01531            }
01532            if (temp == len)
01533                break;
01534            --count;
01535        }
01536     }
01537     return ((temp == len) && length()) ? count-1 : NPOS;
01538 }
01539 
01540 template <class charT>
01541 basic_string<charT>::basic_string () _THROW_ALLOC
01542 {
01543     reference = new basic_string_ref<charT> ();
01544     c_str_ptr = 0;
01545 }
01546 
01547 template <class charT>
01548 basic_string<charT>::basic_string (size_t size, capacity cap)
01549                                    _THROW_ALLOC_LENGTH
01550 {
01551     reference = new basic_string_ref<charT> (size, cap);
01552     c_str_ptr = 0;
01553 }
01554 
01555 template <class charT>
01556 basic_string<charT>::basic_string (const basic_string<charT>& str,
01557                                    size_t pos, size_t n) _THROW_ALLOC_OUTRANGE
01558 {
01559     if (pos > str.length())
01560     {
01561        reference_class::throwrange();
01562     }
01563     size_t rlen =  (n > (str.length() - pos)) ? str.length() - pos : n;
01564     if ((rlen == str.length()) && (str.ref_count() != NPOS))
01565        (reference = str.reference)->count++;
01566     else
01567         reference = new basic_string_ref<charT> (str, pos, rlen);
01568     c_str_ptr = 0;
01569 }
01570 
01571 template <class charT>
01572 basic_string<charT>::basic_string (const charT* s, size_t rlen, size_t xlen)
01573                                    _THROW_ALLOC_LENGTH
01574 {
01575     if (rlen >= (NPOS - xlen))
01576     {
01577         reference_class::throwlength();
01578     }
01579     reference = new basic_string_ref<charT> (s, rlen, rlen+xlen);
01580     c_str_ptr = 0;
01581 }
01582 
01583 template <class charT>
01584 basic_string<charT>::basic_string (const charT* s, size_t n) _THROW_ALLOC_LENGTH
01585 {
01586     reference = new basic_string_ref<charT> (s, n);
01587     c_str_ptr = 0;
01588 }
01589 
01590 template <class charT>
01591 basic_string<charT>::basic_string (const charT* s) _THROW_ALLOC
01592 {
01593     reference = new basic_string_ref<charT> (s);
01594     c_str_ptr = 0;
01595 }
01596 
01597 template <class charT>
01598 basic_string<charT>::basic_string (charT c, size_t rep) _THROW_ALLOC_LENGTH
01599 {
01600     reference = new basic_string_ref<charT> (c, rep);
01601     c_str_ptr = 0;
01602 }
01603 
01604 template <class charT>
01605 basic_string<charT>::basic_string (const vector<charT>& vec) _THROW_ALLOC_LENGTH
01606 {
01607     reference = new basic_string_ref<charT> (vec);
01608     c_str_ptr = 0;
01609 }
01610 
01611 template <class charT>
01612 basic_string<charT>::~basic_string () _THROW_NONE
01613 {
01614     delete_ref();
01615     if (c_str_ptr)
01616         delete[] c_str_ptr;
01617 }
01618 
01619 template <class charT>
01620 basic_string<charT>&
01621 basic_string<charT>::operator= (const basic_string<charT>& str) _THROW_ALLOC
01622 {
01623     if (this != &str)
01624     {
01625         delete_ref();
01626         if (str.ref_count() != NPOS)
01627            (reference = str.reference)->count++;
01628         else
01629             reference = new basic_string_ref<charT> (str, 0, str.length());
01630     }
01631     return *this;
01632 }
01633 
01634 template <class charT>
01635 basic_string<charT>&
01636 basic_string<charT>::operator= (const charT* s) _THROW_ALLOC
01637 {
01638     assign_str (s, baggage_type::length(s));
01639     return *this;
01640 }
01641 
01642 template <class charT>
01643 basic_string<charT>&
01644 basic_string<charT>::operator= (charT c) _THROW_ALLOC
01645 {
01646     if ((ref_count() == 1) && (reserve() >= 1))
01647     {
01648         baggage_type::assign (*(point()), c);
01649         reference->len = 1;
01650     }
01651     else
01652     {
01653         delete_ref();
01654         reference = new basic_string_ref<charT> (c, 1);
01655     }
01656     return *this;
01657 }
01658 
01659 template <class charT>
01660 basic_string<charT>&
01661 basic_string<charT>::operator+= (const basic_string<charT>& rhs) _THROW_ALLOC_LENGTH
01662 {
01663     append_str (rhs.data(), rhs.length());
01664     return *this;
01665 }
01666 
01667 template <class charT>
01668 basic_string<charT>&
01669 basic_string<charT>::operator+= (const charT* s) _THROW_ALLOC_LENGTH
01670 {
01671     append_str (s, baggage_type::length(s));
01672     return *this;
01673 }
01674 
01675 template <class charT>
01676 basic_string<charT>&
01677 basic_string<charT>::operator+= (charT c) _THROW_ALLOC_LENGTH
01678 {
01679     if (length() >= (NPOS-1))
01680     {
01681         reference_class::throwlength();
01682     }
01683     if (!((ref_count() == 1) && (reserve() > length())))
01684     {
01685         reference_pointer tmp;
01686         tmp = new basic_string_ref<charT> (data(), length(), length()+1);
01687         delete_ref();
01688         reference = tmp;
01689     }
01690     baggage_type::assign (*(point()+length()), c);
01691     reference->len++;
01692     return *this;
01693 }
01694 
01695 
01696 template <class charT>
01697 basic_string<charT>&
01698 basic_string<charT>::append (const basic_string<charT>& str, size_t pos, size_t n)
01699                      _THROW_ALLOC_LENGTH_OUTRANGE
01700 {
01701     if (pos > str.length())
01702     {
01703         reference_class::throwrange();
01704     }
01705     append_str (str.data() + pos, (n>(str.length()-pos))?(str.length()-pos):n);
01706     return *this;
01707 }
01708 
01709 template <class charT>
01710 basic_string<charT>&
01711 basic_string<charT>::append (const charT* s, size_t n) _THROW_ALLOC_LENGTH
01712 {
01713     append_str (s, n);
01714     return *this;
01715 }
01716 
01717 template <class charT>
01718 basic_string<charT>&
01719 basic_string<charT>::append (const charT* s) _THROW_ALLOC_LENGTH
01720 {
01721     append_str (s, baggage_type::length(s));
01722     return *this;
01723 }
01724 
01725 template <class charT>
01726 basic_string<charT>&
01727 basic_string<charT>::append (charT c, size_t rep) _THROW_ALLOC_LENGTH
01728 {
01729     if (length() >= (NPOS-rep))
01730     {
01731         reference_class::throwlength();
01732     }
01733     if (rep)
01734     {
01735        if ((ref_count() > 1) || (reserve() < (length() + rep)))
01736        {
01737           reference_pointer tmp;
01738           tmp = new basic_string_ref<charT> (data(), length(), length()+rep);
01739           delete_ref();
01740           reference = tmp;
01741        }
01742        for (size_t count = 0; count < rep; ++count)
01743             baggage_type::assign (*(point()+length()+count), c);
01744        reference->len += rep;
01745     }
01746     return *this;
01747 }
01748 
01749 template <class charT>
01750 basic_string<charT>&
01751 basic_string<charT>::assign (const basic_string<charT>& str, size_t pos, size_t n)
01752                              _THROW_ALLOC_LENGTH_OUTRANGE
01753 {
01754     if (pos > str.length())
01755     {
01756         reference_class::throwrange();
01757     }
01758     size_t rlen = (n > (str.length() - pos)) ? str.length() - pos : n;
01759     if ((rlen == str.length()) && (str.ref_count() != NPOS))
01760     {
01761        delete_ref();
01762        (reference = str.reference)->count++;
01763     }
01764     else
01765        assign_str (str.data()+pos, rlen);
01766     return *this;
01767 }
01768 
01769 template <class charT>
01770 basic_string<charT>&
01771 basic_string<charT>::assign (const charT* s, size_t n) _THROW_ALLOC_LENGTH
01772 {
01773     assign_str (s, n);
01774     return *this;
01775 }
01776 
01777 template <class charT>
01778 basic_string<charT>&
01779 basic_string<charT>::assign (const charT* s) _THROW_ALLOC_LENGTH
01780 {
01781     assign_str (s, baggage_type::length(s));
01782     return *this;
01783 }
01784 
01785 template <class charT>
01786 basic_string<charT>&
01787 basic_string<charT>::assign (charT c, size_t rep) _THROW_ALLOC_LENGTH
01788 {
01789     if (rep == NPOS)
01790     {
01791         reference_class::throwlength();
01792     }
01793     if ((ref_count() > 1) || (rep && (reserve() < rep)))
01794     {
01795         reference_pointer tmp;
01796         tmp = new basic_string_ref<charT> (c, rep);
01797         delete_ref();
01798         reference = tmp;
01799     }
01800     else
01801     {
01802         for (size_t count = 0; count < rep; ++count)
01803             baggage_type::assign (*(point()+count), c);
01804         reference->len = rep;
01805     }
01806     return *this;
01807 }
01808 
01809 template <class charT>
01810 basic_string<charT>&
01811 basic_string<charT>::insert (size_t pos1, const basic_string<charT>& str,
01812                              size_t pos2, size_t n) _THROW_ALLOC_LENGTH_OUTRANGE
01813 {
01814     if (pos2 > str.length())
01815     {
01816         reference_class::throwrange();
01817     }
01818     size_t rlen = (n > (str.length() - pos2)) ? str.length() - pos2 : n;
01819     insert_str (pos1, str.data()+pos2, rlen);
01820     return *this;
01821 }
01822 
01823 template <class charT>
01824 basic_string<charT>&
01825 basic_string<charT>::insert (size_t pos, const charT* s, size_t n)
01826                              _THROW_ALLOC_LENGTH_OUTRANGE
01827 {
01828     insert_str(pos, s, n);
01829     return *this;
01830 }
01831 
01832 template <class charT>
01833 basic_string<charT>&
01834 basic_string<charT>::insert (size_t pos, const charT* s)
01835                              _THROW_ALLOC_LENGTH_OUTRANGE
01836 {
01837     insert_str(pos, s, baggage_type::length(s));
01838     return *this;
01839 }
01840 
01841 template <class charT>
01842 basic_string<charT>&
01843 basic_string<charT>::insert (size_t pos, charT c, size_t rep)
01844                              _THROW_ALLOC_LENGTH_OUTRANGE
01845 {
01846     if (pos > length())
01847     {
01848         reference_class::throwrange();
01849     }
01850     if ((rep == NPOS) || (length() >= (NPOS - rep)))
01851     {
01852         reference_class::throwlength();
01853     }
01854     if (rep)
01855     {
01856         size_t count;
01857         if ((ref_count() > 1) || (reserve() < (length()+rep)))
01858         {
01859            reference_pointer tmp;
01860            tmp = new basic_string_ref<charT> (data(), pos, length()+rep);
01861            if (length())
01862                for (count = length()-pos; count > 0; --count)
01863                     baggage_type::assign (*(tmp->ptr+pos+rep+count-1),
01864                                           *(data()+pos+count-1));
01865            tmp->len = length();
01866            delete_ref();
01867            reference = tmp;
01868         }
01869         else
01870         {
01871            for (count = length()-pos; count > 0; --count)
01872                 baggage_type::assign (*(point()+pos+rep+count-1),
01873                                       *(data()+pos+count-1));
01874         }
01875         for (count = 0; count < rep; ++count)
01876             baggage_type::assign (*(point()+pos+count), c);
01877         reference->len += rep;
01878     }
01879     return *this;
01880 }
01881 
01882 template <class charT>
01883 basic_string<charT>&
01884 basic_string<charT>::erase (size_t pos, size_t n) _THROW_ALLOC_OUTRANGE
01885 {
01886     if (pos > length())
01887     {
01888         reference_class::throwrange();
01889     }
01890     size_t xlen = (n > (length()-pos)) ? (length()-pos) : n;
01891     if (ref_count() > 1)
01892     {
01893         reference_pointer tmp;
01894         tmp = new basic_string_ref<charT> (data(), pos, length());
01895         baggage_type::copy (tmp->ptr+pos, data()+pos+xlen, length()-xlen-pos);
01896         tmp->len = length()-xlen;
01897         delete_ref();
01898         reference = tmp;
01899     }
01900     else if (xlen == length())
01901         reference->len = 0;
01902     else if (xlen)
01903     {
01904         baggage_type::copy (point()+pos, data()+pos+xlen, length()-xlen-pos);
01905         reference->len -= xlen;
01906     }
01907     return *this;
01908 }
01909 
01910 template <class charT>
01911 basic_string<charT>&
01912 basic_string<charT>::replace (size_t pos1, size_t n1, const basic_string<charT>& str,
01913                      size_t pos2, size_t n2) _THROW_ALLOC_LENGTH_OUTRANGE
01914 {
01915     if (pos2 > str.length())
01916     {
01917         reference_class::throwrange();
01918     }
01919     size_t xlen = (n1 > (length()-pos1)) ? (length()-pos1) : n1;
01920     size_t rlen = (n2 > (str.length()-pos2)) ? (str.length()-pos2) : n2;
01921     replace_str (xlen, pos1, str.data()+pos2, rlen);
01922     return *this;
01923 }
01924 
01925 template <class charT>
01926 basic_string<charT>&
01927 basic_string<charT>::replace (size_t pos, size_t n1, const charT* s, size_t n2)
01928                               _THROW_ALLOC_LENGTH_OUTRANGE
01929 {
01930     size_t xlen = (n1 > (length()-pos)) ? (length()-pos) : n1;
01931     replace_str (xlen, pos, s, n2);
01932     return *this;
01933 }
01934 
01935 template <class charT>
01936 basic_string<charT>&
01937 basic_string<charT>::replace (size_t pos, size_t n1, const charT* s)
01938                               _THROW_ALLOC_LENGTH_OUTRANGE
01939 {
01940     size_t xlen = (n1 > (length()-pos)) ? (length()-pos) : n1;
01941     replace_str (xlen, pos, s, baggage_type::length(s));
01942     return *this;
01943 }
01944 
01945 template <class charT>
01946 basic_string<charT>&
01947 basic_string<charT>::replace (size_t pos, size_t n, charT c, size_t rep)
01948                               _THROW_ALLOC_LENGTH_OUTRANGE
01949 {
01950     if (pos > length())
01951     {
01952         reference_class::throwrange();
01953     }
01954     size_t xlen = (n > (length()-pos)) ? (length()-pos) : n;
01955     if ((length()-xlen) >= (NPOS-rep))
01956     {
01957         reference_class::throwlength();
01958     }
01959     if (!rep)
01960         return erase (pos, n);
01961     else
01962     {
01963         size_t count;
01964         if ((ref_count() > 1) || (reserve() < (length()-xlen+rep)))
01965         {
01966             reference_pointer tmp;
01967             tmp = new basic_string_ref<charT> (data(), pos,
01968                   length()+((xlen > rep) ? (xlen-rep) : 0));
01969             if (rep < xlen)
01970                 baggage_type::copy (tmp->ptr+pos+rep, data()+pos+xlen,
01971                                     length()-pos-xlen);
01972             else
01973             {
01974                 for (count = length()-xlen-pos; count > 0; --count)
01975                     baggage_type::assign (*(tmp->ptr+pos+rep+count-1),
01976                                           *(data()+pos+xlen+count-1));
01977             }
01978             tmp->len = length();
01979             delete_ref();
01980             reference = tmp;
01981         }
01982         else
01983         {
01984             if (rep < xlen)
01985                 baggage_type::copy (point()+pos+rep, data()+pos+xlen,
01986                                     length()-pos-xlen);
01987             else
01988             {
01989                 for (count = length()-xlen-pos; count > 0; --count)
01990                     baggage_type::assign (*(point()+pos+rep+count-1),
01991                                           *(data()+pos+xlen+count-1));
01992             }
01993         }
01994         for (count = 0; count < rep; ++count)
01995             baggage_type::assign (*(point()+pos+count), c);
01996         reference->len += (rep-xlen);
01997     }
01998     return *this;
01999 }
02000 
02001 template <class charT>
02002 void
02003 basic_string<charT>::put_at (size_t pos, charT c) _THROW_ALLOC_OUTRANGE
02004 {
02005     if (pos > length())
02006     {
02007         reference_class::throwrange();
02008     }
02009     if ((ref_count() > 1) || (pos == reserve()))
02010     {
02011         reference_pointer tmp;
02012         tmp = new basic_string_ref<charT> (data(), length(),
02013               length()+((pos==length())?1:0));
02014         delete_ref();
02015         reference = tmp;
02016     }
02017     if (pos == length())
02018         ++reference->len;
02019     baggage_type::assign (*(point()+pos), c);
02020 }
02021 
02022 template <class charT>
02023 charT&
02024 basic_string<charT>::operator[] (size_t pos) _THROW_ALLOC_OUTRANGE
02025 {
02026     if (pos >= length())
02027     {
02028         reference_class::throwrange();
02029     }
02030     if (ref_count() > 1)
02031     {
02032         reference_pointer tmp;
02033         tmp = new basic_string_ref<charT> (data(), length(), length());
02034         delete_ref();
02035         reference = tmp;
02036     }
02037     return *(point()+pos);
02038 }
02039 
02040 template <class charT>
02041 const charT*
02042 basic_string<charT>::c_str () const _THROW_ALLOC
02043 {
02044     // cast away const-ness so we can reset c_str_ptr
02045     basic_string<charT>* nc_this = (basic_string<charT>*) this;
02046     if (c_str_ptr)
02047         delete [] nc_this->c_str_ptr;
02048     nc_this->c_str_ptr = new charT [length()+1];
02049     if (length())
02050         baggage_type::copy (nc_this->c_str_ptr, data(), length());
02051     baggage_type::assign (*(nc_this->c_str_ptr+length()), eos());
02052     return c_str_ptr;
02053 }
02054 
02055 template <class charT>
02056 void
02057 basic_string<charT>::resize (size_t n, charT c) _THROW_ALLOC_LENGTH
02058 {
02059     if (n == NPOS)
02060     {
02061         reference_class::throwlength();
02062     }
02063     if ((ref_count() > 1) || (n > reserve()))
02064     {
02065         reference_pointer tmp;
02066         tmp = new basic_string_ref<charT> (data(),
02067               ((n > length()) ? length() : n), n);
02068         delete_ref();
02069         reference = tmp;
02070     }
02071     while (reference->len < n)
02072     {
02073         baggage_type::assign (*(reference->ptr+length()), c);
02074         ++reference->len;
02075     }
02076     reference->len = n;
02077 }
02078 
02079 template <class charT>
02080 void
02081 basic_string<charT>::resize (size_t n) _THROW_ALLOC_LENGTH
02082 {
02083     resize (n, eos());
02084 }
02085 
02086 template <class charT>
02087 void
02088 basic_string<charT>::reserve (size_t res_arg) _THROW_ALLOC_LENGTH
02089 {
02090     if (res_arg == NPOS)
02091     {
02092         reference_class::throwlength();
02093     }
02094     if (res_arg > reserve())
02095     {
02096         reference_pointer tmp;
02097         tmp = new  basic_string_ref<charT> (data(), length(), res_arg);
02098         delete_ref();
02099         reference = tmp;
02100     }
02101 }
02102 
02103 template <class charT>
02104 size_t
02105 basic_string<charT>::copy (charT* s, size_t n, size_t pos) const _THROW_OUTRANGE
02106 {
02107     if (pos > length())
02108     {
02109         reference_class::throwrange();
02110     }
02111     size_t  rlen = (n > (length()-pos)) ? (length()-pos) : n;
02112     if (length())
02113         baggage_type::copy (s, data()+pos, rlen);
02114     return rlen;
02115 }
02116 
02117 template <class charT>
02118 size_t
02119 basic_string<charT>::find (const basic_string<charT>& str, size_t pos) const
02120                            _THROW_NONE
02121 {
02122     return find_str (str.data(), pos, str.length());
02123 }
02124 
02125 template <class charT>
02126 size_t
02127 basic_string<charT>::find (const charT* s, size_t pos, size_t n) const
02128                            _THROW_NONE
02129 {
02130     return find_str (s, pos, n);
02131 }
02132 
02133 template <class charT>
02134 size_t
02135 basic_string<charT>::find (const charT* s, size_t pos) const _THROW_NONE
02136 {
02137     return find_str (s, pos, baggage_type::length(s));
02138 }
02139 
02140 template <class charT>
02141 size_t
02142 basic_string<charT>::find (charT c, size_t pos) const _THROW_NONE
02143 {
02144     while ((pos < length()) && (baggage_type::ne(*(data()+pos), c)))
02145         ++pos;
02146     return ((pos < length()) ? pos : NPOS);
02147 }
02148 
02149 template <class charT>
02150 size_t
02151 basic_string<charT>::rfind (const basic_string<charT>& str, size_t pos) const
02152                             _THROW_NONE
02153 {
02154     return rfind_str (str.data(), pos, str.length());
02155 }
02156 
02157 template <class charT>
02158 size_t
02159 basic_string<charT>::rfind (const charT* s, size_t pos, size_t n) const
02160                             _THROW_NONE
02161 {
02162     return rfind_str (s, pos, n);
02163 }
02164 
02165 template <class charT>
02166 size_t
02167 basic_string<charT>::rfind (const charT* s, size_t pos) const _THROW_NONE
02168 {
02169     return rfind_str (s, pos, baggage_type::length(s));
02170 }
02171 
02172 template <class charT>
02173 size_t
02174 basic_string<charT>::rfind (charT c, size_t pos) const _THROW_NONE
02175 {
02176     size_t count = ((pos < length()) ? pos+1 : length());
02177     if (length() == 0)
02178         return NPOS;
02179     while ((baggage_type::ne(*(data()+count-1), c)) && (count > 1))
02180         --count;
02181     if ((count == 1) && (baggage_type::ne(*(data()), c)))
02182         return NPOS;
02183     else
02184         return count-1;
02185 }
02186 
02187 template <class charT>
02188 size_t
02189 basic_string<charT>::find_first_of (const basic_string<charT>& str, size_t pos) const
02190                                     _THROW_NONE
02191 {
02192     return find_first_of_str (str.data(), pos, str.length());
02193 }
02194 
02195 template <class charT>
02196 size_t
02197 basic_string<charT>::find_first_of (const charT* s, size_t pos, size_t n) const
02198                                     _THROW_NONE
02199 {
02200     return find_first_of_str (s, pos, n);
02201 }
02202 
02203 template <class charT>
02204 size_t
02205 basic_string<charT>::find_first_of (const charT* s, size_t pos) const
02206                                     _THROW_NONE
02207 {
02208     return find_first_of_str (s, pos, baggage_type::length(s));
02209 }
02210 
02211 template <class charT>
02212 size_t
02213 basic_string<charT>::find_first_of (charT c, size_t pos) const _THROW_NONE
02214 {
02215     return find (c, pos);
02216 }
02217 
02218 template <class charT>
02219 size_t
02220 basic_string<charT>::find_last_of (const basic_string<charT>& str, size_t pos) const
02221                                    _THROW_NONE
02222 {
02223     return find_last_of_str (str.data(), pos, str.length());
02224 }
02225 
02226 template <class charT>
02227 size_t
02228 basic_string<charT>::find_last_of (const charT* s, size_t pos, size_t n) const
02229                                    _THROW_NONE
02230 {
02231     return find_last_of_str (s, pos, n);
02232 }
02233 
02234 template <class charT>
02235 size_t
02236 basic_string<charT>::find_last_of (const charT* s, size_t pos) const _THROW_NONE
02237 {
02238     return find_last_of_str (s, pos, baggage_type::length(s));
02239 }
02240 
02241 template <class charT>
02242 size_t
02243 basic_string<charT>::find_last_of (charT c, size_t pos) const _THROW_NONE
02244 {
02245     return rfind (c, pos);
02246 }
02247 
02248 template <class charT>
02249 size_t
02250 basic_string<charT>::find_first_not_of (const basic_string<charT>& str, size_t pos)
02251                                         const _THROW_NONE
02252 {
02253     return find_first_not_of_str (str.data(), pos, str.length());
02254 }
02255 
02256 template <class charT>
02257 size_t
02258 basic_string<charT>::find_first_not_of (const charT* s, size_t pos, size_t n)
02259                                         const _THROW_NONE
02260 {
02261     return find_first_not_of_str (s, pos, n);
02262 }
02263 
02264 template <class charT>
02265 size_t
02266 basic_string<charT>::find_first_not_of (const charT* s, size_t pos) const
02267                                         _THROW_NONE
02268 {
02269     return find_first_not_of_str (s, pos, baggage_type::length(s));
02270 }
02271 
02272 template <class charT>
02273 size_t
02274 basic_string<charT>::find_first_not_of (charT c, size_t pos) const _THROW_NONE
02275 {
02276     while ((pos < length()) && (baggage_type::eq(*(data()+pos), c)))
02277         ++pos;
02278     return ((pos < length()) ? pos : NPOS);
02279 }
02280 
02281 template <class charT>
02282 size_t
02283 basic_string<charT>::find_last_not_of (const basic_string<charT>& str, size_t pos)
02284                                        const _THROW_NONE
02285 {
02286     return find_last_not_of_str (str.data(), pos, str.length());
02287 }
02288 
02289 template <class charT>
02290 size_t
02291 basic_string<charT>::find_last_not_of (const charT* s, size_t pos, size_t n)
02292                                        const _THROW_NONE
02293 {
02294     return find_last_not_of_str (s, pos, n);
02295 }
02296 
02297 template <class charT>
02298 size_t
02299 basic_string<charT>::find_last_not_of (const charT* s, size_t pos) const
02300                                        _THROW_NONE
02301 {
02302     return find_last_not_of_str (s, pos, baggage_type::length(s));
02303 }
02304 
02305 template <class charT>
02306 size_t
02307 basic_string<charT>::find_last_not_of (charT c, size_t pos) const _THROW_NONE
02308 {
02309     size_t count = ((pos < length()) ? pos+1 : length());
02310     if (length() == 0)
02311         return NPOS;
02312     while ((baggage_type::eq(*(data()+count-1), c)) && (count > 1))
02313         --count;
02314     if ((count == 1) && (baggage_type::eq(*(data()), c)))
02315         return NPOS;
02316     else
02317         return count-1;
02318 }
02319 
02320 template <class charT>
02321 basic_string<charT>
02322 basic_string<charT>::substr (size_t pos,  size_t n) const _THROW_ALLOC_OUTRANGE
02323 {
02324     if (pos > length())
02325     {
02326         reference_class::throwrange();
02327     }
02328     if (length())
02329         return basic_string<charT> (data()+pos,
02330         (n > (length()-pos)) ? (length()-pos) : n);
02331     else
02332         return basic_string<charT>();
02333 }
02334 
02335 template <class charT>
02336 int
02337 basic_string<charT>::compare (const basic_string<charT>& str, size_t pos,
02338                               size_t n) const _THROW_OUTRANGE
02339 {
02340     size_t slen   = (n > (length()-pos)) ? (length()-pos) : n;
02341     return compare_str (pos, str.data(), slen, str.length());
02342 }
02343 
02344 template <class charT>
02345 int
02346 basic_string<charT>::compare (const charT* s, size_t pos, size_t n) const
02347                               _THROW_LENGTH_OUTRANGE
02348 {
02349     if (n == NPOS)
02350     {
02351         reference_class::throwlength();
02352     }
02353     return compare_str (pos, s, length()-pos, n);
02354 }
02355 
02356 template <class charT>
02357 int
02358 basic_string<charT>::compare (const charT* s, size_t pos) const _THROW_OUTRANGE
02359 {
02360     return compare_str (pos, s, length()-pos, baggage_type::length(s));
02361 }
02362 
02363 template <class charT>
02364 int
02365 basic_string<charT>::compare (charT c, size_t pos, size_t rep) const
02366                               _THROW_LENGTH_OUTRANGE
02367 {
02368     if (pos > length())
02369     {
02370         reference_class::throwrange();
02371     }
02372     if (rep == NPOS)
02373     {
02374         reference_class::throwlength();
02375     }
02376     if (rep)
02377     {
02378         size_t count = 0;
02379         while ((count < rep) && (count < (length()-pos)) &&
02380                 baggage_type::eq (*(data()+pos+count), c))
02381             ++count;
02382         if ((count == rep) || (count == (length()-pos)))
02383             return (length()-pos-count);
02384         else
02385             return (*(data()+pos+count)-c);
02386     }
02387     else
02388     {
02389         return (length()-pos);
02390     }
02391 }
02392 
02393 template <class charT>
02394 basic_string<charT>
02395 operator+ (const basic_string<charT>& lhs, const basic_string<charT>& rhs)
02396            _THROW_ALLOC_LENGTH
02397 {
02398     typedef  basic_string<charT>::baggage_type  baggage_type;
02399     basic_string<charT> tmp(lhs.data(), lhs.length(), rhs.length());
02400     if (rhs.length())
02401         baggage_type::copy (tmp.point()+lhs.length(), rhs.data(), rhs.length());
02402     tmp.len() += rhs.length();
02403     return tmp;
02404 }
02405 
02406 template <class charT>
02407 basic_string<charT>
02408 operator+ (const charT* lhs, const basic_string<charT>& rhs) _THROW_ALLOC_LENGTH
02409 {
02410     typedef  basic_string<charT>::baggage_type  baggage_type; 
02411     size_t  slen = baggage_type::length(lhs);
02412     basic_string<charT> tmp(lhs, slen, rhs.length());
02413     if (rhs.length())
02414         baggage_type::copy (tmp.point()+slen, rhs.data(), rhs.length());
02415     tmp.len() += rhs.length();
02416     return tmp;
02417 }
02418 
02419 template <class charT>
02420 basic_string<charT>
02421 operator+ (charT lhs, const basic_string<charT>& rhs) _THROW_ALLOC_LENGTH
02422 {
02423     typedef  basic_string<charT>::baggage_type  baggage_type; 
02424     basic_string<charT> tmp(&lhs, 1, rhs.length());
02425     if (rhs.length())
02426         baggage_type::copy (tmp.point()+1, rhs.data(), rhs.length());
02427     tmp.len() += rhs.length();
02428     return tmp;
02429 }
02430 
02431 template <class charT>
02432 basic_string<charT>
02433 operator+ (const basic_string<charT>& lhs, const charT* rhs) _THROW_ALLOC_LENGTH
02434 {
02435     typedef  basic_string<charT>::baggage_type  baggage_type; 
02436     size_t  slen = baggage_type::length(rhs);
02437     basic_string<charT> tmp(lhs.data(), lhs.length(), slen);
02438     if (slen)
02439         baggage_type::copy (tmp.point()+lhs.length(), rhs, slen);
02440     tmp.len() += slen;
02441     return tmp;
02442 }
02443 
02444 template <class charT>
02445 basic_string<charT>
02446 operator+ (const basic_string<charT>& lhs, charT rhs) _THROW_ALLOC_LENGTH
02447 {
02448     typedef  basic_string<charT>::baggage_type  baggage_type; 
02449     basic_string<charT> tmp(lhs.data(), lhs.length(), 1);
02450     baggage_type::assign (*(tmp.point()+lhs.length()), rhs);
02451     ++tmp.len();
02452     return tmp;
02453 }
02454 
02455 template <class charT>
02456 ostream&
02457 operator<< (ostream& o, const basic_string<charT>& s) _THROW_NONE
02458 {
02459     typedef  basic_string<charT>::baggage_type  baggage_type;
02460     for (size_t count = 0; count < s.length(); ++count)
02461         baggage_type::char_out (o, *(s.data()+count));
02462     return o;
02463 }
02464 
02465 template <class charT>
02466 istream&
02467 operator>> (istream& i, basic_string<charT>& s) _THROW_ALLOC_LENGTH
02468 {
02469     typedef  basic_string<charT>::baggage_type  baggage_type; 
02470     s.erase();
02471     while (true)
02472     {
02473         charT  value;
02474         baggage_type::char_in (i, value);
02475         if (!i.operator void*())
02476             break;
02477         if (!baggage_type::is_del (value))
02478         {
02479             s.append(value);
02480             while (true)
02481             {
02482                 baggage_type::char_in (i, value);
02483                 if (!i.operator void*())
02484                     break;
02485                 if (!baggage_type::is_del (value)) 
02486                 {
02487                     s.append(value);
02488                 }
02489                 else
02490                     break;
02491             }
02492             break;
02493         }
02494     }
02495     return i;
02496 }
02497 
02498 typedef  basic_string<char>     cstring;
02499 typedef  basic_string<char>     string;
02500 // typedef  basic_string<wchar_t>  wstring;
02501 
02502 
02503 /* The following is a workaround for a compiler bug in some versions
02504 of the Apogee compiler. This looks pretty weird, and it shouldn't
02505 work, but more obvious constructs cause other error messages.---DRM */
02506 
02507 inline void destroy(string* pointer) {
02508     pointer->~basic_string();
02509 }
02510 
02511 #endif // BSTRING_H
02512 
02513 /***************************************************************************
02514  * $RCSfile: bstring.h,v $   $Author: adelmann $
02515  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:34 $
02516  * IPPL_VERSION_ID: $Id: bstring.h,v 1.1.1.1 2003/01/23 07:40:34 adelmann Exp $ 
02517  ***************************************************************************/
02518 

Generated on Mon Jan 16 13:23:57 2006 for IPPL by  doxygen 1.4.6