/elec/propeller-clock

To get this branch, use:
bzr branch http://bzr.ed.am/elec/propeller-clock

« back to all changes in this revision

Viewing changes to src/utility/string

  • Committer: edam
  • Date: 2012-02-25 01:31:43 UTC
  • Revision ID: tim@ed.am-20120225013143-9fet2y2d3fjlrwez
added ulibc

Show diffs side-by-side

added added

removed removed

 
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(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], 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(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(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(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], 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(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(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(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