This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] Fix for Martin's issue
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Fri, 19 Dec 2003 14:56:44 +0100
- Subject: [Patch] Fix for Martin's issue
Hi,
so here it is, quite easy to fix, as I imagined. I was a little bit
worried that performance could be affected, so I ran three times
the performance testsuite (p4-2400, -O2) and ifstream_extract_int
is:
3.4
---
612r 600u 7s 0mem 8pf
615r 607u 6s 0mem 8pf
610r 599u 7s 0mem 8pf
3.4 + patch
-----------
619r 601u 8s 0mem 7pf
615r 601u 11s 0mem 7pf
618r 601u 13s 0mem 7pf
so, the differences are in the noise, it seems...
Otherwise, the fix is straightforard: just reorder properly the
various branches.
Tested x86-linux, will wait 'til this evening italian time.
Paolo.
///////////
2003-12-19 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.tcc (num_get::_M_extract_int,
num_get::_M_extract_float): According to 22.2.2.1.2, p8-9,
first look for decimal_point and thousands_sep.
* testsuite/22_locale/num_get/get/char/11.cc: New.
* testsuite/22_locale/num_get/get/wchar_t/11.cc: Likewise.
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 Thu Dec 18 23:47:04 2003
--- libstdc++-v3/include/bits/locale_facets.tcc Fri Dec 19 14:18:46 2003
*************** namespace std
*** 169,186 ****
string __found_grouping;
int __sep_pos = 0;
bool __e;
while (__beg != __end)
{
! // Only look in digits.
const char_type __c = *__beg;
! const char_type* __p = __traits_type::find(__lit + _S_izero, 10,
! __c);
! if (__p)
{
! // Try first for acceptable digit; record it if found.
! __xtrc += _S_atoms_in[__p - __lit];
! __found_mantissa = true;
! ++__sep_pos;
++__beg;
}
else if (__lc->_M_use_grouping
--- 169,190 ----
string __found_grouping;
int __sep_pos = 0;
bool __e;
+ const char_type* __p;
while (__beg != __end)
{
! // According to 22.2.2.1.2, p8-9, first look for decimal_point
! // and thousands_sep.
const char_type __c = *__beg;
! if (__traits_type::eq(__c, __lc->_M_decimal_point)
! && !__found_dec && !__found_sci)
{
! // According to the standard, if no grouping chars are seen,
! // no grouping check is applied. Therefore __found_grouping
! // must be adjusted only if __dec comes after some __sep.
! if (__found_grouping.size())
! __found_grouping += static_cast<char>(__sep_pos);
! __xtrc += '.';
! __found_dec = true;
++__beg;
}
else if (__lc->_M_use_grouping
*************** namespace std
*** 201,216 ****
break;
}
}
! else if (__traits_type::eq(__c, __lc->_M_decimal_point)
! && !__found_dec && !__found_sci)
{
! // According to the standard, if no grouping chars are seen,
! // no grouping check is applied. Therefore __found_grouping
! // must be adjusted only if __dec comes after some __sep.
! if (__found_grouping.size())
! __found_grouping += static_cast<char>(__sep_pos);
! __xtrc += '.';
! __found_dec = true;
++__beg;
}
else if ((__e = __traits_type::eq(__c, __lit[_S_ie])
--- 205,215 ----
break;
}
}
! else if (__p = __traits_type::find(__lit + _S_izero, 10, __c))
{
! __xtrc += _S_atoms_in[__p - __lit];
! __found_mantissa = true;
! ++__sep_pos;
++__beg;
}
else if ((__e = __traits_type::eq(__c, __lit[_S_ie])
*************** namespace std
*** 337,350 ****
bool __overflow = false;
_ValueT __result = 0;
const char_type* __lit_zero = __lit + _S_izero;
if (__negative)
{
const _ValueT __min = numeric_limits<_ValueT>::min() / __base;
for (; __beg != __end; ++__beg)
{
! const char_type* __p = __traits_type::find(__lit_zero,
! __len, *__beg);
! if (__p)
{
int __digit = __p - __lit_zero;
if (__digit > 15)
--- 336,369 ----
bool __overflow = false;
_ValueT __result = 0;
const char_type* __lit_zero = __lit + _S_izero;
+ const char_type* __p;
if (__negative)
{
const _ValueT __min = numeric_limits<_ValueT>::min() / __base;
for (; __beg != __end; ++__beg)
{
! // According to 22.2.2.1.2, p8-9, first look for decimal_point
! // and thousands_sep.
! const char_type __c = *__beg;
! if (__traits_type::eq(__c, __lc->_M_decimal_point))
! break;
! else if (__lc->_M_use_grouping
! && __traits_type::eq(__c, __lc->_M_thousands_sep))
! {
! // NB: Thousands separator at the beginning of a string
! // is a no-no, as is two consecutive thousands separators.
! if (__sep_pos)
! {
! __found_grouping += static_cast<char>(__sep_pos);
! __sep_pos = 0;
! }
! else
! {
! __err |= ios_base::failbit;
! break;
! }
! }
! else if (__p = __traits_type::find(__lit_zero, __len, __c))
{
int __digit = __p - __lit_zero;
if (__digit > 15)
*************** namespace std
*** 360,370 ****
__found_num = true;
}
}
else if (__lc->_M_use_grouping
! && __traits_type::eq(*__beg, __lc->_M_thousands_sep))
{
- // NB: Thousands separator at the beginning of a string
- // is a no-no, as is two consecutive thousands separators.
if (__sep_pos)
{
__found_grouping += static_cast<char>(__sep_pos);
--- 379,400 ----
__found_num = true;
}
}
+ else
+ // Not a valid input item.
+ break;
+ }
+ }
+ else
+ {
+ const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
+ for (; __beg != __end; ++__beg)
+ {
+ const char_type __c = *__beg;
+ if (__traits_type::eq(__c, __lc->_M_decimal_point))
+ break;
else if (__lc->_M_use_grouping
! && __traits_type::eq(__c, __lc->_M_thousands_sep))
{
if (__sep_pos)
{
__found_grouping += static_cast<char>(__sep_pos);
*************** namespace std
*** 376,394 ****
break;
}
}
! else
! // Not a valid input item.
! break;
! }
! }
! else
! {
! const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
! for (; __beg != __end; ++__beg)
! {
! const char_type* __p = __traits_type::find(__lit_zero,
! __len, *__beg);
! if (__p)
{
int __digit = __p - __lit_zero;
if (__digit > 15)
--- 406,412 ----
break;
}
}
! else if (__p = __traits_type::find(__lit_zero, __len, __c))
{
int __digit = __p - __lit_zero;
if (__digit > 15)
*************** namespace std
*** 404,423 ****
__found_num = true;
}
}
- else if (__lc->_M_use_grouping
- && __traits_type::eq(*__beg, __lc->_M_thousands_sep))
- {
- if (__sep_pos)
- {
- __found_grouping += static_cast<char>(__sep_pos);
- __sep_pos = 0;
- }
- else
- {
- __err |= ios_base::failbit;
- break;
- }
- }
else
break;
}
--- 422,427 ----
diff -prN libstdc++-v3-orig/testsuite/22_locale/num_get/get/char/11.cc libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc
*** libstdc++-v3-orig/testsuite/22_locale/num_get/get/char/11.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc Fri Dec 19 14:13:39 2003
***************
*** 0 ****
--- 1,68 ----
+ // Copyright (C) 2003 Free Software Foundation
+ //
+ // This file is part of the GNU ISO C++ Library. This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ // GNU General Public License for more details.
+
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING. If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+
+ // 22.2.2.1.1 num_get members
+
+ #include <locale>
+ #include <sstream>
+ #include <testsuite_hooks.h>
+
+ struct Punct: std::numpunct<char>
+ {
+ std::string do_grouping () const { return "\1"; }
+ char do_thousands_sep () const { return '2'; }
+ char do_decimal_point () const { return '4'; }
+ };
+
+ void test01()
+ {
+ using namespace std;
+ typedef istreambuf_iterator<char> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ istringstream iss;
+ iss.imbue(locale(iss.getloc(), static_cast<numpunct<char>*>(new Punct)));
+ const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc());
+ ios_base::iostate err = ios_base::goodbit;
+ iterator_type end;
+ double d = 0.0;
+ double d1 = 13.0;
+ long l = 0l;
+ long l1 = 13l;
+
+ iss.str("1234");
+ err = ios_base::goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, d);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( d == d1 );
+
+ iss.str("1234");
+ iss.clear();
+ err = ios_base::goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, l);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( l == l1 );
+ }
+
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/22_locale/num_get/get/wchar_t/11.cc libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc
*** libstdc++-v3-orig/testsuite/22_locale/num_get/get/wchar_t/11.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc Fri Dec 19 14:13:55 2003
***************
*** 0 ****
--- 1,68 ----
+ // Copyright (C) 2003 Free Software Foundation
+ //
+ // This file is part of the GNU ISO C++ Library. This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ // GNU General Public License for more details.
+
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING. If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+
+ // 22.2.2.1.1 num_get members
+
+ #include <locale>
+ #include <sstream>
+ #include <testsuite_hooks.h>
+
+ struct Punct: std::numpunct<wchar_t>
+ {
+ std::string do_grouping () const { return "\1"; }
+ wchar_t do_thousands_sep () const { return L'2'; }
+ wchar_t do_decimal_point () const { return L'4'; }
+ };
+
+ void test01()
+ {
+ using namespace std;
+ typedef istreambuf_iterator<wchar_t> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ wistringstream iss;
+ iss.imbue(locale(iss.getloc(), static_cast<numpunct<wchar_t>*>(new Punct)));
+ const num_get<wchar_t>& ng = use_facet<num_get<wchar_t> >(iss.getloc());
+ ios_base::iostate err = ios_base::goodbit;
+ iterator_type end;
+ double d = 0.0;
+ double d1 = 13.0;
+ long l = 0l;
+ long l1 = 13l;
+
+ iss.str(L"1234");
+ err = ios_base::goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, d);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( d == d1 );
+
+ iss.str(L"1234");
+ iss.clear();
+ err = ios_base::goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, l);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( l == l1 );
+ }
+
+
+ int main()
+ {
+ test01();
+ return 0;
+ }