[PATCH] PR libstdc++/5331 returned iterator from num_get<>::get
David Seymour
qfp@wn.com.au
Thu Jan 10 07:30:00 GMT 2002
paolo just ask me to send this patch here.
What: num_get<>::get (all signatures) return an iterator which is not
advanced as required by the standard (22.2.2.1).
Fix: num_get<>::_M_extract_float and num_get<>::_M_extract_int do the
work, just don't return the advanced iterator, the following patch makes
them return it.
Compiled and make check.
Cheers Dave
--
David Seymour
djs@wn.com.au
/////////////
2002-01-10 David Seymour <seymour_dj@yahoo.com>
* include/bits/locale_facets.h (num_get<>): Return advanced iterator
for _M_extract_float and _M_extract_int
* include/bits/locale_facets.tcc (num_get<>::_M_extract_float)
(num_get<>::_M_extract_int): Likewise, all callers changed
* testsuite/22_locale/num_get_members_char.cc: Testcase
Index: include/bits/locale_facets.h
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.34
diff -u -3 -p -r1.34 locale_facets.h
--- locale_facets.h 2001/12/15 07:05:03 1.34
+++ locale_facets.h 2002/01/10 15:14:42
@@ -641,11 +641,11 @@ namespace std
protected:
virtual ~num_get() { }
- void
+ iter_type
_M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
string& __xtrc) const;
- void
+ iter_type
_M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
char* __xtrc, int __max, int& __base) const;
Index: include/bits/locale_facets.tcc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.47
diff -u -3 -p -r1.47 locale_facets.tcc
--- locale_facets.tcc 2001/12/27 12:13:23 1.47
+++ locale_facets.tcc 2002/01/10 15:14:47
@@ -88,7 +88,7 @@ namespace std
template<typename _CharT, typename _InIter>
- void
+ _InIter
num_get<_CharT, _InIter>::
_M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
ios_base::iostate& __err, string& __xtrc) const
@@ -213,10 +213,11 @@ namespace std
__xtrc += char();
if (__beg == __end)
__err |= ios_base::eofbit;
+ return __beg;
}
template<typename _CharT, typename _InIter>
- void
+ _InIter
num_get<_CharT, _InIter>::
_M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
ios_base::iostate& __err, char* __xtrc, int __max,
@@ -369,6 +370,7 @@ namespace std
__xtrc[__pos] = char();
if (__beg == __end)
__err |= ios_base::eofbit;
+ return __beg;
}
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
@@ -394,8 +396,8 @@ namespace std
// that can be represented without change" so we have to add 1 to it
// in order to obtain the max number of digits. The same for the
// other do_get for integral types below.
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<bool>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<bool>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -459,8 +461,8 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<long>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<long>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -485,8 +487,9 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned short>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<unsigned short>::digits10 + 1,
+ __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -512,8 +515,9 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned int>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<unsigned int>::digits10 + 1,
+ __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -539,8 +543,9 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned long>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<unsigned long>::digits10 + 1,
+ __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -566,8 +571,8 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<long long>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<long long>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -592,8 +597,9 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned long long>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<unsigned long long>::digits10 + 1,
+ __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -617,7 +623,7 @@ namespace std
// Stage 1: extract and determine the conversion specifier.
string __xtrc;
__xtrc.reserve(32);
- _M_extract_float(__beg, __end, __io, __err, __xtrc);
+ __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
// Stage 2: convert and store results.
char* __sanity;
@@ -644,7 +650,7 @@ namespace std
// Stage 1: extract and determine the conversion specifier.
string __xtrc;
__xtrc.reserve(32);
- _M_extract_float(__beg, __end, __io, __err, __xtrc);
+ __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
// Stage 2: convert and store results.
char* __sanity;
@@ -667,7 +673,7 @@ namespace std
// Stage 1: extract and determine the conversion specifier.
string __xtrc;
__xtrc.reserve(32);
- _M_extract_float(__beg, __end, __io, __err, __xtrc);
+ __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
#if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
// Stage 2: convert and store results.
@@ -721,8 +727,9 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned long>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<unsigned long>::digits10 + 1,
+ __base);
// Stage 2: convert and store results.
char* __sanity;
Index: testsuite/22_locale/num_get_members_char.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/testsuite/22_locale/num_get_members_char.cc,v
retrieving revision 1.1
diff -u -3 -p -r1.1 num_get_members_char.cc
--- num_get_members_char.cc 2001/11/28 04:07:10 1.1
+++ num_get_members_char.cc 2002/01/10 15:14:47
@@ -235,10 +235,35 @@ void test01()
#endif
}
+void test02()
+{
+ // num_get works with other iterators besides streambuf output iterators
+ using namespace std;
+
+ typedef string::const_iterator iter_type;
+ typedef num_get<char, iter_type> num_get_type;
+ long i = 0;
+ const ios_base::iostate goodbit = ios_base::goodbit;
+ const ios_base::iostate eofbit = ios_base::eofbit;
+ ios_base::iostate err = ios_base::goodbit;
+
+ const string str = "42foo";
+ istringstream iss; // need an ios, add my num_get facet
+ iss.imbue(locale(iss.getloc(), new num_get_type));
+
+ const num_get_type& ng = use_facet<num_get_type>(iss.getloc());
+ iter_type end = ng.get(str.begin(), str.end(), iss, err, i);
+ string rem(end, str.end());
+
+ VERIFY( err == goodbit );
+ VERIFY( i == 42 );
+ VERIFY( rem == "foo" );
+}
int main()
{
test01();
+ test02();
return 0;
}
More information about the Libstdc++
mailing list