This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[v3] implement std::collate
- To: gcc-patches at gcc dot gnu dot org, libstdc++ at gcc dot gnu dot org
- Subject: [v3] implement std::collate
- From: Benjamin Kosnik <bkoz at redhat dot com>
- Date: Fri, 17 Aug 2001 19:51:09 -0700
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>&);