Preliminary named locales.

2001-01-29  Benjamin Kosnik  <bkoz@redhat.com>

	Preliminary named locales.
	* acinclude.m4 (GLIBCPP_ENABLE_CLOCALE): New macro.
	* aclocal.m4: Regenerate.
	* configure.in: Use it.
	* configure: Regerate.
	* src/Makefile.am (sources): Add c++locale.cc.
	(build_headers): Add c++locale.h.
	* src/Makefile.in: Regenerate.
	* config/c_locale_gnu.h: New file.
	* config/c_locale_gnu.cc: New file. Non-inline member functions
	for named locales, gnu-specific.
	* config/c_locale_generic.h: New file.
	* config/c_locale_generic.cc: New file. Non-inline member
	functions for named locales, generic version.
	* docs/html/configopts.html: Add documentation on new options.

	* include/bits/locale_facets.h (class _Messages): Remove.
	(class _Moneypunct): Remove.
	* src/locale-inst.cc: Remove.

	* include/bits/locale_facets.h (class _Collate): Remove.
	* src/locale-inst.cc (std): Remove.
	* src/locale.cc: And here.

	* include/bits/localefwd.h (locale::_M_coalesce): New
	function. Correctly put together multi-name locales.
	(_Impl(const _Impl&, category, size_t)): Remove.

	* include/bits/localefwd.h (locale::_Impl): Remove _M_construct_*
	member functions.
	(_M_normalize_category_names): Remove.
	(_M_replace_categories): Fix.

	* src/localename.cc (locale::_Impl::_M_construct_collate): Remove.
	(locale::_Impl::_M_construct_ctype): Remove.
	(locale::_Impl::_M_construct_monetary): Remove.
	(locale::_Impl::_M_construct_numeric): Remove.
	(locale::_Impl::_M_construct_time): Remove.
	(locale::_Impl::_M_construct_messages): Remove.

	* include/bits/locale_facets.h (_Bad_use_facet): Remove.
	(_Use_facet_failure_handle): Remove.
	* src/locale.cc: Remove definitions.
	* src/locale-inst.cc: And here.

	* testsuite/22_locale/ctor_copy_dtor.cc (test01): Fixup. Add tests.

	* src/localename.cc (locale::facet::_S_create_c_locale): Properly
	create and error-check underlying locale object.
	(locale::facet::_S_destroy_c_locale): Add, take care of properly
	tearing down underlying locale object.
	* include/bits/localefwd.h (locale::facet): Declare.
	* testsuite/22_locale/members.cc: Don't test "fr_FR" locale for
	correctness, as glibc apparently has incorrect info in it. Test
	with it when it works again.....

	* include/bits/localefwd.h (locale::_Impl::__vec_string):
	Remove. Number of categories is fixed at six, so just simplify and
	make this an array of strings.
	(locale::_Impl::_M_has_name): Remove.
	(locale::_Impl::_M_name): Remove.
	(locale::_Impl::_M_category_names): Turns into...
	(locale::_Impl::_M_names): ...this.
	(locale::_Impl::_M_has_same_name()): New function.
	* src/localename.cc (locale::_Impl::~_Impl()): Remove here.
	(locale::_Impl::_Impl(size_t __refs, string __str)): Simplify
	signature.
	* src/locale.cc (locale::name()): Construct mangled name
	accurately reflecting combined locale categories.

	* src/locale.cc (locale::classic()): Don't initialize here.
	* src/localename.cc (locale::_Impl::_Impl(size_t __num, size_t
	__refs, bool __has_name, string __str): Do it here.

	* include/bits/localefwd.h: _S_categories_num to
	_S_num_categories. _S_facets_num to _S_num_facets.
	(locale:🆔:id()): Explicitly set _M_index to zero.
	* src/locale.cc: Same.

	* src/locale.cc: (locale::locale(const char*)): Construct named
	locales uniquely.

	* src/locale.cc: Remove numpunct_byname ctors.
	* testsuite/22_locale/numpunct_byname.cc: New file.
	* testsuite/22_locale/numpunct.cc: New file.

	* include/bits/localefwd.h (class locale): Change data members to
	protected, from private.
	(_Impl::_M_get_c_locale): Add member function.
	(locale::facet::_M_get_global_impl()): Add member function.
	* include/bits/locale_facets.h (numpunct::_M_init): Change to take
	a __c_locale pointer.
	(numpunct::numpunct( __c_locale*, size_t)): Add additonal ctor for
	named locales.
	* testsuite/22_locale/members.cc: New file, test name and combine.

	* include/bits/locale_facets.h (class numpunct): Remove class
	_Punct and _Numpunct. Rewrite class numpunct to be correct for
	named locales.
	* include/bits/localefwd.h (locale::_Imp::_M_c_locale): Add.
	* src/localename.cc (_Impl::~_Impl()): Call __frelocale.
	(_Imp::_Impl(size_t, size_t, bool, string)) Initialize _M_c_locale.
	* src/locale-inst.cc: Remove _Numpunct, _Punct instantiations.
	* testsuite/22_locale/numpunct_char_members.cc: New file.

From-SVN: r39347
This commit is contained in:
Benjamin Kosnik 2001-01-30 09:18:51 +00:00
parent f25561bb8c
commit 0214010c60
29 changed files with 2852 additions and 1816 deletions

View File

@ -1,3 +1,110 @@
2001-01-29 Benjamin Kosnik <bkoz@redhat.com>
Preliminary named locales.
* acinclude.m4 (GLIBCPP_ENABLE_CLOCALE): New macro.
* aclocal.m4: Regenerate.
* configure.in: Use it.
* configure: Regerate.
* src/Makefile.am (sources): Add c++locale.cc.
(build_headers): Add c++locale.h.
* src/Makefile.in: Regenerate.
* config/c_locale_gnu.h: New file.
* config/c_locale_gnu.cc: New file. Non-inline member functions
for named locales, gnu-specific.
* config/c_locale_generic.h: New file.
* config/c_locale_generic.cc: New file. Non-inline member
functions for named locales, generic version.
* docs/html/configopts.html: Add documentation on new options.
* include/bits/locale_facets.h (class _Messages): Remove.
(class _Moneypunct): Remove.
* src/locale-inst.cc: Remove.
* include/bits/locale_facets.h (class _Collate): Remove.
* src/locale-inst.cc (std): Remove.
* src/locale.cc: And here.
* include/bits/localefwd.h (locale::_M_coalesce): New
function. Correctly put together multi-name locales.
(_Impl(const _Impl&, category, size_t)): Remove.
* include/bits/localefwd.h (locale::_Impl): Remove _M_construct_*
member functions.
(_M_normalize_category_names): Remove.
(_M_replace_categories): Fix.
* src/localename.cc (locale::_Impl::_M_construct_collate): Remove.
(locale::_Impl::_M_construct_ctype): Remove.
(locale::_Impl::_M_construct_monetary): Remove.
(locale::_Impl::_M_construct_numeric): Remove.
(locale::_Impl::_M_construct_time): Remove.
(locale::_Impl::_M_construct_messages): Remove.
* include/bits/locale_facets.h (_Bad_use_facet): Remove.
(_Use_facet_failure_handle): Remove.
* src/locale.cc: Remove definitions.
* src/locale-inst.cc: And here.
* testsuite/22_locale/ctor_copy_dtor.cc (test01): Fixup. Add tests.
* src/localename.cc (locale::facet::_S_create_c_locale): Properly
create and error-check underlying locale object.
(locale::facet::_S_destroy_c_locale): Add, take care of properly
tearing down underlying locale object.
* include/bits/localefwd.h (locale::facet): Declare.
* testsuite/22_locale/members.cc: Don't test "fr_FR" locale for
correctness, as glibc apparently has incorrect info in it. Test
with it when it works again.....
* include/bits/localefwd.h (locale::_Impl::__vec_string):
Remove. Number of categories is fixed at six, so just simplify and
make this an array of strings.
(locale::_Impl::_M_has_name): Remove.
(locale::_Impl::_M_name): Remove.
(locale::_Impl::_M_category_names): Turns into...
(locale::_Impl::_M_names): ...this.
(locale::_Impl::_M_has_same_name()): New function.
* src/localename.cc (locale::_Impl::~_Impl()): Remove here.
(locale::_Impl::_Impl(size_t __refs, string __str)): Simplify
signature.
* src/locale.cc (locale::name()): Construct mangled name
accurately reflecting combined locale categories.
* src/locale.cc (locale::classic()): Don't initialize here.
* src/localename.cc (locale::_Impl::_Impl(size_t __num, size_t
__refs, bool __has_name, string __str): Do it here.
* include/bits/localefwd.h: _S_categories_num to
_S_num_categories. _S_facets_num to _S_num_facets.
(locale::id::id()): Explicitly set _M_index to zero.
* src/locale.cc: Same.
* src/locale.cc: (locale::locale(const char*)): Construct named
locales uniquely.
* src/locale.cc: Remove numpunct_byname ctors.
* testsuite/22_locale/numpunct_byname.cc: New file.
* testsuite/22_locale/numpunct.cc: New file.
* include/bits/localefwd.h (class locale): Change data members to
protected, from private.
(_Impl::_M_get_c_locale): Add member function.
(locale::facet::_M_get_global_impl()): Add member function.
* include/bits/locale_facets.h (numpunct::_M_init): Change to take
a __c_locale pointer.
(numpunct::numpunct( __c_locale*, size_t)): Add additonal ctor for
named locales.
* testsuite/22_locale/members.cc: New file, test name and combine.
* include/bits/locale_facets.h (class numpunct): Remove class
_Punct and _Numpunct. Rewrite class numpunct to be correct for
named locales.
* include/bits/localefwd.h (locale::_Imp::_M_c_locale): Add.
* src/localename.cc (_Impl::~_Impl()): Call __frelocale.
(_Imp::_Impl(size_t, size_t, bool, string)) Initialize _M_c_locale.
* src/locale-inst.cc: Remove _Numpunct, _Punct instantiations.
* testsuite/22_locale/numpunct_char_members.cc: New file.
2001-01-28 Gabriel Dos Reis <gdr@codesourcery.com>
* testsuite/README: Add more comment.

View File

@ -1054,6 +1054,51 @@ AC_SUBST(EXTRA_CXX_FLAGS)
])
dnl
dnl Check for which locale library to use: gnu or generic.
dnl
dnl GLIBCPP_ENABLE_CLOCALE
dnl --enable-clocale=gnu sets config/c_locale_gnu.cc and friends
dnl --enable-clocale=generic sets config/c_locale_generic.cc and friends
dnl
dnl default is generic
dnl
AC_DEFUN(GLIBCPP_ENABLE_CLOCALE, [
AC_MSG_CHECKING([for clocale to use])
AC_ARG_ENABLE(clocale,
[ --enable-clocale enable model for target locale package.
--enable-clocale=MODEL use MODEL target-speific locale package. [default=generic]
],
if test x$enable_clocale = xno; then
enable_clocale=generic
fi,
enable_clocale=generic)
enable_clocale_flag=$enable_clocale
dnl Check if a valid locale package
case x${enable_clocale_flag} in
xgnu)
CLOCALE_H=config/c_locale_gnu.h
CLOCALE_CC=config/c_locale_gnu.cc
AC_MSG_RESULT(gnu)
;;
xgeneric)
CLOCALE_H=config/c_locale_generic.h
CLOCALE_CC=config/c_locale_generic.cc
AC_MSG_RESULT(generic)
;;
*)
echo "$enable_clocale is an unknown locale package" 1>&2
exit 1
;;
esac
AC_LINK_FILES($CLOCALE_H, include/bits/c++locale.h)
AC_LINK_FILES($CLOCALE_CC, src/c++locale.cc)
])
dnl
dnl Check for which I/O library to use: libio, or something specific.
dnl

View File

@ -1066,6 +1066,51 @@ AC_SUBST(EXTRA_CXX_FLAGS)
])
dnl
dnl Check for which locale library to use: gnu or generic.
dnl
dnl GLIBCPP_ENABLE_CLOCALE
dnl --enable-clocale=gnu sets config/c_locale_gnu.cc and friends
dnl --enable-clocale=generic sets config/c_locale_generic.cc and friends
dnl
dnl default is generic
dnl
AC_DEFUN(GLIBCPP_ENABLE_CLOCALE, [
AC_MSG_CHECKING([for clocale to use])
AC_ARG_ENABLE(clocale,
[ --enable-clocale enable model for target locale package.
--enable-clocale=MODEL use MODEL target-speific locale package. [default=generic]
],
if test x$enable_clocale = xno; then
enable_clocale=generic
fi,
enable_clocale=generic)
enable_clocale_flag=$enable_clocale
dnl Check if a valid locale package
case x${enable_clocale_flag} in
xgnu)
CLOCALE_H=config/c_locale_gnu.h
CLOCALE_CC=config/c_locale_gnu.cc
AC_MSG_RESULT(gnu)
;;
xgeneric)
CLOCALE_H=config/c_locale_generic.h
CLOCALE_CC=config/c_locale_generic.cc
AC_MSG_RESULT(generic)
;;
*)
echo "$enable_clocale is an unknown locale package" 1>&2
exit 1
;;
esac
AC_LINK_FILES($CLOCALE_H, include/bits/c++locale.h)
AC_LINK_FILES($CLOCALE_CC, src/c++locale.cc)
])
dnl
dnl Check for which I/O library to use: libio, or something specific.
dnl

