/home/ntakagi/work/STLport-5.1.5/stlport/stl/_string_base.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1997-1999
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Copyright (c) 1999
00006  * Boris Fomitchev
00007  *
00008  * Copyright (c) 2003
00009  * Francois Dumont
00010  *
00011  * This material is provided "as is", with absolutely no warranty expressed
00012  * or implied. Any use is at your own risk.
00013  *
00014  * Permission to use or copy this software for any purpose is hereby granted
00015  * without fee, provided the above notices are retained on all copies.
00016  * Permission to modify the code and to distribute modified code is granted,
00017  * provided the above notices are retained, and a notice that the code was
00018  * modified is included with the above copyright notice.
00019  *
00020  */
00021 
00022 #ifndef _STLP_STRING_BASE_H
00023 #define _STLP_STRING_BASE_H
00024 
00025 // ------------------------------------------------------------
00026 // Class _String_base.
00027 
00028 // _String_base is a helper class that makes it it easier to write an
00029 // exception-safe version of basic_string.  The constructor allocates,
00030 // but does not initialize, a block of memory.  The destructor
00031 // deallocates, but does not destroy elements within, a block of
00032 // memory.  The destructor assumes that _M_start either is null, or else
00033 // points to a block of memory that was allocated using _String_base's
00034 // allocator and whose size is _M_end_of_storage._M_data - _M_start.
00035 
00036 _STLP_BEGIN_NAMESPACE
00037 
00038 _STLP_MOVE_TO_PRIV_NAMESPACE
00039 
00040 #ifndef _STLP_SHORT_STRING_SZ
00041 #  define _STLP_SHORT_STRING_SZ 16
00042 #endif
00043 
00044 template <class _Tp, class _Alloc>
00045 class _String_base {
00046   typedef _String_base<_Tp, _Alloc> _Self;
00047 protected:
00048   _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
00049 public:
00050   //dums: Some compiler(MSVC6) require it to be public not simply protected!
00051   enum {_DEFAULT_SIZE = _STLP_SHORT_STRING_SZ};
00052   //This is needed by the full move framework
00053   typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
00054   typedef _STLP_alloc_proxy<_Tp*, _Tp, allocator_type> _AllocProxy;
00055   typedef size_t size_type;
00056 private:
00057 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
00058   union _Buffers {
00059     _Tp*  _M_dynamic_buf;
00060     _Tp   _M_static_buf[_DEFAULT_SIZE];
00061   } _M_buffers;
00062 #else
00063   _Tp*    _M_start;
00064 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
00065 protected:
00066 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
00067   bool _M_using_static_buf() const {
00068     return (_M_end_of_storage._M_data == _M_buffers._M_static_buf + _DEFAULT_SIZE);
00069   }
00070   _Tp const* _M_Start() const {
00071     return _M_using_static_buf()?_M_buffers._M_static_buf:_M_buffers._M_dynamic_buf;
00072   }
00073   _Tp* _M_Start() {
00074     return _M_using_static_buf()?_M_buffers._M_static_buf:_M_buffers._M_dynamic_buf;
00075   }
00076 #else
00077   _Tp const* _M_Start() const {return _M_start;}
00078   _Tp* _M_Start() {return _M_start;}
00079 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
00080 
00081   _Tp*    _M_finish;
00082   _AllocProxy _M_end_of_storage;
00083 
00084   _Tp const* _M_Finish() const {return _M_finish;}
00085   _Tp* _M_Finish() {return _M_finish;}
00086 
00087   // Precondition: 0 < __n <= max_size().
00088   void _M_allocate_block(size_t __n = _DEFAULT_SIZE);
00089   void _M_deallocate_block() {
00090 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
00091     if (!_M_using_static_buf() && (_M_buffers._M_dynamic_buf != 0))
00092       _M_end_of_storage.deallocate(_M_buffers._M_dynamic_buf, _M_end_of_storage._M_data - _M_buffers._M_dynamic_buf);
00093 #else
00094     if (_M_start != 0)
00095       _M_end_of_storage.deallocate(_M_start, _M_end_of_storage._M_data - _M_start);
00096 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
00097   }
00098 
00099   size_t max_size() const {
00100     const size_type __string_max_size = size_type(-1) / sizeof(_Tp);
00101     typename allocator_type::size_type __alloc_max_size = _M_end_of_storage.max_size();
00102     return (min)(__alloc_max_size, __string_max_size) - 1;
00103   }
00104 
00105   _String_base(const allocator_type& __a)
00106 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
00107     : _M_finish(_M_buffers._M_static_buf), _M_end_of_storage(__a, _M_buffers._M_static_buf + _DEFAULT_SIZE)
00108 #else
00109     : _M_start(0), _M_finish(0), _M_end_of_storage(__a, (_Tp*)0)
00110 #endif
00111     {}
00112 
00113   _String_base(const allocator_type& __a, size_t __n)
00114 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
00115     : _M_finish(_M_buffers._M_static_buf), _M_end_of_storage(__a, _M_buffers._M_static_buf + _DEFAULT_SIZE) {
00116 #else
00117     : _M_start(0), _M_finish(0), _M_end_of_storage(__a, (_Tp*)0) {
00118 #endif
00119       _M_allocate_block(__n);
00120     }
00121 
00122 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
00123   void _M_move_src (_Self &src) {
00124       if (src._M_using_static_buf()) {
00125         _M_buffers = src._M_buffers;
00126         _M_finish = _M_buffers._M_static_buf + (src._M_finish - src._M_buffers._M_static_buf);
00127         _M_end_of_storage._M_data = _M_buffers._M_static_buf + _DEFAULT_SIZE;
00128       }
00129       else {
00130         _M_buffers._M_dynamic_buf = src._M_buffers._M_dynamic_buf;
00131         _M_finish = src._M_finish;
00132         _M_end_of_storage._M_data = src._M_end_of_storage._M_data;
00133         src._M_buffers._M_dynamic_buf = 0;
00134       }
00135     }
00136 #endif
00137 
00138   _String_base(__move_source<_Self> src)
00139 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
00140     : _M_end_of_storage(__move_source<_AllocProxy>(src.get()._M_end_of_storage)) {
00141       _M_move_src(src.get());
00142 #else
00143     : _M_start(src.get()._M_start), _M_finish(src.get()._M_finish),
00144       _M_end_of_storage(__move_source<_AllocProxy>(src.get()._M_end_of_storage)) {
00145       src.get()._M_start = 0;
00146 #endif
00147     }
00148 
00149   ~_String_base() { _M_deallocate_block(); }
00150 
00151   void _M_reset(_Tp *__start, _Tp *__finish, _Tp *__end_of_storage) {
00152 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
00153     _M_buffers._M_dynamic_buf = __start;
00154 #else
00155     _M_start = __start;
00156 #endif
00157     _M_finish = __finish;
00158     _M_end_of_storage._M_data = __end_of_storage;
00159   }
00160 
00161   void _M_destroy_back () {
00162 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
00163     if (!_M_using_static_buf())
00164 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
00165       _STLP_STD::_Destroy(_M_finish);
00166   }
00167 
00168   void _M_destroy_range(size_t __from_off = 0, size_t __to_off = 1) {
00169 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
00170     if (!_M_using_static_buf())
00171       _STLP_STD::_Destroy_Range(_M_buffers._M_dynamic_buf + __from_off, _M_finish + __to_off);
00172 #else
00173     _STLP_STD::_Destroy_Range(_M_start + __from_off, _M_finish + __to_off);
00174 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
00175   }
00176 
00177   void _M_destroy_ptr_range(_Tp *__f, _Tp *__l) {
00178 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
00179     if (!_M_using_static_buf())
00180 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
00181       _STLP_STD::_Destroy_Range(__f, __l);
00182   }
00183 
00184   void _M_Swap(_Self &__s) {
00185 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
00186     if (_M_using_static_buf()) {
00187       if (__s._M_using_static_buf()) {
00188         _STLP_STD::swap(_M_buffers, __s._M_buffers);
00189         _Tp *__tmp = _M_finish;
00190         _M_finish = _M_buffers._M_static_buf + (__s._M_finish - __s._M_buffers._M_static_buf);
00191         __s._M_finish = __s._M_buffers._M_static_buf + (__tmp - _M_buffers._M_static_buf);
00192         //We need to swap _M_end_of_storage for allocators with state:
00193         _M_end_of_storage.swap(__s._M_end_of_storage);
00194         _M_end_of_storage._M_data = _M_buffers._M_static_buf + _DEFAULT_SIZE;
00195         __s._M_end_of_storage._M_data = __s._M_buffers._M_static_buf + _DEFAULT_SIZE;
00196       } else {
00197         __s._M_Swap(*this);
00198         return;
00199       }
00200     }
00201     else if (__s._M_using_static_buf()) {
00202       _Tp *__tmp = _M_buffers._M_dynamic_buf;
00203       _Tp *__tmp_finish = _M_finish;
00204       _Tp *__tmp_end_data = _M_end_of_storage._M_data;
00205       _M_buffers = __s._M_buffers;
00206       //We need to swap _M_end_of_storage for allocators with state:
00207       _M_end_of_storage.swap(__s._M_end_of_storage);
00208       _M_end_of_storage._M_data = _M_buffers._M_static_buf + _DEFAULT_SIZE;
00209       _M_finish = _M_buffers._M_static_buf + (__s._M_finish - __s._M_buffers._M_static_buf);
00210       __s._M_buffers._M_dynamic_buf = __tmp;
00211       __s._M_end_of_storage._M_data = __tmp_end_data;
00212       __s._M_finish = __tmp_finish;
00213     }
00214     else {
00215       _STLP_STD::swap(_M_buffers._M_dynamic_buf, __s._M_buffers._M_dynamic_buf);
00216       _M_end_of_storage.swap(__s._M_end_of_storage);
00217       _STLP_STD::swap(_M_finish, __s._M_finish);
00218     }
00219 #else
00220     _STLP_STD::swap(_M_start, __s._M_start);
00221     _M_end_of_storage.swap(__s._M_end_of_storage);
00222     _STLP_STD::swap(_M_finish, __s._M_finish);
00223 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
00224   }
00225 
00226   void _STLP_FUNCTION_THROWS _M_throw_length_error() const;
00227   void _STLP_FUNCTION_THROWS _M_throw_out_of_range() const;
00228 };
00229 
00230 #undef _STLP_SHORT_STRING_SZ
00231 
00232 #if defined (_STLP_USE_TEMPLATE_EXPORT)
00233 _STLP_EXPORT_TEMPLATE_CLASS _String_base<char, allocator<char> >;
00234 #  if defined (_STLP_HAS_WCHAR_T)
00235 _STLP_EXPORT_TEMPLATE_CLASS _String_base<wchar_t, allocator<wchar_t> >;
00236 #  endif
00237 #endif /* _STLP_USE_TEMPLATE_EXPORT */
00238 
00239 _STLP_MOVE_TO_STD_NAMESPACE
00240 
00241 _STLP_END_NAMESPACE
00242 
00243 #endif /* _STLP_STRING_BASE_H */
00244 
00245 /*
00246  * Local Variables:
00247  * mode:C++
00248  * End:
00249  */



Generated on Mon Mar 10 15:32:39 2008 by  doxygen 1.5.1