OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libstdc++-v3/] [include/] [ext/] [sso_string_base.h] - Blame information for rev 17

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 17 jlechner
// Short-string-optimized versatile string base -*- C++ -*-
2
 
3
// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the
7
// terms of the GNU General Public License as published by the
8
// Free Software Foundation; either version 2, or (at your option)
9
// any later version.
10
 
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
// GNU General Public License for more details.
15
 
16
// You should have received a copy of the GNU General Public License along
17
// with this library; see the file COPYING.  If not, write to the Free
18
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19
// USA.
20
 
21
// As a special exception, you may use this file as part of a free software
22
// library without restriction.  Specifically, if other files instantiate
23
// templates or use macros or inline functions from this file, or you compile
24
// this file and link it with other files to produce an executable, this
25
// file does not by itself cause the resulting executable to be covered by
26
// the GNU General Public License.  This exception does not however
27
// invalidate any other reasons why the executable file might be covered by
28
// the GNU General Public License.
29
 
30
/** @file ext/sso_string_base.h
31
 *  This file is a GNU extension to the Standard C++ Library.
32
 *  This is an internal header file, included by other library headers.
33
 *  You should not attempt to use it directly.
34
 */
35
 
36
#ifndef _SSO_STRING_BASE_H
37
#define _SSO_STRING_BASE_H 1
38
 
