char_traits.h: Remove generic definitions.
authorBenjamin Kosnik <bkoz@gcc.gnu.org>
Wed, 31 Jul 2002 17:28:08 +0000 (17:28 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Wed, 31 Jul 2002 17:28:08 +0000 (17:28 +0000)
2002-07-30  Benjamin Kosnik  <bkoz@redhat.com>
            Gabriel Dos Reis  <gdr@nerim.net>

* include/bits/char_traits.h: Remove generic definitions.
* include/bits/streambuf_iterator.h (istreambuf_iterator): Use
eof, not -2.
* include/bits/istream.tcc (istream::readsome): Don't check
against eof, instead use constants.
(istream::sync): Same.
(istream::sentry::sentry): Use eq_int_type.
(istream::get): Same.
* include/bits/ostream.tcc: Change __pad to
__pad<_CharT, _Traits>::_S_pad.
* include/bits/locale_facets.h: Add __pad_traits generic and
ostreambuf_iterator specialization.
* include/bits/locale_facets.tcc: Change __pad into struct __pad
with a _CharT and _Traits template parameter and _S_pad static
member function.
* src/locale-inst.cc: Update __pad instantiations.

* include/std/std_fstream.h: Declare _M_underflow_common
specializations.
* src/fstream.cc: New. Add _M_underflow_common specializations.
* include/bits/fstream.tcc (filebuf::close): Use traits_type.
(filebuf::_M_underflow_common(bool)): Remove generic version, as
sys_ungetc and custom int_types don't get along.
* include/std/std_streambuf.h: Add _M_pos.
* src/Makefile.am (sources): Add fstream.cc.
* src/Makefile.in: Regenerate.

* testsuite/21_strings/capacity.cc: Add char_traits specializations.
* testsuite/22_locale/codecvt_members_unicode_char.cc: Same.
* testsuite/22_locale/codecvt_members_unicode_wchar_t.cc: Same.
* testsuite/22_locale/ctor_copy_dtor.cc: Same.
* testsuite/27_io/filebuf_virtuals.cc (test07): Move to...
* testsuite/27_io/filebuf.cc: ...here.
* testsuite/testsuite_hooks.h: Add gnu_char, gnu_int, char_traits
specialization for both.
* testsuite/27_io/streambuf.cc: Add instantiation test,
testsuite_hooks include.
* testsuite/27_io/istream.cc: Same.
* testsuite/27_io/ostream.cc: Same.
* testsuite/27_io/fstream.cc: Same.
* testsuite/27_io/stringstream.cc: Same.
* testsuite/27_io/filebuf.cc: Same.
* testsuite/27_io/stringbuf.cc: Same.

From-SVN: r55905

libstdc++-v3/src/fstream.cc [new file with mode: 0644]

diff --git a/libstdc++-v3/src/fstream.cc b/libstdc++-v3/src/fstream.cc
new file mode 100644 (file)
index 0000000..941e6db
--- /dev/null
@@ -0,0 +1,191 @@
+// File based streams -*- C++ -*-
+
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// 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 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 27.8  File-based streams
+//
+
+#include <fstream>
+
+namespace std 
+{
+  template<> 
+    basic_filebuf<char>::int_type 
+    basic_filebuf<char>::_M_underflow_common(bool __bump)
+    {
+      int_type __ret = traits_type::eof();
+      bool __testin = _M_mode & ios_base::in;
+      bool __testout = _M_mode & ios_base::out;
+
+      if (__testin)
+       {
+         // Check for pback madness, and if so swich back to the
+         // normal buffers and jet outta here before expensive
+         // fileops happen...
+         if (_M_pback_init)
+           {
+             _M_pback_destroy();
+             if (_M_in_cur < _M_in_end)
+               return traits_type::to_int_type(*_M_in_cur);
+           }
+
+         // Sync internal and external buffers.
+         // NB: __testget -> __testput as _M_buf_unified here.
+         bool __testget = _M_in_cur && _M_in_beg < _M_in_cur;
+         bool __testinit = _M_is_indeterminate();
+         if (__testget)
+           {
+             if (__testout)
+               _M_really_overflow();
+             else if (_M_in_cur != _M_filepos)
+               _M_file.seekoff(_M_in_cur - _M_filepos,
+                               ios_base::cur, ios_base::in);
+           }
+
+         if (__testinit || __testget)
+           {
+             streamsize __elen = 0;
+             streamsize __ilen = 0;
+             __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg), 
+                                     _M_buf_size);
+             __ilen = __elen;
+
+             if (0 < __ilen)
+               {
+                 _M_set_determinate(__ilen);
+                 if (__testout)
+                   _M_out_cur = _M_in_cur;
+                 __ret = traits_type::to_int_type(*_M_in_cur);
+                 if (__bump)
+                   _M_in_cur_move(1);
+                 else if (_M_buf_size == 1)
+                   {
+                     // If we are synced with stdio, we have to unget the
+                     // character we just read so that the file pointer
+                     // doesn't move.
+                     _M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur));
+                     _M_set_indeterminate();
+                   }
+               }          
+           }
+       }
+      _M_last_overflowed = false;      
+      return __ret;
+    }
+
+  template<> 
+    basic_filebuf<wchar_t>::int_type 
+    basic_filebuf<wchar_t>::_M_underflow_common(bool __bump)
+    {
+      int_type __ret = traits_type::eof();
+      bool __testin = _M_mode & ios_base::in;
+      bool __testout = _M_mode & ios_base::out;
+
+      if (__testin)
+       {
+         // Check for pback madness, and if so swich back to the
+         // normal buffers and jet outta here before expensive
+         // fileops happen...
+         if (_M_pback_init)
+           {
+             _M_pback_destroy();
+             if (_M_in_cur < _M_in_end)
+               return traits_type::to_int_type(*_M_in_cur);
+           }
+
+         // Sync internal and external buffers.
+         // NB: __testget -> __testput as _M_buf_unified here.
+         bool __testget = _M_in_cur && _M_in_beg < _M_in_cur;
+         bool __testinit = _M_is_indeterminate();
+         if (__testget)
+           {
+             if (__testout)
+               _M_really_overflow();
+             else if (_M_in_cur != _M_filepos)
+               _M_file.seekoff(_M_in_cur - _M_filepos,
+                               ios_base::cur, ios_base::in);
+           }
+
+         if (__testinit || __testget)
+           {
+             const locale __loc = this->getloc();
+             const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc); 
+
+             streamsize __elen = 0;
+             streamsize __ilen = 0;
+             if (__cvt.always_noconv())
+               {
+                 __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg), 
+                                         _M_buf_size);
+                 __ilen = __elen;
+               }
+             else
+               {
+                 char* __buf = static_cast<char*>(__builtin_alloca(_M_buf_size));
+                 __elen = _M_file.xsgetn(__buf, _M_buf_size);
+
+                 const char* __eend;
+                 char_type* __iend;
+                 __res_type __r = __cvt.in(_M_state_cur, __buf, 
+                                           __buf + __elen, __eend, _M_in_beg, 
+                                           _M_in_beg + _M_buf_size, __iend);
+                 if (__r == codecvt_base::ok)
+                   __ilen = __iend - _M_in_beg;
+                 else 
+                   {
+                     // Unwind.
+                     __ilen = 0;
+                     _M_file.seekoff(-__elen, ios_base::cur, ios_base::in);
+                   }
+               }
+
+             if (0 < __ilen)
+               {
+                 _M_set_determinate(__ilen);
+                 if (__testout)
+                   _M_out_cur = _M_in_cur;
+                 __ret = traits_type::to_int_type(*_M_in_cur);
+                 if (__bump)
+                   _M_in_cur_move(1);
+                 else if (_M_buf_size == 1)
+                   {
+                     // If we are synced with stdio, we have to unget the
+                     // character we just read so that the file pointer
+                     // doesn't move.
+                     _M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur));
+                     _M_set_indeterminate();
+                   }
+               }          
+           }
+       }
+      _M_last_overflowed = false;      
+      return __ret;
+    }
+} // namespace std