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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [libstdc++-v3/] [include/] [ext/] [sso_string_base.h] - Blame information for rev 424

Details | Compare with Previous | View Log

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