epoc32/include/stdapis/stlportv5/stl/_string_base.h
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
parent 2 epoc32/include/tools/stlport/stl/_string_base.h@2fe1408b6811
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
williamr@2
     1
/*
williamr@2
     2
 * Copyright (c) 1997-1999
williamr@2
     3
 * Silicon Graphics Computer Systems, Inc.
williamr@2
     4
 *
williamr@2
     5
 * Copyright (c) 1999
williamr@2
     6
 * Boris Fomitchev
williamr@2
     7
 *
williamr@2
     8
 * Copyright (c) 2003
williamr@2
     9
 * Francois Dumont
williamr@2
    10
 *
williamr@2
    11
 * This material is provided "as is", with absolutely no warranty expressed
williamr@2
    12
 * or implied. Any use is at your own risk.
williamr@2
    13
 *
williamr@2
    14
 * Permission to use or copy this software for any purpose is hereby granted
williamr@2
    15
 * without fee, provided the above notices are retained on all copies.
williamr@2
    16
 * Permission to modify the code and to distribute modified code is granted,
williamr@2
    17
 * provided the above notices are retained, and a notice that the code was
williamr@2
    18
 * modified is included with the above copyright notice.
williamr@2
    19
 *
williamr@2
    20
 */
williamr@2
    21
williamr@2
    22
#ifndef _STLP_STRING_BASE_H
williamr@2
    23
#define _STLP_STRING_BASE_H
williamr@2
    24
williamr@2
    25
// ------------------------------------------------------------
williamr@2
    26
// Class _String_base.
williamr@2
    27
williamr@2
    28
// _String_base is a helper class that makes it it easier to write an
williamr@2
    29
// exception-safe version of basic_string.  The constructor allocates,
williamr@2
    30
// but does not initialize, a block of memory.  The destructor
williamr@2
    31
// deallocates, but does not destroy elements within, a block of
williamr@2
    32
// memory.  The destructor assumes that _M_start either is null, or else
williamr@2
    33
// points to a block of memory that was allocated using _String_base's
williamr@2
    34
// allocator and whose size is _M_end_of_storage._M_data - _M_start.
williamr@2
    35
williamr@2
    36
_STLP_BEGIN_NAMESPACE
williamr@2
    37
williamr@2
    38
_STLP_MOVE_TO_PRIV_NAMESPACE
williamr@2
    39
williamr@2
    40
#ifndef _STLP_SHORT_STRING_SZ
williamr@2
    41
#  define _STLP_SHORT_STRING_SZ 16
williamr@2
    42
#endif
williamr@2
    43
williamr@2
    44
template <class _Tp, class _Alloc>
williamr@2
    45