39
namespace __gnu_cxx
40
{
41
  template<typename _CharT, typename _Traits, typename _Alloc>
42
    class __sso_string_base
43
    : protected __vstring_utility<_CharT, _Traits, _Alloc>
44
    {
45
    public:
46
      typedef _Traits                                       traits_type;
47
      typedef typename _Traits::char_type                   value_type;
48
 
49
      typedef __vstring_utility<_CharT, _Traits, _Alloc>    _Util_Base;
50
      typedef typename _Util_Base::_CharT_alloc_type        _CharT_alloc_type;
51
      typedef typename _CharT_alloc_type::size_type         size_type;
52
 
53
    private:
54
      // The maximum number of individual char_type elements of an
55
      // individual string is determined by _S_max_size. This is the
56
      // value that will be returned by max_size().  (Whereas npos
57
      // is the maximum number of bytes the allocator can allocate.)
58
      // If one was to divvy up the theoretical largest size string,
59
      // with a terminating character and m _CharT elements, it'd
60
      // look like this:
61
      // npos = m * sizeof(_CharT) + sizeof(_CharT)
62
      // Solving for m:
63
      // m = npos / sizeof(_CharT) - 1
64
      // In addition, this implementation quarters this amount.
65
      enum { _S_max_size = (((static_cast<size_type>(-1)
66
                              / sizeof(_CharT)) - 1) / 4) };
67
 
68
      // Data Members (private):
69
      typename _Util_Base::template _Alloc_hider<_CharT_alloc_type>
70
                                                            _M_dataplus;
71
      size_type                                             _M_string_length;
72
 
73
      enum { _S_local_capacity = 15 };
74
 
75
      union
76
      {
77
        _CharT           _M_local_data[_S_local_capacity + 1];
78
        size_type        _M_allocated_capacity;
79
      };
80
 
81
      void
82
      _M_data(_CharT* __p)
83
      { _M_dataplus._M_p = __p; }
84
 
85
      void
86
      _M_length(size_type __length)
87
      { _M_string_length = __length; }
88
 
89
      void
90
      _M_capacity(size_type __capacity)
91
      { _M_allocated_capacity = __capacity; }
92
 
93
      bool
94
      _M_is_local() const
95
      { return _M_data() == _M_local_data; }
96
 
97
      // Create & Destroy
98
      _CharT*
99
      _M_create(size_type&, size_type);
100
 
101
      void
102
      _M_dispose()
103
      {
104
        if (!_M_is_local())
105
          _M_destroy(_M_allocated_capacity);
106
      }
107
 
108
      void
109
      _M_destroy(size_type) throw();
110
 
111
      // _M_construct_aux is used to implement the 21.3.1 para 15 which
112
      // requires special behaviour if _InIterator is an integral type
113
      template<typename _InIterator>
114
        void
115
        _M_construct_aux(_InIterator __beg, _InIterator __end, __false_type)
116
        {
117
          typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
118
          _M_construct(__beg, __end, _Tag());
119
        }
120
 
121
      template<typename _InIterator>
122
        void
123
        _M_construct_aux(_InIterator __beg, _InIterator __end, __true_type)
124
        { _M_construct(static_cast<size_type>(__beg),
125
                       static_cast<value_type>(__end)); }
126
 
127
      template<typename _InIterator>
128
        void
129
        _M_construct(_InIterator __beg, _InIterator __end)
130
        {
131
          typedef typename std::__is_integer<_InIterator>::__type _Integral;
132
          _M_construct_aux(__beg, __end, _Integral());
133
        }
134
 
135
      // For Input Iterators, used in istreambuf_iterators, etc.
136
      template<typename _InIterator>
137
        void
138
        _M_construct(_InIterator __beg, _InIterator __end,
139
                     std::input_iterator_tag);
140
 
141
      // For forward_iterators up to random_access_iterators, used for
142
      // string::iterator, _CharT*, etc.
143
      template<typename _FwdIterator>
144
        void
145
        _M_construct(_FwdIterator __beg, _FwdIterator __end,
146
                     std::forward_iterator_tag);
147
 
148
      void
149
      _M_construct(size_type __req, _CharT __c);
150
 
151
    public:
152
      size_type
153
      _M_max_size() const
154
      { return size_type(_S_max_size); }
155
 
156
      _CharT*
157
      _M_data() const
158
      { return _M_dataplus._M_p; }
159
 
160
      size_type
161
      _M_length() const
162
      { return _M_string_length; }
163
 
164
      size_type
165
      _M_capacity() const
166
      {
167
        return _M_is_local() ? size_type(_S_local_capacity)
168
                             : _M_allocated_capacity;
169
      }
170
 
171
      bool
172
      _M_is_shared() const
173
      { return false; }
174
 
175
      void
176
      _M_set_leaked() { }
177
 
178
      void
179
      _M_leak() { }
180
 
181
      void
182
      _M_set_length(size_type __n)
183
      {
184
        _M_length(__n);
185
        traits_type::assign(_M_data()[__n], _CharT());
186
      }
187
 
188
      __sso_string_base()
189
      : _M_dataplus(_Alloc(), _M_local_data)
190
      { _M_set_length(0); }
191
 
192
      __sso_string_base(const _Alloc& __a);
193
 
194
      __sso_string_base(const __sso_string_base& __rcs);
195
 
196
      __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a);
197
 
198
      template<typename _InputIterator>
199
        __sso_string_base(_InputIterator __beg, _InputIterator __end,
200
                          const _Alloc& __a);
201
 
202
      ~__sso_string_base()
203
      { _M_dispose(); }
204
 
205
      _CharT_alloc_type&
206
      _M_get_allocator()
207
      { return _M_dataplus; }
208
 
209
      const _CharT_alloc_type&
210
      _M_get_allocator() const
211
      { return _M_dataplus; }
212
 
213
      void
214
      _M_swap(__sso_string_base& __rcs);
215
 
216
      void
217
      _M_assign(const __sso_string_base& __rcs);
218
 
219
      void
220
      _M_reserve(size_type __res);
221
 
222
      void
223
      _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
224
                size_type __len2);
225
 
226
      void
227
      _M_erase(size_type __pos, size_type __n);
228
 
229
      bool
230
      _M_compare(const __sso_string_base&) const
231
      { return false; }
232
    };
233
 
234
  template<typename _CharT, typename _Traits, typename _Alloc>
235
    void
236
    __sso_string_base<_CharT, _Traits, _Alloc>::
237
    _M_destroy(size_type __size) throw()
238
    { _M_dataplus._CharT_alloc_type::deallocate(_M_data(), __size + 1); }
239
 
240
  template<typename _CharT, typename _Traits, typename _Alloc>
241
    void
242
    __sso_string_base<_CharT, _Traits, _Alloc>::
243
    _M_swap(__sso_string_base& __rcs)
