[v3] libstdc++/2020

Benjamin Kosnik bkoz@redhat.com
Wed Mar 14 12:46:00 GMT 2001


Removes locale cached objects from the buffer structures. This
optimization has now been completely removed. At some point, I'd like
to go through and make sure that the locale data is being used
efficiently (calling use_facet whenever data is needed is not such an
efficient use.)

However, we have to have a correctly functioning locale infrastructure
first. Doing the caching before this was premature.

Note that using basic_filebufs for user-specified character types will
still require careful construction of locales imbued into
basic_filebufs: in particular, codecvt members need to be present
(only codecvt<char>, codecvt<wchar_t> are in the locales as per the
standard.) I'm not error checking for this at the moment, but could
change my mind based on user feedback.

Allows the construction of basic_filebufs with specialized char_types,
but correct usage is still in the hands of the end-user.

-benjamin


2001-03-14  Benjamin Kosnik  <bkoz@redhat.com>

	libstdc++/2020
	* include/bits/std_streambuf.h: Remove cached locale facets.
	(basic_streambuf::_M_buf_fctype): Remove.
	(basic_streambuf::~basic_streambuf): Remove here.
	(basic_streambuf::basic_streambuf): Same.
	(basic_streambuf::imbue): Same.
	* include/bits/fstream.tcc (filebuf::imbue): Remove _M_buf_fctype.
	* include/bits/std_fstream.h (basic_filebuf::_M_fcvt): Remove.
	(basic_filebuf::~basic_filebuf()): Remove here.
	* include/bits/fstream.tcc (basic_filebuf::basic_filebuf): Same.
	(basic_filebuf::imbue): Same.
	* include/bits/localefwd.h (_Count_ones): Remove.
	(locale::_S_num_categories): Just use 6, since this doesn't
	actually change, ever.
	* include/bits/locale_facets.tcc (has_facet): Simplify.
	(use_facet): Same.
	* testsuite/27_io/filebuf.cc (test06): Add tests.


Index: include/bits/fstream.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/fstream.tcc,v
retrieving revision 1.9
diff -c -p -r1.9 fstream.tcc
*** fstream.tcc	2001/03/04 21:34:00	1.9
--- fstream.tcc	2001/03/14 20:37:39
*************** namespace std
*** 86,92 ****
      basic_filebuf() 
      : __streambuf_type(), _M_file(NULL), _M_state_cur(__state_type()), 
      _M_state_beg(__state_type()), _M_last_overflowed(false)
!     { _M_fcvt = &use_facet<__codecvt_type>(this->getloc()); }
  
    template<typename _CharT, typename _Traits>
      basic_filebuf<_CharT, _Traits>::
--- 86,92 ----
      basic_filebuf() 
      : __streambuf_type(), _M_file(NULL), _M_state_cur(__state_type()), 
      _M_state_beg(__state_type()), _M_last_overflowed(false)
!     { }
  
    template<typename _CharT, typename _Traits>
      basic_filebuf<_CharT, _Traits>::
