diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc index 98442418f51..8c37a706db8 100644 --- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc +++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc @@ -71,61 +71,61 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const moneypunct<_CharT, _Intl>& __mp = use_facet >(__loc); + struct _Scoped_str + { + size_t _M_len; + _CharT* _M_str; + + explicit + _Scoped_str(const basic_string<_CharT>& __str) + : _M_len(__str.size()), _M_str(new _CharT[_M_len]) + { __str.copy(_M_str, _M_len); } + + ~_Scoped_str() { delete[] _M_str; } + + void + _M_release(const _CharT*& __p, size_t& __n) + { + __p = _M_str; + __n = _M_len; + _M_str = 0; + } + }; + + _Scoped_str __curr_symbol(__mp.curr_symbol()); + _Scoped_str __positive_sign(__mp.positive_sign()); + _Scoped_str __negative_sign(__mp.negative_sign()); + + const string& __g = __mp.grouping(); + const size_t __g_size = __g.size(); + char* const __grouping = new char[__g_size]; + __g.copy(__grouping, __g_size); + + // All allocations succeeded without throwing, OK to modify *this now. + + _M_grouping = __grouping; + _M_grouping_size = __g_size; + _M_use_grouping = (__g_size + && static_cast(__grouping[0]) > 0 + && (__grouping[0] + != __gnu_cxx::__numeric_traits::__max)); + _M_decimal_point = __mp.decimal_point(); _M_thousands_sep = __mp.thousands_sep(); + + __curr_symbol._M_release(_M_curr_symbol, _M_curr_symbol_size); + __positive_sign._M_release(_M_positive_sign, _M_positive_sign_size); + __negative_sign._M_release(_M_negative_sign, _M_negative_sign_size); + _M_frac_digits = __mp.frac_digits(); + _M_pos_format = __mp.pos_format(); + _M_neg_format = __mp.neg_format(); - char* __grouping = 0; - _CharT* __curr_symbol = 0; - _CharT* __positive_sign = 0; - _CharT* __negative_sign = 0; - __try - { - const string& __g = __mp.grouping(); - _M_grouping_size = __g.size(); - __grouping = new char[_M_grouping_size]; - __g.copy(__grouping, _M_grouping_size); - _M_use_grouping = (_M_grouping_size - && static_cast(__grouping[0]) > 0 - && (__grouping[0] - != __gnu_cxx::__numeric_traits::__max)); + const ctype<_CharT>& __ct = use_facet >(__loc); + __ct.widen(money_base::_S_atoms, + money_base::_S_atoms + money_base::_S_end, _M_atoms); - const basic_string<_CharT>& __cs = __mp.curr_symbol(); - _M_curr_symbol_size = __cs.size(); - __curr_symbol = new _CharT[_M_curr_symbol_size]; - __cs.copy(__curr_symbol, _M_curr_symbol_size); - - const basic_string<_CharT>& __ps = __mp.positive_sign(); - _M_positive_sign_size = __ps.size(); - __positive_sign = new _CharT[_M_positive_sign_size]; - __ps.copy(__positive_sign, _M_positive_sign_size); - - const basic_string<_CharT>& __ns = __mp.negative_sign(); - _M_negative_sign_size = __ns.size(); - __negative_sign = new _CharT[_M_negative_sign_size]; - __ns.copy(__negative_sign, _M_negative_sign_size); - - _M_pos_format = __mp.pos_format(); - _M_neg_format = __mp.neg_format(); - - const ctype<_CharT>& __ct = use_facet >(__loc); - __ct.widen(money_base::_S_atoms, - money_base::_S_atoms + money_base::_S_end, _M_atoms); - - _M_grouping = __grouping; - _M_curr_symbol = __curr_symbol; - _M_positive_sign = __positive_sign; - _M_negative_sign = __negative_sign; - _M_allocated = true; - } - __catch(...) - { - delete [] __grouping; - delete [] __curr_symbol; - delete [] __positive_sign; - delete [] __negative_sign; - __throw_exception_again; - } + _M_allocated = true; } _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11