#ifdef _GLIBCPP_USE_WCHAR_T
#include <bits/std_cwctype.h> // for towupper, etc.
#endif
+
namespace std {
// Definitions for static const data members of locale.
return __incl_prec;
}
- // locale::_Impl
- locale::_Impl::
- ~_Impl() throw()
- {
- std::vector<facet*>::iterator it = _M_facets->begin();
- for (; it != _M_facets->end(); ++it)
- (*it)->_M_remove_reference();
- delete _M_facets;
- delete _M_category_names;
- }
- locale::_Impl::
- _Impl(size_t __numfacets, size_t __refs)
- : _M_num_references(__refs - 1), _M_facets(0), _M_category_names(0),
- _M_has_name(false), _M_cached_name_ok(false), _M_cached_name(string ("*"))
- {
- typedef vector<facet*, allocator<facet*> > __vec_facet;
- typedef vector<string, allocator<string> > __vec_string;
-
- auto_ptr<__vec_facet> __pvf(new __vec_facet(__numfacets, (facet*)0));
- auto_ptr<__vec_string> __pcn(new __vec_string(_S_num_categories,
- string("*")));
- _M_facets = __pvf.release();
- _M_category_names = __pcn.release();
- }
-
- locale::_Impl::
- _Impl(const _Impl& __other, size_t __refs)
- : _M_num_references(__refs), _M_facets(0), _M_category_names(0),
- _M_has_name(__other._M_has_name),
- _M_cached_name_ok(__other._M_cached_name_ok),
- _M_cached_name(__other._M_cached_name)
+ locale::locale(const char* __name)
{
- typedef vector<facet*, allocator<facet*> > __vec_facet;
- typedef vector<string, allocator<string> > __vec_string;
-
- auto_ptr<__vec_facet> __pvf(new __vec_facet(*(__other._M_facets)));
- auto_ptr<__vec_string>
- __pcn(new __vec_string(*(__other._M_category_names)));
-
- std::vector<facet*>::iterator __it = __pvf->begin();
- for (; __it != __pvf->end(); ++__it)
- (*__it)->_M_add_reference();
-
- // These must be last since in the presence of an exception, the
- // destructor for 'this' won't run until AFTER execution has passed
- // the closing brace of the constructor.
- _M_facets = __pvf.release();
- _M_category_names = __pcn.release();
- }
-
- void
- locale::_Impl::
- _M_replace_categories(const _Impl* __other, category __cats)
- {
- assert((__cats & locale::all) && !(__cats & ~locale::all));
-
- unsigned mask = (locale::all & -(unsigned)locale::all);
- for (unsigned ix = 0; (-mask & __cats) != 0; ++ix, (mask <<= 1))
+ _S_initialize();
+ if (strcmp(__name, "C") == 0 || strcmp(__name, "POSIX") == 0)
+ (_M_impl = _S_classic)->_M_add_reference();
+ else
{
- if (mask & __cats)
- {
- _M_replace_category(__other, _S_facet_categories[ix]);
- (*_M_category_names)[ix] = (*(__other->_M_category_names))[ix];
- }
+ // Might throw:
+ _M_impl = new _Impl(*_S_classic, __name, all, 1);
+ _M_impl->_M_has_name = true;
}
}
- void
- locale::_Impl::
- _M_replace_category(const _Impl* __other, const locale::id* const* __idpp)
- {
- for (; *__idpp; ++__idpp)
- _M_replace_facet(__other, *__idpp);
- }
-
- void
- locale::_Impl::
- _M_replace_facet(const _Impl* __other, const locale::id* __idp)
- {
- size_t __index = __idp->_M_index;
- if (__index == 0
- || __other->_M_facets->size() <= __index
- || (*(__other->_M_facets))[__index] == 0)
- throw runtime_error("no locale facet");
-
- _M_install_facet(__idp, (*(__other->_M_facets))[__index]);
- }
+ locale::locale(const locale& __other, const char* __name, category __cat)
+ : _M_impl(new _Impl(*__other._M_impl, __name, _S_normalize_category(__cat), 1))
+ { }
- void
- locale::_Impl::
- _M_install_facet(const locale::id* __idp, facet* __fp)
+ bool
+ locale::operator==(const locale& __rhs) const throw()
{
- if (__fp == 0)
- return;
-
- 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;
+ return((this->name() != "*" && this->name() == __rhs.name())
+ || _M_impl == __rhs._M_impl);
}
-
+
locale::locale(_Impl* __ip) throw()
: _M_impl(__ip)
{ __ip->_M_add_reference(); }
- locale::locale(const locale& __other, const locale& __one, category __cats)
+ locale::locale(const locale& __other, const locale& __one, category __cat)
{
- __cats = _S_normalize_category(__cats); // might throw
+ __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, __cats);
+ _M_impl->_M_replace_categories(__one._M_impl, __cat);
}
catch (...) {
_M_impl->_M_remove_reference();
throw;
}
- _M_impl->_M_cached_name_ok = false;
+ // XXX
+ // _M_impl->_M_cached_name_ok = false;
if (!__other._M_impl->_M_has_name)
_M_impl->_M_has_name = false;
}
string
locale::name() const
- {
- // XXX not done
- return "*";
- }
+ { return _M_impl->_M_name; }
locale const&
locale::classic()
try {
// 26 Standard facets, 2 references.
// One reference for _M_classic, one for _M_global
- _S_classic = _S_global = new _Impl(26, 2);
+ _S_classic = new _Impl(26, 2, true, "C");
+ _S_global = _S_classic;
// collate category
_S_classic->_M_facet_init(new std::collate<char>);
}
int
- locale::_S_normalize_category(int __cats)
+ locale::_S_normalize_category(int __cat)
{
- if ((__cats & all) && !(__cats & ~all))
- return __cats;
-
- // NB: May be a C-style "LC_ALL" category; convert.
- switch (__cats)
+ int __ret;
+ if ((__cat & all) && !(__cat & ~all))
+ __ret = __cat;
+ else
{
- case LC_COLLATE: return collate;
- case LC_CTYPE: return ctype;
- case LC_MONETARY: return monetary;
- case LC_NUMERIC: return numeric;
- case LC_TIME: return time;
+ // 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: return messages;
+ case LC_MESSAGES:
+ __ret = messages;
+ break;
#endif
- case LC_ALL: return all;
+ case LC_ALL:
+ __ret = all;
+ break;
+ default:
+ throw runtime_error("bad locale category");
+ }
}
-
- // XXX Should throw derived class here
- throw runtime_error("bad locale category");
- /* NOTREACHED */
+ return __ret;
}
locale::facet::
facet(size_t __refs) throw()
- : _M_num_references(__refs - 1)
+ : _M_references(__refs - 1)
{ }
void
_M_add_reference() throw()
{
if (this)
- ++_M_num_references;
+ ++_M_references;
} // XXX MT
void
locale::facet::
_M_remove_reference() throw()
{
- if (this && _M_num_references-- == 0)
+ if (this && _M_references-- == 0)
{
try {
delete this;
-
-// Copyright (C) 1997-1999 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
#include <bits/std_cstring.h>
#include <bits/std_cassert.h>
#include <bits/std_vector.h>
+#include <bits/std_stdexcept.h>
namespace std {
-/////////////////////////////
-// locale::_Impl constructors
-/////////////////////////////
+ locale::_Impl::
+ ~_Impl() throw()
+ {
+ std::vector<facet*>::iterator it = _M_facets->begin();
+ for (; it != _M_facets->end(); ++it)
+ (*it)->_M_remove_reference();
+ delete _M_facets;
+ delete _M_category_names;
+ }
- // construct specific categories, leaving unselected ones alone
- //////////
- locale::_Impl::_Impl(const _Impl& other,const string& name, category cats,
- size_t refs)
- : _M_num_references(refs)
+ // This constructor is used to correctly initialize the standard,
+ // required facets.
+ locale::_Impl::
+ _Impl(size_t __numfacets, size_t __refs, bool __has_name = false,
+ string __name = "*")
+ : _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
+ _M_has_name(__has_name), _M_name(__name)
+ {
+ typedef vector<facet*, allocator<facet*> > __vec_facet;
+ typedef vector<string, allocator<string> > __vec_string;
+
+ auto_ptr<__vec_facet> __pvf(new __vec_facet(__numfacets, (facet*)0));
+ auto_ptr<__vec_string> __pcn(new __vec_string(_S_num_categories, _M_name));
+ _M_facets = __pvf.release();
+ _M_category_names = __pcn.release();
+ }
+
+ locale::_Impl::
+ _Impl(const _Impl& __other, size_t __refs)
+ : _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
+ _M_has_name(__other._M_has_name), _M_name(__other._M_name)
+ {
+ typedef vector<facet*, allocator<facet*> > __vec_facet;
+ typedef vector<string, allocator<string> > __vec_string;
+
+ auto_ptr<__vec_facet> __pvf(new __vec_facet(*(__other._M_facets)));
+ auto_ptr<__vec_string>
+ __pcn(new __vec_string(*(__other._M_category_names)));
+
+ std::vector<facet*>::iterator __it = __pvf->begin();
+ for (; __it != __pvf->end(); ++__it)
+ (*__it)->_M_add_reference();
+
+ // These must be last since in the presence of an exception, the
+ // destructor for 'this' won't run until AFTER execution has passed
+ // the closing brace of the constructor.
+ _M_facets = __pvf.release();
+ _M_category_names = __pcn.release();
+ }
+
+ // Construct specific categories, leaving unselected ones alone
+ locale::_Impl::
+ _Impl(const _Impl& __other, const string& __name, category __cat,
+ size_t __refs)
+ : _M_references(__refs - 1)
// , _M_facets(other._M_facets)
// , _M_category_names(other._M_category_names)
- , _M_has_name(other._M_has_name), _M_cached_name_ok(false)
+ , _M_has_name(__other._M_has_name), _M_name(__other._M_name)
{
#if 1
typedef vector<facet*, allocator<facet*> > __vec_facet;
typedef vector<string, allocator<string> > __vec_string;
try {
- _M_facets = new __vec_facet(*(other._M_facets));
+ _M_facets = new __vec_facet(*(__other._M_facets));
}
catch (...) {
delete _M_facets;
throw;
}
try {
- _M_category_names = new __vec_string(*(other._M_category_names));
+ _M_category_names = new __vec_string(*(__other._M_category_names));
}
catch (...) {
delete _M_category_names;
// static void(_Impl::* const ctors[]) (const char*) =
static void(_Impl::* ctors[]) (const char*) =
{
- // NB: order must match the decl order in class locale.
+ // NB: Order must match the decl order in class locale.
&locale::_Impl::_M_construct_collate,
&locale::_Impl::_M_construct_ctype,
&locale::_Impl::_M_construct_monetary,
};
_S_initialize();
- std::vector<facet*>::iterator it = _M_facets->begin();
- for (; it != _M_facets->end(); ++it)
- (*it)->_M_add_reference();
+ std::vector<facet*>::iterator __it = _M_facets->begin();
+ for (; __it != _M_facets->end(); ++__it)
+ (*__it)->_M_add_reference();
try {
- category classix = _S_normalize_category(cats); // might throw
- _M_normalize_category_names(name, classix);
+ category __ccategory = _S_normalize_category(__cat); // might throw
+ _M_normalize_category_names(__name, __ccategory);
unsigned mask = (locale::all & -(unsigned)locale::all);
- for (unsigned ix = 0; (-mask & cats) != 0; ++ix, (mask <<= 1))
+ for (unsigned ix = 0; (-mask & __cat) != 0; ++ix, (mask <<= 1))
{
- if (!(mask & cats))
+ if (!(mask & __cat))
continue;
- if (mask & classix)
+ if (mask & __ccategory)
_M_replace_category(_S_classic, _S_facet_categories[ix]);
else
- (this->*ctors[ix]) (name.c_str());
+ (this->*ctors[ix]) (__name.c_str());
}
}
catch (...) {
- it = _M_facets->begin();
- for (; it != _M_facets->end(); ++it)
- (*it)->_M_remove_reference();
+ __it = _M_facets->begin();
+ for (; __it != _M_facets->end(); ++__it)
+ (*__it)->_M_remove_reference();
throw;
}
}
+
+ void
+ locale::_Impl::
+ _M_replace_categories(const _Impl* __other, category __cat)
+ {
+ assert((__cat & locale::all) && !(__cat & ~locale::all));
+
+ unsigned int __mask = locale::all & -static_cast<unsigned int>(locale::all);
+ for (unsigned int __ix = 0; (-__mask & __cat) != 0; ++__ix, (__mask <<= 1))
+ {
+ if (__mask & __cat)
+ {
+ _M_replace_category(__other, _S_facet_categories[__ix]);
+ (*_M_category_names)[__ix] = (*(__other->_M_category_names))[__ix];
+ }
+ }
+ }
+
+ void
+ locale::_Impl::
+ _M_replace_category(const _Impl* __other, const locale::id* const* __idpp)
+ {
+ for (; *__idpp; ++__idpp)
+ _M_replace_facet(__other, *__idpp);
+ }
+
+ void
+ locale::_Impl::
+ _M_replace_facet(const _Impl* __other, const locale::id* __idp)
+ {
+ size_t __index = __idp->_M_index;
+ if (__index == 0
+ || __other->_M_facets->size() <= __index
+ || (*(__other->_M_facets))[__index] == 0)
+ throw runtime_error("no locale facet");
+
+ _M_install_facet(__idp, (*(__other->_M_facets))[__index]);
+ }
+
+ void
+ locale::_Impl::
+ _M_install_facet(const locale::id* __idp, facet* __fp)
+ {
+ if (__fp == 0)
+ return;
+
+ 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;
+ }
+
locale::category
locale::_Impl::_M_normalize_category_names(const string&,
- locale::category cats)
+ locale::category __cat)
{
-
// The problem to be solved here is that locale names
- // generally have one of two forms: they might have
- // only one component, such as "en_US"; or they might
- // have six, such as "en_US fr_FR en_US C C C", where
- // each component names a category. Each vendor has
- // a different order of categories. Each vendor uses
- // a different format:
- // AIX uses "C C C C C C"
- // Sun uses "/C/C/C/C/C/C"
- // HP uses "/0:C;1:C;2:C;3:C;4:C;5:C;6:C;/"
- // (where the 0th element is for LC_ALL.)
- // Most systems (except AIX) permit the long form only for
- // setlocale(LC_ALL,...), and require the short form for
- // other calls. All this matters because locale names are
- // supposed to be compatible between locale("") and
- // setlocale(..., "") constructors.
+ // generally have one of two forms: they might have
+ // only one component, such as "en_US"; or they might
+ // have six, such as "en_US fr_FR en_US C C C", where
+ // each component names a category. Each vendor has
+ // a different order of categories. Each vendor uses
+ // a different format:
+ // AIX uses "C C C C C C"
+ // Sun uses "/C/C/C/C/C/C"
+ // HP uses "/0:C;1:C;2:C;3:C;4:C;5:C;6:C;/"
+ // (where the 0th element is for LC_ALL.)
+ // Most systems (except AIX) permit the long form only for
+ // setlocale(LC_ALL,...), and require the short form for
+ // other calls. All this matters because locale names are
+ // supposed to be compatible between locale("") and
+ // setlocale(..., "") constructors.
- return cats;
+ return __cat;
#if 0 /* XXX not done */
unsigned mask = (locale::all & -(unsigned)locale::all);
- for (unsigned ix = 0; (-mask & cats) != 0; ++ix, (mask <<= 1))
+ for (unsigned ix = 0; (-mask & __cat) != 0; ++ix, (mask <<= 1))
{
}
#endif
}
- //////////
void
- locale::_Impl::_M_construct_collate(const char* /*name*/)
+ locale::_Impl::_M_construct_collate(const char* /*__name*/)
{
#if 0
- _M_facet_init(new std::collate_byname<char>(name));
- _M_facet_init(new std::collate_byname<wchar_t>(name));
+ _M_facet_init(new std::collate_byname<char>(__name));
+ _M_facet_init(new std::collate_byname<wchar_t>(__name));
#endif
}
void
- locale::_Impl::_M_construct_ctype(const char* /*name*/)
+ locale::_Impl::_M_construct_ctype(const char* /*__name*/)
{
#if 0
- _M_facet_init(new std::ctype_byname<char>(name));
- _M_facet_init(new std::ctype_byname<wchar_t>(name));
- _M_facet_init(new std::codecvt_byname<char,char,mbstate_t>(name));
- _M_facet_init(new std::codecvt_byname<wchar_t,char,mbstate_t>(name));
+ _M_facet_init(new std::ctype_byname<char>(__name));
+ _M_facet_init(new std::ctype_byname<wchar_t>(__name));
+ _M_facet_init(new std::codecvt_byname<char, char, mbstate_t>(__name));
+ _M_facet_init(new std::codecvt_byname<wchar_t, char, mbstate_t>(__name));
#endif
}
void
- locale::_Impl::_M_construct_monetary(const char* /*name*/)
+ locale::_Impl::_M_construct_monetary(const char* /*__name*/)
{
#if 0
- _M_facet_init(new std::moneypunct_byname<char,false>(name));
- _M_facet_init(new std::moneypunct_byname<wchar_t,false>(name));
- _M_facet_init(new std::moneypunct_byname<char,true >(name));
- _M_facet_init(new std::moneypunct_byname<wchar_t,true >(name));
+ _M_facet_init(new std::moneypunct_byname<char, false>(__name));
+ _M_facet_init(new std::moneypunct_byname<wchar_t, false>(__name));
+ _M_facet_init(new std::moneypunct_byname<char, true >(__name));
+ _M_facet_init(new std::moneypunct_byname<wchar_t, true >(__name));
locale::_M_initialize();
- _M_replace_facet(locale::_S_classic, &std::money_get<char>(name)::id);
- _M_replace_facet(locale::_S_classic, &std::money_get<wchar_t>(name)::id);
- _M_replace_facet(locale::_S_classic, &std::money_put<char>(name)::id);
- _M_replace_facet(locale::_S_classic, &std::money_put<wchar_t>(name)::id);
+ _M_replace_facet(locale::_S_classic, &std::money_get<char>(__name)::id);
+ _M_replace_facet(locale::_S_classic, &std::money_get<wchar_t>(__name)::id);
+ _M_replace_facet(locale::_S_classic, &std::money_put<char>(__name)::id);
+ _M_replace_facet(locale::_S_classic, &std::money_put<wchar_t>(__name)::id);
#endif
}
void
- locale::_Impl::_M_construct_numeric(const char* /*name*/)
+ locale::_Impl::_M_construct_numeric(const char* /*__name*/)
{
#if 0
- _M_facet_init(new std::numpunct_byname<char>(name));
- _M_facet_init(new std::numpunct_byname<wchar_t>(name));
+ _M_facet_init(new std::numpunct_byname<char>(__name));
+ _M_facet_init(new std::numpunct_byname<wchar_t>(__name));
locale::_M_initialize();
_M_replace_facet(locale::_S_classic, &std::num_get<char>::id);
}
void
- locale::_Impl::_M_construct_time(const char* /*name*/)
+ locale::_Impl::_M_construct_time(const char* /*__name*/)
{
#if 0
- _M_facet_init(new std::time_get_byname<char>(name));
- _M_facet_init(new std::time_get_byname<wchar_t>(name));
- _M_facet_init(new std::time_put_byname<char>(name));
- _M_facet_init(new std::time_put_byname<wchar_t>(name));
+ _M_facet_init(new std::time_get_byname<char>(__name));
+ _M_facet_init(new std::time_get_byname<wchar_t>(__name));
+ _M_facet_init(new std::time_put_byname<char>(__name));
+ _M_facet_init(new std::time_put_byname<wchar_t>(__name));
#endif
}
void
- locale::_Impl::_M_construct_messages(const char* /*name*/)
+ locale::_Impl::_M_construct_messages(const char* /*__name*/)
{
#if 0
- _M_facet_init(new std::messages_byname<char>(name));
- _M_facet_init(new std::messages_byname<wchar_t>(name));
+ _M_facet_init(new std::messages_byname<char>(__name));
+ _M_facet_init(new std::messages_byname<wchar_t>(__name));
#endif
}
+}
- //////////////////////
- // locale constructors
- //////////////////////
-
- ////////
- locale::locale(const char* std_name)
- {
- _S_initialize();
- if (strcmp(std_name, "C") == 0 || strcmp(std_name, "POSIX"))
- (_M_impl = _S_classic)->_M_add_reference();
- else
- {
- // might throw:
- _M_impl = new _Impl(*_S_classic, string(std_name), all, 1);
- _M_impl->_M_has_name = true;
- }
- }
-
- /////////
- locale::locale(const locale& other, const char* std_name, category cats)
- : _M_impl(new _Impl(*other._M_impl, string(std_name),
- _S_normalize_category(cats), 1)) // might throw
- { }
- ///////
- bool
- locale::operator==(const locale& __rhs) const throw()
- {
- return(_M_impl == __rhs._M_impl
- || (this->name() != "*" && this->name() == __rhs.name()));
- }
-}