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