This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] Add _M_grouping_len to the numpunct cache
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Wed, 14 Jan 2004 14:42:38 +0100
- Subject: [Patch] Add _M_grouping_len to the numpunct cache
Hi,
the below completes the work, changing the last remaining C-string
to char array + length. In this case, we avoid both computing again
and again the string length and also constructing again and again
a basic_string from an immutable C-string in order to pass the former
to __verify_grouping. As a side effect, the tweaked __verify_grouping,
(taking now a const char* and a size_t) is 20 bytes smaller, i.e.,
576 bytes (-O2, stripped), its speed is the same.
An interesting tweak of this work is that __verify_grouping is not a
template anymore: I say interesting because, actually, there was _no_
real reason for that also _before_ the patch: the grouping, according
to the standard is always a basic_string<char>.
Tested x86-linux, will commit later today if nobody objects.
Paolo.
//////////////
2004-01-14 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.h (struct __numpunct_cache):
Add member _M_grouping_len, caching the length of _M_grouping.
(__numpunct_cache<>::_M_cache): Assign the latter.
(__verify_grouping): Move declaration...
* include/bits/locale_facets.tcc (__verify_grouping):
... here, change signature to get a char* and a size_t for
the grouping; not a template anymore.
(__add_grouping, num_put::_M_group_int, num_put::_M_group_float):
Likewise change signature and tweak consistently.
(num_get::_M_extract_float, num_get::_M_extract_int,
num_put::_M_insert_int, num_put::_M_insert_float,
money_get::do_get(string_type&), money_get::do_put(string_type)):
Update callers.
* config/locale/generic/numeric_members.cc
(numpunct<>::_M_initialize_numpunct): Assign the new members.
* config/locale/gnu/numeric_members.cc
(numpunct<>::_M_initialize_numpunct): Likewise.
* src/locale-inst.cc (__add_grouping): Tweak signature.
(__verify_grouping): Don't instantiate, not a template anymore.
diff -urN libstdc++-v3-orig/config/locale/generic/numeric_members.cc libstdc++-v3/config/locale/generic/numeric_members.cc
--- libstdc++-v3-orig/config/locale/generic/numeric_members.cc 2004-01-11 20:20:03.000000000 +0100
+++ libstdc++-v3/config/locale/generic/numeric_members.cc 2004-01-14 00:59:01.000000000 +0100
@@ -57,6 +57,8 @@
for (size_t __i = 0; __i < __num_base::_S_iend; ++__i)
_M_data->_M_atoms_in[__i] = __num_base::_S_atoms_in[__i];
+ _M_data->_M_grouping_len = strlen(_M_data->_M_grouping);
+
_M_data->_M_truename = "true";
_M_data->_M_truename_len = strlen(_M_data->_M_truename);
_M_data->_M_falsename = "false";
@@ -96,6 +98,8 @@
_M_data->_M_atoms_in[__i] = btowc(uc);
}
+ _M_data->_M_grouping_len = strlen(_M_data->_M_grouping);
+
_M_data->_M_truename = L"true";
_M_data->_M_truename_len = wcslen(_M_data->_M_truename);
_M_data->_M_falsename = L"false";
diff -urN libstdc++-v3-orig/config/locale/gnu/numeric_members.cc libstdc++-v3/config/locale/gnu/numeric_members.cc
--- libstdc++-v3-orig/config/locale/gnu/numeric_members.cc 2004-01-11 20:08:13.000000000 +0100
+++ libstdc++-v3/config/locale/gnu/numeric_members.cc 2004-01-14 00:59:01.000000000 +0100
@@ -72,6 +72,8 @@
else
_M_data->_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
}
+ _M_data->_M_grouping_len = strlen(_M_data->_M_grouping);
+
// NB: There is no way to extact this info from posix locales.
// _M_truename = __nl_langinfo_l(YESSTR, __cloc);
_M_data->_M_truename = "true";
@@ -137,6 +139,8 @@
else
_M_data->_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
}
+ _M_data->_M_grouping_len = strlen(_M_data->_M_grouping);
+
// NB: There is no way to extact this info from posix locales.
// _M_truename = __nl_langinfo_l(YESSTR, __cloc);
_M_data->_M_truename = L"true";
diff -urN libstdc++-v3-orig/include/bits/locale_facets.h libstdc++-v3/include/bits/locale_facets.h
--- libstdc++-v3-orig/include/bits/locale_facets.h 2004-01-11 19:07:55.000000000 +0100
+++ libstdc++-v3/include/bits/locale_facets.h 2004-01-14 02:23:13.000000000 +0100
@@ -93,27 +93,14 @@
};
// Used by both numeric and monetary facets.
- // Check to make sure that the __grouping_tmp string constructed in
- // money_get or num_get matches the canonical grouping for a given
- // locale.
- // __grouping_tmp is parsed L to R
- // 1,222,444 == __grouping_tmp of "\1\3\3"
- // __grouping is parsed R to L
- // 1,222,444 == __grouping of "\3" == "\3\3\3"
- template<typename _CharT>
- bool
- __verify_grouping(const basic_string<_CharT>& __grouping,
- const basic_string<_CharT>& __grouping_tmp);
-
- // Used by both numeric and monetary facets.
// Inserts "group separator" characters into an array of characters.
// It's recursive, one iteration per group. It moves the characters
// in the buffer this way: "xxxx12345" -> "12,345xxx". Call this
- // only with __gbeg != __gend.
+ // only with __glen != 0.
template<typename _CharT>
_CharT*
__add_grouping(_CharT* __s, _CharT __sep,
- const char* __gbeg, const char* __gend,
+ const char* __gbeg, size_t __glen,
const _CharT* __first, const _CharT* __last);
// This template permits specializing facet output code for
@@ -1602,10 +1589,11 @@
struct __numpunct_cache : public locale::facet
{
const char* _M_grouping;
+ size_t _M_grouping_len;
bool _M_use_grouping;
const _CharT* _M_truename;
- const _CharT* _M_falsename;
size_t _M_truename_len;
+ const _CharT* _M_falsename;
size_t _M_falsename_len;
_CharT _M_decimal_point;
_CharT _M_thousands_sep;
@@ -1625,10 +1613,10 @@
bool _M_allocated;
__numpunct_cache(size_t __refs = 0) : facet(__refs),
- _M_grouping(NULL), _M_use_grouping(false), _M_truename(NULL),
- _M_falsename(NULL), _M_truename_len(0), _M_falsename_len(0),
- _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()),
- _M_allocated(false)
+ _M_grouping(NULL), _M_grouping_len(0), _M_use_grouping(false),
+ _M_truename(NULL), _M_truename_len(0), _M_falsename(NULL),
+ _M_falsename_len(0), _M_decimal_point(_CharT()),
+ _M_thousands_sep(_CharT()), _M_allocated(false)
{ }
~__numpunct_cache();
@@ -1645,12 +1633,11 @@
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- const string::size_type __len = __np.grouping().size();
- char* __grouping = new char[__len + 1];
- __np.grouping().copy(__grouping, __len);
- __grouping[__len] = char();
+ _M_grouping_len = __np.grouping().size();
+ char* __grouping = new char[_M_grouping_len];
+ __np.grouping().copy(__grouping, _M_grouping_len);
_M_grouping = __grouping;
- _M_use_grouping = __len && __np.grouping()[0] != 0;
+ _M_use_grouping = _M_grouping_len && __np.grouping()[0] != 0;
_M_truename_len = __np.truename().size();
_CharT* __truename = new _CharT[_M_truename_len];
@@ -2421,9 +2408,9 @@
char __mod, _ValueT __v) const;
void
- _M_group_float(const string& __grouping, char_type __sep,
- const char_type* __p, char_type* __new, char_type* __cs,
- int& __len) const;
+ _M_group_float(const char* __grouping, size_t __grouping_len,
+ char_type __sep, const char_type* __p, char_type* __new,
+ char_type* __cs, int& __len) const;
template<typename _ValueT>
iter_type
@@ -2431,9 +2418,9 @@
_ValueT __v) const;
void
- _M_group_int(const string& __grouping, char_type __sep,
- ios_base& __io, char_type* __new, char_type* __cs,
- int& __len) const;
+ _M_group_int(const char* __grouping, size_t __grouping_len,
+ char_type __sep, ios_base& __io, char_type* __new,
+ char_type* __cs, int& __len) const;
void
_M_pad(char_type __fill, streamsize __w, ios_base& __io,
diff -urN libstdc++-v3-orig/include/bits/locale_facets.tcc libstdc++-v3/include/bits/locale_facets.tcc
--- libstdc++-v3-orig/include/bits/locale_facets.tcc 2004-01-13 19:00:34.000000000 +0100
+++ libstdc++-v3/include/bits/locale_facets.tcc 2004-01-14 11:00:50.000000000 +0100
@@ -1,6 +1,6 @@
// Locale support -*- C++ -*-
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -150,6 +150,18 @@
}
};
+ // Used by both numeric and monetary facets.
+ // Check to make sure that the __grouping_tmp string constructed in
+ // money_get or num_get matches the canonical grouping for a given
+ // locale.
+ // __grouping_tmp is parsed L to R
+ // 1,222,444 == __grouping_tmp of "\1\3\3"
+ // __grouping is parsed R to L
+ // 1,222,444 == __grouping of "\3" == "\3\3\3"
+ static bool
+ __verify_grouping(const char* __grouping, size_t __grouping_len,
+ const string& __grouping_tmp);
+
template<typename _CharT, typename _InIter>
_InIter
num_get<_CharT, _InIter>::
@@ -293,8 +305,8 @@
if (!__found_dec)
__found_grouping += static_cast<char>(__sep_pos);
- const string __grouping = __lc->_M_grouping;
- if (!std::__verify_grouping(__grouping, __found_grouping))
+ if (!std::__verify_grouping(__lc->_M_grouping, __lc->_M_grouping_len,
+ __found_grouping))
__err |= ios_base::failbit;
}
@@ -485,8 +497,8 @@
// Add the ending grouping.
__found_grouping += static_cast<char>(__sep_pos);
- const string __grouping = __lc->_M_grouping;
- if (!std::__verify_grouping(__grouping, __found_grouping))
+ if (!std::__verify_grouping(__lc->_M_grouping, __lc->_M_grouping_len,
+ __found_grouping))
__err |= ios_base::failbit;
}
@@ -793,8 +805,8 @@
template<typename _CharT, typename _OutIter>
void
num_put<_CharT, _OutIter>::
- _M_group_int(const string& __grouping, _CharT __sep, ios_base& __io,
- _CharT* __new, _CharT* __cs, int& __len) const
+ _M_group_int(const char* __grouping, size_t __grouping_len, _CharT __sep,
+ ios_base& __io, _CharT* __new, _CharT* __cs, int& __len) const
{
// By itself __add_grouping cannot deal correctly with __cs when
// ios::showbase is set and ios_base::oct || ios_base::hex.
@@ -817,9 +829,9 @@
__new[1] = __cs[1];
}
_CharT* __p;
- __p = std::__add_grouping(__new + __off, __sep, __grouping.data(),
- __grouping.data() + __grouping.size(),
- __cs + __off, __cs + __len);
+ __p = std::__add_grouping(__new + __off, __sep, __grouping,
+ __grouping_len, __cs + __off,
+ __cs + __len);
__len = __p - __new;
}
@@ -854,8 +866,8 @@
// number of digits, but no more.
_CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
* __len * 2));
- _M_group_int(__lc->_M_grouping, __lc->_M_thousands_sep, __io,
- __cs2, __cs, __len);
+ _M_group_int(__lc->_M_grouping, __lc->_M_grouping_len,
+ __lc->_M_thousands_sep, __io, __cs2, __cs, __len);
__cs = __cs2;
}
@@ -878,16 +890,15 @@
template<typename _CharT, typename _OutIter>
void
num_put<_CharT, _OutIter>::
- _M_group_float(const string& __grouping, _CharT __sep, const _CharT* __p,
- _CharT* __new, _CharT* __cs, int& __len) const
+ _M_group_float(const char* __grouping, size_t __grouping_len, _CharT __sep,
+ const _CharT* __p, _CharT* __new, _CharT* __cs, int& __len) const
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 282. What types does numpunct grouping refer to?
// Add grouping, if necessary.
_CharT* __p2;
const int __declen = __p ? __p - __cs : __len;
- __p2 = std::__add_grouping(__new, __sep, __grouping.data(),
- __grouping.data() + __grouping.size(),
+ __p2 = std::__add_grouping(__new, __sep, __grouping, __grouping_len,
__cs, __cs + __declen);
// Tack on decimal part.
@@ -1003,8 +1014,8 @@
// number of digits, but no more.
_CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
* __len * 2));
- _M_group_float(__lc->_M_grouping, __lc->_M_thousands_sep, __p,
- __ws2, __ws, __len);
+ _M_group_float(__lc->_M_grouping, __lc->_M_grouping_len,
+ __lc->_M_thousands_sep, __p, __ws2, __ws, __len);
__ws = __ws2;
}
@@ -1308,7 +1319,9 @@
// Test for grouping fidelity.
if (__grouping.size() && __grouping_tmp.size())
{
- if (!std::__verify_grouping(__grouping, __grouping_tmp))
+ if (!std::__verify_grouping(__grouping.data(),
+ __grouping.size(),
+ __grouping_tmp))
__testvalid = false;
}
@@ -1461,12 +1474,12 @@
const char_type __sep = __intl ? __mpt.thousands_sep()
: __mpf.thousands_sep();
const char* __gbeg = __grouping.data();
- const char* __gend = __gbeg + __grouping.size();
+ const size_t __glen = __grouping.size();
const int __n = (__end - __beg) * 2;
_CharT* __ws2 =
static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
_CharT* __ws_end = std::__add_grouping(__ws2, __sep, __gbeg,
- __gend, __beg, __end);
+ __glen, __beg, __end);
__value.insert(0, __ws2, __ws_end - __ws2);
}
else
@@ -2268,13 +2281,12 @@
__oldlen - __mod);
}
- template<typename _CharT>
- bool
- __verify_grouping(const basic_string<_CharT>& __grouping,
- const basic_string<_CharT>& __grouping_tmp)
+ bool
+ __verify_grouping(const char* __grouping, size_t __grouping_len,
+ const string& __grouping_tmp)
{
const size_t __n = __grouping_tmp.size() - 1;
- const size_t __min = std::min(__n, __grouping.size() - 1);
+ const size_t __min = std::min(__n, __grouping_len - 1);
size_t __i = __n;
bool __test = true;
@@ -2293,15 +2305,16 @@
template<typename _CharT>
_CharT*
- __add_grouping(_CharT* __s, _CharT __sep,
- const char* __gbeg, const char* __gend,
+ __add_grouping(_CharT* __s, _CharT __sep,
+ const char* __gbeg, size_t __glen,
const _CharT* __first, const _CharT* __last)
{
if (__last - __first > *__gbeg)
{
- const bool __bump = __gbeg + 1 != __gend;
+ const bool __bump = __glen != 1;
__s = std::__add_grouping(__s, __sep, __gbeg + __bump,
- __gend, __first, __last - *__gbeg);
+ __glen - __bump, __first,
+ __last - *__gbeg);
__first = __last - *__gbeg;
*__s++ = __sep;
}
diff -urN libstdc++-v3-orig/src/locale-inst.cc libstdc++-v3/src/locale-inst.cc
--- libstdc++-v3-orig/src/locale-inst.cc 2003-12-08 16:37:03.000000000 +0100
+++ libstdc++-v3/src/locale-inst.cc 2004-01-14 02:27:22.000000000 +0100
@@ -272,14 +272,9 @@
// locale functions.
template
C*
- __add_grouping<C>(C*, C, char const*, char const*,
+ __add_grouping<C>(C*, C, char const*, size_t,
C const*, C const*);
- template
- bool
- __verify_grouping<C>(const basic_string<C>&,
- const basic_string<C>&);
-
template class __pad<C, char_traits<C> >;
template