View File

@ -0,0 +1,108 @@
// Wrapper for underlying C-language localization -*- C++ -*-
// Copyright (C) 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
// 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: 22.8 Standard locale categories.
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
#include <locale>
#include <langinfo.h>
namespace std
{
void
locale::facet::_S_create_c_locale(__c_locale& /*__cloc*/, const char*)
{ }
void
locale::facet::_S_destroy_c_locale(__c_locale& /*__cloc*/)
{ }
template<>
void
numpunct<char>::_M_initialize_numpunct(__c_locale /*__cloc*/)
{
// "C" locale
_M_decimal_point = '.';
_M_thousands_sep = ',';
_M_grouping = "";
_M_truename = "true";
_M_falsename = "false";
}
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
numpunct<wchar_t>::_M_initialize_numpunct(__c_locale /*__cloc*/)
{
// "C" locale
_M_decimal_point = L'.';
_M_thousands_sep = L',';
_M_grouping = "";
_M_truename = L"true";
_M_falsename = L"false";
}
#endif
template<>
void
moneypunct<char>::_M_initialize_moneypunct(__c_locale /*__cloc*/)
{
// "C" locale
_M_decimal_point = '.';
_M_thousands_sep = ',';
_M_grouping = "";
_M_curr_symbol = string_type();
_M_positive_sign = string_type();
_M_negative_sign = string_type();
_M_frac_digits = 0;
_M_pos_format = money_base::_S_default_pattern;
_M_neg_format = money_base::_S_default_pattern;
}
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
moneypunct<wchar_t>::_M_initialize_moneypunct(__c_locale /*__cloc*/)
{
// "C" locale
_M_decimal_point = L'.';
_M_thousands_sep = L',';
_M_grouping = "";
_M_curr_symbol = string_type();
_M_positive_sign = string_type();
_M_negative_sign = string_type();
_M_frac_digits = 0;
_M_pos_format = money_base::_S_default_pattern;
_M_neg_format = money_base::_S_default_pattern;
}
#endif
} // namespace std

View File

@ -0,0 +1,39 @@
// Wrapper for underlying C-language localization -*- C++ -*-
// Copyright (C) 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
// 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: 22.8 Standard locale categories.
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
namespace std
{
typedef int* __c_locale;
}

View File

@ -0,0 +1,204 @@
// Wrapper for underlying C-language localization -*- C++ -*-
// Copyright (C) 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
// 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: 22.8 Standard locale categories.
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
#include <locale>
#include <stdexcept>
#include <langinfo.h>
namespace std
{
void
locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s)
{
// XXX
// 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.
throw runtime_error("attempt to create locale from unknown name");
}
}
void
locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
{
if (__cloc)
__freelocale(__cloc);
}
template<>
void
numpunct<char>::_M_initialize_numpunct(__c_locale __cloc)
{
if (!__cloc)
{
// "C" locale
_M_decimal_point = '.';
_M_thousands_sep = ',';
_M_grouping = "";
}
else
{
// Named locale.
_M_decimal_point = *(__nl_langinfo_l(RADIXCHAR, __cloc));
_M_thousands_sep = *(__nl_langinfo_l(THOUSEP, __cloc));
_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
}
// NB: There is no way to extact this info from posix locales.
// _M_truename = __nl_langinfo_l(YESSTR, __cloc);
_M_truename = "true";
// _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
_M_falsename = "false";
}
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc)
{
if (!__cloc)
{
// "C" locale
_M_decimal_point = L'.';
_M_thousands_sep = L',';
_M_grouping = "";
}
else
{
// Named locale.
_M_decimal_point = reinterpret_cast<wchar_t>(__nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc));
_M_thousands_sep = reinterpret_cast<wchar_t>(__nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC,__cloc));
_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
}
// NB: There is no way to extact this info from posix locales.
// _M_truename = __nl_langinfo_l(YESSTR, __cloc);
_M_truename = L"true";
// _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
_M_falsename = L"false";
}
#endif
template<>
void
moneypunct<char>::_M_initialize_moneypunct(__c_locale __cloc)
{
if (!__cloc)
{
// "C" locale
_M_decimal_point = '.';
_M_thousands_sep = ',';
_M_grouping = "";
_M_curr_symbol = string_type();
_M_positive_sign = string_type();
_M_negative_sign = string_type();
_M_frac_digits = 0;
_M_pos_format = money_base::_S_default_pattern;
_M_neg_format = money_base::_S_default_pattern;
}
else
{
// Named locale.
_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT, __cloc));
_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP, __cloc));
_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
if (intl)
{
_M_curr_symbol = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, __cloc));
char __ppreceeds = *(__nl_langinfo_l(__INT_P_CS_PRECEDES,
__cloc));
char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
_M_pos_format = _S_construct_pattern(__ppreceeds, __pspace,
__pposn);
char __npreceeds = *(__nl_langinfo_l(__INT_N_CS_PRECEDES,
__cloc));
char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
_M_neg_format = _S_construct_pattern(__npreceeds, __nspace,
__nposn);
}
else
{
_M_curr_symbol = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc));
char __ppreceeds = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
_M_pos_format = _S_construct_pattern(__ppreceeds, __pspace,
__pposn);
char __npreceeds = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
_M_neg_format = _S_construct_pattern(__npreceeds, __nspace,
__nposn);
}
}
}
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
moneypunct<wchar_t>::_M_initialize_moneypunct(__c_locale /*__cloc*/)
{
// XXX implement
// "C" locale
_M_decimal_point = L'.';
_M_thousands_sep = L',';
_M_grouping = "";
_M_curr_symbol = string_type();
_M_positive_sign = string_type();
_M_negative_sign = string_type();
_M_frac_digits = 0;
_M_pos_format = money_base::_S_default_pattern;
_M_neg_format = money_base::_S_default_pattern;
}
#endif
} // namespace std

View File

@ -0,0 +1,39 @@
// Wrapper for underlying C-language localization -*- C++ -*-
// Copyright (C) 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
// 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: 22.8 Standard locale categories.
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
namespace std
{
typedef __locale_t __c_locale;
}

1632
libstdc++-v3/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,7 @@ GLIBCPP_CHECK_COMPILER_VERSION
# Enable all the crazy c++ stuff. C_MBCHAR must come early.
GLIBCPP_ENABLE_DEBUG($USE_MAINTAINER_MODE)
GLIBCPP_ENABLE_CSTDIO
GLIBCPP_ENABLE_CLOCALE
GLIBCPP_ENABLE_C_MBCHAR([yes])
GLIBCPP_ENABLE_LONG_LONG([no])
GLIBCPP_ENABLE_CHEADERS([c_std])

View File

@ -5,12 +5,14 @@
</H1>
</HEAD>
<I>
prepared by Benjamin Kosnik (bkoz@redhat.com) on September 15, 2000
prepared by Benjamin Kosnik (bkoz@redhat.com) on January 24, 2001
</I>
<P>
<H2>
1. Abstract
1. Abstract Describes the basic locale object, including nested
classes id, facet, and the reference-counted implementation object,
class _Impl.
</H2>
<P>
</P>
@ -18,6 +20,7 @@ prepared by Benjamin Kosnik (bkoz@redhat.com) on September 15, 2000
<P>
<H2>
2. What the standard says
See Chapter 22 of the standard.
</H2>
@ -27,17 +30,44 @@ prepared by Benjamin Kosnik (bkoz@redhat.com) on September 15, 2000
</H2>
<P>
For the required specialization codecvt&lt;wchar_t, char, mbstate_t&gt; ,
conversions are made between the internal character set (always UCS4
on GNU/Linux) and whatever the currently selected locale for the
LC_CTYPE category implements.
The major problem is fitting an object-orientated and non-global locale
design ontop of POSIX and other relevant stanards, which include the
Single Unix (nee X/Open.)
Because POSIX falls down so completely, portibility is an issue.
<P>
<H2>
4. Design
</H2>
The two required specializations are implemented as follows:
Class locale in non-templatized and has three distinct types nested
inside of it:
class facet
22.1.1.1.2 Class locale::facet
Facets actually implement locale functionality. For instance, a facet
called numpunct is the data objects that can be used to query for the
thousands seperator is in the German locale.
Literally, a facet is strictly defined:
- containing
public:
static locale::id id;
- or derived from another facet
The only other thing of interest in this class is the memory
management of facets. Each constructor of a facet class takes a
std::size_t __refs argument: if __refs == 0, the facet is deleted when
no longer used. if __refs == 1, the facet is not destroyed, even when
it is no longer reference.
class id
Provides an index for looking up specific facets.
class _Impl
<P>
<H2>
@ -45,7 +75,7 @@ The two required specializations are implemented as follows:
</H2>
<pre>
typedef ctype<char> cctype;
typedef __locale_t locale;
</pre>
More information can be found in the following testcases:

View File

@ -7,7 +7,7 @@
<META NAME="GENERATOR" CONTENT="vi and eight fingers">
<TITLE>libstdc++-v3 configure options</TITLE>
<LINK REL=StyleSheet HREF="lib3styles.css">
<!-- $Id: configopts.html,v 1.3 2001/01/03 15:53:27 bkoz Exp $ -->
<!-- $Id: configopts.html,v 1.4 2001/01/21 09:36:09 pme Exp $ -->
</HEAD>
<BODY>
@ -69,6 +69,21 @@ options</A></H1>
abstraction. The default is 'stdio'.
</P>
<DT><TT>--enable-clocale </TT>
<DD><P>This is an abbreviated form of <TT>'--enable-clocale=generic'</TT>
(described next).
</P>
<DT><TT>--enable-clocale=MODEL </TT>
<DD><P>Select a target-specific underlying locale package. The
choices are 'gnu' to specify an X/Open (IEEE Std. 1003.1-200x)
model based on langinfo/iconv (from <A
HREF="http://sources.redhat.com/glibc/">glibc</A>, the GNU C
library), or 'generic' to use a generic &quot;C&quot;
abstraction which consists of "C" locale info. The default is
'generic'.
</P>
<DT><TT>--enable-long-long </TT>
<DD><P>The &quot;long long&quot; type was introduced in C99. It is
provided as a GNU extension to C++98 in g++. This flag builds
@ -178,7 +193,7 @@ options</A></H1>
<HR>
<P CLASS="fineprint"><EM>
$Id: configopts.html,v 1.3 2001/01/03 15:53:27 bkoz Exp $
$Id: configopts.html,v 1.4 2001/01/21 09:36:09 pme Exp $
</EM></P>

View File

