This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [FYI] A "problem" in money_get/money_put/time_put
- From: Paolo Carlini <pcarlini at suse dot de>
- To: Paolo Carlini <pcarlini at suse dot de>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Wed, 18 Feb 2004 12:16:04 +0100
- Subject: Re: [FYI] A "problem" in money_get/money_put/time_put
- References: <4032764D.4030501@suse.de> <4033338E.50004@suse.de>
Paolo Carlini wrote:
I'm now working on money_put and money_get.
The below is the corresponding patch, regtested x86-linux: turned out
to be straightforward, but working on it made clear that money_get
is currently using ctype::narrow and isn't using ctype::widen (see
22.2.6.1.2, p4 and note 237), thus the caching bits are even more
urgent for the correctness implications (they bring the widened in
and out atoms).
Will commit later today.
Paolo.
///////////
2004-02-18 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.h (money_get<>::_M_extract):
New, helper for do_get.
(money_put<>::_M_insert): Likewise, for do_put.
* include/bits/locale_facets.tcc (money_get<>::_M_extract,
money_put<>::_M_insert): Define.
(money_get<>::do_get(long double&), money_get<>::do_get(
string_type&), money_put::do_put(long double),
money_put::do_put(const string_type&)): Use the helpers.
diff -prN libstdc++-v3-orig/include/bits/locale_facets.h libstdc++-v3/include/bits/locale_facets.h
*** libstdc++-v3-orig/include/bits/locale_facets.h Sun Feb 8 05:46:41 2004
--- libstdc++-v3/include/bits/locale_facets.h Wed Feb 18 11:33:19 2004
*************** namespace std
*** 4056,4061 ****
--- 4056,4065 ----
virtual iter_type
do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
ios_base::iostate& __err, string_type& __digits) const;
+
+ iter_type
+ _M_extract(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
+ ios_base::iostate& __err, string_type& __digits) const;
};
template<typename _CharT, typename _InIter>
*************** namespace std
*** 4189,4194 ****
--- 4193,4202 ----
virtual iter_type
do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
const string_type& __digits) const;
+
+ iter_type
+ _M_insert(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+ const string_type& __digits) const;
};
template<typename _CharT, typename _OutIter>
diff -prN libstdc++-v3-orig/include/bits/locale_facets.tcc libstdc++-v3/include/bits/locale_facets.tcc
*** libstdc++-v3-orig/include/bits/locale_facets.tcc Tue Feb 17 11:18:33 2004
--- libstdc++-v3/include/bits/locale_facets.tcc Wed Feb 18 11:32:25 2004
*************** namespace std
*** 1130,1160 ****
return __s;
}
-
- template<typename _CharT, typename _InIter>
- _InIter
- money_get<_CharT, _InIter>::
- do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
- ios_base::iostate& __err, long double& __units) const
- {
- string_type __str;
- __beg = this->do_get(__beg, __end, __intl, __io, __err, __str);
-
- const int __cs_size = __str.size() + 1;
- char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
- const locale __loc = __io.getloc();
- const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
- const _CharT* __wcs = __str.c_str();
- __ctype.narrow(__wcs, __wcs + __cs_size, char(), __cs);
- std::__convert_to_v(__cs, __units, __err, _S_get_c_locale());
- return __beg;
- }
-
template<typename _CharT, typename _InIter>
_InIter
money_get<_CharT, _InIter>::
! do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
! ios_base::iostate& __err, string_type& __units) const
{
// These contortions are quite unfortunate.
typedef moneypunct<_CharT, true> __money_true;
--- 1130,1140 ----
return __s;
}
template<typename _CharT, typename _InIter>
_InIter
money_get<_CharT, _InIter>::
! _M_extract(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
! ios_base::iostate& __err, string_type& __units) const
{
// These contortions are quite unfortunate.
typedef moneypunct<_CharT, true> __money_true;
*************** namespace std
*** 1358,1410 ****
return __beg;
}
! template<typename _CharT, typename _OutIter>
! _OutIter
! money_put<_CharT, _OutIter>::
! do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
! long double __units) const
{
const locale __loc = __io.getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
! #ifdef _GLIBCXX_USE_C99
! // First try a buffer perhaps big enough.
! int __cs_size = 64;
! char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
! // _GLIBCXX_RESOLVE_LIB_DEFECTS
! // 328. Bad sprintf format modifier in money_put<>::do_put()
! int __len = std::__convert_from_v(__cs, __cs_size, "%.0Lf", __units,
! _S_get_c_locale());
! // If the buffer was not large enough, try again with the correct size.
! if (__len >= __cs_size)
! {
! __cs_size = __len + 1;
! __cs = static_cast<char*>(__builtin_alloca(__cs_size));
! __len = std::__convert_from_v(__cs, __cs_size, "%.0Lf", __units,
! _S_get_c_locale());
! }
! #else
! // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
! const int __cs_size = numeric_limits<long double>::max_exponent10 + 3;
! char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
! int __len = std::__convert_from_v(__cs, 0, "%.0Lf", __units,
! _S_get_c_locale());
! #endif
! _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
! * __cs_size));
! __ctype.widen(__cs, __cs + __len, __ws);
! const string_type __digits(__ws, __len);
! return this->do_put(__s, __intl, __io, __fill, __digits);
}
template<typename _CharT, typename _OutIter>
_OutIter
money_put<_CharT, _OutIter>::
! do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
! const string_type& __digits) const
{
typedef typename string_type::size_type size_type;
typedef money_base::part part;
!
const locale __loc = __io.getloc();
const size_type __width = static_cast<size_type>(__io.width());
--- 1338,1378 ----
return __beg;
}
! template<typename _CharT, typename _InIter>
! _InIter
! money_get<_CharT, _InIter>::
! do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
! ios_base::iostate& __err, long double& __units) const
{
+ string_type __str;
+ __beg = _M_extract(__beg, __end, __intl, __io, __err, __str);
+
+ const int __cs_size = __str.size() + 1;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
const locale __loc = __io.getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
! const _CharT* __wcs = __str.c_str();
! __ctype.narrow(__wcs, __wcs + __cs_size, char(), __cs);
! std::__convert_to_v(__cs, __units, __err, _S_get_c_locale());
! return __beg;
}
+ template<typename _CharT, typename _InIter>
+ _InIter
+ money_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
+ ios_base::iostate& __err, string_type& __units) const
+ { return _M_extract(__beg, __end, __intl, __io, __err, __units); }
+
template<typename _CharT, typename _OutIter>
_OutIter
money_put<_CharT, _OutIter>::
! _M_insert(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
! const string_type& __digits) const
{
typedef typename string_type::size_type size_type;
typedef money_base::part part;
!
const locale __loc = __io.getloc();
const size_type __width = static_cast<size_type>(__io.width());
*************** namespace std
*** 1556,1564 ****
__s = std::__write(__s, __res.data(), __len);
}
__io.width(0);
! return __s;
}
// NB: Not especially useful. Without an ios_base object or some
// kind of locale reference, we are left clawing at the air where
--- 1524,1576 ----
__s = std::__write(__s, __res.data(), __len);
}
__io.width(0);
! return __s;
}
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ money_put<_CharT, _OutIter>::
+ do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+ long double __units) const
+ {
+ const locale __loc = __io.getloc();
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+ #ifdef _GLIBCXX_USE_C99
+ // First try a buffer perhaps big enough.
+ int __cs_size = 64;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 328. Bad sprintf format modifier in money_put<>::do_put()
+ int __len = std::__convert_from_v(__cs, __cs_size, "%.0Lf", __units,
+ _S_get_c_locale());
+ // If the buffer was not large enough, try again with the correct size.
+ if (__len >= __cs_size)
+ {
+ __cs_size = __len + 1;
+ __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ __len = std::__convert_from_v(__cs, __cs_size, "%.0Lf", __units,
+ _S_get_c_locale());
+ }
+ #else
+ // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
+ const int __cs_size = numeric_limits<long double>::max_exponent10 + 3;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ int __len = std::__convert_from_v(__cs, 0, "%.0Lf", __units,
+ _S_get_c_locale());
+ #endif
+ _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
+ * __cs_size));
+ __ctype.widen(__cs, __cs + __len, __ws);
+ const string_type __digits(__ws, __len);
+ return _M_insert(__s, __intl, __io, __fill, __digits);
+ }
+
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ money_put<_CharT, _OutIter>::
+ do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+ const string_type& __digits) const
+ { return _M_insert(__s, __intl, __io, __fill, __digits); }
// NB: Not especially useful. Without an ios_base object or some
// kind of locale reference, we are left clawing at the air where