/home/ntakagi/work/STLport-5.1.5/stlport/stl/_string_base.hGo 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 ![]() |