244
    {
245
      // NB: Implement Option 3 of DR 431 (see N1599).
246
      std::__alloc_swap<_CharT_alloc_type>::_S_do_it(_M_get_allocator(),
247
                                                     __rcs._M_get_allocator());
248
 
249
      if (_M_is_local())
250
        if (__rcs._M_is_local())
251
          {
252
            if (_M_length() && __rcs._M_length())
253
              {
254
                _CharT __tmp_data[_S_local_capacity + 1];
255
                traits_type::copy(__tmp_data, __rcs._M_local_data,
256
                                  _S_local_capacity + 1);
257
                traits_type::copy(__rcs._M_local_data, _M_local_data,
258
                                  _S_local_capacity + 1);
259
                traits_type::copy(_M_local_data, __tmp_data,
260
                                  _S_local_capacity + 1);
261
              }
262
            else if (__rcs._M_length())
263
              {
264
                traits_type::copy(_M_local_data, __rcs._M_local_data,
265
                                  _S_local_capacity + 1);
266
                _M_length(__rcs._M_length());
267
                __rcs._M_set_length(0);
268
                return;
269
              }
270
            else if (_M_length())
271
              {
272
                traits_type::copy(__rcs._M_local_data, _M_local_data,
273
                                  _S_local_capacity + 1);
274
                __rcs._M_length(_M_length());
275
                _M_set_length(0);
276
                return;
277
              }
278
          }
279
        else
280
          {
281
            const size_type __tmp_capacity = __rcs._M_allocated_capacity;
282
            traits_type::copy(__rcs._M_local_data, _M_local_data,
283
                              _S_local_capacity + 1);
284
            _M_data(__rcs._M_data());
285
            __rcs._M_data(__rcs._M_local_data);
286
            _M_capacity(__tmp_capacity);
287
          }
288
      else
289
        {
290
          const size_type __tmp_capacity = _M_allocated_capacity;
291
          if (__rcs._M_is_local())
292
            {
293
              traits_type::copy(_M_local_data, __rcs._M_local_data,
294
                                _S_local_capacity + 1);
295
              __rcs._M_data(_M_data());
296
              _M_data(_M_local_data);
297
            }
298
          else
299
            {
300
              _CharT* __tmp_ptr = _M_data();
301
              _M_data(__rcs._M_data());
302
              __rcs._M_data(__tmp_ptr);
303
              _M_capacity(__rcs._M_allocated_capacity);
304
            }
305
          __rcs._M_capacity(__tmp_capacity);
306
        }
307
 
308
      const size_type __tmp_length = _M_length();
309
      _M_length(__rcs._M_length());
310
      __rcs._M_length(__tmp_length);
311
    }
312
 
313
  template<typename _CharT, typename _Traits, typename _Alloc>
314
    _CharT*
315
    __sso_string_base<_CharT, _Traits, _Alloc>::
316
    _M_create(size_type& __capacity, size_type __old_capacity)
317
    {
318
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
319
      // 83.  String::npos vs. string::max_size()
320
      if (__capacity > size_type(_S_max_size))
321
        std::__throw_length_error(__N("__sso_string_base::_M_create"));
322
 
323
      // The below implements an exponential growth policy, necessary to
324
      // meet amortized linear time requirements of the library: see
325
      // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
326
      if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
327
        __capacity = 2 * __old_capacity;
328
 
329
      // NB: Need an array of char_type[__capacity], plus a terminating
330
      // null char_type() element.
331
      return _M_dataplus._CharT_alloc_type::allocate(__capacity + 1);
332
    }
333
 
334
  template<typename _CharT, typename _Traits, typename _Alloc>
335
    __sso_string_base<_CharT, _Traits, _Alloc>::
336
    __sso_string_base(const _Alloc& __a)
337
    : _M_dataplus(__a, _M_local_data)
338
    { _M_set_length(0); }
339
 
340
  template<typename _CharT, typename _Traits, typename _Alloc>
341
    __sso_string_base<_CharT, _Traits, _Alloc>::
342
    __sso_string_base(const __sso_string_base& __rcs)
343
    : _M_dataplus(__rcs._M_get_allocator(), _M_local_data)
