/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: Tim Marston
  • Date: 2013-03-31 17:07:36 UTC
  • Revision ID: tim@ed.am-20130331170736-hphm2hg0y6l7w6z1
made rtc-test's DS1307 library a symlink to the main one in src/util

Show diffs side-by-side

added added

removed removed

Lines of Context:
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