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]

[v3] implement std::collate



The by_name testcase needs to be finished off, but I'm checking in this as is.

-benjamin


2001-08-17  Benjamin Kosnik  <bkoz@redhat.com>

	Implement std::collate.	
	* config/locale/collate_specializations_gnu.cc: Add here, implement in
	MT-safe way.
	* config/locale/collate_specializations_generic.cc: Add here, but
	in a less sophisticated manner.
	* include/bits/locale_facets.tcc (collate): Add generic definition.
	* include/bits/locale_facets.h (~collate): Mark virtual.
	(collate::_M_compare_helper): New.
	(collate::_M_transform_helper): New.
	* src/locale.cc: Remove unnecessary specializations.
	* src/string-inst.cc: Tweak instantiation of ctors.
	
	* acinclude.m4 (GLIBCPP_ENABLE_CLOCALE): Do configury for collate.
	* aclocal.m4: Regenerate.
	* configure: Regenerate.
	* src/Makefile.am (sources): Add collate.cc.
	* src/Makefile.in: Regenerate.
	
	* testsuite/22_locale/collate_byname.cc: New.
	* testsuite/22_locale/collate.cc: New file.
	* testsuite/22_locale/collate_char_members.cc: New file.
	* testsuite/22_locale/collate_wchar_t_members.cc: New file.	
	