344
    { _M_construct(__rcs._M_data(), __rcs._M_data() + __rcs._M_length()); }
345
 
346
  template<typename _CharT, typename _Traits, typename _Alloc>
347
    __sso_string_base<_CharT, _Traits, _Alloc>::
348
    __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a)
349
    : _M_dataplus(__a, _M_local_data)
350
    { _M_construct(__n, __c); }
351
 
352
  template<typename _CharT, typename _Traits, typename _Alloc>
353
    template<typename _InputIterator>
354
    __sso_string_base<_CharT, _Traits, _Alloc>::
355
    __sso_string_base(_InputIterator __beg, _InputIterator __end,
356
                      const _Alloc& __a)
357
    : _M_dataplus(__a, _M_local_data)
358
    { _M_construct(__beg, __end); }
359
 
360
  // NB: This is the special case for Input Iterators, used in
361
  // istreambuf_iterators, etc.
362
  // Input Iterators have a cost structure very different from
363
  // pointers, calling for a different coding style.
364
  template<typename _CharT, typename _Traits, typename _Alloc>
365
    template<typename _InIterator>
366
      void
367
      __sso_string_base<_CharT, _Traits, _Alloc>::
368
      _M_construct(_InIterator __beg, _InIterator __end,
369
                   std::input_iterator_tag)
370
      {
371
        size_type __len = 0;
372
        size_type __capacity = size_type(_S_local_capacity);
373
 
374
        while (__beg != __end && __len < __capacity)
375
          {
376
            _M_data()[__len++] = *__beg;
377
            ++__beg;
378
          }
379
 
380
        try
381
          {
382
            while (__beg != __end)
383
              {
384
                if (__len == __capacity)
385
                  {
386
                    // Allocate more space.
387
                    __capacity = __len + 1;
388
                    _CharT* __another = _M_create(__capacity, __len);
389
                    _S_copy(__another, _M_data(), __len);
390
                    _M_dispose();
391
                    _M_data(__another);
392
                    _M_capacity(__capacity);
393
                  }
394
                _M_data()[__len++] = *__beg;
395
                ++__beg;
396
              }
397
          }
398
        catch(...)
399
          {
400
            _M_dispose();
401
            __throw_exception_again;
402
          }
403
 
404
        _M_set_length(__len);
405
      }
406
 
407
  template<typename _CharT, typename _Traits, typename _Alloc>
408
    template<typename _InIterator>
409
      void
410
      __sso_string_base<_CharT, _Traits, _Alloc>::
411
      _M_construct(_InIterator __beg, _InIterator __end,
412
                   std::forward_iterator_tag)
413
      {
414
        // NB: Not required, but considered best practice.
415
        if (__builtin_expect(_S_is_null_pointer(__beg) && __beg != __end, 0))
416
          std::__throw_logic_error(__N("__sso_string_base::"
417
                                       "_M_construct NULL not valid"));
418
 
419
        size_type __dnew = static_cast<size_type>(std::distance(__beg, __end));
420
 
421
        if (__dnew > size_type(_S_local_capacity))
422
          {
423
            _M_data(_M_create(__dnew, size_type(0)));
424
            _M_capacity(__dnew);
425
          }
426
 
427
        // Check for out_of_range and length_error exceptions.
428
        try
429
          { _S_copy_chars(_M_data(), __beg, __end); }
430
        catch(...)
431
          {
432
            _M_dispose();
433
            __throw_exception_again;
434
          }
435
 
436
        _M_set_length(__dnew);
437
      }
438
 
439
  template<typename _CharT, typename _Traits, typename _Alloc>
440
    void
441
    __sso_string_base<_CharT, _Traits, _Alloc>::
442
    _M_construct(size_type __n, _CharT __c)
443
    {
444
      if (__n > size_type(_S_local_capacity))
445
        {
446
          _M_data(_M_create(__n, size_type(0)));
447
          _M_capacity(__n);
448
        }
449
 
450
      if (__n)
451
        _S_assign(_M_data(), __n, __c);
452
 
453
      _M_set_length(__n);
454
    }
455
 
