/*************************************************************************** * * _locale.h - definition of the std::locale class * * This is an internal header file used to implement the C++ Standard * Library. It should never be #included directly by a program. * * $Id: _locale.h 597181 2007-11-21 18:59:19Z faridz $ * *************************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * Copyright 1994-2005 Rogue Wave Software. * **************************************************************************/ #ifndef _RWSTD_LOC_LOCALE_INCLUDED #define _RWSTD_LOC_LOCALE_INCLUDED #include #include #include _RWSTD_NAMESPACE (__rw) { enum __rw_locale_category { __rw_cat_none = 0x0100, __rw_cat_collate = 0x0200, __rw_cat_ctype = 0x0400, __rw_cat_monetary = 0x0800, __rw_cat_numeric = 0x1000, __rw_cat_time = 0x2000, __rw_cat_messages = 0x4000, __rw_cat_all = 0x7e00 }; class _RWSTD_EXPORT __rw_locale; inline const __rw_facet* __rw_get_std_facet (const _STD::locale&, __rw_facet::_C_facet_type, __rw_facet::_C_ctor_t*); inline const __rw_facet* __rw_get_facet_by_id (const _STD::locale&, const __rw_facet_id&, const __rw_facet*); // called from has_facet and use_facet to strips top level // const-qualifier from the type of Facet template inline const __rw_facet* __rw_get_facet (const _STD::locale&, const _Facet*); } // namespace __rw _RWSTD_NAMESPACE (std) { // 22.1.2, p1 template inline const _Facet& use_facet (const locale &__loc _RWSTD_DUMMY_ARG (const _Facet* = 0)) { // Facet could be a const SomeFacet; strip the const qualifier // and, for non-standard facets, use dynamic_cast to make sure // that the dynamic type of `pfacet' is the same as Facet const _RW::__rw_facet* const __pfacet = _RW::__rw_get_facet (__loc, (_Facet*)0); _RWSTD_REQUIRES (__pfacet, (_RWSTD_ERROR_BAD_CAST, _RWSTD_FUNC ("use_facet (const locale&)"))); return *_RWSTD_STATIC_CAST (const _Facet*, __pfacet); } // 22.1.2, p5 template inline bool has_facet (const locale &__loc _RWSTD_DUMMY_ARG (const _Facet* = 0)) { // Facet could be a const SomeFacet; strip the const qualifier const _RW::__rw_facet* const __pfacet = _RW::__rw_get_facet (__loc, (_Facet*)0); return 0 != __pfacet; } // forward declare standard facets before referencing them below _EXPORT template class codecvt; _EXPORT template class collate; _EXPORT template class ctype; _EXPORT template struct money_get; _EXPORT template struct money_put; _EXPORT template struct moneypunct; _EXPORT template struct num_get; _EXPORT template struct num_put; _EXPORT template struct numpunct; _EXPORT template class time_get; _EXPORT template struct time_put; _EXPORT template class messages; // 22.1.1 struct _RWSTD_CLASS_EXPORT locale { // 22.1.1.1.1, p1 typedef int category; // 22.1.1.1.2 typedef _RW::__rw_facet facet; // 22.1.1.1.3 typedef _RW::__rw_facet_id id; // values (including none) must not conflict with any LC_XXX constants _RWSTD_STATIC_CONST (category, none = _RW::__rw_cat_none); _RWSTD_STATIC_CONST (category, collate = _RW::__rw_cat_collate); _RWSTD_STATIC_CONST (category, ctype = _RW::__rw_cat_ctype); _RWSTD_STATIC_CONST (category, monetary = _RW::__rw_cat_monetary); _RWSTD_STATIC_CONST (category, numeric = _RW::__rw_cat_numeric); _RWSTD_STATIC_CONST (category, time = _RW::__rw_cat_time); _RWSTD_STATIC_CONST (category, messages = _RW::__rw_cat_messages); _RWSTD_STATIC_CONST (category, all = _RW::__rw_cat_all); // 22.1.1.2, p1 _RWSTD_MEMBER_EXPORT locale () _THROWS (()); // 22.1.1.2, p3 _RWSTD_MEMBER_EXPORT locale (const locale&) _THROWS (()); // 22.1.1.2, p6 _RWSTD_MEMBER_EXPORT _EXPLICIT locale (const char*); // 22.1.1.2, p9 _RWSTD_MEMBER_EXPORT locale (const locale&, const char*, category); #ifndef _RWSTD_NO_MEMBER_TEMPLATES // 22.1.1.2, p12 template locale (const locale&, _Facet*); # ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE // 22.1.1.3, p1 template locale combine (const locale&) const; # endif // _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE // 22.1.1.4, p3 template bool operator() (const basic_string<_CharT, _Traits, _Allocator>&, const basic_string<_CharT, _Traits, _Allocator>&) const; #else // if defined (_RWSTD_NO_MEMBER_TEMPLATES) template locale (const locale &__rhs, _Facet *__facet) : _C_body (0) { // initialize facet's member id to point to Facet::id if (__facet && !__facet->_C_pid) { // unusual cast (to size_t** rather than size_t*&) // done to work around an HP aCC 3.3x bug *_RWSTD_CONST_CAST (_RWSTD_SIZE_T**, &__facet->_C_pid) = &_Facet::id._C_id; } // uninitialized Facet::id will be initialized by has_facet<>() // prevent passing `facet' the ctor if it is installed // in `rhs' to potentially avoid creating a whole new body if ( has_facet<_Facet>(__rhs) && &use_facet<_Facet>(__rhs) == __facet) __facet = 0; *this = locale (*__rhs._C_body, __facet); } # ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE template locale combine (const locale &__rhs) const { // unitialized Facet::id will be initialized by has_facet<>() _RWSTD_REQUIRES (has_facet<_Facet>(__rhs), (_RWSTD_ERROR_FACET_NOT_FOUND, _RWSTD_FUNC ("locale::combine (const locale&)"), _Facet::id._C_id, __rhs.name ().c_str ())); return locale (__rhs, &use_facet<_Facet>(__rhs)); } # endif // _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE template bool operator() (const basic_string<_CharT, _Traits, _Allocator> &__x, const basic_string<_CharT, _Traits, _Allocator> &__y) const { // qualify collate to distinguish it from locale::collate return use_facet<_STD::collate<_CharT> >(*this) .compare (__x.data (), __x.data () + __x.length (), __y.data (), __y.data () + __y.length ()) < 0; } #endif // _RWSTD_NO_MEMBER_TEMPLATES // 22.1.1.2, p14 _RWSTD_MEMBER_EXPORT locale (const locale&, const locale&, category); // 22.1.1.2, p16 _RWSTD_MEMBER_EXPORT ~locale() _THROWS (()); // 22.1.1.2, p4 _RWSTD_MEMBER_EXPORT const locale& operator= (const locale&) _THROWS (()); // 22.1.1.3, p5 _RWSTD_MEMBER_EXPORT string name () const; // 22.1.1.4, p1 _RWSTD_MEMBER_EXPORT bool operator== (const locale&) const; // 22.1.1.4, p2 _RWSTD_MEMBER_EXPORT bool operator!= (const locale &__rhs) const { return !(*this == __rhs); } // 22.1.1.5, p1 _RWSTD_MEMBER_EXPORT static locale global (const locale&); // 22.1.1.5, p4 _RWSTD_MEMBER_EXPORT static const locale& classic (); private: _RWSTD_MEMBER_EXPORT _EXPLICIT locale (_RW::__rw_locale &__rhs) _THROWS (()) : _C_body (&__rhs) { } _RWSTD_MEMBER_EXPORT locale (_RW::__rw_locale&, const facet*); _RW::__rw_locale *_C_body; // reference-counted body #if defined (__SUNPRO_CC) && __SUNPRO_CC <= 0x540 // working around a SunPro member access control bug (see PR #25910) public: #endif // SunPro <= 5.4 // (try to) retrieve a facet from a locale given an id // may initialize the id if it isn't initialized yet _RWSTD_MEMBER_EXPORT const facet* _C_get_facet (const id&) const; _RWSTD_MEMBER_EXPORT const facet* _C_get_std_facet (facet::_C_facet_type, facet::_C_ctor_t*) const; friend class _RW::__rw_locale; friend struct _RW::__rw_access; // function arguments below are qualified to work around // a SunPro 5.5 and prior bug (PR #28626) friend const facet* _RW::__rw_get_std_facet (const _STD::locale&, _RW::__rw_facet::_C_facet_type, _RW::__rw_facet::_C_ctor_t*); friend const _RW::__rw_facet* _RW::__rw_get_facet_by_id (const _STD::locale&, const _RW::__rw_facet_id&, const _RW::__rw_facet*); }; } // namespace std _RWSTD_NAMESPACE (__rw) { inline const __rw_facet* __rw_get_facet_by_id (const _STD::locale &__loc, const __rw_facet_id &__id, const __rw_facet*) { // initialize Facet::id and retrieve facet if it's installed return __loc._C_get_facet (__id); } template inline const __rw_facet* __rw_get_facet (const _STD::locale &__loc, const _Facet *__dummy) { // resolves either to one of the overloads of __rw_get_facet_by_id // defined for the set of standard facets or the overload for the base // locale::facet* if _Facet is not derived from any of the former const __rw_facet* const __pfacet = __rw_get_facet_by_id (__loc, _Facet::id, __dummy); return _RWSTD_DYNAMIC_CAST (const _Facet*, __pfacet); } inline const __rw_facet* __rw_get_std_facet (const _STD::locale &__loc, __rw_facet::_C_facet_type __type, __rw_facet::_C_ctor_t *__ctor) { // expose an implementation detail of locale body for efficiency struct _Facets { __rw_facet *__facets [__rw_facet::_C_last_type / 2]; }; const _Facets* const __pfacets = _RWSTD_REINTERPRET_CAST (const _Facets*, __loc._C_body); _RWSTD_ASSERT (0 != __pfacets); const __rw_facet *__facet = __pfacets->__facets [__type >> 1]; if (!__facet) __facet = __loc._C_get_std_facet (__type, __ctor); #if !defined (__HP_aCC) || _RWSTD_HP_aCC_MINOR > 3800 // working around an HP aCC ICE (PR #28838) _RWSTD_ASSERT (0 != __facet); #endif // HP aCC return __facet; } // functions' type must be __rw_facet::_C_ctor_t // i.e., as if they were declared as follows: // __rw_facet::_C_ctor_t __rw_ct_ctype; // the declaration above causes a Compaq C++ 6.5 ICE (PR #30188) _RWSTD_EXPORT __rw_facet* __rw_ct_ctype (_RWSTD_SIZE_T, const char*); _RWSTD_EXPORT __rw_facet* __rw_ct_numpunct (_RWSTD_SIZE_T, const char*); _RWSTD_EXPORT __rw_facet* __rw_ct_num_get (_RWSTD_SIZE_T, const char*); _RWSTD_EXPORT __rw_facet* __rw_ct_num_put (_RWSTD_SIZE_T, const char*); #define _RWSTD_OVERLOAD_GET_FACET(F) \ _RWSTD_EXPORT const __rw_facet* \ __rw_get_facet_by_id (const _STD::locale&, \ const __rw_facet_id&, const F*) #define _Facet(name, T, U) _STD::name #define _InIter(T) _STD::istreambuf_iterator< T, _STD::char_traits > #define _OutIter(T) _STD::ostreambuf_iterator< T, _STD::char_traits > // convenience typedefs to allow them to be used as macro arguments typedef _STD::codecvt __rw_codecvt_c; typedef _Facet (moneypunct, char, false) __rw_mpunct_c_0; typedef _Facet (moneypunct, char, true) __rw_mpunct_c_1; typedef _Facet (money_get, char, _InIter (char)) __rw_mget_c; typedef _Facet (money_put, char, _OutIter (char)) __rw_mput_c; typedef _Facet (num_get, char, _InIter (char)) __rw_nget_c; typedef _Facet (num_put, char, _OutIter (char)) __rw_nput_c; typedef _Facet (time_get, char, _InIter (char)) __rw_tget_c; typedef _Facet (time_put, char, _OutIter (char)) __rw_tput_c; // inline definitions of heavily used use_facet specializations // for iostream efficiency _RWSTD_SPECIALIZED_FUNCTION inline const __rw_facet* __rw_get_facet (const _STD::locale &__loc, const _STD::ctype*) { return __rw_get_std_facet (__loc, __rw_facet::_C_ctype, __rw_ct_ctype); } _RWSTD_SPECIALIZED_FUNCTION inline const __rw_facet* __rw_get_facet (const _STD::locale &__loc, const _STD::numpunct*) { return __rw_get_std_facet (__loc, __rw_facet::_C_numpunct, __rw_ct_numpunct); } _RWSTD_SPECIALIZED_FUNCTION inline const __rw_facet* __rw_get_facet (const _STD::locale &__loc, const __rw_nget_c*) { return __rw_get_std_facet (__loc, __rw_facet::_C_num_get, __rw_ct_num_get); } _RWSTD_SPECIALIZED_FUNCTION inline const __rw_facet* __rw_get_facet (const _STD::locale &__loc, const __rw_nput_c*) { return __rw_get_std_facet (__loc, __rw_facet::_C_num_put, __rw_ct_num_put); } // declarations of __rw_get_facet_by_id overloads _RWSTD_OVERLOAD_GET_FACET (_STD::ctype); _RWSTD_OVERLOAD_GET_FACET (__rw_codecvt_c); _RWSTD_OVERLOAD_GET_FACET (_STD::collate); _RWSTD_OVERLOAD_GET_FACET (__rw_mget_c); _RWSTD_OVERLOAD_GET_FACET (__rw_mput_c); _RWSTD_OVERLOAD_GET_FACET (__rw_mpunct_c_0); _RWSTD_OVERLOAD_GET_FACET (__rw_mpunct_c_1); _RWSTD_OVERLOAD_GET_FACET (__rw_nget_c); _RWSTD_OVERLOAD_GET_FACET (__rw_nput_c); _RWSTD_OVERLOAD_GET_FACET (_STD::numpunct); _RWSTD_OVERLOAD_GET_FACET (__rw_tget_c); _RWSTD_OVERLOAD_GET_FACET (__rw_tput_c); _RWSTD_OVERLOAD_GET_FACET (_STD::messages); #ifndef _RWSTD_NO_WCHAR_T typedef _STD::codecvt __rw_codecvt_w; typedef _Facet (moneypunct, wchar_t, false) __rw_mpunct_w_0; typedef _Facet (moneypunct, wchar_t, true) __rw_mpunct_w_1; typedef _Facet (money_get, wchar_t, _InIter (wchar_t)) __rw_mget_w; typedef _Facet (money_put, wchar_t, _OutIter (wchar_t)) __rw_mput_w; typedef _Facet (num_get, wchar_t, _InIter (wchar_t)) __rw_nget_w; typedef _Facet (num_put, wchar_t, _OutIter (wchar_t)) __rw_nput_w; typedef _Facet (time_get, wchar_t, _InIter (wchar_t)) __rw_tget_w; typedef _Facet (time_put, wchar_t, _OutIter (wchar_t)) __rw_tput_w; _RWSTD_OVERLOAD_GET_FACET (_STD::ctype); _RWSTD_OVERLOAD_GET_FACET (__rw_codecvt_w); _RWSTD_OVERLOAD_GET_FACET (_STD::collate); _RWSTD_OVERLOAD_GET_FACET (__rw_mget_w); _RWSTD_OVERLOAD_GET_FACET (__rw_mput_w); _RWSTD_OVERLOAD_GET_FACET (__rw_mpunct_w_0); _RWSTD_OVERLOAD_GET_FACET (__rw_mpunct_w_1); _RWSTD_OVERLOAD_GET_FACET (__rw_nget_w); _RWSTD_OVERLOAD_GET_FACET (__rw_nput_w); _RWSTD_OVERLOAD_GET_FACET (_STD::numpunct); _RWSTD_OVERLOAD_GET_FACET (__rw_tget_w); _RWSTD_OVERLOAD_GET_FACET (__rw_tput_w); _RWSTD_OVERLOAD_GET_FACET (_STD::messages); #endif // _RWSTD_NO_WCHAR_T // clean up #undef _RWSTD_OVERLOAD_GET_FACET #undef _Facet #undef _InIter #undef _OutIter } // namespace __rw _RWSTD_NAMESPACE (std) { #ifndef _RWSTD_NO_MEMBER_TEMPLATES template inline locale::locale (const locale &__rhs, _Facet *__facet) : _C_body (0) { // initialize facet's member id to point to Facet::id if (__facet && !__facet->_C_pid) { // unusual cast (to size_t** rather than size_t*&) // done to work around an HP aCC 3.3x bug *_RWSTD_CONST_CAST (_RWSTD_SIZE_T**, &__facet->_C_pid) = &_Facet::id._C_id; } // uninitialized Facet::id will be initialized by has_facet<>() // prevent passing `facet' the ctor if it is installed in `rhs' // to potentially avoid creating a whole new locale body if (_RW::__rw_get_facet (__rhs, (_Facet*)0) == __facet) __facet = 0; *this = locale (*__rhs._C_body, __facet); } # ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE template inline locale locale::combine (const locale &__rhs) const { // unitialized Facet::id will be initialized by has_facet<>() _RWSTD_REQUIRES (has_facet<_Facet>(__rhs), (_RWSTD_ERROR_FACET_NOT_FOUND, _RWSTD_FUNC ("locale::combine (const locale&)"), _Facet::id._C_id, __rhs.name ().c_str ())); return locale (*this, &use_facet<_Facet>(__rhs)); } # endif // _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE template inline bool locale::operator() (const basic_string<_CharT, _Traits, _Allocator> &__x, const basic_string<_CharT, _Traits, _Allocator> &__y) const { // qualify collate to distinguish it from locale::collate return use_facet<_STD::collate<_CharT> >(*this) .compare (__x.data (), __x.data () + __x.length (), __y.data (), __y.data () + __y.length ()) < 0; } #endif // _RWSTD_NO_MEMBER_TEMPLATES } // namespace std #endif // _RWSTD_LOC_LOCALE_INCLUDED