@ -1,6 +1,6 @@
// Locale support -*- C++ -*-
// Copyright (C) 1997-2000 Free Software Foundation, Inc.
// Copyright (C) 1997, 1998, 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
@ -37,49 +37,15 @@
#define _CPP_BITS_LOCFACETS_H 1
#include <bits/std_ctime.h> // For struct tm
#include <typeinfo> // For bad_cast, which shouldn't be here.
#include <bits/std_ios.h> // For ios_base
#ifdef _GLIBCPP_USE_WCHAR_T
# include <langinfo.h> // For codecvt
# include <bits/std_cwctype.h> // For wctype_t
# include <iconv.h> // For codecvt using iconv, iconv_t
# include <langinfo.h> // For codecvt using nl_langinfo
#endif
namespace std
{
// XXX This function is to be specialized for the "required" facets to
// be constructed lazily. The specializations must be declared after
// the definitions of the facets themselves; but they shouldn't be
// inline. Corresponding new's in locale::classic() should then be
// eliminated. Note that ctype<> should not get this treatment;
// see the use_facet<> specializations below.
//
struct _Bad_use_facet : public bad_cast
{
_Bad_use_facet() throw() {}
_Bad_use_facet(_Bad_use_facet const& __b) throw()
: bad_cast(__b) { }
_Bad_use_facet&
operator=(_Bad_use_facet const& __b) throw()
{
static_cast<bad_cast*>(this)->operator=(__b);
return *this;
}
virtual char const*
what() const throw();
virtual
~_Bad_use_facet() throw();
};
template<typename _Facet>
const _Facet&
_Use_facet_failure_handler(const locale&)
{ throw _Bad_use_facet(); }
// 22.2.1.1 Template class ctype
// Include host-specific ctype enums for ctype_base.
#include <bits/ctype_base.h>
@ -809,12 +775,30 @@ namespace std
locale::id num_put<_CharT, _OutIter>::id;
template<typename _CharT>
class _Punct : public locale::facet
class numpunct : public locale::facet
{
public:
// Types:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
static locale::id id;
private:
char_type _M_decimal_point;
char_type _M_thousands_sep;
string _M_grouping;
string_type _M_truename;
string_type _M_falsename;
public:
explicit
numpunct(size_t __refs = 0) : locale::facet(__refs)
{ _M_initialize_numpunct(); }
explicit
numpunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
{ _M_initialize_numpunct(__cloc); }
char_type
decimal_point() const
@ -827,49 +811,6 @@ namespace std
string
grouping() const
{ return do_grouping(); }
protected:
explicit
_Punct(size_t __refs = 0) : locale::facet(__refs) { }
virtual
~_Punct() { }
virtual char_type
do_decimal_point() const
{ return _M_decimal_point; }
virtual char_type
do_thousands_sep() const
{ return _M_thousands_sep; }
virtual string
do_grouping() const
{ return _M_grouping; }
private:
char_type _M_decimal_point;
char_type _M_thousands_sep;
string _M_grouping;
protected:
// for use at construction time only:
void
_M_init(char_type __d, char_type __t, const string& __g)
{
_M_decimal_point = __d;
_M_thousands_sep = __t;
_M_grouping = __g;
}
};
template<typename _CharT>
class _Numpunct : public _Punct<_CharT>
{
public:
// Types:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
string_type
truename() const
@ -880,11 +821,20 @@ namespace std
{ return do_falsename(); }
protected:
explicit
_Numpunct(size_t __refs = 0) : _Punct<_CharT> (__refs) { }
virtual
~_Numpunct() { }
~numpunct() { }
virtual char_type
do_decimal_point() const
{ return _M_decimal_point; }
virtual char_type
do_thousands_sep() const
{ return _M_thousands_sep; }
virtual string
do_grouping() const
{ return _M_grouping; }
virtual string_type
do_truename() const
@ -894,85 +844,66 @@ namespace std
do_falsename() const
{ return _M_falsename; }
private:
string_type _M_truename;
string_type _M_falsename;
protected:
// For use only during construction
// For use at construction time only.
void
_M_boolnames_init(const string_type& __t, const string_type& __f)
{
_M_truename = __t;
_M_falsename = __f;
}
_M_initialize_numpunct(__c_locale __cloc = NULL);
};
template<typename _CharT>
class numpunct : public _Numpunct<_CharT>
locale::id numpunct<_CharT>::id;
template<typename _CharT>
void
numpunct<_CharT>::_M_initialize_numpunct(__c_locale /*__cloc*/)
{
// NB: Cannot be made generic.
}
template<>
void
numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
#endif
template<typename _CharT>
class numpunct_byname : public numpunct<_CharT>
{
__c_locale _M_c_locale_numpunct;
public:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
explicit
numpunct_byname(const char* __s, size_t __refs = 0)
: numpunct<_CharT>(__refs)
{
_S_create_c_locale(_M_c_locale_numpunct, __s);
_M_initialize_numpunct(_M_c_locale_numpunct);
}
protected:
virtual
~numpunct_byname()
{ _S_destroy_c_locale(_M_c_locale_numpunct); }
};
template<typename _CharT>
class collate : public locale::facet
{
public:
// Types:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
static locale::id id;
explicit
numpunct(size_t __refs = 0) : _Numpunct<_CharT>(__refs) { }
protected:
virtual
~numpunct() { }
};
template<typename _CharT>
locale::id numpunct<_CharT>::id;
template<>
numpunct<char>::numpunct(size_t __refs): _Numpunct<char>(__refs)
{
_M_init('.', ',', "");
_M_boolnames_init("true", "false");
}
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
numpunct<wchar_t>::numpunct(size_t __refs): _Numpunct<wchar_t>(__refs)
{
_M_init(L'.', L',', "");
_M_boolnames_init(L"true", L"false");
}
#endif
template<typename _CharT>
class numpunct_byname : public numpunct<_CharT>
{
public:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
explicit
numpunct_byname(const char*, size_t __refs = 0);
protected:
virtual
~numpunct_byname() { }
};
template<>
numpunct_byname<char>::numpunct_byname(const char*, size_t __refs);
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
numpunct_byname<wchar_t>::numpunct_byname(const char*, size_t __refs);
#endif
template<typename _CharT>
class _Collate : public locale::facet
{
public:
// Types:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
collate(size_t __refs = 0) : locale::facet(__refs) { }
int
compare(const _CharT* __lo1, const _CharT* __hi1,
@ -988,99 +919,50 @@ namespace std
{ return do_hash(__lo, __hi); }
protected:
explicit
_Collate(size_t __refs = 0) : locale::facet(__refs) { }
~_Collate() { } // virtual
~collate() { } // virtual
virtual int
do_compare(const _CharT* __lo1, const _CharT* __hi1,
const _CharT* __lo2, const _CharT* __hi2) const = 0;
const _CharT* __lo2, const _CharT* __hi2) const;
virtual string_type
do_transform(const _CharT* __lo, const _CharT* __hi) const = 0;
do_transform(const _CharT* __lo, const _CharT* __hi) const;
virtual long
do_hash(const _CharT* __lo, const _CharT* __hi) const = 0;
};
template<typename _CharT>
class collate : public _Collate<_CharT>
{
public:
// Types:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
explicit
collate(size_t __refs = 0) : _Collate<_CharT> (__refs) { }
static locale::id id;
protected:
virtual
~collate() { }
do_hash(const _CharT* __lo, const _CharT* __hi) const;
};
template<typename _CharT>
locale::id collate<_CharT>::id;
// Required specializations.
template<>
class collate<char> : public _Collate<char>
{
public:
// Types:
typedef char char_type;
typedef basic_string<char> string_type;
int
collate<char>::do_compare(const char* __lo1, const char* __hi1,
const char* __lo2, const char* __hi2) const;
explicit
collate(size_t __refs = 0);
static locale::id id;
protected:
virtual
~collate();
virtual int
do_compare(const char* __lo1, const char* __hi1,
const char* __lo2, const char* __hi2) const;
virtual string_type
do_transform(const char* __lo, const char* __hi) const;
virtual long
do_hash(const char* __lo, const char* __hi) 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<>
class collate<wchar_t> : public _Collate<wchar_t>
{
public:
// Types:
typedef wchar_t char_type;
typedef basic_string<wchar_t> string_type;
explicit
collate(size_t __refs = 0);
int
collate<wchar_t>::do_compare(const wchar_t* __lo1, const wchar_t* __hi1,
const wchar_t* __lo2,
const wchar_t* __hi2) const;
static locale::id id;
protected:
virtual
~collate();
template<>
wstring
collate<wchar_t>::do_transform(const wchar_t* __lo,
const wchar_t* __hi) const;
virtual int
do_compare(const wchar_t* __lo1, const wchar_t* __hi1,
const wchar_t* __lo2, const wchar_t* __hi2) const;
virtual string_type
do_transform(const wchar_t* __lo, const wchar_t* __hi) const;
virtual long
do_hash(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>
@ -1356,17 +1238,58 @@ namespace std
struct pattern { char field[4]; };
static const pattern _S_default_pattern;
// Construct and return valid pattern consisting of some combination of:
// space none symbol sign value
static pattern
_S_construct_pattern(char __preceeds, char __space, char __posn);
};
template<typename _CharT>
class _Moneypunct : public _Punct<_CharT>, public money_base
template<typename _CharT, bool _Intl>
class moneypunct : public locale::facet, public money_base
{
public:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
// Types:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
static const bool intl = _Intl;
static locale::id id;
private:
char_type _M_decimal_point;
char_type _M_thousands_sep;
string _M_grouping;
string_type _M_curr_symbol;
string_type _M_positive_sign;
string_type _M_negative_sign;
int _M_frac_digits;
pattern _M_pos_format;
pattern _M_neg_format;
public:
explicit
moneypunct(size_t __refs = 0) : locale::facet(__refs)
{ _M_initialize_moneypunct(); }
explicit
moneypunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
{ _M_initialize_moneypunct(__cloc); }
char_type
decimal_point() const
{ return decimal_point(); }
char_type
thousands_sep() const
{ return thousands_sep(); }
string
grouping() const
{ return grouping(); }
string_type
curr_symbol() const
curr_symbol() const
{ return do_curr_symbol(); }
string_type
@ -1378,66 +1301,60 @@ namespace std
{ return do_negative_sign(); }
int
frac_digits() const
frac_digits() const
{ return do_frac_digits(); }
pattern
pos_format() const
pos_format() const
{ return do_pos_format(); }
pattern
neg_format() const
neg_format() const
{ return do_neg_format(); }
protected:
explicit
_Moneypunct(size_t __refs = 0) : _Punct<_CharT> (__refs) { }
virtual
~_Moneypunct() { }
virtual string_type
do_curr_symbol() const
{ return basic_string<_CharT>(); }
virtual string_type
do_positive_sign() const
{ return basic_string<_CharT>(); }
virtual string_type
do_negative_sign() const
{ return basic_string<_CharT>(); }
virtual int
do_frac_digits() const
{ return 0; }
virtual pattern
do_pos_format() const
{ return money_base::_S_default_pattern; }
virtual pattern
do_neg_format() const
{ return money_base::_S_default_pattern; }
};
template<typename _CharT, bool _Intl>
class moneypunct : public _Moneypunct<_CharT>
{
public:
// Types:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
static const bool intl = _Intl;
static locale::id id;
explicit
moneypunct(size_t __refs = 0) : _Moneypunct<_CharT> (__refs) { }
protected:
virtual
~moneypunct() { }
virtual char_type
do_decimal_point() const
{ return _M_decimal_point; }
virtual char_type
do_thousands_sep() const
{ return _M_thousands_sep; }
virtual string
do_grouping() const
{ return _M_grouping; }
virtual string_type
do_curr_symbol() const
{ return _M_curr_symbol; }
virtual string_type
do_positive_sign() const
{ return _M_positive_sign; }
virtual string_type
do_negative_sign() const
{ return _M_negative_sign; }
virtual int
do_frac_digits() const
{ return _M_frac_digits; }
virtual pattern
do_pos_format() const
{ return _M_pos_format; }
virtual pattern
do_neg_format() const
{ return _M_neg_format; }
// For use at construction time only.
void
_M_initialize_moneypunct(__c_locale __cloc = NULL);
};
template<typename _CharT, bool _Intl>
@ -1447,38 +1364,48 @@ namespace std
const bool moneypunct<_CharT, _Intl>::intl;
template<typename _CharT, bool _Intl>
class moneypunct_byname : public moneypunct<_CharT,_Intl>
void
moneypunct<_CharT, _Intl>::_M_initialize_moneypunct(__c_locale /*__cloc*/)
{
// NB: Cannot be made generic.
}
template<>
void
moneypunct<char>::_M_initialize_moneypunct(__c_locale __cloc);
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
moneypunct<wchar_t>::_M_initialize_moneypunct(__c_locale __cloc);
#endif
template<typename _CharT, bool _Intl>
class moneypunct_byname : public moneypunct<_CharT, _Intl>
{
__c_locale _M_c_locale_moneypunct;
public:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
static const bool intl = _Intl;
explicit
moneypunct_byname(const char*, size_t __refs = 0);
moneypunct_byname(const char* __s, size_t __refs = 0)
: moneypunct<_CharT, _Intl>(__refs)
{
_S_create_c_locale(_M_c_locale_moneypunct, __s);
_M_initialize_moneypunct(_M_c_locale_moneypunct);
}
protected:
virtual
~moneypunct_byname() { }
~moneypunct_byname()
{ _S_destroy_c_locale(_M_c_locale_moneypunct); }
};
template<typename _CharT, bool _Intl>
const bool moneypunct_byname<_CharT, _Intl>::intl;
template<>
moneypunct_byname<char, false>::
moneypunct_byname(const char*, size_t __refs);
template<>
moneypunct_byname<char, true>::
moneypunct_byname(const char*, size_t __refs);
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
moneypunct_byname<wchar_t,false>::
moneypunct_byname(const char*, size_t __refs);
template<>
moneypunct_byname<wchar_t,true>::
moneypunct_byname (const char*, size_t __refs);
#endif
struct messages_base
{
@ -1486,11 +1413,16 @@ namespace std
};
template<typename _CharT>
class _Messages : public locale::facet, public messages_base
class messages : public locale::facet, public messages_base
{
public:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
static locale::id id;
explicit
messages(size_t __refs = 0) : locale::facet(__refs) { }
catalog
open(const basic_string<char>& __s, const locale& __loc) const
@ -1505,11 +1437,8 @@ namespace std
{ return do_close(__c); }
protected:
explicit
_Messages(size_t __refs = 0) : locale::facet(__refs) { }
virtual
~_Messages() { }
~messages() { }
// NB: Probably these should be pure, and implemented only in
// specializations of messages<>. But for now...
@ -1522,22 +1451,7 @@ namespace std
{ return __dfault; }
virtual void
do_close (catalog) const { }
};
template<typename _CharT>
class messages : public _Messages<_CharT>
{
public:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
static locale::id id;
explicit
messages(size_t __refs = 0) : _Messages<_CharT> (__refs) { }
protected:
virtual
~messages() { }
do_close(catalog) const { }
};
template<typename _CharT>

View File

@ -1,6 +1,6 @@
// Locale support -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
// Copyright (C) 1997, 1998, 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
@ -39,8 +39,10 @@
#include <bits/std_memory.h> // For auto_ptr
#include <bits/sbuf_iter.h> // For streambuf_iterators
#include <bits/std_cctype.h> // For isspace
#include <typeinfo> // For bad_cast
#include <bits/std_vector.h>
namespace std
{
template<typename _Facet>
@ -49,7 +51,6 @@ namespace std
{
locale __copy(*this);
__copy._M_impl->_M_replace_facet(__other._M_impl, &_Facet::id);
__copy._M_impl->_M_has_name = false;
return __copy;
}
@ -58,8 +59,6 @@ namespace std
locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
const basic_string<_CharT, _Traits, _Alloc>& __s2) const
{
// XXX should not need to qualify here.
// typedef collate<_CharT> __collate_type;
typedef std::collate<_CharT> __collate_type;
const __collate_type* __fcoll = &use_facet<__collate_type>(*this);
return (__fcoll->compare(__s1.data(), __s1.data() + __s1.length(),
@ -71,12 +70,12 @@ namespace std
use_facet(const locale& __loc)
{
typedef locale::_Impl::__vec_facet __vec_facet;
locale::id& __id = _Facet::id; // check member id
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]; // check derivation
if (__i >= __facet->size() || __fp == 0)
return _Use_facet_failure_handler<_Facet>(__loc);
const locale::facet* __fp = (*__facet)[__i];
if (__fp == 0 || __i >= __facet->size())
throw bad_cast();
return static_cast<const _Facet&>(*__fp);
}
@ -85,7 +84,7 @@ namespace std
has_facet(const locale& __loc) throw()
{
typedef locale::_Impl::__vec_facet __vec_facet;
locale::id& __id = _Facet::id; // check member id
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);

View File

@ -1,6 +1,6 @@
// Locale support -*- C++ -*-
// Copyright (C) 1997-2000 Free Software Foundation, Inc.
// Copyright (C) 1997, 1998, 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
@ -38,9 +38,16 @@
#include <bits/std_climits.h> // For CHAR_BIT
#include <bits/std_string.h> // For string
#include <bits/std_cctype.h> // For isspace, etc.
#include <bits/c++locale.h> // Defines __c_locale.
namespace std
{
// NB: Don't instantiate required wchar_t facets if no wchar_t support.
#ifdef _GLIBCPP_USE_WCHAR_T
# define _GLIBCPP_NUM_FACETS 26
#else
# 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
@ -163,10 +170,6 @@ namespace std
// 22.2.4 collation
template<typename _CharT>
class collate;
template<> class collate<char>;
#ifdef _GLIBCPP_USE_WCHAR_T
template<> class collate<wchar_t>;
#endif
template<typename _CharT> class
collate_byname;
@ -199,19 +202,19 @@ namespace std
template<typename _CharT>
class messages_byname;
// 22.1.1 Class locale
class locale
{
public:
// Types:
typedef unsigned int category;
typedef unsigned int category;
// Forward decls and friends:
class facet;
class id;
class _Impl;
friend class facet;
friend class _Impl;
template<typename _Facet>
@ -223,7 +226,7 @@ namespace std
has_facet(const locale&) throw();
// Category values:
// NB much depends on the order in which these appear:
// NB: Order must match _S_facet_categories definition in locale.cc
static const category none = 0;
static const category ctype = 1 << 0;
static const category numeric = 1 << 1;
@ -235,23 +238,20 @@ namespace std
numeric | time | messages);
// Construct/copy/destroy:
inline
locale() throw();
inline
locale(const locale& __other) throw();
explicit
locale(const char* __std_name);
locale(const locale& __other, const char* __std_name, category __cat);
locale(const locale& __base, const char* __s, category __cat);
locale(const locale& __other, const locale& __one, category __cat);
locale(const locale& __base, const locale& __add, category __cat);
template<typename _Facet>
locale(const locale& __other, _Facet* __f);
inline
~locale() throw();
const locale&
@ -294,8 +294,8 @@ namespace std
// Current global reference locale
static _Impl* _S_global;
static const int _S_categories_num = _Count_ones<all>::_M_count;
static const int _S_facets_num = 26;
static const size_t _S_num_categories = _Count_ones<all>::_M_count;
static const size_t _S_num_facets = _GLIBCPP_NUM_FACETS;
explicit
locale(_Impl*) throw();
@ -304,8 +304,11 @@ namespace std
_S_initialize()
{ if (!_S_classic) classic(); }
static int
_S_normalize_category(int);
static category
_S_normalize_category(category);
void
_M_coalesce(const locale& __base, const locale& __add, category __cat);
};
@ -314,8 +317,7 @@ namespace std
{
public:
// Types.
typedef vector<facet*, allocator<facet*> > __vec_facet;
typedef vector<string, allocator<string> > __vec_string;
typedef vector<facet*, allocator<facet*> > __vec_facet;
// Friends.
friend class locale;
@ -333,9 +335,8 @@ namespace std
// Data Members.
size_t _M_references;
__vec_facet* _M_facets;
__vec_string* _M_category_names;
bool _M_has_name;
string _M_name;
string _M_names[_S_num_categories];
__c_locale _M_c_locale;
static const locale::id* const _S_id_ctype[];
static const locale::id* const _S_id_numeric[];
static const locale::id* const _S_id_collate[];
@ -353,19 +354,25 @@ namespace std
{
if (_M_references-- == 0) // XXX MT
{
try {
delete this;
}
catch(...) {
}
try
{ delete this; }
catch(...)
{ }
}
}
_Impl(const _Impl&, size_t);
_Impl(const _Impl&, const string&, category, size_t);
_Impl(size_t, size_t, bool __has_name = false, string __name = "*");
_Impl(string __name, size_t);
~_Impl() throw();
bool
_M_check_same_name()
{
bool __ret = true;
for (size_t i = 0; i < _S_num_categories - 1; ++i)
__ret &= _M_names[i] == _M_names[i + 1];
return __ret;
}
void
_M_replace_categories(const _Impl*, category);
@ -380,53 +387,19 @@ namespace std
template<typename _Facet>
inline void
_M_facet_init(_Facet* __facet)
_M_init_facet(_Facet* __facet)
{ _M_install_facet(&_Facet::id, __facet); }
void
_M_construct_collate(const char*);
void
_M_construct_ctype(const char*);
void
_M_construct_monetary(const char*);
void
_M_construct_numeric(const char*);
void
_M_construct_time(const char*);
void
_M_construct_messages(const char*);
category
_M_normalize_category_names(const string&, category __cat);
};
// class locale inlines, that need declaration of locale::_Imp
locale::locale() throw()
{
_S_initialize();
(_M_impl = _S_global)->_M_add_reference();
} // XXX MT
locale::locale(const locale& __other) throw()
{ (_M_impl = __other._M_impl)->_M_add_reference(); }
template<typename _Facet>
locale::locale(const locale& __other, _Facet* __f)
{
_M_impl = new _Impl(*__other._M_impl, 1);
_M_impl->_M_install_facet(&_Facet::id, __f);
_M_impl->_M_has_name = false;
_M_impl->_M_name = "*";
for (int __i = 0; __i < _S_num_categories; ++__i)
_M_impl->_M_names[__i] = "*";
}
locale::~locale() throw()
{ _M_impl->_M_remove_reference(); }
// 22.1.1.1.2 Class locale::facet
class locale::facet
{
@ -440,6 +413,12 @@ namespace std
virtual
~facet() { };
static void
_S_create_c_locale(__c_locale& __cloc, const char* __s);
static void
_S_destroy_c_locale(__c_locale& __cloc);
private:
size_t _M_references;
@ -459,6 +438,7 @@ namespace std
// 22.1.1.1.3 Class locale::id
class locale::id
{
private:
friend class locale;
friend class locale::_Impl;
template<typename _Facet>
@ -467,9 +447,7 @@ namespace std
template<typename _Facet>
friend bool
has_facet(const locale&) throw ();
public:
id() { };
private:
// NB: There is no accessor for _M_index because it may be used
// before the constructor is run; the effect of calling a member
// function (even an inline) would be undefined.
@ -482,6 +460,12 @@ namespace std
operator=(const id&); // not defined
id(const id&); // not defined
public:
// NB: This class is always a static data member, and thus can be
// counted on to be zero-initialized.
// XXX id() : _M_index(0) { }
id() { }
};
template<typename _Facet>
@ -491,7 +475,6 @@ namespace std
template<typename _Facet>
bool
has_facet(const locale& __loc) throw();
} // namespace std
#endif /* _CPP_BITS_LOCCORE_H */

View File

@ -1,6 +1,6 @@
// -*- C++ -*- forwarding header.
// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc.
// Copyright (C) 1997, 1998, 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
@ -36,6 +36,8 @@
#ifndef _CPP_CLOCALE
#define _CPP_CLOCALE 1
#include <bits/c++config.h>
#pragma GCC system_header
#include <locale.h>

View File

@ -1,3 +1,7 @@
2001-01-28 benjamin kosnik <bkoz@fillmore.constant.com>
* Makefile.am (LIBIO_SRCS): Remove stdio.c.
2000-10-29 Benjamin Kosnik <bkoz@gnu.org>
* Makefile.am (INCLUDES): Change to $(top_builddir)/include.

View File

@ -48,8 +48,8 @@ libio_headers = \
if GLIBCPP_NEED_LIBIO
LIBIO_SRCS = \
filedoalloc.c genops.c fileops.c stdfiles.c c_codecvt.c iofclose.c \
iofopen.c stdio.c
filedoalloc.c genops.c fileops.c stdfiles.c c_codecvt.c \
iofclose.c iofopen.c
else
LIBIO_SRCS =
endif

View File

@ -129,7 +129,7 @@ INCLUDES = -nostdinc++ -I$(top_builddir)/include -I$(GLIBCPP_INCLUDE_DIR) $(
libio_headers = libio.h libioP.h iolibio.h
@GLIBCPP_NEED_LIBIO_TRUE@LIBIO_SRCS = filedoalloc.c genops.c fileops.c stdfiles.c c_codecvt.c iofclose.c iofopen.c stdio.c
@GLIBCPP_NEED_LIBIO_TRUE@LIBIO_SRCS = filedoalloc.c genops.c fileops.c stdfiles.c c_codecvt.c iofclose.c iofopen.c
@GLIBCPP_NEED_LIBIO_FALSE@LIBIO_SRCS =
@GLIBCPP_NEED_WLIBIO_TRUE@LIBIO_WSRCS = wfiledoalloc.c wfileops.c wgenops.c iofwide.c
@GLIBCPP_NEED_WLIBIO_FALSE@LIBIO_WSRCS =
@ -157,7 +157,7 @@ libio_la_LIBADD =
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@stdfiles.lo \
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@c_codecvt.lo \
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@iofclose.lo \
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@iofopen.lo stdio.lo \
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@iofopen.lo \
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@wfiledoalloc.lo \
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@wfileops.lo \
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@wgenops.lo \
@ -174,7 +174,7 @@ libio_la_LIBADD =
@GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_TRUE@stdfiles.lo \
@GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_TRUE@c_codecvt.lo \
@GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_TRUE@iofclose.lo \
@GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_TRUE@iofopen.lo stdio.lo
@GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_TRUE@iofopen.lo
@GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_FALSE@libio_la_OBJECTS =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)

View File

@ -21,7 +21,7 @@
## Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
## USA.
## $Id: Makefile.am,v 1.64 2001/01/11 07:27:49 bkoz Exp $
## $Id: Makefile.am,v 1.65 2001/01/25 22:39:28 mmitchel Exp $
AUTOMAKE_OPTIONS = 1.3 gnits
MAINT_CHARSET = latin1
@ -168,7 +168,8 @@ libio_headers =
endif
build_headers = \
bits/std_limits.h bits/c++config.h bits/c++io.h bits/c++threads.h \
bits/std_limits.h \
bits/c++config.h bits/c++io.h bits/c++locale.h bits/c++threads.h \
bits/atomicity.h bits/os_defines.h \
bits/ctype_base.h bits/ctype_noninline.h bits/ctype_inline.h
@ -178,7 +179,7 @@ sources = \
stdexcept.cc bitset.cc \
globals.cc \
c++io.cc ios.cc strstream.cc \
locale.cc localename.cc codecvt.cc \
c++locale.cc locale.cc localename.cc codecvt.cc \
locale-inst.cc stl-inst.cc misc-inst.cc valarray-inst.cc string-inst.cc
wstring_sources = \

View File

@ -167,10 +167,10 @@ std_headers = algorithm bitset complex deque fstream functional iomanip ios i
@GLIBCPP_NEED_LIBIO_TRUE@libio_headers = $(top_srcdir)/libio/_G_config.h $(top_srcdir)/libio/libio.h
@GLIBCPP_NEED_LIBIO_FALSE@libio_headers =
build_headers = bits/std_limits.h bits/c++config.h bits/c++io.h bits/c++threads.h bits/atomicity.h bits/os_defines.h bits/ctype_base.h bits/ctype_noninline.h bits/ctype_inline.h
build_headers = bits/std_limits.h bits/c++config.h bits/c++io.h bits/c++locale.h bits/c++threads.h bits/atomicity.h bits/os_defines.h bits/ctype_base.h bits/ctype_noninline.h bits/ctype_inline.h
sources = limitsMEMBERS.cc complex_io.cc stdexcept.cc bitset.cc globals.cc c++io.cc ios.cc strstream.cc locale.cc localename.cc codecvt.cc locale-inst.cc stl-inst.cc misc-inst.cc valarray-inst.cc string-inst.cc
sources = limitsMEMBERS.cc complex_io.cc stdexcept.cc bitset.cc globals.cc c++io.cc ios.cc strstream.cc c++locale.cc locale.cc localename.cc codecvt.cc locale-inst.cc stl-inst.cc misc-inst.cc valarray-inst.cc string-inst.cc
wstring_sources = wstring-inst.cc
@ -259,9 +259,9 @@ libinst_wstring_la_LDFLAGS =
libinst_wstring_la_LIBADD =
libinst_wstring_la_OBJECTS = wstring-inst.lo
libstdc___la_OBJECTS = limitsMEMBERS.lo complex_io.lo stdexcept.lo \
bitset.lo globals.lo c++io.lo ios.lo strstream.lo locale.lo \
localename.lo codecvt.lo locale-inst.lo stl-inst.lo misc-inst.lo \
valarray-inst.lo string-inst.lo
bitset.lo globals.lo c++io.lo ios.lo strstream.lo c++locale.lo \
locale.lo localename.lo codecvt.lo locale-inst.lo stl-inst.lo \
misc-inst.lo valarray-inst.lo string-inst.lo
CXXFLAGS = @CXXFLAGS@
CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)

View File

@ -1,6 +1,6 @@
// Locale support -*- C++ -*-
// Copyright (C) 1999, 2000 Free Software Foundation, Inc.
// Copyright (C) 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
@ -54,7 +54,6 @@ namespace std {
template class moneypunct<char, true>;
template class moneypunct_byname<char, false>;
template class moneypunct_byname<char, true>;
template class _Moneypunct<char>;
template class money_get<char, obuf_iterator>;
template class money_put<char, obuf_iterator>;
template class money_get<char, ibuf_iterator>;
@ -66,7 +65,6 @@ namespace std {
template class moneypunct<wchar_t, true>;
template class moneypunct_byname<wchar_t, false>;
template class moneypunct_byname<wchar_t, true>;
template class _Moneypunct<wchar_t>;
template class money_get<wchar_t, wobuf_iterator>;
template class money_put<wchar_t, wobuf_iterator>;
template class money_get<wchar_t, wibuf_iterator>;
@ -77,23 +75,15 @@ namespace std {
// numpunct, numpunct_byname, num_get, and num_put
template class numpunct<char>;
template class numpunct_byname<char>;
template class _Numpunct<char>;
template class num_get<char, ibuf_iterator>;
template class num_put<char, obuf_iterator>;
#ifdef _GLIBCPP_USE_WCHAR_T
template class numpunct<wchar_t>;
template class numpunct_byname<wchar_t>;
template class _Numpunct<wchar_t>;
template class num_get<wchar_t, wibuf_iterator>;
template class num_put<wchar_t, wobuf_iterator>;
#endif
// _Punct
template class _Punct<char>;
#ifdef _GLIBCPP_USE_WCHAR_T
template class _Punct<wchar_t>;
#endif
// time_get and time_put
template class time_put<char, obuf_iterator>;
template class time_put_byname<char, obuf_iterator>;
@ -108,11 +98,9 @@ namespace std {
#endif
// messages
template class _Messages<char>;
template class messages<char>;
template class messages_byname<char>;
#ifdef _GLIBCPP_USE_WCHAR_T
template class _Messages<wchar_t>;
template class messages<wchar_t>;
template class messages_byname<wchar_t>;
#endif
@ -134,12 +122,12 @@ namespace std {
#endif
// collate
template class _Collate<char>;
template class collate<char>;
template class collate_byname<char>;
template class _Weekdaynames<char, int>;
template class _Monthnames<char, int>;
#ifdef _GLIBCPP_USE_WCHAR_T
template class _Collate<wchar_t>;
template class collate<wchar_t>;
template class collate_byname<wchar_t>;
template class _Weekdaynames<wchar_t, int>;
template class _Monthnames<wchar_t, int>;
@ -155,10 +143,6 @@ namespace std {
template
const codecvt<char, char, mbstate_t>&
use_facet<codecvt<char, char, mbstate_t> >(const locale&);
template
const num_put<char, obuf_iterator>&
_Use_facet_failure_handler<num_put<char, obuf_iterator> >
(const locale &);
#ifdef _GLIBCPP_USE_WCHAR_T
template
const num_put<wchar_t, wobuf_iterator>&
@ -169,10 +153,6 @@ namespace std {
template
const codecvt<wchar_t, char, mbstate_t>&
use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const &);
template
const num_put<wchar_t, wobuf_iterator>&
_Use_facet_failure_handler<num_put<wchar_t, wobuf_iterator> >
(const locale &);
#endif
// has_facet
@ -296,12 +276,11 @@ namespace std {
template
locale::facet**
fill_n<locale::facet**, unsigned int, locale::facet*>
(locale::facet**, unsigned int, locale::facet* const &);
(locale::facet**, unsigned int, locale::facet* const&);
template
locale::facet**
fill_n<locale::facet**, unsigned long, locale::facet*>
(locale::facet**, unsigned long, locale::facet* const &);
(locale::facet**, unsigned long, locale::facet* const&);
} //std

View File

@ -1,4 +1,4 @@
// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
// Copyright (C) 1997, 1998, 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
@ -55,8 +55,8 @@ namespace std
locale::_Impl* locale::_S_classic;
locale::_Impl* locale::_S_global;
const int locale::_S_categories_num;
const int locale::_S_facets_num;
const size_t locale::_S_num_categories;
const size_t locale::_S_num_facets;
// Definitions for locale::id of standard facets.
locale::id ctype<char>::id;
@ -180,9 +180,457 @@ namespace std
0
};
// Construct and return valid pattern consisting of some combination of:
// space none symbol sign value
money_base::pattern
money_base::_S_construct_pattern(char __preceeds, char __space, char __posn)
{
pattern __ret;
// This insanely complicated routine attempts to construct a valid
// pattern for use with monyepunct. A couple of invariants:
// if (__preceeds) symbol -> value
// else value -> symbol
// if (__space) space
// else none
// none == never first
// space never first or last
// Any elegant implementations of this are welcome.
switch (__posn)
{
case 1:
// 1 The sign precedes the value and symbol.
if (__space)
{
// Pattern starts with sign.
if (__preceeds)
{
__ret.field[1] = symbol;
__ret.field[2] = space;
__ret.field[3] = value;
}
else
{
__ret.field[1] = value;
__ret.field[2] = space;
__ret.field[3] = symbol;
}
__ret.field[0] = sign;
}
else
{
// Pattern starts with sign and ends with none.
if (__preceeds)
{
__ret.field[1] = symbol;
__ret.field[2] = value;
}
else
{
__ret.field[1] = value;
__ret.field[2] = symbol;
}
__ret.field[0] = sign;
__ret.field[3] = none;
}
break;
case 2:
// 2 The sign follows the value and symbol.
if (__space)
{
// Pattern either ends with sign.
if (__preceeds)
{
__ret.field[0] = symbol;
__ret.field[1] = space;
__ret.field[2] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = space;
__ret.field[2] = symbol;
}
__ret.field[3] = sign;
}
else
{
// Pattern ends with sign then none.
if (__preceeds)
{
__ret.field[0] = symbol;
__ret.field[1] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = symbol;
}
__ret.field[2] = sign;
__ret.field[3] = none;
}
break;
case 3:
// 3 The sign immediately precedes the symbol.
if (__space)
{
// Have space.
if (__preceeds)
{
__ret.field[0] = sign;
__ret.field[1] = symbol;
__ret.field[2] = space;
__ret.field[3] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = space;
__ret.field[2] = sign;
__ret.field[3] = symbol;
}
}
else
{
// Have none.
if (__preceeds)
{
__ret.field[0] = sign;
__ret.field[1] = symbol;
__ret.field[2] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = sign;
__ret.field[2] = symbol;
}
__ret.field[3] = none;
}
break;
case 4:
// 4 The sign immediately follows the symbol.
if (__space)
{
// Have space.
if (__preceeds)
{
__ret.field[0] = symbol;
__ret.field[1] = sign;
__ret.field[2] = space;
__ret.field[3] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = space;
__ret.field[2] = symbol;
__ret.field[3] = sign;
}
}
else
{
// Have none.
if (__preceeds)
{
__ret.field[0] = symbol;
__ret.field[1] = sign;
__ret.field[2] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = symbol;
__ret.field[2] = sign;
}
__ret.field[3] = none;
}
break;
default:
;
}
return __ret;
}
locale::~locale() throw()
{ _M_impl->_M_remove_reference(); }
void
locale::_M_coalesce(const locale& __base, const locale& __add,
category __cat)
{
__cat = _S_normalize_category(__cat);
_M_impl = new _Impl(*__base._M_impl, 1);
try
{ _M_impl->_M_replace_categories(__add._M_impl, __cat); }
catch (...)
{
_M_impl->_M_remove_reference();
throw;
}
}
locale::locale() throw()
{
_S_initialize();
(_M_impl = _S_global)->_M_add_reference();
} // XXX MT
locale::locale(const locale& __other) throw()
{ (_M_impl = __other._M_impl)->_M_add_reference(); }
locale::locale(_Impl* __ip) throw()
: _M_impl(__ip)
{ __ip->_M_add_reference(); }
locale::locale(const char* __s)
{
if (__s)
{
if (strcmp(__s, "C") == 0 || strcmp(__s, "POSIX") == 0)
(_M_impl = _S_classic)->_M_add_reference();
else
_M_impl = new _Impl(__s, 1);
}
else
throw runtime_error("attempt to create locale from NULL name");
}
locale::locale(const locale& __base, const char* __s, category __cat)
{
// NB: There are complicated, yet more efficient ways to do
// this. Building up locales on a per-category way is tedious, so
// let's do it this way until people complain.
locale __add(__s);
_M_coalesce(__base, __add, __cat);
}
locale::locale(const locale& __base, const locale& __add, category __cat)
{ _M_coalesce(__base, __add, __cat); }
bool
locale::operator==(const locale& __rhs) const throw()
{
string __name = this->name();
return (_M_impl == __rhs._M_impl
|| (__name != "*" && __name == __rhs.name()));
}
const locale&
locale::operator=(const locale& __other) throw()
{
__other._M_impl->_M_add_reference();
_M_impl->_M_remove_reference();
_M_impl = __other._M_impl;
return *this;
}
locale
locale::global(const locale& __other)
{
// XXX MT
_S_initialize();
locale __old(_S_global);
__other._M_impl->_M_add_reference();
_S_global->_M_remove_reference();
_S_global = __other._M_impl;
if (_S_global->_M_check_same_name() && _S_global->_M_names[0] != "*")
setlocale(LC_ALL, __other.name().c_str());
return __old;
}
string
locale::name() const
{
string __ret;
// Need some kind of separator character. This one was pretty much
// arbitrarily chosen as to not conflict with glibc locales: the
// exact formatting is not set in stone.
const char __separator = '|';
if (_M_impl->_M_check_same_name())
__ret = _M_impl->_M_names[0];
else
{
for (size_t i = 0; i < _S_num_categories; ++i)
__ret += __separator + _M_impl->_M_names[i];
}
return __ret;
}
locale const&
locale::classic()
{
static locale* __classic_locale;
// XXX MT
if (!_S_classic)
{
try
{
// 26 Standard facets, 2 references.
// One reference for _M_classic, one for _M_global
_S_classic = new _Impl("C", 2);
_S_global = _S_classic;
// Finesse static init order hassles
__classic_locale = new locale(_S_classic);
}
catch(...)
{
delete __classic_locale;
if (_S_classic)
{
_S_classic->_M_remove_reference();
_S_global->_M_remove_reference();
}
_S_classic = _S_global = 0;
// XXX MT
throw;
}
}
return *__classic_locale;
}
locale::category
locale::_S_normalize_category(category __cat)
{
int __ret;
if (__cat == none || (__cat & all) && !(__cat & ~all))
__ret = __cat;
else
{
// NB: May be a C-style "LC_ALL" category; convert.
switch (__cat)
{
case LC_COLLATE:
__ret = collate;
break;
case LC_CTYPE:
__ret = ctype;
break;
case LC_MONETARY:
__ret = monetary;
break;
case LC_NUMERIC:
__ret = numeric;
break;
case LC_TIME:
__ret = time;
break;
#ifdef _GLIBCPP_HAVE_LC_MESSAGES
case LC_MESSAGES:
__ret = messages;
break;
#endif
case LC_ALL:
__ret = all;
break;
default:
throw runtime_error("bad locale category");
}
}
return __ret;
}
locale::facet::
facet(size_t __refs) throw()
: _M_references(__refs)
{ }
void
locale::facet::
_M_add_reference() throw()
{ ++_M_references; } // XXX MT
void
locale::facet::
_M_remove_reference() throw()
{
if (_M_references)
--_M_references;
else
{
try
{ delete this; } // XXX MT
catch (...)
{ }
}
}
// Definitions for static const data members of ctype_base.
const ctype_base::mask ctype_base::space;
const ctype_base::mask ctype_base::print;
const ctype_base::mask ctype_base::cntrl;
const ctype_base::mask ctype_base::upper;
const ctype_base::mask ctype_base::lower;
const ctype_base::mask ctype_base::alpha;
const ctype_base::mask ctype_base::digit;
const ctype_base::mask ctype_base::punct;
const ctype_base::mask ctype_base::xdigit;
const ctype_base::mask ctype_base::alnum;
const ctype_base::mask ctype_base::graph;
// Platform-specific initialization code for ctype tables.
#include <bits/ctype_noninline.h>
const size_t ctype<char>::table_size;
ctype<char>::~ctype()
{ if (_M_del) delete[] this->table(); }
// These are dummy placeholders as these virtual functions are never called.
bool
ctype<char>::do_is(mask, char_type) const
{ return false; }
const char*
ctype<char>::do_is(const char_type* __c, const char_type*, mask*) const
{ return __c; }
const char*
ctype<char>::do_scan_is(mask, const char_type* __c, const char_type*) const
{ return __c; }
const char*
ctype<char>::do_scan_not(mask, const char_type* __c, const char_type*) const
{ return __c; }
char
ctype<char>::do_widen(char __c) const
{ return __c; }
const char*
ctype<char>::do_widen(const char* __low, const char* __high,
char* __dest) const
{
memcpy(__dest, __low, __high - __low);
return __high;
}
char
ctype<char>::do_narrow(char __c, char /*__dfault*/) const
{ return __c; }
const char*
ctype<char>::do_narrow(const char* __low, const char* __high,
char /*__dfault*/, char* __dest) const
{
memcpy(__dest, __low, __high - __low);
return __high;
}
ctype_byname<char>::ctype_byname(const char* /*__s*/, size_t __refs)
: ctype<char>(new mask[table_size], true, __refs)
{ }
// Definitions for static const data members of money_base
const money_base::pattern
money_base::_S_default_pattern = {{symbol, sign, none, value}};;
money_base::_S_default_pattern = {{symbol, sign, none, value}};
template<>
_Format_cache<char>::_Format_cache()
@ -565,300 +1013,8 @@ namespace std
return __incl_prec;
}
locale::locale(_Impl* __ip) throw()
: _M_impl(__ip)
{ __ip->_M_add_reference(); }
locale::locale(const char* __name)
{
if (__name)
{
if (strcmp(__name, "C") == 0 || strcmp(__name, "POSIX") == 0)
(_M_impl = _S_classic)->_M_add_reference();
// Might throw:
else
// XXX Named locale support not finished.
// _M_impl = new _Impl(_S_facets_num, 1, true, __name);
_M_impl = new _Impl(*_S_classic, __name, all, 1);
}
else
throw runtime_error("attempt to create named locale from NULL name");
}
locale::locale(const locale& __other, const char* __name, category __cat)
{
if (__name)
{
if (__other.name() == __name)
(_M_impl = __other._M_impl)->_M_add_reference();
// Might throw:
else
_M_impl = new _Impl(*__other._M_impl, __name, __cat, 1);
}
else
throw runtime_error("attempt to create locale from NULL named locale");
}
locale::locale(const locale& __other, const locale& __one, category __cat)
{
__cat = _S_normalize_category(__cat); // might throw
_M_impl = new _Impl(*__other._M_impl, 1); // might throw
try {
_M_impl->_M_replace_categories(__one._M_impl, __cat);
}
catch (...) {
_M_impl->_M_remove_reference();
throw;
}
// XXX
// _M_impl->_M_cached_name_ok = false;
if (!__other._M_impl->_M_has_name)
_M_impl->_M_has_name = false;
}
bool
locale::operator==(const locale& __rhs) const throw()
{
return (_M_impl == __rhs._M_impl
|| (this->name() != "*" && this->name() == __rhs.name()));
}
const locale&
locale::operator=(const locale& __other) throw()
{
__other._M_impl->_M_add_reference();
_M_impl->_M_remove_reference();
_M_impl = __other._M_impl;
return *this;
}
locale
locale::global(const locale& __other)
{
// XXX MT
_S_initialize();
locale __keep(_S_global);
__other._M_impl->_M_add_reference();
_S_global->_M_remove_reference();
_S_global = __other._M_impl;
if (_S_global->_M_has_name)
setlocale(LC_ALL, __other.name().c_str());
return __keep;
}
string
locale::name() const
{ return _M_impl->_M_name; }
locale const&
locale::classic()
{
static locale* __classic_locale;
// XXX MT
if (!_S_classic)
{
try {
// 26 Standard facets, 2 references.
// One reference for _M_classic, one for _M_global
_S_classic = new _Impl(_S_facets_num, 2, true, "C");
_S_global = _S_classic;
_S_classic->_M_facet_init(new std::collate<char>);
_S_classic->_M_facet_init(new std::ctype<char>);
_S_classic->_M_facet_init(new codecvt<char, char, mbstate_t>);
_S_classic->_M_facet_init(new moneypunct<char, false>);
_S_classic->_M_facet_init(new moneypunct<char,true >);
_S_classic->_M_facet_init(new money_get<char>);
_S_classic->_M_facet_init(new money_put<char>);
_S_classic->_M_facet_init(new numpunct<char>);
_S_classic->_M_facet_init(new num_get<char>);
_S_classic->_M_facet_init(new num_put<char>);
_S_classic->_M_facet_init(new time_get<char>);
_S_classic->_M_facet_init(new time_put<char>);
_S_classic->_M_facet_init(new std::messages<char>);
#ifdef _GLIBCPP_USE_WCHAR_T
_S_classic->_M_facet_init(new std::collate<wchar_t>);
_S_classic->_M_facet_init(new std::ctype<wchar_t>);
_S_classic->_M_facet_init(new codecvt<wchar_t, char, mbstate_t>);
_S_classic->_M_facet_init(new moneypunct<wchar_t, false>);
_S_classic->_M_facet_init(new moneypunct<wchar_t,true >);
_S_classic->_M_facet_init(new money_get<wchar_t>);
_S_classic->_M_facet_init(new money_put<wchar_t>);
_S_classic->_M_facet_init(new numpunct<wchar_t>);
_S_classic->_M_facet_init(new num_get<wchar_t>);
_S_classic->_M_facet_init(new num_put<wchar_t>);
_S_classic->_M_facet_init(new time_get<wchar_t>);
_S_classic->_M_facet_init(new time_put<wchar_t>);
_S_classic->_M_facet_init(new std::messages<wchar_t>);
#endif
// Finesse static init order hassles
__classic_locale = new locale(_S_classic);
}
catch(...) {
delete __classic_locale;
if (_S_classic)
{
_S_classic->_M_remove_reference();
_S_global->_M_remove_reference();
}
_S_classic = _S_global = 0;
// XXX MT
throw;
}
}
return *__classic_locale;
}
int
locale::_S_normalize_category(int __cat)
{
int __ret;
if ((__cat & all) && !(__cat & ~all))
__ret = __cat;
else
{
// NB: May be a C-style "LC_ALL" category; convert.
switch (__cat)
{
case LC_COLLATE:
__ret = collate;
break;
case LC_CTYPE:
__ret = ctype;
break;
case LC_MONETARY:
__ret = monetary;
break;
case LC_NUMERIC:
__ret = numeric;
break;
case LC_TIME:
__ret = time;
break;
#ifdef _GLIBCPP_HAVE_LC_MESSAGES
case LC_MESSAGES:
__ret = messages;
break;
#endif
case LC_ALL:
__ret = all;
break;
default:
throw runtime_error("bad locale category");
}
}
return __ret;
}
locale::facet::
facet(size_t __refs) throw()
: _M_references(__refs - 1)
{ }
void
locale::facet::
_M_add_reference() throw()
{
if (this)
++_M_references;
} // XXX MT
void
locale::facet::
_M_remove_reference() throw()
{
if (this && _M_references-- == 0)
{
try {
delete this;
} // XXX MT
catch (...) {
}
}
}
char const*
_Bad_use_facet::
what() const throw()
{ return "_Bad_use_facet thrown from use_facet"; }
_Bad_use_facet::
~_Bad_use_facet() throw() { }
// Definitions for static const data members of ctype_base.
const ctype_base::mask ctype_base::space;
const ctype_base::mask ctype_base::print;
const ctype_base::mask ctype_base::cntrl;
const ctype_base::mask ctype_base::upper;
const ctype_base::mask ctype_base::lower;
const ctype_base::mask ctype_base::alpha;
const ctype_base::mask ctype_base::digit;
const ctype_base::mask ctype_base::punct;
const ctype_base::mask ctype_base::xdigit;
const ctype_base::mask ctype_base::alnum;
const ctype_base::mask ctype_base::graph;
// Platform-specific initialization code for ctype tables.
#include <bits/ctype_noninline.h>
const size_t ctype<char>::table_size;
ctype<char>::~ctype()
{ if (_M_del) delete[] this->table(); }
// These are dummy placeholders as these virtual functions are never called.
bool
ctype<char>::do_is(mask, char_type) const
{ return false; }
const char*
ctype<char>::do_is(const char_type* __c, const char_type*, mask*) const
{ return __c; }
const char*
ctype<char>::do_scan_is(mask, const char_type* __c, const char_type*) const
{ return __c; }
const char*
ctype<char>::do_scan_not(mask, const char_type* __c, const char_type*) const
{ return __c; }
char
ctype<char>::do_widen(char __c) const
{ return __c; }
const char*
ctype<char>::do_widen(const char* __low, const char* __high,
char* __dest) const
{
memcpy(__dest, __low, __high - __low);
return __high;
}
char
ctype<char>::do_narrow(char __c, char /*__dfault*/) const
{ return __c; }
const char*
ctype<char>::do_narrow(const char* __low, const char* __high,
char /*__dfault*/, char* __dest) const
{
memcpy(__dest, __low, __high - __low);
return __high;
}
ctype_byname<char>::ctype_byname(const char* /*__s*/, size_t __refs)
: ctype<char>(new mask[table_size], true, __refs)
{ }
collate<char>::collate(size_t __refs)
: _Collate<char>(__refs) { }
: locale::facet(__refs) { }
collate<char>::~collate() { }
@ -896,9 +1052,6 @@ namespace std
collate_byname<char>::collate_byname(const char* /*__s*/, size_t __refs)
: collate<char>(__refs) { }
numpunct_byname<char>::numpunct_byname(const char* /*__s*/, size_t __refs)
: numpunct<char>(__refs) { }
moneypunct_byname<char, false>::moneypunct_byname(const char* /*__s*/,
size_t __refs)
: moneypunct<char, false>(__refs) { }
@ -1068,8 +1221,7 @@ namespace std
: ctype<wchar_t>(__refs) { }
collate<wchar_t>::
collate(size_t __refs)
: _Collate<wchar_t> (__refs) { }
collate(size_t __refs): locale::facet(__refs) { }
collate<wchar_t>::
~collate() { }
@ -1094,27 +1246,14 @@ namespace std
return 0; // XXX not done
}
numpunct_byname<wchar_t>::
numpunct_byname(const char* /*__s*/, size_t __refs)
: numpunct<wchar_t> (__refs) { }
collate_byname<wchar_t>::
collate_byname(const char* /*__s*/, size_t __refs)
: collate<wchar_t> (__refs) { }
moneypunct_byname<wchar_t, false>::
moneypunct_byname(const char* /*__s*/, size_t __refs)
: moneypunct<wchar_t, false> (__refs) { }
moneypunct_byname<wchar_t, true>::
moneypunct_byname(const char* /*__s*/, size_t __refs)
: moneypunct<wchar_t, true> (__refs) { }
messages_byname<wchar_t>::
messages_byname(const char* /*__s*/, size_t __refs)
: messages<wchar_t> (__refs) { }
#endif // _GLIBCPP_USE_WCHAR_T
} // namespace std

View File

@ -25,7 +25,6 @@
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
#include <bits/std_clocale.h>
#include <bits/std_locale.h>
#include <bits/std_cstring.h>
@ -33,21 +32,21 @@
#include <bits/std_stdexcept.h>
namespace std {
locale::_Impl::
~_Impl() throw()
{
std::vector<facet*>::iterator it = _M_facets->begin();
__vec_facet::iterator it = _M_facets->begin();
for (; it != _M_facets->end(); ++it)
(*it)->_M_remove_reference();
if (*it)
(*it)->_M_remove_reference();
delete _M_facets;
delete _M_category_names;
locale::facet::_S_destroy_c_locale(_M_c_locale);
}
// Clone existing _Impl object.
locale::_Impl::
_Impl(const _Impl& __imp, size_t __refs)
: _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
_M_has_name(__imp._M_has_name), _M_name(__imp._M_name)
: _M_references(__refs - 1), _M_facets(0), _M_c_locale(0) // XXX
{
try
{ _M_facets = new __vec_facet(*(__imp._M_facets)); }
@ -57,121 +56,89 @@ namespace std {
throw;
}
try
{ _M_category_names = new __vec_string(*(__imp._M_category_names)); }
catch(...)
{
delete _M_category_names;
throw;
}
for (size_t i = 0; i < _S_num_categories; ++i)
_M_names[i] = __imp._M_names[i];
std::vector<facet*>::iterator __it = _M_facets->begin();
for (; __it != _M_facets->end(); ++__it)
(*__it)->_M_add_reference();
}
// This constructor is used to correctly initialize named locales,
// including the standard "C" locale.
locale::_Impl::
_Impl(size_t __num, size_t __refs, bool __has_name, string __str)
: _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
_M_has_name(__has_name), _M_name(__str)
{
try
{ _M_facets = new __vec_facet(__num, NULL); }
catch(...)
{
delete _M_facets;
throw;
}
try
{ _M_category_names = new __vec_string(_S_categories_num, _M_name); }
catch(...)
{
delete _M_category_names;
throw;
}
}
// Construct specific categories, leaving unselected ones alone
locale::_Impl::
_Impl(const _Impl& __imp, const string& __str, category __cat, size_t __refs)
: _M_references(__refs - 1)
{
__cat = _S_normalize_category(__cat); // might throw
try
{ _M_facets = new __vec_facet(*(__imp._M_facets)); }
catch(...)
{
delete _M_facets;
throw;
}
try
{ _M_category_names = new __vec_string(*(__imp._M_category_names)); }
catch(...)
{
delete _M_category_names;
throw;
}
static void(_Impl::* ctors[]) (const char*) =
{
// NB: Order must match the decl order in class locale.
&locale::_Impl::_M_construct_ctype,
&locale::_Impl::_M_construct_numeric,
&locale::_Impl::_M_construct_collate,
&locale::_Impl::_M_construct_time,
&locale::_Impl::_M_construct_monetary,
&locale::_Impl::_M_construct_messages,
0
};
__vec_facet::iterator __it = _M_facets->begin();
for (; __it != _M_facets->end(); ++__it)
(*__it)->_M_add_reference();
if (*__it)
(*__it)->_M_add_reference();
}
try
{
unsigned mask = (locale::all & -(unsigned)locale::all);
for (unsigned ix = 0; (-mask & __cat) != 0; ++ix, (mask <<= 1))
{
if (!(mask & __cat))
continue;
if (mask & __cat)
_M_replace_category(_S_classic, _S_facet_categories[ix]);
else
(this->*ctors[ix])(__str.c_str());
}
}
// Construct named _Impl, including the standard "C" locale.
locale::_Impl::
_Impl(string __str, size_t __refs)
: _M_references(__refs - 1), _M_facets(0)
{
// Initialize the underlying locale model, which also checks to
// see if the given name is valid.
if (__str != "C" && __str != "POSIX")
locale::facet::_S_create_c_locale(_M_c_locale, __str.c_str());
else
_M_c_locale = NULL;
// Allocate facet container.
try
{ _M_facets = new __vec_facet(_S_num_facets, NULL); }
catch(...)
{
__it = _M_facets->begin();
for (; __it != _M_facets->end(); ++__it)
(*__it)->_M_remove_reference();
delete _M_facets;
throw;
}
// XXX May need to be adjusted
if (__cat == all)
_M_name = __str;
_M_has_name = __str != "*";
// Name all the categories.
for (size_t i = 0; i < _S_num_categories; ++i)
_M_names[i] = __str;
// Construct all standard facets and add them to _M_facets.
// XXX Eventually, all should use __c_locale 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>(_M_c_locale));
_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>(_M_c_locale));
_M_init_facet(new num_get<char>);
_M_init_facet(new num_put<char>);
_M_init_facet(new time_get<char>);
_M_init_facet(new time_put<char>);
_M_init_facet(new std::messages<char>);
#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>(_M_c_locale));
_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>(_M_c_locale));
_M_init_facet(new num_get<wchar_t>);
_M_init_facet(new num_put<wchar_t>);
_M_init_facet(new time_get<wchar_t>);
_M_init_facet(new time_put<wchar_t>);
_M_init_facet(new std::messages<wchar_t>);
#endif
}
void
locale::_Impl::
_M_replace_categories(const _Impl* __imp, category __cat)
{
category __mask = locale::all & -static_cast<unsigned int>(locale::all);
for (unsigned int __ix = 0; (-__mask & __cat) != 0; ++__ix, (__mask <<= 1))
const string __none("*");
category __mask;
for (unsigned int __ix = 0; __ix < _S_num_categories; ++__ix)
{
__mask = 1 << __ix;
if (__mask & __cat)
{
// Need to replace entry in _M_facets with other locale's info.
_M_replace_category(__imp, _S_facet_categories[__ix]);
(*_M_category_names)[__ix] = (*(__imp->_M_category_names))[__ix];
// If both have names, go ahead and mangle.
if (_M_names[__ix] != __none && __imp->_M_names[__ix] != __none)
_M_names[__ix] = __imp->_M_names[__ix];
}
}
}
@ -201,91 +168,36 @@ namespace std {
locale::_Impl::
_M_install_facet(const locale::id* __idp, facet* __fp)
{
if (__fp == 0)
return;
if (__fp)
{
size_t& __index = __idp->_M_index;
if (!__index)
__index = ++locale::id::_S_highwater; // XXX MT
if (__index >= _M_facets->size())
_M_facets->resize(__index + 1, 0); // might throw
size_t& __index = __idp->_M_index;
if (!__index)
__index = ++locale::id::_S_highwater; // XXX MT
if (__index >= _M_facets->size())
_M_facets->resize(__index + 1, 0); // might throw
facet*& __fpr = (*_M_facets)[__index];
// Order matters, here:
__fp->_M_add_reference();
if (__fpr)
__fpr->_M_remove_reference();
__fpr = __fp;
}
void
locale::_Impl::_M_construct_collate(const char* __s)
{
_M_facet_init(new collate_byname<char>(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_facet_init(new collate_byname<wchar_t>(__s, 0));
#endif
}
void
locale::_Impl::_M_construct_ctype(const char* __s)
{
_M_facet_init(new ctype_byname<char>(__s, 0));
_M_facet_init(new codecvt_byname<char, char, mbstate_t>(__s));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_facet_init(new ctype_byname<wchar_t>(__s, 0));
_M_facet_init(new codecvt_byname<wchar_t, char, mbstate_t>(__s));
#endif
}
void
locale::_Impl::_M_construct_monetary(const char* __s)
{
_M_replace_facet(locale::_S_classic, &money_get<char>::id);
_M_replace_facet(locale::_S_classic, &money_put<char>::id);
_M_facet_init(new moneypunct_byname<char, false>(__s, 0));
_M_facet_init(new moneypunct_byname<char, true >(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_replace_facet(locale::_S_classic, &money_get<wchar_t>::id);
_M_replace_facet(locale::_S_classic, &money_put<wchar_t>::id);
_M_facet_init(new moneypunct_byname<wchar_t, false>(__s, 0));
_M_facet_init(new moneypunct_byname<wchar_t, true >(__s, 0));
#endif
}
void
locale::_Impl::_M_construct_numeric(const char* __s)
{
_M_replace_facet(locale::_S_classic, &num_get<char>::id);
_M_replace_facet(locale::_S_classic, &num_put<char>::id);
_M_facet_init(new numpunct_byname<char>(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_replace_facet(locale::_S_classic, &num_get<wchar_t>::id);
_M_replace_facet(locale::_S_classic, &num_put<wchar_t>::id);
_M_facet_init(new numpunct_byname<wchar_t>(__s, 0));
#endif
}
void
locale::_Impl::_M_construct_time(const char* __s)
{
_M_facet_init(new time_get_byname<char>(__s, 0));
_M_facet_init(new time_put_byname<char>(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_facet_init(new time_get_byname<wchar_t>(__s, 0));
_M_facet_init(new time_put_byname<wchar_t>(__s, 0));
#endif
}
void
locale::_Impl::_M_construct_messages(const char* __s)
{
_M_facet_init(new messages_byname<char>(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_facet_init(new messages_byname<wchar_t>(__s, 0));
#endif
facet*& __fpr = (*_M_facets)[__index];
if (__fpr)
{
// Replacing an existing facet.
// Order matters, here:
__fp->_M_add_reference();
if (__fpr)
__fpr->_M_remove_reference();
__fpr = __fp;
}
else
{
// Installing a newly created facet into an empty
// _M_facets container, say a newly-constructed,
// swanky-fresh _Impl.
(*_M_facets)[__index] = __fp;
}
}
}
}

View File

@ -1,6 +1,6 @@
// 2000-09-13 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2000 Free Software Foundation
// Copyright (C) 2000, 2001 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
@ -33,6 +33,14 @@ typedef std::codecvt_byname<wchar_t, char, std::mbstate_t> w_codecvt_byname;
class gnu_codecvt: public c_codecvt { };
class gnu_facet: public std::locale::facet
{
public:
static std::locale::id id;
};
std::locale::id gnu_facet::id;
void test01()
{
using namespace std;
@ -65,14 +73,7 @@ void test01()
{ VERIFY( false ); }
try
{ VERIFY (has_facet<c_codecvt_byname>(loc02)); }
catch(bad_cast& obj)
{ VERIFY( true ); }
catch(...)
{ VERIFY( false ); }
try
{ VERIFY (has_facet<w_codecvt_byname>(loc02)); }
{ use_facet<gnu_facet>(loc02); }
catch(bad_cast& obj)
{ VERIFY( true ); }
catch(...)
@ -92,14 +93,7 @@ void test01()
{ VERIFY( false ); }
try
{ VERIFY (has_facet<c_codecvt_byname>(loc13)); }
catch(bad_cast& obj)
{ VERIFY( true ); }
catch(...)
{ VERIFY( false ); }
try
{ VERIFY (has_facet<w_codecvt_byname>(loc13)); }
{ use_facet<gnu_facet>(loc13); }
catch(bad_cast& obj)
{ VERIFY( true ); }
catch(...)
@ -134,32 +128,99 @@ void test01()
// 4
// locale(const locale& other, const char* std_name, category)
locale loc09(loc06, "C", locale::ctype);
VERIFY (loc09.name() != "fr_FR");
VERIFY (loc09.name() != "C");
VERIFY (loc09 != loc01);
VERIFY (loc09 != loc06);
// XXX somehow check that the ctype, codecvt facets have "C" locale bits...
{
// This is the same as 5 only use "C" for loc("C")
locale loc09(loc06, "C", locale::ctype);
VERIFY (loc09.name() != "fr_FR");
VERIFY (loc09.name() != "C");
VERIFY (loc09.name() != "*");
VERIFY (loc09 != loc01);
VERIFY (loc09 != loc06);
locale loc10(loc02, "C", locale::ctype);
VERIFY (loc10.name() == "*");
VERIFY (loc10 != loc01); // As not named, even tho facets same...
VERIFY (loc10 != loc02);
// XXX somehow check that the ctype, codecvt facets have "C" locale bits...
locale loc10(loc02, "C", locale::ctype);
VERIFY (loc10.name() == "*");
VERIFY (loc10 != loc01); // As not named, even tho facets same...
VERIFY (loc10 != loc02);
locale loc11(loc01, "C", locale::ctype);
VERIFY (loc11.name() == "C");
VERIFY (loc11 == loc01);
// XXX somehow check that the ctype, codecvt facets have "C" locale bits...
locale loc11(loc01, "C", locale::ctype);
VERIFY (loc11.name() == "C");
VERIFY (loc11 == loc01);
try
{ locale loc12(loc01, static_cast<const char*>(NULL), locale::ctype); }
catch(runtime_error& obj)
{ VERIFY (true); }
catch(...)
{ VERIFY (false); }
try
{ locale loc12(loc01, static_cast<const char*>(NULL), locale::ctype); }
catch(runtime_error& obj)
{ VERIFY (true); }
catch(...)
{ VERIFY (false); }
try
{ locale loc13(loc01, "localized by the wu-tang clan", locale::ctype); }
catch(runtime_error& obj)
{ VERIFY (true); }
catch(...)
{ VERIFY (false); }
locale loc14(loc06, "C", locale::none);
VERIFY (loc14.name() == "fr_FR");
VERIFY (loc14 == loc06);
locale loc15(loc06, "C", locale::collate);
VERIFY (loc15.name() != "fr_FR");
VERIFY (loc15.name() != "C");
VERIFY (loc15.name() != "*");
VERIFY (loc15.name() != loc09.name());
VERIFY (loc15 != loc01);
VERIFY (loc15 != loc06);
VERIFY (loc15 != loc09);
}
// 5
// locale(const locale& other, const locale& one, category)
{
// This is the exact same as 4, with locale("C") for "C"
locale loc09(loc06, loc01, locale::ctype);
VERIFY (loc09.name() != "fr_FR");
VERIFY (loc09.name() != "C");
VERIFY (loc09.name() != "*");
VERIFY (loc09 != loc01);
VERIFY (loc09 != loc06);
locale loc10(loc02, loc01, locale::ctype);
VERIFY (loc10.name() == "*");
VERIFY (loc10 != loc01); // As not named, even tho facets same...
VERIFY (loc10 != loc02);
locale loc11(loc01, loc01, locale::ctype);
VERIFY (loc11.name() == "C");
VERIFY (loc11 == loc01);
try
{ locale loc12(loc01, static_cast<const char*>(NULL), locale::ctype); }
catch(runtime_error& obj)
{ VERIFY (true); }
catch(...)
{ VERIFY (false); }
try
{ locale loc13(loc01, locale("wu-tang clan"), locale::ctype); }
catch(runtime_error& obj)
{ VERIFY (true); }
catch(...)
{ VERIFY (false); }
locale loc14(loc06, loc01, locale::none);
VERIFY (loc14.name() == "fr_FR");
VERIFY (loc14 == loc06);
locale loc15(loc06, loc01, locale::collate);
VERIFY (loc15.name() != "fr_FR");
VERIFY (loc15.name() != "C");
VERIFY (loc15.name() != "*");
VERIFY (loc15.name() != loc09.name());
VERIFY (loc15 != loc01);
VERIFY (loc15 != loc06);
VERIFY (loc15 != loc09);
}
}
#endif /* !defined(_GLIBCPP_USE_WCHAR_T) */

View File

@ -22,6 +22,8 @@
#include <cwchar> // for mbstate_t
#include <locale>
#include <stdexcept>
#include <string>
#include <iterator>
#include <debug_assert.h>
@ -169,37 +171,66 @@ std::locale::id gnu_facet::id;
void test01()
{
// 1
gnu_collate obj01;
gnu_ctype obj02;
gnu_codecvt obj03;
gnu_moneypunct obj04;
gnu_moneypunct_true obj05;
gnu_money_get obj06;
gnu_money_put obj07;
gnu_numpunct obj08;
gnu_num_get obj09;
gnu_num_put obj10;
gnu_time_get obj11;
gnu_time_put obj12;
gnu_messages obj13;
gnu_time_put_out obj14(0);
gnu_time_put_byname obj15("gnu_message_byname", 0);
gnu_time_get_in obj16(0);
gnu_time_get_byname obj17("gnu_message_byname", 0);
gnu_num_put_out obj18(0);
gnu_num_get_in obj19(0);
gnu_numpunct_byname obj20("gnu_message_byname", 0);
gnu_money_put_out obj21(0);
gnu_money_get_in obj22(0);
gnu_moneypunct_byname_false obj23("gnu_message_byname", 0);
gnu_moneypunct_byname_true obj24("gnu_message_byname", 0);
gnu_ctype_byname obj25("gnu_message_byname", 0);
gnu_collate_byname obj26("gnu_message_byname", 0);
gnu_messages_byname obj27("gnu_message_byname", 0);
bool test = true;
const std::string name_no("*");
const std::string name_c("C");
try
{
gnu_collate obj01;
gnu_ctype obj02;
gnu_codecvt obj03;
gnu_moneypunct obj04;
gnu_moneypunct_true obj05;
gnu_money_get obj06;
gnu_money_put obj07;
gnu_numpunct obj08;
gnu_num_get obj09;
gnu_num_put obj10;
gnu_time_get obj11;
gnu_time_put obj12;
gnu_messages obj13;
gnu_time_put_out obj14(0);
gnu_time_put_byname obj15("C", 0);
gnu_time_get_in obj16(0);
gnu_time_get_byname obj17("C", 0);
gnu_num_put_out obj18(0);
gnu_num_get_in obj19(0);
gnu_numpunct_byname obj20("C", 0);
gnu_money_put_out obj21(0);
gnu_money_get_in obj22(0);
gnu_moneypunct_byname_false obj23("C", 0);
gnu_moneypunct_byname_true obj24("C", 0);
gnu_ctype_byname obj25("C", 0);
gnu_collate_byname obj26("C", 0);
gnu_messages_byname obj27("C", 0);
}
catch (std::runtime_error& obj)
{
// named locale not valid
VERIFY( false );
}
catch (std::exception& obj)
{
// some other error
VERIFY( false );
}
// 2
gnu_facet obj28;
try
{
gnu_facet obj28;
}
catch (std::runtime_error& obj)
{
// named locale not valid
VERIFY( false );
}
catch (std::exception& obj)
{
// some other error
VERIFY( false );
}
}
int main ()

View File

@ -0,0 +1,140 @@
// 2001-01-19 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.3.1.1 numpunct members
#include <locale>
#include <string>
#include <debug_assert.h>
// creating unnamed locales 1 using new + combine
void
test01()
{
using namespace std;
bool test = true;
const string name_c("C");
const string str_unnamed("*");
string str;
// construct a locale object with the specialized facet.
locale loc_c = locale::classic();
locale loc_1(locale::classic(), new numpunct<char>);
// check names
VERIFY( loc_c.name() == name_c );
VERIFY( loc_1.name() == str_unnamed );
// sanity check the constructed locale has the specialized facet.
VERIFY( has_facet<numpunct<char> >(loc_1) );
VERIFY( has_facet<numpunct<char> >(loc_c) );
// extract facet
const numpunct<char>& f_nump_1 = use_facet<numpunct<char> >(loc_1);
const numpunct<char>& f_nump_c = use_facet<numpunct<char> >(loc_c);
// attempt to re-synthesize classic locale
locale loc_2 = loc_1.combine<numpunct<char> >(loc_c);
VERIFY( loc_2.name() == str_unnamed );
VERIFY( loc_2 != loc_c );
}
void
test02()
{
using namespace std;
bool test = true;
const string name_c("C");
const string name_no("*");
string str;
// construct a locale object with the specialized facet.
locale loc_c = locale::classic();
locale loc_1(locale::classic(),
new numpunct_byname<char>("fr_FR"));
locale loc_fr("fr_FR");
// check names
VERIFY( loc_c.name() == name_c );
VERIFY( loc_1.name() == name_no );
// sanity check the constructed locale has the specialized facet.
VERIFY( has_facet<numpunct<char> >(loc_1) );
VERIFY( has_facet<numpunct<char> >(loc_c) );
// attempt to re-synthesize classic locale
locale loc_2 = loc_1.combine<numpunct<char> >(loc_c);
VERIFY( loc_2.name() == name_no );
VERIFY( loc_2 != loc_c );
// extract facet
const numpunct<char>& f_nump_1 = use_facet<numpunct<char> >(loc_1);
const numpunct<char>& f_nump_2 = use_facet<numpunct<char> >(loc_2);
const numpunct<char>& f_nump_c = use_facet<numpunct<char> >(loc_c);
const numpunct<char>& f_nump_fr = use_facet<numpunct<char> >(loc_fr);
// sanity check the data is correct.
char dp1 = f_nump_c.decimal_point();
char th1 = f_nump_c.thousands_sep();
string g1 = f_nump_c.grouping();
string t1 = f_nump_c.truename();
string f1 = f_nump_c.falsename();
char dp2 = f_nump_1.decimal_point();
char th2 = f_nump_1.thousands_sep();
string g2 = f_nump_1.grouping();
string t2 = f_nump_1.truename();
string f2 = f_nump_1.falsename();
char dp3 = f_nump_2.decimal_point();
char th3 = f_nump_2.thousands_sep();
string g3 = f_nump_2.grouping();
string t3 = f_nump_2.truename();
string f3 = f_nump_2.falsename();
char dp4 = f_nump_fr.decimal_point();
char th4 = f_nump_fr.thousands_sep();
string g4 = f_nump_fr.grouping();
string t4 = f_nump_fr.truename();
string f4 = f_nump_fr.falsename();
#if 0
// XXX these should not be the same if named locales are working correctly.
VERIFY( dp1 != dp2 );
VERIFY( th1 != th2 );
#endif
VERIFY( dp1 == dp3 );
VERIFY( th1 == th3 );
VERIFY( t1 == t3 );
VERIFY( f1 == f3 );
}
int main()
{
test01();
test02();
return 0;
}

View File

@ -0,0 +1,34 @@
// 2001-01-23 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.3 the numeric punctuation facet
#include <locale>
// Should be able to instantiate this for other types besides char, wchar_t
class gnu_numpunct: public std::numpunct<unsigned char>
{ };
int main()
{
gnu_numpunct facet01;
return 0;
}

View File

@ -0,0 +1,73 @@
// 2001-01-24 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.3.2 Template class numpunct_byname
#include <locale>
#include <debug_assert.h>
void test01()
{
using namespace std;
bool test = true;
string str;
locale loc_byname(locale::classic(), new numpunct_byname<char>("de_DE"));
str = loc_byname.name();
locale loc_de("de_DE");
str = loc_de.name();
VERIFY( loc_de != loc_byname );
// cache the numpunct facets
const numpunct<char>& nump_byname = use_facet<numpunct<char> >(loc_byname);
const numpunct<char>& nump_de = use_facet<numpunct<char> >(loc_de);
// sanity check that the data match
char dp1 = nump_byname.decimal_point();
char th1 = nump_byname.thousands_sep();
string g1 = nump_byname.grouping();
string t1 = nump_byname.truename();
string f1 = nump_byname.falsename();
char dp2 = nump_de.decimal_point();
char th2 = nump_de.thousands_sep();
string g2 = nump_de.grouping();
string t2 = nump_de.truename();
string f2 = nump_de.falsename();
VERIFY( dp1 == dp2 );
VERIFY( th1 == th2 );
VERIFY( g1 == g2 );
VERIFY( t1 == t2 );
VERIFY( f1 == f2 );
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,91 @@
// 2001-01-17 bkoz
// Copyright (C) 2001 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.3.1.1 nunpunct members
#include <locale>
#include <debug_assert.h>
void test01()
{
using namespace std;
bool test = true;
string str;
// basic construction
locale loc_c = locale::classic();
str = loc_c.name();
locale loc_us("en_US");
str = loc_us.name();
VERIFY( loc_c != loc_us );
locale loc_fr("fr_FR");
str = loc_fr.name();
VERIFY( loc_c != loc_fr );
VERIFY( loc_us != loc_fr );
locale loc_combo(loc_us, loc_fr, locale::numeric);
str = loc_combo.name();
VERIFY( loc_combo != loc_fr );
VERIFY( loc_combo != loc_us );
VERIFY( loc_combo != loc_c );
// cache the numpunct facets
const numpunct<char>& nump_c = use_facet<numpunct<char> >(loc_c);
const numpunct<char>& nump_us = use_facet<numpunct<char> >(loc_us);
const numpunct<char>& nump_fr = use_facet<numpunct<char> >(loc_fr);
const numpunct<char>& nump_combo = use_facet<numpunct<char> >(loc_combo);
// sanity check the data is correct.
char dp1 = nump_c.decimal_point();
char th1 = nump_c.thousands_sep();
string g1 = nump_c.grouping();
string t1 = nump_c.truename();
string f1 = nump_c.falsename();
char dp2 = nump_us.decimal_point();
char th2 = nump_us.thousands_sep();
string g2 = nump_us.grouping();
string t2 = nump_us.truename();
string f2 = nump_us.falsename();
char dp3 = nump_fr.decimal_point();
char th3 = nump_fr.thousands_sep();
string g3 = nump_fr.grouping();
string t3 = nump_fr.truename();
string f3 = nump_fr.falsename();
char dp4 = nump_combo.decimal_point();
char th4 = nump_combo.thousands_sep();
string g4 = nump_combo.grouping();
string t4 = nump_combo.truename();
string f4 = nump_combo.falsename();
}
int main()
{
test01();
return 0;
}