From f4ca8e2772e77b39efdb735ccf6dfd1b73389778 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Thu, 15 Sep 2005 17:27:23 +0000 Subject: [PATCH] re PR libstdc++/23875 (operator<<(short) should not call operator<<(long), etc.) 2005-09-15 Paolo Carlini PR libstdc++/23875 * include/std/std_ostream.h (operator<<(short), operator<<(unsigned short), operator<<(int), operator<<(unsigned int), operator<<(float)): Don't call operator<<(long), operator<<(unsigned long), or operator<<(double), do the work mandated by the resolution of DR117... * include/bits/ostream.tcc (operator<<(short), operator<<(unsigned short), operator<<(int), operator<<(unsigned int), operator<<(float)): ... here. * testsuite/27_io/basic_ostream/inserters_arithmetic/pod/23875.cc: New. From-SVN: r104313 --- libstdc++-v3/ChangeLog | 12 ++ libstdc++-v3/include/bits/ostream.tcc | 142 ++++++++++++++++++ libstdc++-v3/include/std/std_ostream.h | 29 +--- .../inserters_arithmetic/pod/23875.cc | 85 +++++++++++ 4 files changed, 244 insertions(+), 24 deletions(-) create mode 100644 libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/pod/23875.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9585c6cf129..1d8713e473e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2005-09-15 Paolo Carlini + + PR libstdc++/23875 + * include/std/std_ostream.h (operator<<(short), operator<<(unsigned + short), operator<<(int), operator<<(unsigned int), operator<<(float)): + Don't call operator<<(long), operator<<(unsigned long), or + operator<<(double), do the work mandated by the resolution of DR117... + * include/bits/ostream.tcc (operator<<(short), operator<<(unsigned + short), operator<<(int), operator<<(unsigned int), operator<<(float)): + ... here. + * testsuite/27_io/basic_ostream/inserters_arithmetic/pod/23875.cc: New. + 2005-09-15 Mark Mitchell * testsuite/testsuite_character.h: Specialize character<> diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc index cd9585073ae..e26ad50d6b8 100644 --- a/libstdc++-v3/include/bits/ostream.tcc +++ b/libstdc++-v3/include/bits/ostream.tcc @@ -119,6 +119,122 @@ namespace std return *this; } + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(short __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 117. basic_ostream uses nonexistent num_put member functions. + long __l; + const ios_base::fmtflags __fmt = (this->flags() + & ios_base::basefield); + if (__fmt == ios_base::oct || __fmt == ios_base::hex) + __l = static_cast(static_cast(__n)); + else + __l = static_cast(__n); + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __l).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(unsigned short __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 117. basic_ostream uses nonexistent num_put member functions. + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), + static_cast(__n)).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(int __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 117. basic_ostream uses nonexistent num_put member functions. + long __l; + const ios_base::fmtflags __fmt = (this->flags() + & ios_base::basefield); + if (__fmt == ios_base::oct || __fmt == ios_base::hex) + __l = static_cast(static_cast(__n)); + else + __l = static_cast(__n); + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __l).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(unsigned int __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 117. basic_ostream uses nonexistent num_put member functions. + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), + static_cast(__n)).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + template basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: @@ -213,6 +329,32 @@ namespace std } #endif + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(float __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 117. basic_ostream uses nonexistent num_put member functions. + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), + static_cast(__n)).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + template basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: diff --git a/libstdc++-v3/include/std/std_ostream.h b/libstdc++-v3/include/std/std_ostream.h index fce5a4194bb..ffc1a281730 100644 --- a/libstdc++-v3/include/std/std_ostream.h +++ b/libstdc++-v3/include/std/std_ostream.h @@ -173,34 +173,16 @@ namespace std operator<<(bool __n); __ostream_type& - operator<<(short __n) - { - const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; - if (__fmt == ios_base::oct || __fmt == ios_base::hex) - return this->operator<<(static_cast - (static_cast(__n))); - else - return this->operator<<(static_cast(__n)); - } + operator<<(short __n); __ostream_type& - operator<<(unsigned short __n) - { return this->operator<<(static_cast(__n)); } + operator<<(unsigned short __n); __ostream_type& - operator<<(int __n) - { - const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; - if (__fmt == ios_base::oct || __fmt == ios_base::hex) - return this->operator<<(static_cast - (static_cast(__n))); - else - return this->operator<<(static_cast(__n)); - } + operator<<(int __n); __ostream_type& - operator<<(unsigned int __n) - { return this->operator<<(static_cast(__n)); } + operator<<(unsigned int __n); #ifdef _GLIBCXX_USE_LONG_LONG __ostream_type& @@ -214,8 +196,7 @@ namespace std operator<<(double __f); __ostream_type& - operator<<(float __f) - { return this->operator<<(static_cast(__f)); } + operator<<(float __f); __ostream_type& operator<<(long double __f); diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/pod/23875.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/pod/23875.cc new file mode 100644 index 00000000000..760103c197f --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/pod/23875.cc @@ -0,0 +1,85 @@ +// 2005-09-15 Paolo Carlini + +// Copyright (C) 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 27.6.2.5.2 Arithmetic inserters + +#include +#include +#include + +bool test __attribute__((unused)) = true; +using __gnu_test::pod_ushort; + +namespace std +{ + template<> + basic_ostream& + basic_ostream:: + operator<<(long) + { + VERIFY( false ); + return *this; + } + + template<> + basic_ostream& + basic_ostream:: + operator<<(unsigned long) + { + VERIFY( false ); + return *this; + } + + template<> + basic_ostream& + basic_ostream:: + operator<<(double) + { + VERIFY( false ); + return *this; + } +} + +// libstdc++/23875 +void test01() +{ + std::basic_ostringstream ostr; + + short s = 1; + ostr << s; + + unsigned short us = 1; + ostr << us; + + int i = 1; + ostr << i; + + unsigned int ui = 1; + ostr << ui; + + float f = 1.0f; + ostr << f; +} + +int main() +{ + test01(); + return 0; +}