This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] libstdc++/23875


Hi,

the below fixes the problem described in the PR. As expected, together
with consistency with istream and, at minimum, an higher QoI, comes more
redundancy in the code. This is not a new issue, however: I believe that
all the arithmetic inserters and extractors can delegate the work to a
templatized _M_insert (_M_extract, respectively), in complete analogy
with the num_put::do_put and num_get::do_get facilities; only, now,
after fixing some bugs, the issue becomes much more evident.
Unfortunately, that nice clean-up seems not suited for 4.1.0 and I plan
to explore it later, probably will file a DR about it to be sure (if
people insist maybe for 4.1.1... ;)

Tested x86-linux.

Paolo.

/////////////////
2005-09-15  Paolo Carlini  <pcarlini@suse.de>

	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.
Index: include/bits/ostream.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/ostream.tcc,v
retrieving revision 1.56
diff -u -r1.56 ostream.tcc
--- include/bits/ostream.tcc	17 Aug 2005 02:12:56 -0000	1.56
+++ include/bits/ostream.tcc	14 Sep 2005 23:23:35 -0000
@@ -122,6 +122,122 @@
   template<typename _CharT, typename _Traits>
     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<long>(static_cast<unsigned short>(__n));
+	      else
+		__l = static_cast<long>(__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<typename _CharT, typename _Traits>
+    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<unsigned long>(__n)).failed())
+		__err |= ios_base::badbit;
+	    }
+	  catch(...)
+	    { this->_M_setstate(ios_base::badbit); }
+	  if (__err)
+	    this->setstate(__err);
+	}
+      return *this;
+    }
+
+  template<typename _CharT, typename _Traits>
+    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<long>(static_cast<unsigned int>(__n));
+	      else
+		__l = static_cast<long>(__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<typename _CharT, typename _Traits>
+    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<unsigned long>(__n)).failed())
+		__err |= ios_base::badbit;
+	    }
+	  catch(...)
+	    { this->_M_setstate(ios_base::badbit); }
+	  if (__err)
+	    this->setstate(__err);
+	}
+      return *this;
+    }
+
+  template<typename _CharT, typename _Traits>
+    basic_ostream<_CharT, _Traits>&
+    basic_ostream<_CharT, _Traits>::
     operator<<(long __n)
     {
       sentry __cerb(*this);
@@ -216,6 +332,32 @@
   template<typename _CharT, typename _Traits>
     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<double>(__n)).failed())
+		__err |= ios_base::badbit;
+	    }
+	  catch(...)
+	    { this->_M_setstate(ios_base::badbit); }
+	  if (__err)
+	    this->setstate(__err);
+	}
+      return *this;
+    }
+
+  template<typename _CharT, typename _Traits>
+    basic_ostream<_CharT, _Traits>&
+    basic_ostream<_CharT, _Traits>::
     operator<<(double __n)
     {
       sentry __cerb(*this);
Index: include/std/std_ostream.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/std/std_ostream.h,v
retrieving revision 1.18
diff -u -r1.18 std_ostream.h
--- include/std/std_ostream.h	17 Aug 2005 02:14:05 -0000	1.18
+++ include/std/std_ostream.h	14 Sep 2005 23:23:35 -0000
@@ -173,34 +173,16 @@
       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<long>
-				  (static_cast<unsigned short>(__n)));
-	else
-	  return this->operator<<(static_cast<long>(__n));
-      }
+      operator<<(short __n);
 
       __ostream_type& 
-      operator<<(unsigned short __n)
-      { return this->operator<<(static_cast<unsigned long>(__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<long>
-				  (static_cast<unsigned int>(__n)));
-	else
-	  return this->operator<<(static_cast<long>(__n));
-      }
+      operator<<(int __n);
 
       __ostream_type& 
-      operator<<(unsigned int __n)
-      { return this->operator<<(static_cast<unsigned long>(__n)); }
+      operator<<(unsigned int __n);
 
 #ifdef _GLIBCXX_USE_LONG_LONG
       __ostream_type& 
@@ -214,8 +196,7 @@
       operator<<(double __f);
 
       __ostream_type& 
-      operator<<(float __f)
-      { return this->operator<<(static_cast<double>(__f)); }
+      operator<<(float __f);
 
       __ostream_type& 
       operator<<(long double __f);
Index: testsuite/27_io/basic_ostream/inserters_arithmetic/pod/23875.cc
===================================================================
RCS file: testsuite/27_io/basic_ostream/inserters_arithmetic/pod/23875.cc
diff -N testsuite/27_io/basic_ostream/inserters_arithmetic/pod/23875.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/27_io/basic_ostream/inserters_arithmetic/pod/23875.cc	14 Sep 2005 23:23:38 -0000
@@ -0,0 +1,85 @@
+// 2005-09-15  Paolo Carlini  <pcarlini@suse.de>
+
+// 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 <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_character.h>
+
+bool test __attribute__((unused)) = true;
+using __gnu_test::pod_ushort;
+
+namespace std
+{
+  template<>
+    basic_ostream<pod_ushort>&
+    basic_ostream<pod_ushort>::
+    operator<<(long)
+    {
+      VERIFY( false );
+      return *this;
+    }
+
+  template<>
+    basic_ostream<pod_ushort>&
+    basic_ostream<pod_ushort>::
+    operator<<(unsigned long)
+    {
+      VERIFY( false );
+      return *this;
+    }
+  
+  template<>
+    basic_ostream<pod_ushort>&
+    basic_ostream<pod_ushort>::
+    operator<<(double)
+    {
+      VERIFY( false );
+      return *this;
+    }
+}
+
+// libstdc++/23875
+void test01()
+{
+  std::basic_ostringstream<pod_ushort> 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;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]