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

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [or1knd-elf/] [include/] [c++/] [4.8.0/] [ext/] [sso_string_base.h] - Blame information for rev 35

Details | Compare with Previous | View Log

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