michael@0: /* michael@0: * Copyright (c) 1999 michael@0: * Silicon Graphics Computer Systems, Inc. michael@0: * michael@0: * Copyright (c) 1999 michael@0: * Boris Fomitchev michael@0: * michael@0: * This material is provided "as is", with absolutely no warranty expressed michael@0: * or implied. Any use is at your own risk. michael@0: * michael@0: * Permission to use or copy this software for any purpose is hereby granted michael@0: * without fee, provided the above notices are retained on all copies. michael@0: * Permission to modify the code and to distribute modified code is granted, michael@0: * provided the above notices are retained, and a notice that the code was michael@0: * modified is included with the above copyright notice. michael@0: * michael@0: */ michael@0: #include "stlport_prefix.h" michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include "c_locale.h" michael@0: #include "aligned_buffer.h" michael@0: #include "acquire_release.h" michael@0: #include "locale_impl.h" michael@0: michael@0: _STLP_BEGIN_NAMESPACE michael@0: michael@0: static const char _Nameless[] = "*"; michael@0: michael@0: static inline bool is_C_locale_name (const char* name) michael@0: { return ((name[0] == 'C') && (name[1] == 0)); } michael@0: michael@0: locale::facet * _STLP_CALL _get_facet(locale::facet *f) michael@0: { michael@0: if (f != 0) michael@0: f->_M_incr(); michael@0: return f; michael@0: } michael@0: michael@0: void _STLP_CALL _release_facet(locale::facet *&f) michael@0: { michael@0: if ((f != 0) && (f->_M_decr() == 0)) { michael@0: delete f; michael@0: f = 0; michael@0: } michael@0: } michael@0: michael@0: size_t locale::id::_S_max = 27; michael@0: michael@0: static void _Stl_loc_assign_ids(); michael@0: michael@0: static _Stl_aligned_buffer<_Locale_impl::Init> __Loc_init_buf; michael@0: michael@0: _Locale_impl::Init::Init() { michael@0: if (_M_count()._M_incr() == 1) { michael@0: _Locale_impl::_S_initialize(); michael@0: } michael@0: } michael@0: michael@0: _Locale_impl::Init::~Init() { michael@0: if (_M_count()._M_decr() == 0) { michael@0: _Locale_impl::_S_uninitialize(); michael@0: } michael@0: } michael@0: michael@0: _Refcount_Base& _Locale_impl::Init::_M_count() const { michael@0: static _Refcount_Base _S_count(0); michael@0: return _S_count; michael@0: } michael@0: michael@0: _Locale_impl::_Locale_impl(const char* s) michael@0: : _Refcount_Base(0), name(s), facets_vec() { michael@0: facets_vec.reserve( locale::id::_S_max ); michael@0: new (&__Loc_init_buf) Init(); michael@0: } michael@0: michael@0: _Locale_impl::_Locale_impl( _Locale_impl const& locimpl ) michael@0: : _Refcount_Base(0), name(locimpl.name), facets_vec() { michael@0: for_each( locimpl.facets_vec.begin(), locimpl.facets_vec.end(), _get_facet); michael@0: facets_vec = locimpl.facets_vec; michael@0: new (&__Loc_init_buf) Init(); michael@0: } michael@0: michael@0: _Locale_impl::_Locale_impl( size_t n, const char* s) michael@0: : _Refcount_Base(0), name(s), facets_vec(n, 0) { michael@0: new (&__Loc_init_buf) Init(); michael@0: } michael@0: michael@0: _Locale_impl::~_Locale_impl() { michael@0: (&__Loc_init_buf)->~Init(); michael@0: for_each( facets_vec.begin(), facets_vec.end(), _release_facet); michael@0: } michael@0: michael@0: // Initialization of the locale system. This must be called before michael@0: // any locales are constructed. (Meaning that it must be called when michael@0: // the I/O library itself is initialized.) michael@0: void _STLP_CALL _Locale_impl::_S_initialize() { michael@0: _Stl_loc_assign_ids(); michael@0: make_classic_locale(); michael@0: } michael@0: michael@0: // Release of the classic locale ressources. Has to be called after the last michael@0: // locale destruction and not only after the classic locale destruction as michael@0: // the facets can be shared between different facets. michael@0: void _STLP_CALL _Locale_impl::_S_uninitialize() { michael@0: //Not necessary anymore as classic facets are now 'normal' dynamically allocated michael@0: //facets with a reference counter telling to _release_facet when the facet can be michael@0: //deleted. michael@0: //free_classic_locale(); michael@0: } michael@0: michael@0: // _Locale_impl non-inline member functions. michael@0: void _STLP_CALL _Locale_impl::_M_throw_bad_cast() { michael@0: _STLP_THROW(bad_cast()); michael@0: } michael@0: michael@0: void _Locale_impl::insert(_Locale_impl *from, const locale::id& n) { michael@0: if (n._M_index > 0 && n._M_index < from->size()) { michael@0: this->insert(from->facets_vec[n._M_index], n); michael@0: } michael@0: } michael@0: michael@0: locale::facet* _Locale_impl::insert(locale::facet *f, const locale::id& n) { michael@0: if (f == 0 || n._M_index == 0) michael@0: return 0; michael@0: michael@0: if (n._M_index >= facets_vec.size()) { michael@0: facets_vec.resize(n._M_index + 1); michael@0: } michael@0: michael@0: if (f != facets_vec[n._M_index]) michael@0: { michael@0: _release_facet(facets_vec[n._M_index]); michael@0: facets_vec[n._M_index] = _get_facet(f); michael@0: } michael@0: michael@0: return f; michael@0: } michael@0: michael@0: // michael@0: // content which is dependent on the name michael@0: // michael@0: michael@0: /* Six functions, one for each category. Each of them takes a michael@0: * a name, constructs that appropriate category facets by name, michael@0: * and inserts them into the locale. */ michael@0: _Locale_name_hint* _Locale_impl::insert_ctype_facets(const char* &name, char *buf, _Locale_name_hint* hint) { michael@0: if (name[0] == 0) michael@0: name = _Locale_ctype_default(buf); michael@0: michael@0: if (name == 0 || name[0] == 0 || is_C_locale_name(name)) { michael@0: _Locale_impl* i2 = locale::classic()._M_impl; michael@0: this->insert(i2, ctype::id); michael@0: this->insert(i2, codecvt::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: this->insert(i2, ctype::id); michael@0: this->insert(i2, codecvt::id); michael@0: #endif michael@0: } else { michael@0: locale::facet* ct = 0; michael@0: locale::facet* cvt = 0; michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: locale::facet* wct = 0; michael@0: locale::facet* wcvt = 0; michael@0: #endif michael@0: int __err_code; michael@0: _Locale_ctype *__lct = _STLP_PRIV __acquire_ctype(name, buf, hint, &__err_code); michael@0: if (!__lct) { michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "ctype"); michael@0: return hint; michael@0: } michael@0: michael@0: if (hint == 0) hint = _Locale_get_ctype_hint(__lct); michael@0: michael@0: _STLP_TRY { michael@0: ct = new ctype_byname(__lct); michael@0: } michael@0: _STLP_UNWIND(_STLP_PRIV __release_ctype(__lct)); michael@0: michael@0: _STLP_TRY { michael@0: cvt = new codecvt_byname(name); michael@0: } michael@0: _STLP_UNWIND(delete ct); michael@0: michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: _STLP_TRY { michael@0: _Locale_ctype *__lwct = _STLP_PRIV __acquire_ctype(name, buf, hint, &__err_code); michael@0: if (!__lwct) { michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "ctype"); michael@0: return hint; michael@0: } michael@0: michael@0: _STLP_TRY { michael@0: wct = new ctype_byname(__lwct); michael@0: } michael@0: _STLP_UNWIND(_STLP_PRIV __release_ctype(__lwct)); michael@0: michael@0: _Locale_codecvt *__lwcvt = _STLP_PRIV __acquire_codecvt(name, buf, hint, &__err_code); michael@0: if (__lwcvt) { michael@0: _STLP_TRY { michael@0: wcvt = new codecvt_byname(__lwcvt); michael@0: } michael@0: _STLP_UNWIND(_STLP_PRIV __release_codecvt(__lwcvt); delete wct); michael@0: } michael@0: } michael@0: _STLP_UNWIND(delete cvt; delete ct); michael@0: #endif michael@0: michael@0: this->insert(ct, ctype::id); michael@0: this->insert(cvt, codecvt::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: this->insert(wct, ctype::id); michael@0: if (wcvt) this->insert(wcvt, codecvt::id); michael@0: #endif michael@0: } michael@0: return hint; michael@0: } michael@0: michael@0: _Locale_name_hint* _Locale_impl::insert_numeric_facets(const char* &name, char *buf, _Locale_name_hint* hint) { michael@0: if (name[0] == 0) michael@0: name = _Locale_numeric_default(buf); michael@0: michael@0: _Locale_impl* i2 = locale::classic()._M_impl; michael@0: michael@0: // We first insert name independant facets taken from the classic locale instance: michael@0: this->insert(i2, michael@0: num_put > >::id); michael@0: this->insert(i2, michael@0: num_get > >::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: this->insert(i2, michael@0: num_get > >::id); michael@0: this->insert(i2, michael@0: num_put > >::id); michael@0: #endif michael@0: michael@0: if (name == 0 || name[0] == 0 || is_C_locale_name(name)) { michael@0: this->insert(i2, numpunct::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: this->insert(i2, numpunct::id); michael@0: #endif michael@0: } michael@0: else { michael@0: locale::facet* punct = 0; michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: locale::facet* wpunct = 0; michael@0: #endif michael@0: michael@0: int __err_code; michael@0: _Locale_numeric *__lpunct = _STLP_PRIV __acquire_numeric(name, buf, hint, &__err_code); michael@0: if (!__lpunct) { michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "numpunct"); michael@0: return hint; michael@0: } michael@0: michael@0: if (hint == 0) hint = _Locale_get_numeric_hint(__lpunct); michael@0: _STLP_TRY { michael@0: punct = new numpunct_byname(__lpunct); michael@0: } michael@0: _STLP_UNWIND(_STLP_PRIV __release_numeric(__lpunct)); michael@0: michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: _Locale_numeric *__lwpunct = _STLP_PRIV __acquire_numeric(name, buf, hint, &__err_code); michael@0: if (!__lwpunct) { michael@0: delete punct; michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "numpunct"); michael@0: return hint; michael@0: } michael@0: if (__lwpunct) { michael@0: _STLP_TRY { michael@0: wpunct = new numpunct_byname(__lwpunct); michael@0: } michael@0: _STLP_UNWIND(_STLP_PRIV __release_numeric(__lwpunct); delete punct); michael@0: } michael@0: #endif michael@0: michael@0: this->insert(punct, numpunct::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: this->insert(wpunct, numpunct::id); michael@0: #endif michael@0: } michael@0: return hint; michael@0: } michael@0: michael@0: _Locale_name_hint* _Locale_impl::insert_time_facets(const char* &name, char *buf, _Locale_name_hint* hint) { michael@0: if (name[0] == 0) michael@0: name = _Locale_time_default(buf); michael@0: michael@0: if (name == 0 || name[0] == 0 || is_C_locale_name(name)) { michael@0: _Locale_impl* i2 = locale::classic()._M_impl; michael@0: this->insert(i2, michael@0: time_get > >::id); michael@0: this->insert(i2, michael@0: time_put > >::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: this->insert(i2, michael@0: time_get > >::id); michael@0: this->insert(i2, michael@0: time_put > >::id); michael@0: #endif michael@0: } else { michael@0: locale::facet *get = 0; michael@0: locale::facet *put = 0; michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: locale::facet *wget = 0; michael@0: locale::facet *wput = 0; michael@0: #endif michael@0: michael@0: int __err_code; michael@0: _Locale_time *__time = _STLP_PRIV __acquire_time(name, buf, hint, &__err_code); michael@0: if (!__time) { michael@0: // time facets category is not mandatory for correct stream behavior so if platform michael@0: // do not support it we do not generate a runtime_error exception. michael@0: if (__err_code == _STLP_LOC_NO_MEMORY) { michael@0: _STLP_THROW_BAD_ALLOC; michael@0: } michael@0: return hint; michael@0: } michael@0: michael@0: if (!hint) hint = _Locale_get_time_hint(__time); michael@0: _STLP_TRY { michael@0: get = new time_get_byname > >(__time); michael@0: put = new time_put_byname > >(__time); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: wget = new time_get_byname > >(__time); michael@0: wput = new time_put_byname > >(__time); michael@0: #endif michael@0: } michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: _STLP_UNWIND(delete wget; delete put; delete get; _STLP_PRIV __release_time(__time)); michael@0: #else michael@0: _STLP_UNWIND(delete get; _STLP_PRIV __release_time(__time)); michael@0: #endif michael@0: michael@0: _STLP_PRIV __release_time(__time); michael@0: michael@0: this->insert(get, time_get > >::id); michael@0: this->insert(put, time_put > >::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: this->insert(wget, time_get > >::id); michael@0: this->insert(wput, time_put > >::id); michael@0: #endif michael@0: } michael@0: return hint; michael@0: } michael@0: michael@0: _Locale_name_hint* _Locale_impl::insert_collate_facets(const char* &name, char *buf, _Locale_name_hint* hint) { michael@0: if (name[0] == 0) michael@0: name = _Locale_collate_default(buf); michael@0: michael@0: if (name == 0 || name[0] == 0 || is_C_locale_name(name)) { michael@0: _Locale_impl* i2 = locale::classic()._M_impl; michael@0: this->insert(i2, collate::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: this->insert(i2, collate::id); michael@0: #endif michael@0: } michael@0: else { michael@0: locale::facet *col = 0; michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: locale::facet *wcol = 0; michael@0: #endif michael@0: michael@0: int __err_code; michael@0: _Locale_collate *__coll = _STLP_PRIV __acquire_collate(name, buf, hint, &__err_code); michael@0: if (!__coll) { michael@0: if (__err_code == _STLP_LOC_NO_MEMORY) { michael@0: _STLP_THROW_BAD_ALLOC; michael@0: } michael@0: return hint; michael@0: } michael@0: michael@0: if (hint == 0) hint = _Locale_get_collate_hint(__coll); michael@0: _STLP_TRY { michael@0: col = new collate_byname(__coll); michael@0: } michael@0: _STLP_UNWIND(_STLP_PRIV __release_collate(__coll)); michael@0: michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: _Locale_collate *__wcoll = _STLP_PRIV __acquire_collate(name, buf, hint, &__err_code); michael@0: if (!__wcoll) { michael@0: if (__err_code == _STLP_LOC_NO_MEMORY) { michael@0: delete col; michael@0: _STLP_THROW_BAD_ALLOC; michael@0: } michael@0: } michael@0: if (__wcoll) { michael@0: _STLP_TRY { michael@0: wcol = new collate_byname(__wcoll); michael@0: } michael@0: _STLP_UNWIND(_STLP_PRIV __release_collate(__wcoll); delete col); michael@0: } michael@0: #endif michael@0: michael@0: this->insert(col, collate::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: if (wcol) this->insert(wcol, collate::id); michael@0: #endif michael@0: } michael@0: return hint; michael@0: } michael@0: michael@0: _Locale_name_hint* _Locale_impl::insert_monetary_facets(const char* &name, char *buf, _Locale_name_hint* hint) { michael@0: if (name[0] == 0) michael@0: name = _Locale_monetary_default(buf); michael@0: michael@0: _Locale_impl* i2 = locale::classic()._M_impl; michael@0: michael@0: // We first insert name independant facets taken from the classic locale instance: michael@0: this->insert(i2, money_get > >::id); michael@0: this->insert(i2, money_put > >::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: this->insert(i2, money_get > >::id); michael@0: this->insert(i2, money_put > >::id); michael@0: #endif michael@0: michael@0: if (name == 0 || name[0] == 0 || is_C_locale_name(name)) { michael@0: this->insert(i2, moneypunct::id); michael@0: this->insert(i2, moneypunct::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: this->insert(i2, moneypunct::id); michael@0: this->insert(i2, moneypunct::id); michael@0: #endif michael@0: } michael@0: else { michael@0: locale::facet *punct = 0; michael@0: locale::facet *ipunct = 0; michael@0: michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: locale::facet* wpunct = 0; michael@0: locale::facet* wipunct = 0; michael@0: #endif michael@0: michael@0: int __err_code; michael@0: _Locale_monetary *__mon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code); michael@0: if (!__mon) { michael@0: if (__err_code == _STLP_LOC_NO_MEMORY) { michael@0: _STLP_THROW_BAD_ALLOC; michael@0: } michael@0: return hint; michael@0: } michael@0: michael@0: if (hint == 0) hint = _Locale_get_monetary_hint(__mon); michael@0: michael@0: _STLP_TRY { michael@0: punct = new moneypunct_byname(__mon); michael@0: } michael@0: _STLP_UNWIND(_STLP_PRIV __release_monetary(__mon)); michael@0: michael@0: _Locale_monetary *__imon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code); michael@0: if (!__imon) { michael@0: delete punct; michael@0: if (__err_code == _STLP_LOC_NO_MEMORY) { michael@0: _STLP_THROW_BAD_ALLOC; michael@0: } michael@0: return hint; michael@0: } michael@0: michael@0: _STLP_TRY { michael@0: ipunct = new moneypunct_byname(__imon); michael@0: } michael@0: _STLP_UNWIND(_STLP_PRIV __release_monetary(__imon); delete punct); michael@0: michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: _STLP_TRY { michael@0: _Locale_monetary *__wmon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code); michael@0: if (!__wmon) { michael@0: if (__err_code == _STLP_LOC_NO_MEMORY) { michael@0: _STLP_THROW_BAD_ALLOC; michael@0: } michael@0: } michael@0: michael@0: if (__wmon) { michael@0: _STLP_TRY { michael@0: wpunct = new moneypunct_byname(__wmon); michael@0: } michael@0: _STLP_UNWIND(_STLP_PRIV __release_monetary(__wmon)); michael@0: michael@0: _Locale_monetary *__wimon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code); michael@0: if (!__wimon) { michael@0: delete wpunct; michael@0: if (__err_code == _STLP_LOC_NO_MEMORY) { michael@0: _STLP_THROW_BAD_ALLOC; michael@0: } michael@0: wpunct = 0; michael@0: } michael@0: else { michael@0: _STLP_TRY { michael@0: wipunct = new moneypunct_byname(__wimon); michael@0: } michael@0: _STLP_UNWIND(_STLP_PRIV __release_monetary(__wimon); delete wpunct); michael@0: } michael@0: } michael@0: } michael@0: _STLP_UNWIND(delete ipunct; delete punct); michael@0: #endif michael@0: michael@0: this->insert(punct, moneypunct::id); michael@0: this->insert(ipunct, moneypunct::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: if (wpunct) this->insert(wpunct, moneypunct::id); michael@0: if (wipunct) this->insert(wipunct, moneypunct::id); michael@0: #endif michael@0: } michael@0: return hint; michael@0: } michael@0: michael@0: _Locale_name_hint* _Locale_impl::insert_messages_facets(const char* &name, char *buf, _Locale_name_hint* hint) { michael@0: if (name[0] == 0) michael@0: name = _Locale_messages_default(buf); michael@0: michael@0: if (name == 0 || name[0] == 0 || is_C_locale_name(name)) { michael@0: _Locale_impl* i2 = locale::classic()._M_impl; michael@0: this->insert(i2, messages::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: this->insert(i2, messages::id); michael@0: #endif michael@0: } michael@0: else { michael@0: locale::facet *msg = 0; michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: locale::facet *wmsg = 0; michael@0: #endif michael@0: michael@0: int __err_code; michael@0: _Locale_messages *__msg = _STLP_PRIV __acquire_messages(name, buf, hint, &__err_code); michael@0: if (!__msg) { michael@0: if (__err_code == _STLP_LOC_NO_MEMORY) { michael@0: _STLP_THROW_BAD_ALLOC; michael@0: } michael@0: return hint; michael@0: } michael@0: michael@0: _STLP_TRY { michael@0: msg = new messages_byname(__msg); michael@0: } michael@0: _STLP_UNWIND(_STLP_PRIV __release_messages(__msg)); michael@0: michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: _STLP_TRY { michael@0: _Locale_messages *__wmsg = _STLP_PRIV __acquire_messages(name, buf, hint, &__err_code); michael@0: if (!__wmsg) { michael@0: if (__err_code == _STLP_LOC_NO_MEMORY) { michael@0: _STLP_THROW_BAD_ALLOC; michael@0: } michael@0: } michael@0: michael@0: if (__wmsg) { michael@0: _STLP_TRY { michael@0: wmsg = new messages_byname(__wmsg); michael@0: } michael@0: _STLP_UNWIND(_STLP_PRIV __release_messages(__wmsg)); michael@0: } michael@0: } michael@0: _STLP_UNWIND(delete msg); michael@0: #endif michael@0: michael@0: this->insert(msg, messages::id); michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: if (wmsg) this->insert(wmsg, messages::id); michael@0: #endif michael@0: } michael@0: return hint; michael@0: } michael@0: michael@0: static void _Stl_loc_assign_ids() { michael@0: // This assigns ids to every facet that is a member of a category, michael@0: // and also to money_get/put, num_get/put, and time_get/put michael@0: // instantiated using ordinary pointers as the input/output michael@0: // iterators. (The default is [io]streambuf_iterator.) michael@0: michael@0: money_get > >::id._M_index = 8; michael@0: money_put > >::id._M_index = 9; michael@0: num_get > >::id._M_index = 10; michael@0: num_put > >::id._M_index = 11; michael@0: time_get > >::id._M_index = 12; michael@0: time_put > >::id._M_index = 13; michael@0: michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: money_get > >::id._M_index = 21; michael@0: money_put > >::id._M_index = 22; michael@0: num_get > >::id._M_index = 23; michael@0: num_put > > ::id._M_index = 24; michael@0: time_get > >::id._M_index = 25; michael@0: time_put > >::id._M_index = 26; michael@0: #endif michael@0: // locale::id::_S_max = 27; michael@0: } michael@0: michael@0: // To access those static instance use the getter below, they guaranty michael@0: // a correct initialization. michael@0: static locale *_Stl_classic_locale = 0; michael@0: static locale *_Stl_global_locale = 0; michael@0: michael@0: locale* _Stl_get_classic_locale() { michael@0: static _Locale_impl::Init init; michael@0: return _Stl_classic_locale; michael@0: } michael@0: michael@0: locale* _Stl_get_global_locale() { michael@0: static _Locale_impl::Init init; michael@0: return _Stl_global_locale; michael@0: } michael@0: michael@0: #if defined (_STLP_MSVC) || defined (__ICL) || defined (__ISCPP__) || defined (__DMC__) michael@0: /* michael@0: * The following static variable needs to be initialized before STLport michael@0: * users static variable in order for him to be able to use Standard michael@0: * streams in its variable initialization. michael@0: * This variable is here because MSVC do not allow to change the initialization michael@0: * segment in a given translation unit, iostream.cpp already contains an michael@0: * initialization segment specification. michael@0: */ michael@0: # pragma warning (disable : 4073) michael@0: # pragma init_seg(lib) michael@0: #endif michael@0: michael@0: static ios_base::Init _IosInit; michael@0: michael@0: void _Locale_impl::make_classic_locale() { michael@0: // This funcion will be called once: during build classic _Locale_impl michael@0: michael@0: // The classic locale contains every facet that belongs to a category. michael@0: static _Stl_aligned_buffer<_Locale_impl> _Locale_classic_impl_buf; michael@0: _Locale_impl *classic = new(&_Locale_classic_impl_buf) _Locale_impl("C"); michael@0: michael@0: locale::facet* classic_facets[] = { michael@0: 0, michael@0: new collate(1), michael@0: new ctype(0, false, 1), michael@0: new codecvt(1), michael@0: new moneypunct(1), michael@0: new moneypunct(1), michael@0: new numpunct(1), michael@0: new messages(1), michael@0: new money_get > >(1), michael@0: new money_put > >(1), michael@0: new num_get > >(1), michael@0: new num_put > >(1), michael@0: new time_get > >(1), michael@0: new time_put > >(1), michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: new collate(1), michael@0: new ctype(1), michael@0: new codecvt(1), michael@0: new moneypunct(1), michael@0: new moneypunct(1), michael@0: new numpunct(1), michael@0: new messages(1), michael@0: new money_get > >(1), michael@0: new money_put > >(1), michael@0: new num_get > >(1), michael@0: new num_put > >(1), michael@0: new time_get > >(1), michael@0: new time_put > >(1), michael@0: #endif michael@0: 0 michael@0: }; michael@0: michael@0: const size_t nb_classic_facets = sizeof(classic_facets) / sizeof(locale::facet *); michael@0: classic->facets_vec.reserve(nb_classic_facets); michael@0: classic->facets_vec.assign(&classic_facets[0], &classic_facets[0] + nb_classic_facets); michael@0: michael@0: static locale _Locale_classic(classic); michael@0: _Stl_classic_locale = &_Locale_classic; michael@0: michael@0: static locale _Locale_global(classic); michael@0: _Stl_global_locale = &_Locale_global; michael@0: } michael@0: michael@0: // Declarations of (non-template) facets' static data members michael@0: // size_t locale::id::_S_max = 27; // made before michael@0: michael@0: locale::id collate::id = { 1 }; michael@0: locale::id ctype::id = { 2 }; michael@0: locale::id codecvt::id = { 3 }; michael@0: locale::id moneypunct::id = { 4 }; michael@0: locale::id moneypunct::id = { 5 }; michael@0: locale::id numpunct::id = { 6 } ; michael@0: locale::id messages::id = { 7 }; michael@0: michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: locale::id collate::id = { 14 }; michael@0: locale::id ctype::id = { 15 }; michael@0: locale::id codecvt::id = { 16 }; michael@0: locale::id moneypunct::id = { 17 } ; michael@0: locale::id moneypunct::id = { 18 } ; michael@0: locale::id numpunct::id = { 19 }; michael@0: locale::id messages::id = { 20 }; michael@0: #endif michael@0: michael@0: _STLP_DECLSPEC _Locale_impl* _STLP_CALL _get_Locale_impl(_Locale_impl *loc) michael@0: { michael@0: _STLP_ASSERT( loc != 0 ); michael@0: loc->_M_incr(); michael@0: return loc; michael@0: } michael@0: michael@0: void _STLP_CALL _release_Locale_impl(_Locale_impl *& loc) michael@0: { michael@0: _STLP_ASSERT( loc != 0 ); michael@0: if (loc->_M_decr() == 0) { michael@0: if (*loc != *_Stl_classic_locale) michael@0: delete loc; michael@0: else michael@0: loc->~_Locale_impl(); michael@0: loc = 0; michael@0: } michael@0: } michael@0: michael@0: _STLP_DECLSPEC _Locale_impl* _STLP_CALL _copy_Nameless_Locale_impl(_Locale_impl *loc) michael@0: { michael@0: _STLP_ASSERT( loc != 0 ); michael@0: _Locale_impl *loc_new = new _Locale_impl(*loc); michael@0: loc_new->name = _Nameless; michael@0: return loc_new; michael@0: } michael@0: michael@0: /* _GetFacetId implementation have to be here in order to be in the same translation unit michael@0: * as where id are initialize (in _Stl_loc_assign_ids) */ michael@0: _STLP_MOVE_TO_PRIV_NAMESPACE michael@0: michael@0: _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_get > >*) michael@0: { return money_get > >::id; } michael@0: _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_put > >*) michael@0: { return money_put > >::id; } michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_get > >*) michael@0: { return money_get > >::id; } michael@0: _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_put > >*) michael@0: { return money_put > >::id; } michael@0: #endif michael@0: michael@0: _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_get > >*) michael@0: { return num_get > >::id; } michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_get > >*) michael@0: { return num_get > >::id; } michael@0: #endif michael@0: michael@0: _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_put > >*) michael@0: { return num_put > >::id; } michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_put > >*) michael@0: { return num_put > >::id; } michael@0: #endif michael@0: michael@0: _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_get > >*) michael@0: { return time_get > >::id; } michael@0: _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_put > >*) michael@0: { return time_put > >::id; } michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_get > >*) michael@0: { return time_get > >::id; } michael@0: _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_put > >*) michael@0: { return time_put > >::id; } michael@0: #endif michael@0: michael@0: _STLP_MOVE_TO_STD_NAMESPACE michael@0: michael@0: _STLP_END_NAMESPACE michael@0: