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
This commit is contained in:
parent
8041c62955
commit
3ca652c199
@ -1,3 +1,12 @@
|
||||
2017-12-13 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
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.
|
||||
|
||||
2017-12-12 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/83395
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
168
libstdc++-v3/testsuite/26_numerics/complex/dr2714.cc
Normal file
168
libstdc++-v3/testsuite/26_numerics/complex/dr2714.cc
Normal file
@ -0,0 +1,168 @@
|
||||
// Copyright (C) 2017 Free Software Foundation, Inc.
|
||||
//
|
||||
// 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 3, 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 COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-options "-std=gnu++98" }
|
||||
|
||||
#include <complex>
|
||||
#include <sstream>
|
||||
#include <complex>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
std::istringstream in(" 1 (2) ( 2.0 , 0.5 ) ");
|
||||
std::complex<double> c1, c2, c3;
|
||||
in >> c1 >> c2 >> c3;
|
||||
VERIFY( in.good() );
|
||||
VERIFY( c1.real() == 1 && c1.imag() == 0 );
|
||||
VERIFY( c2.real() == 2 && c2.imag() == 0 );
|
||||
VERIFY( c3.real() == 2 && c3.imag() == 0.5 );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
std::wistringstream in(L" ( 2.0 , 0.5 ) ");
|
||||
std::complex<double> c;
|
||||
in >> c;
|
||||
VERIFY( in.good() );
|
||||
VERIFY( c.real() == 2.0 && c.imag() == 0.5 );
|
||||
}
|
||||
|
||||
void
|
||||
test03()
|
||||
{
|
||||
std::istringstream in;
|
||||
std::complex<double> c(-1, -1);
|
||||
const std::complex<double> c0 = c;
|
||||
|
||||
in.str("a");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
in.clear();
|
||||
|
||||
in.str(" ( ) ");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
in.clear();
|
||||
VERIFY( in.get() == ')' );
|
||||
|
||||
in.str("(,");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
in.clear();
|
||||
VERIFY( in.get() == ',' );
|
||||
|
||||
in.str("(b)");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
|
||||
in.clear();
|
||||
VERIFY( in.get() == 'b' );
|
||||
in.str("( c)");
|
||||
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
in.clear();
|
||||
VERIFY( in.get() == 'c' );
|
||||
|
||||
in.str("(99d");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
in.clear();
|
||||
VERIFY( in.get() == 'd' );
|
||||
|
||||
in.str("(99 e");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
in.clear();
|
||||
VERIFY( in.get() == 'e' );
|
||||
|
||||
in.str("(99, f");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
in.clear();
|
||||
VERIFY( in.get() == 'f' );
|
||||
|
||||
in.str("(99, 88g");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
in.clear();
|
||||
VERIFY( in.get() == 'g' );
|
||||
|
||||
in.str("(99, 88 h");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
in.clear();
|
||||
VERIFY( in.get() == 'h' );
|
||||
|
||||
in.str("(99, )");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
in.clear();
|
||||
VERIFY( in.get() == ')' );
|
||||
|
||||
VERIFY( c == c0 );
|
||||
}
|
||||
|
||||
void
|
||||
test04()
|
||||
{
|
||||
// PR libstdc++/59568
|
||||
std::istringstream in;
|
||||
std::complex<double> c;
|
||||
|
||||
in.str("");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
VERIFY( in.eof() );
|
||||
in.clear();
|
||||
|
||||
in.str(" ");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
VERIFY( in.eof() );
|
||||
in.clear();
|
||||
|
||||
in.str("(99");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
VERIFY( in.eof() );
|
||||
in.clear();
|
||||
|
||||
in.str("(99,");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
VERIFY( in.eof() );
|
||||
in.clear();
|
||||
|
||||
in.str("(99,99");
|
||||
in >> c;
|
||||
VERIFY( in.fail() );
|
||||
VERIFY( in.eof() );
|
||||
in.clear();
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
test04();
|
||||
}
|
Loading…
Reference in New Issue
Block a user