Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*      Copyright (C) 2004 Garrett A. Kajmowicz
  2.  
  3.         This file is part of the uClibc++ Library.
  4.  
  5.         This library is free software; you can redistribute it and/or
  6.         modify it under the terms of the GNU Lesser General Public
  7.         License as published by the Free Software Foundation; either
  8.         version 2.1 of the License, or (at your option) 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 GNU
  13.         Lesser General Public License for more details.
  14.  
  15.         You should have received a copy of the GNU Lesser General Public
  16.         License along with this library; if not, write to the Free Software
  17.         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18. */
  19.  
  20. #include <basic_definitions>
  21. #include <char_traits>
  22. #include <string.h>
  23. #include <func_exception>
  24. #include <memory>
  25. #include <vector>
  26.  
  27.  
  28. #ifdef __UCLIBCXX_HAS_WCHAR__
  29. #include <cwchar>
  30. #include <cwctype>
  31. #endif
  32.  
  33. #ifndef __HEADER_STD_STRING
  34. #define __HEADER_STD_STRING 1
  35.  
  36. #pragma GCC visibility push(default)
  37.  
  38. namespace std{
  39.  
  40.         //Basic basic_string
  41.  
  42.         template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> > class basic_string;
  43.  
  44.         typedef basic_string<char> string;
  45.         #ifdef __UCLIBCXX_HAS_WCHAR__
  46.         typedef basic_string<wchar_t> wstring;
  47.         #endif
  48.  
  49.  
  50.  
  51. //template<class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> > class _UCXXEXPORT basic_string
  52. template<class Ch, class Tr, class A> class basic_string
  53.         : public std::vector<Ch, A>
  54. {
  55. public:
  56.         typedef Tr traits_type;
  57.         typedef typename Tr::char_type value_type;
  58.         typedef A allocator_type;
  59.         typedef typename A::size_type size_type;
  60.         typedef typename A::difference_type difference_type;
  61.  
  62.         typedef typename A::reference reference;
  63.         typedef typename A::const_reference const_reference;
  64.         typedef typename A::pointer pointer;
  65.         typedef typename A::const_pointer const_pointer;
  66.  
  67.         typedef typename vector<Ch, A>::iterator iterator;
  68.         typedef typename vector<Ch, A>::const_iterator const_iterator;
  69.  
  70.         typedef typename vector<Ch, A>::reverse_iterator reverse_iterator;
  71.         typedef typename vector<Ch, A>::const_reverse_iterator const_reverse_iterator;
  72.  
  73.         static const size_type npos = (size_type)-1;
  74.  
  75.         explicit _UCXXEXPORT basic_string(const A& al = A()) : vector<Ch, A>(al){ return; }
  76.  
  77.         _UCXXEXPORT basic_string(const basic_string& str, size_type pos = 0, size_type n = npos, const A& al = A());    //Below
  78.  
  79.         _UCXXEXPORT basic_string(const Ch* s, size_type n, const A& al = A())
  80.                 : vector<Ch, A>(al)
  81.         {
  82.                 if(n == npos){
  83.                         __throw_out_of_range();
  84.                 }
  85.                 if(s > 0){
  86.                         resize(n);
  87.                         Tr::copy(vector<Ch, A>::data, s, vector<Ch, A>::elements);
  88.                 }
  89.         }
  90.  
  91.         _UCXXEXPORT basic_string(const Ch* s, const A& al = A());               //Below
  92.  
  93.         _UCXXEXPORT basic_string(size_type n, Ch c, const A& al = A())
  94.                 : vector<Ch, A>(n, c, al)
  95.         {
  96.         }
  97.  
  98.         template<class InputIterator> _UCXXEXPORT basic_string(InputIterator begin, InputIterator end, const A& a = A())
  99.                 :vector<Ch, A>(begin, end)
  100.         {
  101.  
  102.         }
  103.  
  104.         _UCXXEXPORT ~basic_string() {
  105.                 return;
  106.         }
  107.  
  108.         _UCXXEXPORT basic_string& operator=(const basic_string& str);   //Below
  109.  
  110.         _UCXXEXPORT basic_string& operator=(const Ch* s){
  111.                 vector<Ch, A>::clear();
  112.                 if(s!=0){
  113.                         size_type len = Tr::length(s);
  114.                         resize(len);
  115.                         Tr::copy( vector<Ch, A>::data, s, len);
  116.                 }
  117.                 return *this;
  118.         }
  119.  
  120.         _UCXXEXPORT basic_string& operator=(Ch c){
  121.                 vector<Ch, A>::clear();
  122.                 vector<Ch, A>::push_back(c);
  123.                 return *this;
  124.         }
  125.  
  126.         inline _UCXXEXPORT size_type length() const { return vector<Ch, A>::size(); }
  127.  
  128.         void _UCXXEXPORT resize(size_type n, Ch c = Ch()){
  129.                 vector<Ch, A>::resize(n, c);
  130.         }
  131.  
  132.         _UCXXEXPORT basic_string& operator+=(const basic_string& str){
  133.                 return append(str);
  134.         }
  135.  
  136.         _UCXXEXPORT basic_string& operator+=(const Ch * s){
  137.                 return append(s);
  138.         }
  139.  
  140.         _UCXXEXPORT basic_string& operator+=(Ch c){
  141.                 vector<Ch, A>::push_back(c);
  142.                 return *this;
  143.         }
  144.  
  145.         _UCXXEXPORT basic_string& append(const basic_string& str){
  146.                 size_t temp = vector<Ch, A>::elements;
  147.                 resize(vector<Ch, A>::elements + str.elements);
  148.                 Tr::copy( vector<Ch, A>::data + temp, str.vector<Ch, A>::data, str.elements);
  149.  
  150.                 return *this;
  151.         }
  152.  
  153.         _UCXXEXPORT basic_string& append(const basic_string& str, size_type pos, size_type n){
  154.                 if(pos > str.size()){
  155.                         __throw_out_of_range();
  156.                 }
  157.  
  158.                 size_type rlen = str.elements - pos;
  159.                 if(rlen > n){
  160.                         rlen = n;
  161.                 }
  162.                 if(vector<Ch, A>::elements > npos - rlen){
  163.                         __throw_length_error();
  164.                 }
  165.                 size_t temp = vector<Ch, A>::elements;
  166.                 resize(vector<Ch, A>::elements + rlen);
  167.                 Tr::copy( vector<Ch, A>::data + temp, str.vector<Ch, A>::data + pos, rlen);
  168.                 return *this;
  169.         }
  170.  
  171.         _UCXXEXPORT basic_string& append(const Ch* s, size_type n){
  172.                 size_t temp = vector<Ch, A>::elements;
  173.                 resize(vector<Ch, A>::elements + n);
  174.                 Tr::copy( vector<Ch, A>::data + temp, s, n);
  175.                 return *this;
  176.         }
  177.  
  178.         _UCXXEXPORT basic_string& append(const Ch* s){
  179.                 size_type strLen = Tr::length(s);
  180.                 size_t temp = vector<Ch, A>::elements;
  181.                 resize(vector<Ch, A>::elements + strLen);
  182.                 Tr::copy( vector<Ch, A>::data + temp, s, strLen);
  183.                 return *this;
  184.         }
  185.  
  186.         _UCXXEXPORT basic_string& append(size_type n, Ch c){
  187.                 vector<Ch, A>::resize(vector<Ch, A>::elements + n, c);
  188.                 return *this;
  189.         }
  190.  
  191.         _UCXXEXPORT basic_string& assign(const basic_string& str){
  192.                 operator=(str);
  193.                 return *this;
  194.         }
  195.  
  196.         _UCXXEXPORT basic_string& assign(const basic_string& str, size_type pos, size_type n){
  197.                 if(pos > str.elements){
  198.                         __throw_out_of_range();
  199.                 }
  200.                 size_type r = str.elements - pos;
  201.                 if(r > n){
  202.                         r = n;
  203.                 }
  204.                 resize(r);
  205.                 Tr::copy(vector<Ch, A>::data, str.vector<Ch, A>::data + pos, r);
  206.                 return *this;
  207.         }
  208.  
  209.         _UCXXEXPORT basic_string& assign(const Ch* s, size_type n){
  210.                 resize(n);
  211.                 Tr::copy(vector<Ch, A>::data, s, n);
  212.                 return *this;
  213.         }
  214.  
  215.         _UCXXEXPORT basic_string& assign(const Ch* s){
  216.                 size_type len = Tr::length(s);
  217.                 return assign(s, len);
  218.         }
  219.  
  220.         _UCXXEXPORT basic_string& assign(size_type n, Ch c){
  221.                 vector<Ch, A>::clear();
  222.                 vector<Ch, A>::resize(n, Ch() );
  223.                 return *this;
  224.         }
  225.  
  226.         template<class InputIterator> _UCXXEXPORT basic_string& assign(InputIterator first, InputIterator last){
  227.                 vector<Ch, A>::resize(0, Ch());
  228.                 while (first != last){
  229.                         append(*first);
  230.                         ++first;
  231.                 }
  232.                 return *this;
  233.         }
  234.  
  235.         _UCXXEXPORT basic_string& insert(size_type pos1, const basic_string& str, size_type pos2=0, size_type n=npos){
  236.                 if(pos1 > vector<Ch, A>::elements || pos2 > str.elements){
  237.                         __throw_out_of_range();
  238.                 }
  239.                 size_type r = str.elements - pos2;
  240.                 if( r > n){
  241.                         r = n;
  242.                 }
  243.                 if(vector<Ch, A>::elements > npos - r){
  244.                         __throw_length_error();
  245.                 }
  246.                 size_type temp = vector<Ch, A>::elements;
  247.                 resize(vector<Ch, A>::elements + r);
  248.                 Tr::move(vector<Ch, A>::data + pos1 + r, vector<Ch, A>::data + pos1, temp - pos1);
  249.                 Tr::copy(vector<Ch, A>::data + pos1, str.vector<Ch, A>::data + pos2, r);
  250.                 return *this;
  251.         }
  252.  
  253.         _UCXXEXPORT basic_string& insert(size_type pos, const Ch* s, size_type n){
  254.                 if(pos > vector<Ch, A>::elements){
  255.                         __throw_out_of_range();
  256.                 }
  257.                 if(vector<Ch, A>::elements > npos - n){
  258.                         __throw_length_error();
  259.                 }
  260.                 size_type temp = vector<Ch, A>::elements;
  261.                 resize(vector<Ch, A>::elements + n);
  262.                 Tr::move(vector<Ch, A>::data + pos + n, vector<Ch, A>::data + pos, temp - pos);
  263.                 Tr::copy(vector<Ch, A>::data + pos, s, n);
  264.                 return *this;
  265.         }
  266.  
  267.         inline _UCXXEXPORT basic_string& insert(size_type pos, const Ch* s){
  268.                 size_type len = Tr::length(s);
  269.                 return insert(pos, s, len);
  270.         }
  271.  
  272.         _UCXXEXPORT basic_string& insert(size_type pos, size_type n, Ch c){
  273.                 if(pos > vector<Ch, A>::elements){
  274.                         __throw_out_of_range();
  275.                 }
  276.                 if(vector<Ch, A>::elements > npos - n){
  277.                         __throw_length_error();
  278.                 }
  279.                 size_type temp = vector<Ch, A>::elements;
  280.                 resize(vector<Ch, A>::elements + n);
  281.                 Tr::move(vector<Ch, A>::data + pos + n, vector<Ch, A>::data + pos, temp - pos);
  282.                 Tr::assign(vector<Ch, A>::data + pos, n, c);
  283.                 return *this;
  284.         }
  285.  
  286.         using vector<Ch, A>::insert;
  287. //      void insert(iterator p, size_type n, charT c);
  288. //      template<class InputIterator> void insert(iterator p, InputIterator first, InputIterator last);
  289.  
  290.         _UCXXEXPORT basic_string& erase(size_type pos = 0, size_type n = npos){
  291.                 size_type xlen = vector<Ch, A>::elements - pos;
  292.  
  293.                 if(xlen > n){
  294.                         xlen = n;
  295.                 }
  296.                 size_type temp = vector<Ch, A>::elements;
  297.  
  298.                 Tr::move(vector<Ch, A>::data + pos, vector<Ch, A>::data + pos + xlen, temp - pos - xlen);
  299.                 resize(temp - xlen);
  300.                 return *this;
  301.         }
  302.  
  303.         _UCXXEXPORT iterator erase(iterator position){
  304.                 if(position == vector<Ch, A>::end()){
  305.                         return position;
  306.                 }
  307.  
  308.                 ++position;
  309.  
  310.                 iterator temp = position;
  311.  
  312.                 while(position != vector<Ch, A>::end()){
  313.                         *(position-1) = *position;
  314.                         ++position;
  315.                 }
  316.                 vector<Ch, A>::pop_back();
  317.                 return temp;
  318.         }
  319.  
  320.         _UCXXEXPORT iterator erase(iterator first, iterator last){
  321.                 size_t count = last - first;
  322.  
  323.                 iterator temp = last;
  324.  
  325.                 while(last != vector<Ch, A>::end()){
  326.                         *(last - count) = *last;
  327.                         ++last;
  328.                 }
  329.  
  330.                 resize( vector<Ch, A>::elements-count);
  331.  
  332.                 return temp;
  333.         }
  334.  
  335.         _UCXXEXPORT basic_string&
  336.                 replace(size_type pos1, size_type n1, const basic_string& str, size_type pos2=0, size_type n2=npos)
  337.         {
  338.                 if(pos1 > vector<Ch, A>::elements){
  339.                         __throw_out_of_range();
  340.                 }
  341.                 size_type xlen = vector<Ch, A>::elements - pos1;
  342.                 if(xlen >  n1){
  343.                         xlen = n1;
  344.                 }
  345.                 size_type rlen = str.elements - pos2;
  346.                 if(rlen > n2){
  347.                         rlen = n2;
  348.                 }
  349.                 if((vector<Ch, A>::elements - xlen) >= (npos - rlen)){
  350.                         __throw_length_error();
  351.                 }
  352.  
  353.                 size_t temp = vector<Ch, A>::elements;
  354.  
  355.                 if(rlen > xlen){                //Only if making larger
  356.                         resize(temp - xlen + rlen);
  357.                 }
  358.  
  359.                 //Final length = vector<Ch, A>::elements - xlen + rlen
  360.                 //Initial block is of size pos1
  361.                 //Block 2 is of size len
  362.  
  363.                 Tr::move(vector<Ch, A>::data + pos1 + rlen, vector<Ch, A>::data + pos1 + xlen, temp - pos1 - xlen);
  364.                 Tr::copy(vector<Ch, A>::data + pos1, str.vector<Ch, A>::data + pos2, rlen);
  365.                 resize(temp - xlen + rlen);
  366.                 return *this;
  367.         }
  368.  
  369.         _UCXXEXPORT basic_string& replace(size_type pos, size_type n1, const Ch* s, size_type n2){
  370.                 return replace(pos,n1,basic_string<Ch,Tr,A>(s,n2));
  371.  
  372.         }
  373.  
  374.         inline _UCXXEXPORT basic_string& replace(size_type pos, size_type n1, const Ch* s){
  375.                 return replace(pos,n1,basic_string<Ch,Tr,A>(s));
  376.         }
  377.  
  378.         _UCXXEXPORT basic_string& replace(size_type pos, size_type n1, size_type n2, Ch c){
  379.                 return replace(pos,n1,basic_string<Ch, Tr, A>(n2,c));
  380.         }
  381. //      _UCXXEXPORT basic_string& replace(iterator i1, iterator i2, const basic_string& str);
  382. //      _UCXXEXPORT basic_string& replace(iterator i1, iterator i2, const Ch* s, size_type n);
  383. //      _UCXXEXPORT basic_string& replace(iterator i1, iterator i2, const Ch* s);
  384. //      _UCXXEXPORT basic_string& replace(iterator i1, iterator i2, size_type n, Ch c);
  385. /*      template<class InputIterator> _UCXXEXPORT basic_string& replace(iterator i1, iterator i2,
  386.                 InputIterator j1, InputIterator j2);*/
  387.  
  388.         size_type _UCXXEXPORT copy(Ch* s, size_type n, size_type pos = 0) const{
  389.                 if(pos > vector<Ch, A>::elements){
  390.                         __throw_out_of_range();
  391.                 }
  392.                 size_type r = vector<Ch, A>::elements - pos;
  393.                 if(r > n){
  394.                         r = n;
  395.                 }
  396.                 Tr::copy(s, vector<Ch, A>::data + pos, r);
  397.                 return r;
  398.         }
  399.  
  400.         _UCXXEXPORT void swap(basic_string<Ch,Tr,A>& s){
  401.                 //Data pointers
  402.  
  403.                 vector<Ch, A>::swap(s);
  404.         }
  405.  
  406.         _UCXXEXPORT const Ch* c_str() const{
  407.                 const_cast<basic_string<Ch,Tr,A> *>(this)->reserve(vector<Ch, A>::elements+1);
  408.                 vector<Ch, A>::data[vector<Ch, A>::elements] = 0;       //Add 0 at the end
  409.                 return vector<Ch, A>::data;
  410.         }
  411.  
  412.         _UCXXEXPORT const Ch* data() const{
  413.                 return vector<Ch, A>::data;
  414.         }
  415.         _UCXXEXPORT allocator_type get_allocator() const{
  416.                 return vector<Ch, A>::a;
  417.         }
  418.  
  419.         _UCXXEXPORT size_type find (const basic_string& str, size_type pos = 0) const;  //Below
  420.  
  421.         _UCXXEXPORT size_type find (const Ch* s, size_type pos, size_type n) const{
  422.                 return find(basic_string<Ch, Tr, A>(s,n), pos);
  423.         }
  424.         _UCXXEXPORT size_type find (const Ch* s, size_type pos = 0) const{
  425.                 return find(basic_string<Ch, Tr, A>(s), pos);
  426.         }
  427.         _UCXXEXPORT size_type find (Ch c, size_type pos = 0) const{
  428.                 for(size_type i = pos; i < length(); ++i){
  429.                         if(this->operator[](i) == c){
  430.                                 return i;
  431.                         }
  432.                 }
  433.                 return npos;
  434.         }
  435.         _UCXXEXPORT size_type rfind(const basic_string& str, size_type pos = npos) const{
  436.                 if(pos >= length()){
  437.                         pos = length();
  438.                 }
  439.                 for(size_type i = pos; i > 0; --i){
  440.                         if(str == substr(i-1, str.length())){
  441.                                 return i-1;
  442.                         }
  443.                 }
  444.                 return npos;
  445.         }
  446.         _UCXXEXPORT size_type rfind(const Ch* s, size_type pos, size_type n) const{
  447.                 return rfind(basic_string<Ch, Tr, A>(s,n),pos);
  448.         }
  449.         _UCXXEXPORT size_type rfind(const Ch* s, size_type pos = npos) const{
  450.                 return rfind(basic_string<Ch, Tr, A>(s),pos);
  451.         }
  452.         _UCXXEXPORT size_type rfind(Ch c, size_type pos = npos) const{
  453.                 return rfind(basic_string<Ch, Tr, A>(1,c),pos);
  454.         }
  455.  
  456.         _UCXXEXPORT size_type find_first_of(const basic_string& str, size_type pos = 0) const{
  457.                 for(size_type i = pos; i < length(); ++i){
  458.                         for(size_type j = 0; j < str.length() ; ++j){
  459.                                 if( Tr::eq(str[j], this->operator[](i)) ){
  460.                                         return i;
  461.                                 }
  462.                         }
  463.                 }
  464.                 return npos;
  465.         }
  466.  
  467.         _UCXXEXPORT size_type find_first_of(const Ch* s, size_type pos, size_type n) const{
  468.                 return find_first_of(basic_string<Ch, Tr, A>(s,n),pos);
  469.         }
  470.         _UCXXEXPORT size_type find_first_of(const Ch* s, size_type pos = 0) const{
  471.                 return find_first_of(basic_string<Ch, Tr, A>(s),pos);
  472.         }
  473.         _UCXXEXPORT size_type find_first_of(Ch c, size_type pos = 0) const{
  474.                 for(size_type i = pos; i< length(); ++i){
  475.                         if( Tr::eq(this->operator[](i), c) ){
  476.                                 return i;
  477.                         }
  478.                 }
  479.                 return npos;
  480.         }
  481.  
  482.         _UCXXEXPORT size_type find_last_of (const basic_string& str, size_type pos = npos) const{
  483.                 if(pos > length()){
  484.                         pos = length();
  485.                 }
  486.                 for(size_type i = pos; i >0 ; --i){
  487.                         for(size_type j = 0 ; j < str.length(); ++j){
  488.                                 if( Tr::eq(this->operator[](i-1), str[j]) ){
  489.                                         return i-1;
  490.                                 }
  491.                         }
  492.                 }
  493.                 return npos;
  494.         }
  495.         _UCXXEXPORT size_type find_last_of (const Ch* s, size_type pos, size_type n) const{
  496.                 return find_last_of(basic_string<Ch, Tr, A>(s,n),pos);
  497.         }
  498.         _UCXXEXPORT size_type find_last_of (const Ch* s, size_type pos = npos) const{
  499.                 return find_last_of(basic_string<Ch, Tr, A>(s),pos);
  500.         }
  501.         _UCXXEXPORT size_type find_last_of (Ch c, size_type pos = npos) const{
  502.                 if(pos > length()){
  503.                         pos = length();
  504.                 }
  505.                 for(size_type i = pos; i >0 ; --i){
  506.                         if( Tr::eq(this->operator[](i-1), c) ){
  507.                                 return i-1;
  508.                         }
  509.                 }
  510.                 return npos;
  511.         }
  512.  
  513.         _UCXXEXPORT size_type find_first_not_of(const basic_string& str, size_type pos = 0) const{
  514.                 bool foundCharacter;
  515.                 for(size_type i = pos; i < length(); ++i){
  516.                         foundCharacter = false;
  517.                         for(size_type j = 0; j < str.length() ; ++j){
  518.                                 if( Tr::eq(str[j], this->operator[](i)) ){
  519.                                         foundCharacter = true;
  520.                                 }
  521.                         }
  522.                         if(foundCharacter == false){
  523.                                 return i;
  524.                         }
  525.                 }
  526.                 return npos;
  527.         }
  528.  
  529.         _UCXXEXPORT size_type find_first_not_of(const Ch* s, size_type pos, size_type n) const{
  530.                 return find_first_not_of(basic_string<Ch, Tr, A>(s,n),pos);
  531.         }
  532.         _UCXXEXPORT size_type find_first_not_of(const Ch* s, size_type pos = 0) const{
  533.                 return find_first_not_of(basic_string<Ch, Tr, A>(s),pos);
  534.         }
  535.         _UCXXEXPORT size_type find_first_not_of(Ch c, size_type pos = 0) const{
  536.                 for(size_type i = pos; i < length() ; ++i){
  537.                         if(this->operator[](i) != c){
  538.                                 return i;
  539.                         }
  540.                 }
  541.                 return npos;
  542.         }
  543.         _UCXXEXPORT size_type find_last_not_of (const basic_string& str, size_type pos = npos) const{
  544.                 size_type xpos(length() - 1);
  545.                 if(xpos > pos){
  546.                         xpos = pos;
  547.                 }
  548.  
  549.                 while(xpos != npos && npos != str.find_first_of(this->at(xpos))){
  550.                         --xpos;
  551.                 }
  552.  
  553.                 return xpos;
  554.         }
  555.  
  556.         _UCXXEXPORT size_type find_last_not_of (const Ch* s, size_type pos, size_type n) const{
  557.                 return find_last_not_of(basic_string<Ch, Tr, A>(s,n),pos);
  558.         }
  559.         _UCXXEXPORT size_type find_last_not_of (const Ch* s, size_type pos = npos) const{
  560.                 return find_last_not_of(basic_string<Ch, Tr, A>(s),pos);
  561.         }
  562.         _UCXXEXPORT size_type find_last_not_of (Ch c, size_type pos = npos) const{
  563.                 size_type xpos(length() - 1);
  564.                 if(xpos > pos){
  565.                         xpos = pos;
  566.                 }
  567.                 while(xpos != npos && Tr::eq(this->at(xpos), c)){
  568.                         --xpos;
  569.                 }
  570.                 return xpos;
  571.  
  572.         }
  573.  
  574.         _UCXXEXPORT basic_string substr(size_type pos = 0, size_type n = npos) const;
  575.  
  576.         _UCXXEXPORT int compare(const basic_string& str) const{
  577.                 size_type rlen = vector<Ch, A>::elements;
  578.                 if(rlen >  str.elements){
  579.                         rlen = str.elements;
  580.                 }
  581.                 int retval = Tr::compare(vector<Ch, A>::data, str.vector<Ch, A>::data, rlen);
  582.                 if(retval == 0){
  583.                         if(vector<Ch, A>::elements < str.elements){
  584.                                 retval = -1;
  585.                         }
  586.                         if(vector<Ch, A>::elements > str.elements){
  587.                                 retval = 1;
  588.                         }
  589.                 }
  590.                 return retval;
  591.         }
  592.  
  593.         _UCXXEXPORT int compare(size_type pos1, size_type n1, const basic_string& str,
  594.                 size_type pos2=0, size_type n2=npos) const{
  595.                 size_type len1 = vector<Ch, A>::elements - pos1;
  596.                 if(len1 > n1){
  597.                         len1 = n1;
  598.                 }
  599.                 size_type len2 = str.vector<Ch, A>::elements - pos2;
  600.                 if(len2 > n2){
  601.                         len2 = n2;
  602.                 }
  603.                 size_type rlen = len1;
  604.                 if(rlen > len2){
  605.                         rlen = len2;
  606.                 }
  607.                 int retval = Tr::compare(vector<Ch, A>::data + pos1, str.vector<Ch, A>::data + pos2, rlen);
  608.                 if(retval == 0){
  609.                         if(len1 < len2){
  610.                                 retval = -1;
  611.                         }
  612.                         if(len1 > len2){
  613.                                 retval = 1;
  614.                         }
  615.                 }
  616.                 return retval;
  617.         }
  618.  
  619.         _UCXXEXPORT int compare(const Ch* s) const{
  620.                 size_type slen = Tr::length(s);
  621.                 size_type rlen = slen;
  622.                 if(rlen > vector<Ch, A>::elements){
  623.                         rlen=vector<Ch, A>::elements;
  624.                 }
  625.                 int retval = Tr::compare(vector<Ch, A>::data, s, rlen);
  626.                 if(retval==0){
  627.                         if(vector<Ch, A>::elements < slen){
  628.                                 retval = -1;
  629.                         }
  630.                         if(vector<Ch, A>::elements > slen){
  631.                                 retval = 1;
  632.                         }
  633.                 }
  634.                 return retval;
  635.         }
  636.  
  637.         _UCXXEXPORT int compare(size_type pos1, size_type n1, const Ch* s, size_type n2 = npos) const{
  638.                 size_type len1 = vector<Ch, A>::elements - pos1;
  639.                 if(len1 > n1){
  640.                         len1 = n1;
  641.                 }
  642.                 size_type slen = Tr::length(s);
  643.                 size_type len2 = slen;
  644.                 if(len2 > n2){
  645.                         len2 = n2;
  646.                 }
  647.                 size_type rlen = len1;
  648.                 if(rlen > len2){
  649.                         rlen = len2;
  650.                 }
  651.                 int retval  = Tr::compare(vector<Ch, A>::data + pos1, s, rlen);
  652.                 if(retval == 0){
  653.                         if(len1 < len2){
  654.                                 retval = -1;
  655.                         }
  656.                         if(len1 > len2){
  657.                                 retval = 1;
  658.                         }
  659.                 }
  660.                 return retval;
  661.         }
  662.  
  663. };
  664.  
  665.  
  666. //Functions
  667.  
  668. template<class Ch,class Tr,class A> _UCXXEXPORT basic_string<Ch,Tr,A>::basic_string(const Ch* s, const A& al)
  669.         : vector<Ch, A>(al)
  670. {
  671.         if(s!=0){
  672.                 size_type temp = Tr::length(s);
  673.                 append(s, temp);
  674.         }
  675. }
  676.  
  677. template<class Ch,class Tr,class A> _UCXXEXPORT basic_string<Ch,Tr,A>::
  678.         basic_string(const basic_string& str, size_type pos, size_type n, const A& al)
  679.         : vector<Ch, A>(al)
  680. {
  681.         if(pos>str.size()){
  682.                 __throw_out_of_range();
  683.         }
  684.         size_type rlen = str.size() - pos;
  685.         if( rlen > n){
  686.                 rlen = n;
  687.         }
  688.         resize(rlen);
  689.         Tr::copy(vector<Ch, A>::data, str.vector<Ch, A>::data + pos, vector<Ch, A>::elements);
  690. }
  691.  
  692. template<class Ch,class Tr,class A> _UCXXEXPORT basic_string<Ch,Tr,A>&
  693.         basic_string<Ch,Tr,A>::operator=(const basic_string<Ch,Tr,A> & str)
  694. {
  695.         if(&str == this){       //Check if we are doing a=a
  696.                 return *this;
  697.         }
  698.         vector<Ch, A>::clear();
  699.         resize(str.elements);
  700.         Tr::copy( vector<Ch, A>::data, str.vector<Ch, A>::data, str.elements);
  701.         return *this;
  702. }
  703.  
  704.  
  705. template<class Ch,class Tr,class A> _UCXXEXPORT typename basic_string<Ch,Tr,A>::size_type
  706.         basic_string<Ch,Tr,A>::find (const basic_string<Ch,Tr,A>& str, size_type pos) const
  707. {
  708.         if(str.length() > length()){
  709.                 return npos;
  710.         }
  711.         size_type max_string_start = 1 + length() - str.length();
  712.         for(size_type i = pos; i < max_string_start; ++i){
  713.                 if(str == substr(i, str.length())){
  714.                         return i;
  715.                 }
  716.         }
  717.         return npos;
  718. }
  719.  
  720.  
  721. template<class Ch,class Tr,class A>
  722.         _UCXXEXPORT basic_string<Ch, Tr, A> basic_string<Ch,Tr,A>::substr(size_type pos, size_type n) const
  723. {
  724.         if(pos > vector<Ch, A>::elements){
  725.                 __throw_out_of_range();
  726.         }
  727.         size_type rlen = vector<Ch, A>::elements - pos;
  728.         if(rlen > n){
  729.                 rlen = n;
  730.         }
  731.         return basic_string<Ch,Tr,A>(vector<Ch, A>::data + pos,rlen);
  732. }
  733.  
  734.  
  735.  
  736.  
  737. #ifdef __UCLIBCXX_EXPAND_STRING_CHAR__
  738. #ifndef __UCLIBCXX_COMPILE_STRING__
  739.  
  740. #ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__
  741.  
  742.         template <> _UCXXEXPORT string::basic_string(const allocator<char> &);
  743.         template <> _UCXXEXPORT string::basic_string(size_type n, char c, const allocator<char> & );
  744.         template <> _UCXXEXPORT string::basic_string(const char* s, const allocator<char>& al);
  745.         template <> _UCXXEXPORT string::basic_string(const basic_string& str, size_type pos, size_type n, const allocator<char>& al);
  746.         template <> _UCXXEXPORT string::~basic_string();
  747.  
  748. #endif
  749.  
  750.         template <> _UCXXEXPORT string & string::append(const char * s, size_type n);
  751.  
  752.  
  753.         template <> _UCXXEXPORT string::size_type string::find(const string & str, size_type pos) const;
  754.         template <> _UCXXEXPORT string::size_type string::find(const char* s, size_type pos) const;
  755.         template <> _UCXXEXPORT string::size_type string::find (char c, size_type pos) const;
  756.  
  757.         template <> _UCXXEXPORT string::size_type string::rfind(const string & str, size_type pos) const;
  758.         template <> _UCXXEXPORT string::size_type string::rfind(char c, size_type pos) const;
  759.         template <> _UCXXEXPORT string::size_type string::rfind(const char* s, size_type pos) const;
  760.  
  761.         template <> _UCXXEXPORT string::size_type string::find_first_of(const string &, size_type) const;
  762.         template <> _UCXXEXPORT string::size_type string::find_first_of(const char *, size_type pos, size_type n) const;
  763.         template <> _UCXXEXPORT string::size_type string::find_first_of(const char*, size_type pos) const;
  764.         template <> _UCXXEXPORT string::size_type string::find_first_of(char c, size_type pos) const;
  765.  
  766.         template <> _UCXXEXPORT string::size_type string::find_last_of (const string & , size_type pos) const;
  767.         template <> _UCXXEXPORT string::size_type string::find_last_of (const char* s, size_type pos, size_type n) const;
  768.         template <> _UCXXEXPORT string::size_type string::find_last_of (const char* s, size_type pos) const;
  769.         template <> _UCXXEXPORT string::size_type string::find_last_of (char c, size_type pos) const;
  770.  
  771.         template <> _UCXXEXPORT string::size_type string::find_first_not_of(const string &, size_type) const;
  772.         template <> _UCXXEXPORT string::size_type string::find_first_not_of(const char*, size_type, size_type) const;
  773.         template <> _UCXXEXPORT string::size_type string::find_first_not_of(const char*, size_type) const;
  774.         template <> _UCXXEXPORT string::size_type string::find_first_not_of(char c, size_type) const;
  775.  
  776.         template <> _UCXXEXPORT int string::compare(const string & str) const;
  777.         template <> _UCXXEXPORT int string::compare(
  778.                 size_type pos1, size_type n1, const string & str, size_type pos2, size_type n2) const;
  779.  
  780.         template <> _UCXXEXPORT string string::substr(size_type pos, size_type n) const;
  781.  
  782.         template <> _UCXXEXPORT string & string::operator=(const string & str);
  783.         template <> _UCXXEXPORT string & string::operator=(const char * s);
  784.  
  785. #endif
  786. #endif
  787.  
  788.  
  789.  
  790.  
  791. //typedef basic_string<char> string;
  792.  
  793. template<class charT, class traits, class Allocator> _UCXXEXPORT basic_string<charT,traits,Allocator>
  794.         operator+(const basic_string<charT,traits,Allocator>& lhs, const basic_string<charT,traits,Allocator>& rhs)
  795. {
  796.         basic_string<charT,traits,Allocator> temp(lhs);
  797.         temp.append(rhs);
  798.         return temp;
  799. }
  800.  
  801. template<class charT, class traits, class Allocator> _UCXXEXPORT basic_string<charT,traits,Allocator>
  802.         operator+(const charT* lhs, const basic_string<charT,traits,Allocator>& rhs)
  803. {
  804.         basic_string<charT,traits,Allocator> temp(lhs);
  805.         temp.append(rhs);
  806.         return temp;
  807. }
  808.  
  809.  
  810. template<class charT, class traits, class Allocator> _UCXXEXPORT basic_string<charT,traits,Allocator>
  811.         operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs)
  812. {
  813.         basic_string<charT,traits,Allocator> temp(1, lhs);
  814.         temp.append(rhs);
  815.         return temp;
  816. }
  817.  
  818. template<class charT, class traits, class Allocator> _UCXXEXPORT basic_string<charT,traits,Allocator>
  819.         operator+(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs)
  820. {
  821.         basic_string<charT,traits,Allocator> temp(lhs);
  822.         temp.append(rhs);
  823.         return temp;
  824. }
  825.  
  826. template<class charT, class traits, class Allocator> _UCXXEXPORT basic_string<charT,traits,Allocator>
  827.         operator+(const basic_string<charT,traits,Allocator>& lhs, charT rhs)
  828. {
  829.         basic_string<charT,traits,Allocator> temp(lhs);
  830.         temp+=rhs;
  831.         return temp;
  832. }
  833.  
  834. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  835.         operator==(const basic_string<charT,traits,Allocator>& lhs, const basic_string<charT,traits,Allocator>& rhs)
  836. {
  837.         if(lhs.compare(rhs) == 0){
  838.                 return true;
  839.         }
  840.         return false;
  841. }
  842.  
  843. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  844.         operator==(const charT* lhs, const basic_string<charT,traits,Allocator>& rhs)
  845. {
  846.         if(rhs.compare(lhs) == 0){
  847.                 return true;
  848.         }
  849.         return false;
  850. }
  851.  
  852. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  853.         operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs)
  854. {
  855.         if(lhs.compare(rhs)==0){
  856.                 return true;
  857.         }
  858.         return false;
  859. }
  860.  
  861. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  862.         operator!=(const basic_string<charT,traits,Allocator>& lhs, const basic_string<charT,traits,Allocator>& rhs)
  863. {
  864.         if(lhs.compare(rhs) !=0){
  865.                 return true;
  866.         }
  867.         return false;
  868. }
  869.  
  870. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  871.         operator!=(const charT* lhs, const basic_string<charT,traits,Allocator>& rhs)
  872. {
  873.         basic_string<charT,traits,Allocator> temp(lhs);
  874.         return (temp != rhs);
  875. }
  876.  
  877. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  878.         operator!=(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs)
  879. {
  880.         basic_string<charT,traits,Allocator> temp(rhs);
  881.         return (lhs != temp);
  882. }
  883.  
  884. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  885.         operator< (const basic_string<charT,traits,Allocator>& lhs, const basic_string<charT,traits,Allocator>& rhs)
  886. {
  887.         if(lhs.compare(rhs) < 0){
  888.                 return true;
  889.         }
  890.         return false;
  891. }
  892.  
  893. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  894.         operator< (const basic_string<charT,traits,Allocator>& lhs, const charT* rhs)
  895. {
  896.         basic_string<charT,traits,Allocator> temp(rhs);
  897.         if(lhs.compare(rhs) < 0){
  898.                 return true;
  899.         }
  900.         return false;
  901. }
  902.  
  903. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  904.         operator< (const charT* lhs, const basic_string<charT,traits,Allocator>& rhs)
  905. {
  906.         basic_string<charT,traits,Allocator> temp(lhs);
  907.         if(temp.compare(rhs) < 0){
  908.                 return true;
  909.         }
  910.         return false;
  911. }
  912.  
  913.  
  914. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  915.         operator> (const basic_string<charT,traits,Allocator>& lhs, const basic_string<charT,traits,Allocator>& rhs)
  916. {
  917.         if(lhs.compare(rhs) > 0){
  918.                 return true;
  919.         }
  920.         return false;
  921. }
  922.  
  923. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  924.         operator> (const basic_string<charT,traits,Allocator>& lhs, const charT* rhs)
  925. {
  926.         basic_string<charT,traits,Allocator> temp(rhs);
  927.         if(lhs.compare(rhs) > 0){
  928.                 return true;
  929.         }
  930.         return false;
  931. }
  932.  
  933. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  934.         operator> (const charT* lhs, const basic_string<charT,traits,Allocator>& rhs)
  935. {
  936.         basic_string<charT,traits,Allocator> temp(lhs);
  937.         if(temp.compare(rhs) > 0){
  938.                 return true;
  939.         }
  940.         return false;
  941. }
  942.  
  943. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  944.         operator<=(const basic_string<charT,traits,Allocator>& lhs, const basic_string<charT,traits,Allocator>& rhs)
  945. {
  946.         if(lhs.compare(rhs) <=0){
  947.                 return true;
  948.         }
  949.         return false;
  950. }
  951.  
  952. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  953.         operator<=(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs)
  954. {
  955.         basic_string<charT,traits,Allocator> temp(rhs);
  956.         if(lhs.compare(temp) <=0 ){
  957.                 return true;
  958.         }
  959.         return false;
  960. }
  961.  
  962. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  963.         operator<=(const charT* lhs, const basic_string<charT,traits,Allocator>& rhs)
  964. {
  965.         basic_string<charT,traits,Allocator> temp(lhs);
  966.         if(temp.compare(rhs) <= 0){
  967.                 return true;
  968.         }
  969.         return false;
  970. }
  971.  
  972. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  973.         operator>=(const basic_string<charT,traits,Allocator>& lhs, const basic_string<charT,traits,Allocator>& rhs)
  974. {
  975.         if(lhs.compare(rhs) >=0){
  976.                 return true;
  977.         }
  978.         return false;
  979. }
  980.  
  981. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  982.         operator>=(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs)
  983. {
  984.         basic_string<charT,traits,Allocator> temp(rhs);
  985.         if(lhs.compare(temp) >=0 ){
  986.                 return true;
  987.         }
  988.         return false;
  989. }
  990.  
  991. template<class charT, class traits, class Allocator> _UCXXEXPORT bool
  992.         operator>=(const charT* lhs, const basic_string<charT,traits,Allocator>& rhs)
  993. {
  994.         basic_string<charT,traits,Allocator> temp(lhs);
  995.         if(temp.compare(rhs) >=0 ){
  996.                 return true;
  997.         }
  998.         return false;
  999. }
  1000.  
  1001. template<class charT, class traits, class Allocator> _UCXXEXPORT void
  1002.         swap(basic_string<charT,traits,Allocator>& lhs, basic_string<charT,traits,Allocator>& rhs)
  1003. {
  1004.         lhs.swap(rhs);
  1005. }
  1006.  
  1007. /*template<class charT, class traits, class Allocator> _UCXXEXPORT basic_ostream<charT, traits>&
  1008.         operator<<(basic_ostream<charT, traits>& os, const basic_string<charT,traits,Allocator>& str)
  1009. {
  1010.         return os.write(str.data(), str.length());
  1011. }*/
  1012.  
  1013. #ifdef __UCLIBCXX_EXPAND_STRING_CHAR__
  1014. #ifndef __UCLIBCXX_COMPILE_STRING__
  1015.  
  1016. //Operators we can avoid duplication of
  1017.  
  1018. template <> _UCXXEXPORT bool operator==(const string & lhs, const string & rhs);
  1019. template <> _UCXXEXPORT bool operator==(const char * lhs, const string & rhs);
  1020. template <> _UCXXEXPORT bool operator==(const string & lhs, const char * rhs);
  1021.  
  1022. template <> _UCXXEXPORT bool operator!=(const string & lhs, const string & rhs);
  1023. template <> _UCXXEXPORT bool operator!=(const char * lhs, const string & rhs);
  1024. template <> _UCXXEXPORT bool operator!=(const string & lhs, const char * rhs);
  1025.  
  1026. template <> _UCXXEXPORT string operator+(const string & lhs, const char* rhs);
  1027. template <> _UCXXEXPORT string operator+(const char* lhs, const string & rhs);
  1028. template <> _UCXXEXPORT string operator+(const string & lhs, const string & rhs);
  1029.  
  1030. template <> _UCXXEXPORT bool operator> (const string & lhs, const string & rhs);
  1031. template <> _UCXXEXPORT bool operator< (const string & lhs, const string & rhs);
  1032.  
  1033.  
  1034. #endif
  1035. #endif
  1036.  
  1037.  
  1038. }
  1039.  
  1040. #pragma GCC visibility pop
  1041.  
  1042. #endif
  1043.