class _String_base {
williamr@2
    46
  typedef _String_base<_Tp, _Alloc> _Self;
williamr@2
    47
protected:
williamr@2
    48
  _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
williamr@2
    49
public:
williamr@2
    50
  //dums: Some compiler(MSVC6) require it to be public not simply protected!
williamr@2
    51
  enum {_DEFAULT_SIZE = _STLP_SHORT_STRING_SZ};
williamr@2
    52
  //This is needed by the full move framework
williamr@2
    53
  typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
williamr@2
    54
  typedef _STLP_alloc_proxy<_Tp*, _Tp, allocator_type> _AllocProxy;
williamr@2
    55
  typedef size_t size_type;
williamr@2
    56
private:
williamr@2
    57
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@2
    58
  union _Buffers {
williamr@2
    59
    _Tp*  _M_dynamic_buf;
williamr@2
    60
    _Tp   _M_static_buf[_DEFAULT_SIZE];
williamr@2
    61
  } _M_buffers;
williamr@2
    62
#else
williamr@2
    63
  _Tp*    _M_start;
williamr@2
    64
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@2
    65
protected:
williamr@2
    66
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@2
    67
  bool _M_using_static_buf() const {
williamr@2
    68
    return (_M_end_of_storage._M_data == _M_buffers._M_static_buf + _DEFAULT_SIZE);
williamr@2
    69
  }
williamr@2
    70
  _Tp const* _M_Start() const {
williamr@2
    71
    return _M_using_static_buf()?_M_buffers._M_static_buf:_M_buffers._M_dynamic_buf;
williamr@2
    72
  }
williamr@2
    73
  _Tp* _M_Start() {
williamr@2
    74
    return _M_using_static_buf()?_M_buffers._M_static_buf:_M_buffers._M_dynamic_buf;
williamr@2
    75
  }
williamr@2
    76
#else
williamr@2
    77
  _Tp const* _M_Start() const {return _M_start;}
williamr@2
    78
  _Tp* _M_Start() {return _M_start;}
williamr@2
    79
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@2
    80
williamr@2
    81
  _Tp*    _M_finish;
williamr@2
    82
  _AllocProxy _M_end_of_storage;
williamr@2
    83
williamr@2
    84
  _Tp const* _M_Finish() const {return _M_finish;}
williamr@2
    85
  _Tp* _M_Finish() {return _M_finish;}
williamr@2
    86
williamr@2
    87
  // Precondition: 0 < __n <= max_size().
williamr@2
    88
  void _M_allocate_block(size_t __n = _DEFAULT_SIZE);
williamr@2
    89
  void _M_deallocate_block() {
williamr@2
    90
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@2
    91
    if (!_M_using_static_buf() && (_M_buffers._M_dynamic_buf != 0))
williamr@2
    92
      _M_end_of_storage.deallocate(_M_buffers._M_dynamic_buf, _M_end_of_storage._M_data - _M_buffers._M_dynamic_buf);
williamr@2
    93
#else
williamr@2
    94
    if (_M_start != 0)
williamr@2
    95
      _M_end_of_storage.deallocate(_M_start, _M_end_of_storage._M_data - _M_start);
williamr@2
    96
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@2
    97
  }
williamr@2
    98
williamr@2
    99
  size_t max_size() const {
williamr@2
   100
    const size_type __string_max_size = size_type(-1) / sizeof(_Tp);
williamr@2
   101
    typename allocator_type::size_type __alloc_max_size = _M_end_of_storage.max_size();
williamr@2
   102
    return (min)(__alloc_max_size, __string_max_size) - 1;
williamr@2
   103
  }
williamr@2
   104
williamr@2
   105
  _String_base(const allocator_type& __a)
williamr@2
   106
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@2
   107
    : _M_finish(_M_buffers._M_static_buf), _M_end_of_storage(__a, _M_buffers._M_static_buf + _DEFAULT_SIZE)
williamr@2
   108
#else
williamr@2
   109
    : _M_start(0), _M_finish(0), _M_end_of_storage(__a, (_Tp*)0)
williamr@2
   110
#endif
williamr@2
   111
    {}
williamr@2
   112
williamr@2
   113
  _String_base(const allocator_type& __a, size_t __n)
williamr@2
   114
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@2
   115
    : _M_finish(_M_buffers._M_static_buf), _M_end_of_storage(__a, _M_buffers._M_static_buf + _DEFAULT_SIZE) {
williamr@2
   116
#else
williamr@2
   117
    : _M_start(0), _M_finish(0), _M_end_of_storage(__a, (_Tp*)0) {
williamr@2
   118
#endif
williamr@2
   119
      _M_allocate_block(__n);
williamr@2
   120
    }
williamr@2
   121
williamr@2
   122
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@2
   123
  void _M_move_src (_Self &src) {
williamr@2
   124
      if (src._M_using_static_buf()) {
williamr@2
   125
        _M_buffers = src._M_buffers;
williamr@2
   126
        _M_finish = _M_buffers._M_static_buf + (src._M_finish - src._M_buffers._M_static_buf);
williamr@2
   127
        _M_end_of_storage._M_data = _M_buffers._M_static_buf + _DEFAULT_SIZE;
williamr@2
   128
      }
williamr@2
   129
      else {
williamr@2
   130
        _M_buffers._M_dynamic_buf = src._M_buffers._M_dynamic_buf;
williamr@2
   131
        _M_finish = src._M_finish;
williamr@2
   132
        _M_end_of_storage._M_data = src._M_end_of_storage._M_data;
williamr@2
   133
        src._M_buffers._M_dynamic_buf = 0;
williamr@2
   134
      }
williamr@2
   135
    }
williamr@2
   136
#endif
williamr@2
   137
williamr@2
   138
  _String_base(__move_source<_Self> src)
williamr@2
   139
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@2
   140
    : _M_end_of_storage(__move_source<_AllocProxy>(src.get()._M_end_of_storage)) {
williamr@2
   141
      _M_move_src(src.get());
williamr@2
   142
#else
williamr@2
   143
    : _M_start(src.get()._M_start), _M_finish(src.get()._M_finish),
williamr@2
   144
      _M_end_of_storage(__move_source<_AllocProxy>(src.get()._M_end_of_storage)) {
williamr@2
   145
      src.get()._M_start = 0;
williamr@2
   146
#endif
williamr@2
   147
    }
williamr@2
   148
williamr@2
   149
  ~_String_base() { _M_deallocate_block(); }
williamr@2
   150
williamr@2
   151
  void _M_reset(_Tp *__start, _Tp *__finish, _Tp *__end_of_storage) {
williamr@2
   152
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@2
   153
    _M_buffers._M_dynamic_buf = __start;
williamr@2
   154
#else
williamr@2
   155
    _M_start = __start;
williamr@2
   156
#endif
williamr@2
   157
    _M_finish = __finish;
williamr@2
   158
    _M_end_of_storage._M_data = __end_of_storage;
williamr@2
   159
  }
williamr@2
   160
williamr@2
   161
  void _M_destroy_back () {
williamr@2
   162
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@2
   163
    if (!_M_using_static_buf())
williamr@2
   164
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@2
   165
      _STLP_STD::_Destroy(_M_finish);
williamr@2
   166
  }
williamr@2
   167
williamr@2
   168
  void _M_destroy_range(size_t __from_off = 0, size_t __to_off = 1) {
williamr@2
   169
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@2
   170
    if (!_M_using_static_buf())
williamr@2
   171
      _STLP_STD::_Destroy_Range(_M_buffers._M_dynamic_buf + __from_off, _M_finish + __to_off);
williamr@2
   172
#else
williamr@2
   173
    _STLP_STD::_Destroy_Range(_M_start + __from_off, _M_finish + __to_off);
williamr@2
   174
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@2
   175
  }
williamr@2
   176
williamr@2
   177
  void _M_destroy_ptr_range(_Tp *__f, _Tp *__l) {
williamr@2
   178
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@2
   179
    if (!_M_using_static_buf())
williamr@2
   180
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@2
   181
      _STLP_STD::_Destroy_Range(__f, __l);
williamr@2
   182
  }
williamr@2
   183
williamr@2
   184
  void _M_Swap(_Self &__s) {
williamr@2
   185
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@2
   186
    if (_M_using_static_buf()) {
williamr@2
   187
      if (__s._M_using_static_buf()) {
williamr@2
   188
        _STLP_STD::swap(_M_buffers, __s._M_buffers);
williamr@2
   189
        _Tp *__tmp = _M_finish;
williamr@2
   190
        _M_finish = _M_buffers._M_static_buf + (__s._M_finish - __s._M_buffers._M_static_buf);
williamr@2
   191
        __s._M_finish = __s._M_buffers._M_static_buf + (__tmp - _M_buffers._M_static_buf);
williamr@2
   192
        //We need to swap _M_end_of_storage for allocators with state:
williamr@2
   193
        _M_end_of_storage.swap(__s._M_end_of_storage);
williamr@2
   194
        _M_end_of_storage._M_data = _M_buffers._M_static_buf + _DEFAULT_SIZE;
williamr@2
   195
        __s._M_end_of_storage._M_data = __s._M_buffers._M_static_buf + _DEFAULT_SIZE;
williamr@2
   196
      } else {
williamr@2
   197
        __s._M_Swap(*this);
williamr@2
   198
        return;
williamr@2
   199
      }
williamr@2
   200
    }
williamr@2
   201
    else if (__s._M_using_static_buf()) {
williamr@2
   202
      _Tp *__tmp = _M_buffers._M_dynamic_buf;
williamr@2
   203
      _Tp *__tmp_finish = _M_finish;
williamr@2
   204
      _Tp *__tmp_end_data = _M_end_of_storage._M_data;
williamr@2
   205
      _M_buffers = __s._M_buffers;
williamr@2
   206
      //We need to swap _M_end_of_storage for allocators with state:
williamr@2
   207
      _M_end_of_storage.swap(__s._M_end_of_storage);
williamr@2
   208
      _M_end_of_storage._M_data = _M_buffers._M_static_buf + _DEFAULT_SIZE;
williamr@2
   209
      _M_finish = _M_buffers._M_static_buf + (__s._M_finish - __s._M_buffers._M_static_buf);
williamr@2
   210
      __s._M_buffers._M_dynamic_buf = __tmp;
williamr@2
   211
      __s._M_end_of_storage._M_data = __tmp_end_data;
williamr@2
   212
      __s._M_finish = __tmp_finish;
williamr@2
   213
    }
williamr@2
   214
    else {
williamr@2
   215
      _STLP_STD::swap(_M_buffers._M_dynamic_buf, __s._M_buffers._M_dynamic_buf);
williamr@2
   216
      _M_end_of_storage.swap(__s._M_end_of_storage);
williamr@2
   217
      _STLP_STD::swap(_M_finish, __s._M_finish);
williamr@2
   218
    }
williamr@2
   219
#else
williamr@2
   220
    _STLP_STD::swap(_M_start, __s._M_start);
williamr@2
   221
    _M_end_of_storage.swap(__s._M_end_of_storage);
williamr@2
   222
    _STLP_STD::swap(_M_finish, __s._M_finish);
williamr@2
   223
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@2
   224
  }
williamr@2
   225
williamr@2
   226
  void _STLP_FUNCTION_THROWS _M_throw_length_error() const;
williamr@2
   227
  void _STLP_FUNCTION_THROWS _M_throw_out_of_range() const;
williamr@2
   228
};
williamr@2
   229
williamr@2
   230
#undef _STLP_SHORT_STRING_SZ
williamr@2
   231
williamr@2
   232
#if defined (_STLP_USE_TEMPLATE_EXPORT)
williamr@2
   233
_STLP_EXPORT_TEMPLATE_CLASS _String_base<char, allocator<char> >;
williamr@2
   234
#  if defined (_STLP_HAS_WCHAR_T)
williamr@2
   235
_STLP_EXPORT_TEMPLATE_CLASS _String_base<wchar_t, allocator<wchar_t> >;
williamr@2
   236
#  endif
williamr@2
   237
#endif /* _STLP_USE_TEMPLATE_EXPORT */
williamr@2
   238
williamr@2
   239
_STLP_MOVE_TO_STD_NAMESPACE
williamr@2
   240
williamr@2
   241
_STLP_END_NAMESPACE
williamr@2
   242
williamr@2
   243
#endif /* _STLP_STRING_BASE_H */
williamr@2
   244
williamr@2
   245
/*
williamr@2
   246
 * Local Variables:
williamr@2
   247
 * mode:C++
williamr@2
   248
 * End:
williamr@2
   249
 */