/home/ntakagi/work/STLport-5.1.5/stlport/stl/_string_sum_methods.hGo to the documentation of this file.00001 /* 00002 * Copyright (c) 2003 00003 * Francois Dumont 00004 * 00005 * This material is provided "as is", with absolutely no warranty expressed 00006 * or implied. Any use is at your own risk. 00007 * 00008 * Permission to use or copy this software for any purpose is hereby granted 00009 * without fee, provided the above notices are retained on all copies. 00010 * Permission to modify the code and to distribute modified code is granted, 00011 * provided the above notices are retained, and a notice that the code was 00012 * modified is included with the above copyright notice. 00013 * 00014 */ 00015 00016 /* 00017 * All the necessary methods used for template expressions with basic_string 00018 * This file do not have to be macro guarded as it is only used in the _string.h 00019 * file and it is a part of the basic_string definition. 00020 */ 00021 00022 public: 00023 template <class _Left, class _Right, class _StorageDir> 00024 basic_string(_STLP_PRIV __bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir> const& __s) 00025 : _STLP_STRING_SUM_BASE(_Reserve_t(), __s.size(), __s.get_allocator()) 00026 { _M_append_sum(__s); } 00027 00028 template <class _Left, class _Right, class _StorageDir> 00029 basic_string(_STLP_PRIV __bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir> const& __s, 00030 size_type __pos, size_type __n = npos, 00031 const allocator_type& __a = allocator_type()) 00032 : _STLP_STRING_SUM_BASE(_Reserve_t(), (__pos <= __s.size()) ? ((min) (__n, __s.size() - __pos)) : 0, __a) { 00033 size_type __size = __s.size(); 00034 if (__pos > __size) 00035 this->_M_throw_out_of_range(); 00036 else 00037 _M_append_sum_pos(__s, __pos, (min) (__n, __size - __pos)); 00038 } 00039 00040 private: 00041 _CharT* _M_append_fast(_STLP_PRIV __char_wrapper<_CharT> __c, _CharT *__buf) { 00042 _STLP_STD::_Copy_Construct(__buf, __c.getValue()); 00043 return __buf + 1; 00044 } 00045 _CharT* _M_append_fast(_CharT const* __s, size_type __s_size, _CharT *__buf) 00046 { return uninitialized_copy(__s, __s + __s_size, __buf); } 00047 _CharT* _M_append_fast(_STLP_PRIV __cstr_wrapper<_CharT> const& __s, _CharT *__buf) 00048 { return _M_append_fast(__s.c_str(), __s.size(), __buf); } 00049 _CharT* _M_append_fast(_STLP_PRIV __bstr_wrapper<_CharT, _Traits, _Alloc> __s, _CharT *__buf) 00050 { return _M_append_fast(__s.b_str(), __buf); } 00051 _CharT* _M_append_fast(_Self const& __s, _CharT *__buf) 00052 { return _M_append_fast(__s.data(), __s.size(), __buf); } 00053 _CharT* _M_append_fast(_STLP_PRIV __sum_storage_elem<_CharT, _Traits, _Alloc> const&, _CharT *__buf) 00054 { return __buf; } 00055 template <class _Left, class _Right, class _StorageDir> 00056 _CharT* _M_append_fast(_STLP_PRIV __bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir> const& __s, _CharT *__buf) 00057 { return _M_append_fast(__s.getRhs(), _M_append_fast(__s.getLhs(), __buf)); } 00058 00059 _CharT* _M_append_fast_pos(_STLP_PRIV __char_wrapper<_CharT> __c, _CharT *__buf, size_type /*__pos*/, size_type __n) { 00060 if (__n == 0) 00061 return __buf; 00062 _STLP_STD::_Copy_Construct(__buf, __c.getValue()); 00063 return __buf + 1; 00064 } 00065 _CharT* _M_append_fast_pos(_CharT const* __s, size_type __s_size, _CharT *__buf, 00066 size_type __pos, size_type __n) 00067 { return uninitialized_copy(__s + __pos, __s + __pos + (min)(__n, __s_size - __pos), __buf); } 00068 _CharT* _M_append_fast_pos(_STLP_PRIV __cstr_wrapper<_CharT> const& __s, _CharT *__buf, 00069 size_type __pos, size_type __n) 00070 { return _M_append_fast_pos(__s.c_str(), __s.size(), __buf, __pos, __n); } 00071 _CharT* _M_append_fast_pos(_STLP_PRIV __bstr_wrapper<_CharT, _Traits, _Alloc> __s, _CharT *__buf, 00072 size_type __pos, size_type __n) 00073 { return _M_append_fast_pos(__s.b_str(), __buf, __pos, __n); } 00074 _CharT* _M_append_fast_pos(_Self const& __s, _CharT *__buf, 00075 size_type __pos, size_type __n) 00076 { return _M_append_fast_pos(__s.data(), __s.size(), __buf, __pos, __n); } 00077 _CharT* _M_append_fast_pos(_STLP_PRIV __sum_storage_elem<_CharT, _Traits, _Alloc> const&, _CharT *__buf, 00078 size_type, size_type) 00079 { return __buf; } 00080 00081 template <class _Left, class _Right, class _StorageDir> 00082 _CharT* _M_append_fast_pos(_STLP_PRIV __bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir> const& __s, 00083 _CharT *__buf, size_type __pos, size_type __n) { 00084 if (__n == 0) { 00085 return __buf; 00086 } 00087 size_type __lhs_size = __s.getLhs().size(); 00088 if (__pos < __lhs_size) { 00089 if (__n < (__lhs_size - __pos)) { 00090 return _M_append_fast_pos(__s.getLhs(), __buf, __pos, __n); 00091 } else { 00092 return _M_append_fast_pos(__s.getRhs(), _M_append_fast_pos(__s.getLhs(), __buf, __pos, __n), 00093 0, __n - (__lhs_size - __pos)); 00094 } 00095 } else { 00096 return _M_append_fast_pos(__s.getRhs(), __buf, __pos - __lhs_size, __n); 00097 } 00098 } 00099 00100 /* Note: We always force use of dynamic buffer if the short string optim option is activated 00101 * to avoid complicated code if the basic_string was instanciated with a non POD type. 00102 * In such a case we should use assignment for objects in the static array something that we 00103 * do not do. 00104 */ 00105 size_type _M_get_additional_size(size_type __new_size, const __false_type& /*_Char_Is_POD*/) const { 00106 #if defined (_STLP_USE_SHORT_STRING_OPTIM) 00107 //To avoid problem with the string assumptions, never allocate a dynamic buffer smaller or equal 00108 //than the static one: 00109 if (__new_size < _Base::_DEFAULT_SIZE + 1) 00110 return (_Base::_DEFAULT_SIZE + 1) - __new_size; 00111 #endif /* _STLP_USE_SHORT_STRING_OPTIM */ 00112 return 0; 00113 } 00114 size_type _M_get_additional_size(size_type, const __true_type& /*_Char_Is_POD*/) const 00115 { return 0; } 00116 00117 template <class _Left, class _Right, class _StorageDir> 00118 _Self& _M_append_sum (_STLP_PRIV __bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir> const& __s) { 00119 size_type __s_size = __s.size(); 00120 if (__s_size == 0) 00121 return *this; 00122 const size_type __old_size = this->size(); 00123 if (__s_size > this->max_size() || __old_size > (this->max_size() - __s_size)) 00124 this->_M_throw_length_error(); 00125 size_type __offset_size = _M_get_additional_size(__old_size + __s_size, _Char_Is_POD()); 00126 if (__old_size + __s_size + __offset_size > this->capacity()) { 00127 const size_type __len = __old_size + __offset_size + (max)(__old_size, __s_size) + 1; 00128 pointer __new_start = this->_M_end_of_storage.allocate(__len); 00129 pointer __new_finish = __new_start; 00130 _STLP_TRY { 00131 __new_finish = uninitialized_copy(this->_M_Start(), this->_M_Finish(), __new_start); 00132 __new_finish = this->_M_append_fast(__s, __new_finish); 00133 this->_M_construct_null(__new_finish); 00134 } 00135 _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish), 00136 this->_M_end_of_storage.deallocate(__new_start,__len))) 00137 this->_M_destroy_range(); 00138 this->_M_deallocate_block(); 00139 this->_M_reset(__new_start, __new_finish, __new_start + __len); 00140 } 00141 else { 00142 _M_append_sum_no_overflow(__s, 0, __s_size); 00143 } 00144 return *this; 00145 } 00146 00147 template <class _Left, class _Right, class _StorageDir> 00148 _Self& _M_append_sum_pos(_STLP_PRIV __bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir> const& __s, 00149 size_type __pos, size_type __n) { 00150 size_type __s_size = (min)(__s.size() - __pos, __n); 00151 if (__s_size == 0) 00152 return *this; 00153 const size_type __old_size = this->size(); 00154 if (__s_size > this->max_size() || __old_size > (this->max_size() - __s_size)) 00155 this->_M_throw_length_error(); 00156 size_type __offset_size = _M_get_additional_size(__old_size + __s_size, _Char_Is_POD()); 00157 if (__old_size + __s_size + __offset_size > this->capacity()) { 00158 const size_type __len = __old_size + __offset_size + (max)(__old_size, __s_size) + 1; 00159 pointer __new_start = this->_M_end_of_storage.allocate(__len); 00160 pointer __new_finish = __new_start; 00161 _STLP_TRY { 00162 __new_finish = uninitialized_copy(this->_M_Start(), this->_M_Finish(), __new_start); 00163 __new_finish = _M_append_fast_pos(__s, __new_finish, __pos, __s_size); 00164 this->_M_construct_null(__new_finish); 00165 } 00166 _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish), 00167 this->_M_end_of_storage.deallocate(__new_start,__len))) 00168 this->_M_destroy_range(); 00169 this->_M_deallocate_block(); 00170 this->_M_reset(__new_start, __new_finish, __new_start + __len); 00171 } 00172 else { 00173 _M_append_sum_no_overflow(__s, __pos, __s_size); 00174 } 00175 return *this; 00176 } 00177 00178 template <class _Left, class _Right, class _StorageDir> 00179 void _M_append_sum_no_overflow(_STLP_PRIV __bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir> const& __s, 00180 size_type __pos, size_type __n) { 00181 pointer __finish = this->_M_Finish(); 00182 _M_append_fast_pos(__s, __finish + 1, __pos + 1, __n - 1); 00183 _STLP_TRY { 00184 this->_M_construct_null(__finish + __n); 00185 } 00186 _STLP_UNWIND(this->_M_destroy_ptr_range(__finish + 1, __finish + __n)) 00187 /* The call to the traits::assign method is only important for non POD types because the instance 00188 * pointed to by _M_finish has been constructed (default constructor) and should not be constructed 00189 * (copy constructor) once again. For POD it is irrelevant, uninitialized_copy could be fine, 00190 * but we are not going to make two implementations just for that. 00191 */ 00192 _Traits::assign(*this->_M_finish, __s[__pos]); 00193 this->_M_finish += __n; 00194 }
Generated on Mon Mar 10 15:32:41 2008 by ![]() |