diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2017-12-13 17:02:14 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2017-12-13 17:02:14 +0000 |
commit | 3ca652c1995cd691850a53c656c958a83c3fecde (patch) | |
tree | 6c85c79c6bd41d1703c081e063e3a6db5195e718 /libstdc++-v3/include/std/complex | |
parent | 8041c629555ad2cbe8740d3a645332efcbd4e8d6 (diff) | |
download | gcc-3ca652c1995cd691850a53c656c958a83c3fecde.zip gcc-3ca652c1995cd691850a53c656c958a83c3fecde.tar.gz gcc-3ca652c1995cd691850a53c656c958a83c3fecde.tar.bz2 |
PR libstdc++/59568 fix error handling for std::complex stream extraction
PR libstdc++/59568
* include/std/complex (operator>>): Implement proposed resolution to
LWG 2714. Use putback if and only if a character has been successfully
extracted but isn't a delimiter. Use ctype::widen and traits::eq when
testing if extracted characters match delimiters.
* testsuite/26_numerics/complex/dr2714.cc: New test.
From-SVN: r255608
Diffstat (limited to 'libstdc++-v3/include/std/complex')
-rw-r--r-- | libstdc++-v3/include/std/complex | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex index 61f8cc1..bfe1034 100644 --- a/libstdc++-v3/include/std/complex +++ b/libstdc++-v3/include/std/complex @@ -492,31 +492,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) { - _Tp __re_x, __im_x; + bool __fail = true; _CharT __ch; - __is >> __ch; - if (__ch == '(') + if (__is >> __ch) { - __is >> __re_x >> __ch; - if (__ch == ',') + if (_Traits::eq(__ch, __is.widen('('))) { - __is >> __im_x >> __ch; - if (__ch == ')') - __x = complex<_Tp>(__re_x, __im_x); - else - __is.setstate(ios_base::failbit); + _Tp __u; + if (__is >> __u >> __ch) + { + const _CharT __rparen = __is.widen(')'); + if (_Traits::eq(__ch, __rparen)) + { + __x = __u; + __fail = false; + } + else if (_Traits::eq(__ch, __is.widen(','))) + { + _Tp __v; + if (__is >> __v >> __ch) + { + if (_Traits::eq(__ch, __rparen)) + { + __x = complex<_Tp>(__u, __v); + __fail = false; + } + else + __is.putback(__ch); + } + } + else + __is.putback(__ch); + } } - else if (__ch == ')') - __x = __re_x; else - __is.setstate(ios_base::failbit); - } - else - { - __is.putback(__ch); - __is >> __re_x; - __x = __re_x; + { + __is.putback(__ch); + _Tp __u; + if (__is >> __u) + { + __x = __u; + __fail = false; + } + } } + if (__fail) + __is.setstate(ios_base::failbit); return __is; } |