456
  template<typename _CharT, typename _Traits, typename _Alloc>
457
    void
458
    __sso_string_base<_CharT, _Traits, _Alloc>::
459
    _M_assign(const __sso_string_base& __rcs)
460
    {
461
      if (this != &__rcs)
462
        {
463
          const size_type __rsize = __rcs._M_length();
464
          const size_type __capacity = _M_capacity();
465
 
466
          if (__rsize > __capacity)
467
            {
468
              size_type __new_capacity = __rsize;
469
              _CharT* __tmp = _M_create(__new_capacity, __capacity);
470
              _M_dispose();
471
              _M_data(__tmp);
472
              _M_capacity(__new_capacity);
473
            }
474
 
475
          if (__rsize)
476
            _S_copy(_M_data(), __rcs._M_data(), __rsize);
477
 
478
          _M_set_length(__rsize);
479
        }
480
    }
481
 
482
  template<typename _CharT, typename _Traits, typename _Alloc>
483
    void
484
    __sso_string_base<_CharT, _Traits, _Alloc>::
485
    _M_reserve(size_type __res)
486
    {
487
      // Make sure we don't shrink below the current size.
488
      if (__res < _M_length())
489
        __res = _M_length();
490
 
491
      const size_type __capacity = _M_capacity();
492
      if (__res != __capacity)
493
        {
494
          if (__res > __capacity
495
              || __res > size_type(_S_local_capacity))
496
            {
497
              _CharT* __tmp = _M_create(__res, __capacity);
498
              _S_copy(__tmp, _M_data(), _M_length() + 1);
499
              _M_dispose();
500
              _M_data(__tmp);
501
              _M_capacity(__res);
502
            }
503
          else if (!_M_is_local())
504
            {
505
              _S_copy(_M_local_data, _M_data(), _M_length() + 1);
506
              _M_destroy(__capacity);
507
              _M_data(_M_local_data);
508
            }
509
        }
510
    }
511
 
512
  template<typename _CharT, typename _Traits, typename _Alloc>
513
    void
514
    __sso_string_base<_CharT, _Traits, _Alloc>::
515
    _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
516
              const size_type __len2)
517
    {
518
      const size_type __how_much = _M_length() - __pos - __len1;
519
 
520
      size_type __new_capacity = _M_length() + __len2 - __len1;
521
      _CharT* __r = _M_create(__new_capacity, _M_capacity());
522
 
523
      if (__pos)
524
        _S_copy(__r, _M_data(), __pos);
525
      if (__s && __len2)
526
        _S_copy(__r + __pos, __s, __len2);
527
      if (__how_much)
528
        _S_copy(__r + __pos + __len2,
529
                _M_data() + __pos + __len1, __how_much);
530
 
531
      _M_dispose();
532
      _M_data(__r);
533
      _M_capacity(__new_capacity);
534
    }
535
 
536
  template<typename _CharT, typename _Traits, typename _Alloc>
537
    void
538
    __sso_string_base<_CharT, _Traits, _Alloc>::
539
    _M_erase(size_type __pos, size_type __n)
540
    {
541
      const size_type __how_much = _M_length() - __pos - __n;
542
 
543
      if (__how_much && __n)
544
        _S_move(_M_data() + __pos, _M_data() + __pos + __n,
545
                __how_much);
546
 
547
      _M_set_length(_M_length() - __n);
548
    }
549
 
550
  template<>
551
    inline bool
552
    __sso_string_base<char, std::char_traits<char>,
553
                      std::allocator<char> >::
554
    _M_compare(const __sso_string_base& __rcs) const
555
    {
556
      if (this == &__rcs)
557
        return true;
558
      return false;
559
    }
560
 
561
  template<>
562
    inline bool
563
    __sso_string_base<wchar_t, std::char_traits<wchar_t>,
564
                      std::allocator<wchar_t> >::
565
    _M_compare(const __sso_string_base& __rcs) const
566
    {
567
      if (this == &__rcs)
568
        return true;
569
      return false;
570
    }
571
} // namespace __gnu_cxx
572
 
573
#endif /* _SSO_STRING_BASE_H */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.