Index: acinclude.m4
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/acinclude.m4,v
retrieving revision 1.172
diff -c -p -r1.172 acinclude.m4
*** acinclude.m4	2001/08/14 01:24:25	1.172
--- acinclude.m4	2001/08/18 02:46:32
*************** AC_DEFUN(GLIBCPP_ENABLE_CLOCALE, [
*** 1060,1065 ****
--- 1060,1066 ----
        CCODECVT_H=config/locale/codecvt_specializations_generic.h
        CMESSAGES_H=config/locale/messages_members_generic.h
        CMESSAGES_CC=config/locale/messages_members_generic.cc
+       CCOLLATE_CC=config/locale/collate_specializations_generic.cc
        ;;
      xgnu)
        AC_MSG_RESULT(gnu)
*************** AC_DEFUN(GLIBCPP_ENABLE_CLOCALE, [
*** 1085,1090 ****
--- 1086,1092 ----
        CCODECVT_H=config/locale/codecvt_specializations_ieee_1003.1-200x.h
        CMESSAGES_H=config/locale/messages_members_gnu.h
        CMESSAGES_CC=config/locale/messages_members_gnu.cc
+       CCOLLATE_CC=config/locale/collate_specializations_gnu.cc
        ;;
      xieee_1003.1)
        AC_MSG_RESULT(generic)
*************** AC_DEFUN(GLIBCPP_ENABLE_CLOCALE, [
*** 1097,1102 ****
--- 1099,1105 ----
        CCODECVT_H=config/locale/codecvt_specializations_ieee_1003.1-200x.h
        CMESSAGES_H=config/locale/messages_members_ieee_1003.1-200x.h
        CMESSAGES_CC=config/locale/messages_members_ieee_1003.1-200x.cc
+       CCOLLATE_CC=config/locale/collate_specializations_generic.cc
        ;;
      *)
        echo "$enable_clocale is an unknown locale package" 1>&2
*************** AC_DEFUN(GLIBCPP_ENABLE_CLOCALE, [
*** 1114,1120 ****
    AC_SUBST(CCODECVT_H)
    AC_SUBST(CMESSAGES_H)
    AC_LINK_FILES($CLOCALE_CC, src/c++locale.cc)
!   AC_LINK_FILES($CMESSAGES_CC, src/messages_members.cc)
  ])
  
  
--- 1117,1124 ----
    AC_SUBST(CCODECVT_H)
    AC_SUBST(CMESSAGES_H)
    AC_LINK_FILES($CLOCALE_CC, src/c++locale.cc)
!   AC_LINK_FILES($CMESSAGES_CC, src/messages.cc)
!   AC_LINK_FILES($CCOLLATE_CC, src/collate.cc)
  ])
  
  
Index: config/locale/c_locale_gnu.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/locale/c_locale_gnu.cc,v
retrieving revision 1.1
diff -c -p -r1.1 c_locale_gnu.cc
*** c_locale_gnu.cc	2001/08/08 02:48:58	1.1
--- c_locale_gnu.cc	2001/08/18 02:47:21
***************
*** 1,3 ****
--- 1,4 ----
+ 
  // Wrapper for underlying C-language localization -*- C++ -*-
  
  // Copyright (C) 2001 Free Software Foundation, Inc.
*************** namespace std 
*** 46,52 ****
      // perhaps locale::categories could be made equivalent to LC_*_MASK
      //    _M_c_locale = __newlocale(1 << LC_ALL, __str.c_str(), NULL);
      //    _M_c_locale = __newlocale(locale::all, __str.c_str(), NULL);
!     __cloc = __newlocale(LC_ALL, __s, NULL);
      if (!__cloc)
        {
  	// This named locale is not supported by the underlying OS.
--- 47,53 ----
      // perhaps locale::categories could be made equivalent to LC_*_MASK
      //    _M_c_locale = __newlocale(1 << LC_ALL, __str.c_str(), NULL);
      //    _M_c_locale = __newlocale(locale::all, __str.c_str(), NULL);
!     __cloc = __newlocale(1 << LC_ALL, __s, 0);
      if (!__cloc)
        {
  	// This named locale is not supported by the underlying OS.
Index: include/bits/locale_facets.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.15
diff -c -p -r1.15 locale_facets.h
*** locale_facets.h	2001/08/08 02:48:59	1.15
--- locale_facets.h	2001/08/18 02:47:27
*************** namespace std
*** 520,525 ****
--- 520,526 ----
      _S_literals[] = "-+xX0123456789abcdef0123456789ABCDEF";
  
     template<> _Format_cache<char>::_Format_cache();
+ 
  #ifdef _GLIBCPP_USE_WCHAR_T
     template<> _Format_cache<wchar_t>::_Format_cache();
  #endif
*************** namespace std
*** 907,912 ****
--- 908,914 ----
    template<> 
      void
      numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
+ 
  #ifdef _GLIBCPP_USE_WCHAR_T
    template<> 
      void
*************** namespace std
*** 944,956 ****
      {
      public:
        // Types:
!       typedef _CharT               char_type;
!       typedef basic_string<_CharT> string_type;
  
        static locale::id id;
  
        explicit 
!       collate(size_t __refs = 0) : locale::facet(__refs) { }
  
        int 
        compare(const _CharT* __lo1, const _CharT* __hi1,
--- 946,975 ----
      {
      public:
        // Types:
!       typedef _CharT               	char_type;
!       typedef basic_string<_CharT> 	string_type;
  
+     protected:
+       // Underlying "C" library locale information saved from
+       // initialization, needed by collate_byname as well.
+       __c_locale			_M_c_locale_collate;
+  
+     public:
        static locale::id id;
  
        explicit 
!       collate(size_t __refs = 0)
!       : locale::facet(__refs), _M_c_locale_collate(NULL)
!       { } 
! 
!       // Non-standard.
!       explicit 
!       collate(__c_locale __cloc, size_t __refs = 0) 
!       : locale::facet(__refs)
!       { 
! 	if (__cloc)
! 	  _M_c_locale_collate = _S_clone_c_locale(__cloc); 
!       }
  
        int 
        compare(const _CharT* __lo1, const _CharT* __hi1,
*************** namespace std
*** 965,972 ****
        hash(const _CharT* __lo, const _CharT* __hi) const
        { return this->do_hash(__lo, __hi); }
        
    protected:
!       ~collate() { } // virtual
  
        virtual int  
        do_compare(const _CharT* __lo1, const _CharT* __hi1,
--- 984,1003 ----
        hash(const _CharT* __lo, const _CharT* __hi) const
        { return this->do_hash(__lo, __hi); }
        
+       // Used to abstract out _CharT bits in virtual member functions, below.
+       int
+       _M_compare_helper(const _CharT*, const _CharT*) const;
+ 
+       size_t
+       _M_transform_helper(_CharT*, const _CharT*, size_t) const;;
+ 
    protected:
!       virtual
!       ~collate() 
!       {
! 	if (_M_c_locale_collate)
! 	  _S_destroy_c_locale(_M_c_locale_collate); 
!       }
  
        virtual int  
        do_compare(const _CharT* __lo1, const _CharT* __hi1,
*************** namespace std
*** 982,1015 ****
    template<typename _CharT>
      locale::id collate<_CharT>::id;
  
!   // Required specializations.
    template<>
      int 
!     collate<char>::do_compare(const char* __lo1, const char* __hi1, 
! 			      const char* __lo2, const char* __hi2) const;
  
    template<>
!     string
!     collate<char>::do_transform(const char* __lo, const char* __hi) const;
  
-   template<>
-     long
-     collate<char>::do_hash(const char* __lo, const char* __hi) const;
  #ifdef _GLIBCPP_USE_WCHAR_T
    template<>
      int 
!     collate<wchar_t>::do_compare(const wchar_t* __lo1, const wchar_t* __hi1, 
! 				 const wchar_t* __lo2, 
! 				 const wchar_t* __hi2) const;
! 
!   template<>
!     wstring
!     collate<wchar_t>::do_transform(const wchar_t* __lo, 
! 				   const wchar_t* __hi) const;
  
    template<>
!     long
!     collate<wchar_t>::do_hash(const wchar_t* __lo, const wchar_t* __hi) const;
  #endif
  
    template<typename _CharT>
--- 1013,1036 ----
    template<typename _CharT>
      locale::id collate<_CharT>::id;
  
!   // Specializations.
    template<>
      int 
!     collate<char>::_M_compare_helper(const char*, const char*) const;
  
    template<>
!     size_t
!     collate<char>::_M_transform_helper(char*, const char*, size_t) const;
  
  #ifdef _GLIBCPP_USE_WCHAR_T
    template<>
      int 
!     collate<wchar_t>::_M_compare_helper(const wchar_t*, const wchar_t*) const;
  
    template<>
!     size_t
!     collate<wchar_t>::_M_transform_helper(wchar_t*, const wchar_t*, 
! 					  size_t) const;
  #endif
  
    template<typename _CharT>
*************** namespace std
*** 1021,1039 ****
        typedef basic_string<_CharT> string_type;
  
        explicit 
!       collate_byname(const char*, size_t __refs = 0);
  
      protected:
        virtual 
        ~collate_byname() { }
      };
  
-   template<>
-     collate_byname<char>::collate_byname(const char*, size_t __refs);
- #ifdef _GLIBCPP_USE_WCHAR_T
-   template<>
-     collate_byname<wchar_t>::collate_byname(const char*, size_t __refs);
- #endif
  
    class time_base
    {
--- 1042,1056 ----
        typedef basic_string<_CharT> string_type;
  
        explicit 
!       collate_byname(const char* __s, size_t __refs = 0)
!       : collate<_CharT>(__refs) 
!       { _S_create_c_locale(_M_c_locale_collate, __s); }
  
      protected:
        virtual 
        ~collate_byname() { }
      };
  
  
    class time_base
    {
*************** namespace std
*** 1420,1425 ****
--- 1437,1443 ----
    template<> 
      void
      moneypunct<char>::_M_initialize_moneypunct(__c_locale __cloc);
+ 
  #ifdef _GLIBCPP_USE_WCHAR_T
    template<> 
      void
*************** namespace std
*** 1470,1479 ****
      protected:
        // Underlying "C" library locale information saved from
        // initialization, needed by messages_byname as well.
!       __c_locale	_M_c_locale_messages;
        #if 1
        // Only needed if glibc < 2.3
!       const char*	_M_name_messages;
        #endif
  
      public:
--- 1488,1497 ----
      protected:
        // Underlying "C" library locale information saved from
        // initialization, needed by messages_byname as well.
!       __c_locale			_M_c_locale_messages;
        #if 1
        // Only needed if glibc < 2.3
!       const char*			_M_name_messages;
        #endif
  
      public:
*************** namespace std
*** 1485,1490 ****
--- 1503,1509 ----
        _M_name_messages("C")
        { }
  
+       // Non-standard.
        explicit 
        messages(__c_locale __cloc, const char* __name, size_t __refs = 0) 
        : locale::facet(__refs)
Index: include/bits/locale_facets.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.19
diff -c -p -r1.19 locale_facets.tcc
*** locale_facets.tcc	2001/07/04 02:39:01	1.19
--- locale_facets.tcc	2001/08/18 02:47:30
*************** namespace std
*** 968,974 ****
      __output_float(_OutIter __s, ios_base& __io, _CharT __fill,
                      const char* __sptr, size_t __slen)
      {
!       // XXX Not currently done: non streambuf_iterator
        return __s;
      }
  
--- 968,974 ----
      __output_float(_OutIter __s, ios_base& __io, _CharT __fill,
                      const char* __sptr, size_t __slen)
      {
!       // XXX Not currently done: non-streambuf_iterator
        return __s;
      }
  
*************** namespace std
*** 1217,1226 ****
          __err |= __io.failbit;
        return __out;
      }
- } // std::
  
! #endif /* _CPP_BITS_LOCFACETS_TCC */
  
- // Local Variables:
- // mode:c++
- // End:
--- 1217,1291 ----
          __err |= __io.failbit;
        return __out;
      }
  
!   // Generic version does nothing.
!   template<typename _CharT>
!     int
!     collate<_CharT>::
!     _M_compare_helper(const _CharT*, const _CharT*) const
!     { return 0; }
! 
!   // Generic version does nothing.
!   template<typename _CharT>
!     size_t
!     collate<_CharT>::
!     _M_transform_helper(_CharT*, const _CharT*, size_t) const
!     { return 0; }
! 
!   template<typename _CharT>
!     int
!     collate<_CharT>::
!     do_compare(const _CharT* __lo1, const _CharT* __hi1,
! 	       const _CharT* __lo2, const _CharT* __hi2) const
!     { 
!       const string_type __one(__lo1, __hi1);
!       const string_type __two(__lo2, __hi2);
!       return _M_compare_helper(__one.c_str(), __two.c_str());
!     }
! 
!  template<typename _CharT>
!     collate<_CharT>::string_type
!     collate<_CharT>::
!     do_transform(const _CharT* __lo, const _CharT* __hi) const
!     {
!       string_type __orig(__lo, __hi);
!       string_type __trans(__orig.size(), char_type());
!       size_t __res = _M_transform_helper(__trans.begin().base(), 
! 					 __orig.c_str(), __trans.size());
!       while (__res >= __trans.size())
! 	{
! 	  // Increment size of translated string.
! 	  string_type::size_type __newsize = __trans.size() * 2;
! 	  __trans.resize(__newsize);
! 	  __res = _M_transform_helper(__trans.begin().base(), __orig.c_str(), 
! 				      __trans.size());
! 	}
!       return __trans;
!     }
! 
!  template<typename _CharT>
!     long
!     collate<_CharT>::
!     do_hash(const _CharT* __lo, const _CharT* __hi) const
!     { 
!       unsigned long __val = 0;
!       for (; __lo < __hi; ++__lo)
! 	__val = *__lo + ((__val << 7) | 
! 		       (__val >> (numeric_limits<unsigned long>::digits - 1)));
!       return static_cast<long>(__val);
!     }
! } // namespace std
! 
! #endif // _CPP_BITS_LOCFACETS_TCC
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
  
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/Makefile.am,v
retrieving revision 1.94
diff -c -p -r1.94 Makefile.am
*** Makefile.am	2001/08/14 01:24:30	1.94
--- Makefile.am	2001/08/18 02:47:32
*************** INCLUDES = \
*** 64,70 ****
  sources = \
  	basic_file.cc bitset.cc c++locale.cc cmath.cc codecvt.cc \
  	complex_io.cc functexcept.cc globals.cc ios.cc limits.cc \
! 	locale.cc locale-inst.cc localename.cc messages_members.cc \
  	misc-inst.cc stdexcept.cc stl-inst.cc string-inst.cc strstream.cc \
  	valarray-inst.cc wstring-inst.cc
  
--- 64,71 ----
  sources = \
  	basic_file.cc bitset.cc c++locale.cc cmath.cc codecvt.cc \
  	complex_io.cc functexcept.cc globals.cc ios.cc limits.cc \
! 	locale.cc locale-inst.cc localename.cc \
! 	messages.cc collate.cc \
  	misc-inst.cc stdexcept.cc stl-inst.cc string-inst.cc strstream.cc \
  	valarray-inst.cc wstring-inst.cc
  
Index: src/locale.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/locale.cc,v
retrieving revision 1.38
diff -c -p -r1.38 locale.cc
*** locale.cc	2001/08/08 02:49:01	1.38
--- locale.cc	2001/08/18 02:47:35
*************** namespace std 
*** 1003,1054 ****
      return __incl_prec;
    }
  
-   template <>
-   collate<char>::collate(size_t __refs)
-   : locale::facet(__refs) { }
-   
-   template<>
-   collate<char>::~collate() { }
-   
-   template<>
-   int 
-   collate<char>::do_compare(const char* __lo1, const char* __hi1, 
- 			    const char* __lo2, const char* __hi2) const
-   {
-     for (; __lo1 < __hi1 && __lo2 < __hi2; ++__lo1, ++__lo2) 
-       if (*__lo1 != *__lo2) 
- 	return (*__lo1 < *__lo2) ? -1 : 1;
-     if (__lo1 < __hi1) 
-       return 1;
-     else if (__lo2 < __hi2) 
-       return -1;
-     else 
-       return 0;
-   }
-   
-   template<>
-   string
-   collate<char>::
-   do_transform(const char* __lo, const char* __hi) const
-   { return string(__lo, __hi - __lo); }
-   
    template<>
-   long
-   collate<char>::
-   do_hash(const char* __lo, const char* __hi) const
-   {
-     unsigned long __val = 0xdeadbeef;
-     for (; __lo < __hi; ++__lo)
-       __val = *__lo ^ ((__val << 7) & 
- 		   (__val >> (numeric_limits<unsigned long>::digits - 1)));
-     return __val;
-   }
- 
-   template<>  
-   collate_byname<char>::collate_byname(const char* /*__s*/, size_t __refs)
-   : collate<char>(__refs) { }
- 
-   template<>
    moneypunct_byname<char, false>::moneypunct_byname(const char* /*__s*/, 
  						    size_t __refs)
    : moneypunct<char, false>(__refs) { }
--- 1003,1009 ----
*************** namespace std 
*** 1214,1254 ****
    ctype_byname<wchar_t>::
    ctype_byname(const char* /*__s*/, size_t __refs)
    : ctype<wchar_t>(__refs) { }
- 
-   template<>
-   collate<wchar_t>::
-   collate(size_t __refs): locale::facet(__refs) { }
-   
-   template<>
-   collate<wchar_t>::
-   ~collate() { }
- 
-   template<>
-   int 
-   collate<wchar_t>::
-   do_compare(const wchar_t* /*__lo1*/, const wchar_t* /*__hi1*/,
- 	     const wchar_t* /*__lo2*/, const wchar_t* /*__hi2*/) const
-   {
-     return 0; // XXX not done
-   }
- 
-   template<>  
-   wstring collate<wchar_t>::
-   do_transform(const wchar_t* /*__lo*/, const wchar_t* /*__hi*/) const
-   {
-     return wstring(); // XXX not done
-   }
-   
-   template<>
-   long collate<wchar_t>::
-   do_hash(const wchar_t* /*__lo*/, const wchar_t* /*__hi*/) const
-   {
-     return 0; // XXX not done
-   }
- 
-   template<>
-   collate_byname<wchar_t>::
-   collate_byname(const char* /*__s*/, size_t __refs)
-   : collate<wchar_t> (__refs) { }
  #endif //  _GLIBCPP_USE_WCHAR_T
  } // namespace std
--- 1169,1173 ----
Index: src/localename.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/localename.cc,v
retrieving revision 1.16
diff -c -p -r1.16 localename.cc
*** localename.cc	2001/08/08 02:49:01	1.16
--- localename.cc	2001/08/18 02:47:36
*************** namespace std
*** 91,101 ****
  
      // Construct all standard facets and add them to _M_facets.
      // XXX Eventually, all should use __clocale ctor like numpunct
!     _M_init_facet(new std::collate<char>);
      _M_init_facet(new std::ctype<char>);
      _M_init_facet(new codecvt<char, char, mbstate_t>);
      _M_init_facet(new moneypunct<char, false>(__cloc));
!     _M_init_facet(new moneypunct<char,true >);
      _M_init_facet(new money_get<char>);
      _M_init_facet(new money_put<char>);
      _M_init_facet(new numpunct<char>(__cloc));
--- 91,102 ----
  
      // Construct all standard facets and add them to _M_facets.
      // XXX Eventually, all should use __clocale ctor like numpunct
!     // XXX how to deal cleanly, consistently with null ("C") __cloc?
!     _M_init_facet(new std::collate<char>(__cloc));
      _M_init_facet(new std::ctype<char>);
      _M_init_facet(new codecvt<char, char, mbstate_t>);
      _M_init_facet(new moneypunct<char, false>(__cloc));
!     _M_init_facet(new moneypunct<char,true>(__cloc));
      _M_init_facet(new money_get<char>);
      _M_init_facet(new money_put<char>);
      _M_init_facet(new numpunct<char>(__cloc));
*************** namespace std
*** 106,116 ****
      _M_init_facet(new std::messages<char>(__cloc, __str.c_str()));
      
  #ifdef  _GLIBCPP_USE_WCHAR_T
!     _M_init_facet(new std::collate<wchar_t>);
      _M_init_facet(new std::ctype<wchar_t>);
      _M_init_facet(new codecvt<wchar_t, char, mbstate_t>);
      _M_init_facet(new moneypunct<wchar_t, false>(__cloc));
!     _M_init_facet(new moneypunct<wchar_t,true >);
      _M_init_facet(new money_get<wchar_t>);
      _M_init_facet(new money_put<wchar_t>);
      _M_init_facet(new numpunct<wchar_t>(__cloc));
--- 107,117 ----
      _M_init_facet(new std::messages<char>(__cloc, __str.c_str()));
      
  #ifdef  _GLIBCPP_USE_WCHAR_T
!     _M_init_facet(new std::collate<wchar_t>(__cloc));
      _M_init_facet(new std::ctype<wchar_t>);
      _M_init_facet(new codecvt<wchar_t, char, mbstate_t>);
      _M_init_facet(new moneypunct<wchar_t, false>(__cloc));
!     _M_init_facet(new moneypunct<wchar_t,true>(__cloc));
      _M_init_facet(new money_get<wchar_t>);
      _M_init_facet(new money_put<wchar_t>);
      _M_init_facet(new numpunct<wchar_t>(__cloc));
Index: src/string-inst.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/string-inst.cc,v
retrieving revision 1.16
diff -c -p -r1.16 string-inst.cc
*** string-inst.cc	2001/06/06 08:49:10	1.16
--- string-inst.cc	2001/08/18 02:47:36
*************** namespace std 
*** 75,80 ****
--- 75,83 ----
    template
      S::basic_string(C*, C*, const allocator<C>&);
  
+   template
+     S::basic_string(const C*, const C*, const allocator<C>&);
+ 
    template 
      S::basic_string(S::iterator, S::iterator, const allocator<C>&);
  


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