*************** namespace std
*** 94,100 ****
      : __streambuf_type(),  _M_file(NULL), _M_state_cur(__state_type()), 
      _M_state_beg(__state_type()), _M_last_overflowed(false)
      {
-       _M_fcvt = &use_facet<__codecvt_type>(this->getloc());
        _M_filebuf_init();
        _M_file->sys_open(__fd, __mode);
        if (this->is_open())
--- 94,99 ----
*************** namespace std
*** 486,492 ****
        bool __testopen = this->is_open();
        bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
        bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
!       int __width = _M_fcvt->encoding();
        if (__width < 0)
  	__width = 0;
        bool __testfail = __off != 0  && __width <= 0;
--- 485,493 ----
        bool __testopen = this->is_open();
        bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
        bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
! 
!       // Should probably do has_facet checks here.
!       int __width = use_facet<__codecvt_type>(_M_buf_locale).encoding();
        if (__width < 0)
  	__width = 0;
        bool __testfail = __off != 0  && __width <= 0;
*************** namespace std
*** 557,573 ****
      imbue(const locale& __loc)
      {
        bool __testbeg = gptr() == eback() && pptr() == pbase();
!       bool __teststate = _M_fcvt->encoding() == -1;
!       
!       _M_buf_locale_init = true;
!       if (__testbeg && !__teststate && _M_buf_locale != __loc)
  	{
- 	  // XXX Will need to save these older values.
  	  _M_buf_locale = __loc;
! 	  _M_fcvt = &use_facet<__codecvt_type>(_M_buf_locale);
! 	  // XXX Necessary?
! 	  _M_buf_fctype = &use_facet<__ctype_type>(_M_buf_locale); 
  	}
        // NB this may require the reconversion of previously
        // converted chars. This in turn may cause the reconstruction
        // of the original file. YIKES!!
--- 558,570 ----
      imbue(const locale& __loc)
      {
        bool __testbeg = gptr() == eback() && pptr() == pbase();
! 
!       if (__testbeg && _M_buf_locale != __loc)
  	{
  	  _M_buf_locale = __loc;
! 	  _M_buf_locale_init = true;
  	}
+ 
        // NB this may require the reconversion of previously
        // converted chars. This in turn may cause the reconstruction
        // of the original file. YIKES!!
Index: include/bits/locale_facets.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.11
diff -c -p -r1.11 locale_facets.tcc
*** locale_facets.tcc	2001/03/12 21:42:57	1.11
--- locale_facets.tcc	2001/03/14 20:37:42
*************** namespace std
*** 70,77 ****
      use_facet(const locale& __loc)
      {
        typedef locale::_Impl::__vec_facet        __vec_facet;
!       locale::id& __id = _Facet::id;         
!       size_t __i = __id._M_index;
        __vec_facet* __facet = __loc._M_impl->_M_facets;
        const locale::facet* __fp = (*__facet)[__i]; 
        if (__fp == 0 || __i >= __facet->size())
--- 70,76 ----
      use_facet(const locale& __loc)
      {
        typedef locale::_Impl::__vec_facet        __vec_facet;
!       size_t __i = _Facet::id._M_index;
        __vec_facet* __facet = __loc._M_impl->_M_facets;
        const locale::facet* __fp = (*__facet)[__i]; 
        if (__fp == 0 || __i >= __facet->size())
*************** namespace std
*** 84,91 ****
      has_facet(const locale& __loc) throw()
      {
        typedef locale::_Impl::__vec_facet        __vec_facet;
!       locale::id& __id = _Facet::id;         
!       size_t __i = __id._M_index;
        __vec_facet* __facet = __loc._M_impl->_M_facets;
        return (__i < __facet->size() && (*__facet)[__i] != 0);
      }
--- 83,89 ----
      has_facet(const locale& __loc) throw()
      {
        typedef locale::_Impl::__vec_facet        __vec_facet;
!       size_t __i = _Facet::id._M_index;
        __vec_facet* __facet = __loc._M_impl->_M_facets;
        return (__i < __facet->size() && (*__facet)[__i] != 0);
      }
Index: include/bits/localefwd.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/localefwd.h,v
retrieving revision 1.14
diff -c -p -r1.14 localefwd.h
*** localefwd.h	2001/02/19 18:52:24	1.14
--- localefwd.h	2001/03/14 20:37:43
*************** namespace std
*** 52,86 ****
  # define  _GLIBCPP_NUM_FACETS 13
  #endif
  
-   // _Count_ones: compile-time computation of number of 1-bits in a value N
-   // This takes only 5 (or 6) instantiations, doing recursive descent
-   // in parallel -- ncm
-   template<unsigned int _Num, int _Shift = (sizeof(unsigned) * CHAR_BIT)/2,
-            unsigned int _Mask = (~0u >> _Shift) >
-     struct _Count_ones;
- 
-   // It is preferable to use enumerators instead of integral static data
-   // members to avoid emission of superflous variables -- gdr.
-   template<unsigned int _Num, unsigned int _Mask>
-     struct _Count_ones<_Num, 0, _Mask> 
-     {
-       enum
-       {
-         _M_count = _Num
-       };
-     };
- 
-   template<unsigned int _Num, int _Shift, unsigned int _Mask>
-     struct _Count_ones 
-     {
-       enum
-       {
-         _M_halfcount = _Count_ones<_Num, _Shift/2,
-                                    (_Mask^((~_Mask)>>(_Shift/2))) >::_M_count,
-         _M_count = (_M_halfcount&_Mask) + ((_M_halfcount>>_Shift)&_Mask)
-       };
-     };
- 
    // 22.1.1 Locale
    template<typename _Tp, typename _Alloc> 
      class vector;
--- 52,57 ----
*************** namespace std
*** 297,303 ****
      // Current global reference locale
      static _Impl* 	_S_global;  
  
!     static const size_t	_S_num_categories = _Count_ones<all>::_M_count;
      static const size_t _S_num_facets = _GLIBCPP_NUM_FACETS;
  
      explicit 
--- 268,274 ----
      // Current global reference locale
      static _Impl* 	_S_global;  
  
!     static const size_t	_S_num_categories = 6;
      static const size_t _S_num_facets = _GLIBCPP_NUM_FACETS;
  
      explicit 
Index: include/bits/std_fstream.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/std_fstream.h,v
retrieving revision 1.4
diff -c -p -r1.4 std_fstream.h
*** std_fstream.h	2001/03/04 21:34:00	1.4
--- std_fstream.h	2001/03/14 20:37:44
*************** namespace std {
*** 75,83 ****
        __state_type		_M_state_cur;
        __state_type 		_M_state_beg; 	
  
-       // Cached value from use_facet.
-       const __codecvt_type*	_M_fcvt;       
-       
        // MT lock inherited from libio or other low-level io library.
        __c_lock          	_M_lock;
  
--- 75,80 ----
*************** namespace std {
*** 95,101 ****
        ~basic_filebuf() 
        { 
  	this->close();
- 	_M_fcvt = NULL;
  	_M_last_overflowed = false;
        }
  
--- 92,97 ----
Index: include/bits/std_streambuf.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/std_streambuf.h,v
retrieving revision 1.7
diff -c -p -r1.7 std_streambuf.h
*** std_streambuf.h	2001/03/04 21:34:00	1.7
--- std_streambuf.h	2001/03/14 20:37:45
*************** namespace std
*** 116,124 ****
        // True iff locale is initialized.
        bool 			_M_buf_locale_init;
  
-       // Cached use_facet<ctype>, which is based on the current locale info.
-       const __ctype_type*	_M_buf_fctype;      
- 
        // Necessary bits for putback buffer management. Only used in
        // the basic_filebuf class, as necessary for the standard
        // requirements. The only basic_streambuf member function that
--- 116,121 ----
*************** namespace std
*** 276,282 ****
  	_M_buf_size = 0;
  	_M_buf_size_opt = 0;
  	_M_mode = ios_base::openmode(0);
- 	_M_buf_fctype = NULL;
  	_M_buf_locale_init = false;
  
        }
--- 273,278 ----
*************** namespace std
*** 387,393 ****
        _M_out_end(0), _M_mode(ios_base::openmode(0)), _M_buf_locale(locale()), 
        _M_buf_locale_init(false), _M_pback_size(1), _M_pback(NULL), 
        _M_pback_cur_save(NULL), _M_pback_end_save(NULL), _M_pback_init(false)
!       { _M_buf_fctype = &use_facet<__ctype_type>(this->getloc()); }
  
        // Get area:
        char_type* 
--- 383,389 ----
        _M_out_end(0), _M_mode(ios_base::openmode(0)), _M_buf_locale(locale()), 
        _M_buf_locale_init(false), _M_pback_size(1), _M_pback(NULL), 
        _M_pback_cur_save(NULL), _M_pback_end_save(NULL), _M_pback_init(false)
!       { }
  
        // Get area:
        char_type* 
*************** namespace std
*** 441,450 ****
        { 
  	_M_buf_locale_init = true;
  	if (_M_buf_locale != __loc)
! 	 {
! 	   _M_buf_locale = __loc;
! 	   _M_buf_fctype = &use_facet<__ctype_type>(_M_buf_locale); 
! 	 }	
        }
  
        // Buffer management and positioning:
--- 437,443 ----
        { 
  	_M_buf_locale_init = true;
  	if (_M_buf_locale != __loc)
! 	  _M_buf_locale = __loc;
        }
  
        // Buffer management and positioning:
Index: testsuite/27_io/filebuf.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/27_io/filebuf.cc,v
retrieving revision 1.9
diff -c -p -r1.9 filebuf.cc
*** filebuf.cc	2001/02/28 03:20:36	1.9
--- filebuf.cc	2001/03/14 20:37:48
***************
*** 1,6 ****
  // 990117 bkoz test functionality of basic_filebuf for char_type == char
  
! // Copyright (C) 1997-1999, 2000 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
--- 1,6 ----
  // 990117 bkoz test functionality of basic_filebuf for char_type == char
  
! // Copyright (C) 1997-1999, 2000, 2001 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
*************** bool test04()
*** 529,534 ****
--- 529,572 ----
  // should be able to instantiate basic_filebuf for non-standard types.
  template class std::basic_filebuf<short, std::char_traits<short> >;
  
+ // test06
+ // libstdc++/2020
+ // should be able to use custom char_type
+ class gnu_char_type
+ {
+   unsigned long character;
+ public:
+   // operator ==
+   bool
+   operator==(const gnu_char_type& __lhs) 
+   { return character == __lhs.character; }
+ 
+   // operator <
+   bool
+   operator<(const gnu_char_type& __lhs) 
+   { return character < __lhs.character; }
+ 
+   // to_char_type
+   gnu_char_type(const unsigned long& __l) : character(__l) { } 
+ 
+   // to_int_type
+   operator unsigned long() const { return character; }
+ };
+ 
+ bool test06()
+ {
+   bool test = true;
+   typedef std::basic_filebuf<gnu_char_type> gnu_filebuf;
+   
+   try
+     { gnu_filebuf obj; }
+   catch(std::exception& obj)
+     { 
+       test = false; 
+       VERIFY( test );
+     }
+   return test;
+ }
  
  int main() 
  {
*************** int main() 
*** 538,543 ****
--- 576,582 ----
    test03();
    test04();
  
+   test06();
    return 0;
  }
  



More information about the Gcc-patches mailing list