#include <clocale>
#include <cstring>
#include <locale>
#include <vector>
#include <stdexcept>
namespace std
{
locale::_Impl::
~_Impl() throw()
{
__vec_facet::iterator it = _M_facets->begin();
for (; it != _M_facets->end(); ++it)
if (*it)
(*it)->_M_remove_reference();
delete _M_facets;
}
locale::_Impl::
_Impl(const _Impl& __imp, size_t __refs)
: _M_references(__refs), _M_facets(0) {
try
{ _M_facets = new __vec_facet(*(__imp._M_facets)); }
catch(...)
{
delete _M_facets;
__throw_exception_again;
}
for (size_t i = 0; i < _S_num_categories; ++i)
_M_names[i] = __imp._M_names[i];
__vec_facet::iterator __it = _M_facets->begin();
for (; __it != _M_facets->end(); ++__it)
if (*__it)
(*__it)->_M_add_reference();
}
locale::_Impl::
_Impl(string __str, size_t __refs)
: _M_references(__refs), _M_facets(0)
{
__c_locale __cloc;
locale::facet::_S_create_c_locale(__cloc, __str.c_str());
__c_locale __cloc_c = NULL;
if (__str != "C" && __str != "POSIX")
__cloc_c = __cloc;
try
{ _M_facets = new __vec_facet(_S_num_facets, NULL); }
catch(...)
{
delete _M_facets;
__throw_exception_again;
}
for (size_t i = 0; i < _S_num_categories; ++i)
_M_names[i] = __str;
_M_init_facet(new std::collate<char>(__cloc));
_M_init_facet(new std::ctype<char>(__cloc));
_M_init_facet(new codecvt<char, char, mbstate_t>);
_M_init_facet(new moneypunct<char, false>(__cloc_c));
_M_init_facet(new moneypunct<char, true>(__cloc_c));
_M_init_facet(new money_get<char>);
_M_init_facet(new money_put<char>);
_M_init_facet(new numpunct<char>(__cloc_c));
_M_init_facet(new num_get<char>);
_M_init_facet(new num_put<char>);
_M_init_facet(new __timepunct<char>(__cloc_c, __str.c_str()));
_M_init_facet(new time_get<char>);
_M_init_facet(new time_put<char>);
_M_init_facet(new std::messages<char>(__cloc, __str.c_str()));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_init_facet(new std::collate<wchar_t>(__cloc));
_M_init_facet(new std::ctype<wchar_t>(__cloc));
_M_init_facet(new codecvt<wchar_t, char, mbstate_t>);
_M_init_facet(new moneypunct<wchar_t, false>(__cloc_c));
_M_init_facet(new moneypunct<wchar_t, true>(__cloc_c));
_M_init_facet(new money_get<wchar_t>);
_M_init_facet(new money_put<wchar_t>);
_M_init_facet(new numpunct<wchar_t>(__cloc_c));
_M_init_facet(new num_get<wchar_t>);
_M_init_facet(new num_put<wchar_t>);
_M_init_facet(new __timepunct<wchar_t>(__cloc_c, __str.c_str()));
_M_init_facet(new time_get<wchar_t>);
_M_init_facet(new time_put<wchar_t>);
_M_init_facet(new std::messages<wchar_t>(__cloc, __str.c_str()));
#endif
locale::facet::_S_destroy_c_locale(__cloc);
}
void
locale::_Impl::
_M_replace_categories(const _Impl* __imp, category __cat)
{
const string __none("*");
category __mask;
for (unsigned int __ix = 0; __ix < _S_num_categories; ++__ix)
{
__mask = 1 << __ix;
if (__mask & __cat)
{
_M_replace_category(__imp, _S_facet_categories[__ix]);
if (_M_names[__ix] != __none && __imp->_M_names[__ix] != __none)
_M_names[__ix] = __imp->_M_names[__ix];
}
}
}
void
locale::_Impl::
_M_replace_category(const _Impl* __imp, const locale::id* const* __idpp)
{
for (; *__idpp; ++__idpp)
_M_replace_facet(__imp, *__idpp);
}
void
locale::_Impl::
_M_replace_facet(const _Impl* __imp, const locale::id* __idp)
{
size_t __index = __idp->_M_index;
if (__index == 0
|| __imp->_M_facets->size() <= __index
|| (*(__imp->_M_facets))[__index] == 0)
__throw_runtime_error("no locale facet");
_M_install_facet(__idp, (*(__imp->_M_facets))[__index]);
}
void
locale::_Impl::
_M_install_facet(const locale::id* __idp, facet* __fp)
{
if (__fp)
{
size_t& __index = __idp->_M_index;
if (!__index)
__index = ++locale::id::_S_highwater;
if (__index >= _M_facets->size())
_M_facets->resize(__index + 1, 0);
facet*& __fpr = (*_M_facets)[__index];
if (__fpr)
{
__fp->_M_add_reference();
__fpr->_M_remove_reference();
__fpr = __fp;
}
else
{
(*_M_facets)[__index] = __fp;
}
}
}
}