blob: a497ba9da164947fa3a812db6710b02d768f7a9f [file] [log] [blame]
/***************************************************************************
*
* _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$
*
***************************************************************************
*
* 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 <string>
#include <loc/_facet.h>
#include <rw/_defs.h>
_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 <class _Facet>
inline const __rw_facet*
__rw_get_facet (const _STD::locale&, const _Facet*);
} // namespace __rw
_RWSTD_NAMESPACE (std) {
// 22.1.2, p1
template <class _Facet>
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 <class _Facet>
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 _InternT, class _ExternT, class _StateT>
class codecvt;
_EXPORT template <class _CharT>
class collate;
_EXPORT template <class _CharT>
class ctype;
_EXPORT template <class _CharT, class _Iter>
struct money_get;
_EXPORT template <class _CharT, class _Iter>
struct money_put;
_EXPORT template <class _CharT, bool _Intl>
struct moneypunct;
_EXPORT template <class _CharT, class _Iter>
struct num_get;
_EXPORT template <class _CharT, class _Iter>
struct num_put;
_EXPORT template <class _CharT>
struct numpunct;
_EXPORT template <class _CharT, class _Iter>
class time_get;
_EXPORT template <class _CharT, class _Iter>
struct time_put;
_EXPORT template <class _CharT>
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);
// 22.1.1.2, p12
template <class _Facet>
locale (const locale&, _Facet*);
#ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
// 22.1.1.3, p1
template <class _Facet>
locale combine (const locale&) const;
#endif // _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
// 22.1.1.4, p3
template <class _CharT, class _Traits, class _Allocator>
bool operator() (const basic_string<_CharT, _Traits, _Allocator>&,
const basic_string<_CharT, _Traits, _Allocator>&) const;
// 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 <class _Facet>
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<T, U >
#define _InIter(T) _STD::istreambuf_iterator< T, _STD::char_traits<T > >
#define _OutIter(T) _STD::ostreambuf_iterator< T, _STD::char_traits<T > >
// convenience typedefs to allow them to be used as macro arguments
typedef _STD::codecvt<char, char, _RWSTD_MBSTATE_T> __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<char>*)
{
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<char>*)
{
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<char>);
_RWSTD_OVERLOAD_GET_FACET (__rw_codecvt_c);
_RWSTD_OVERLOAD_GET_FACET (_STD::collate<char>);
_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<char>);
_RWSTD_OVERLOAD_GET_FACET (__rw_tget_c);
_RWSTD_OVERLOAD_GET_FACET (__rw_tput_c);
_RWSTD_OVERLOAD_GET_FACET (_STD::messages<char>);
#ifndef _RWSTD_NO_WCHAR_T
typedef _STD::codecvt<wchar_t, char, _RWSTD_MBSTATE_T> __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<wchar_t>);
_RWSTD_OVERLOAD_GET_FACET (__rw_codecvt_w);
_RWSTD_OVERLOAD_GET_FACET (_STD::collate<wchar_t>);
_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<wchar_t>);
_RWSTD_OVERLOAD_GET_FACET (__rw_tget_w);
_RWSTD_OVERLOAD_GET_FACET (__rw_tput_w);
_RWSTD_OVERLOAD_GET_FACET (_STD::messages<wchar_t>);
#endif // _RWSTD_NO_WCHAR_T
// clean up
#undef _RWSTD_OVERLOAD_GET_FACET
#undef _Facet
#undef _InIter
#undef _OutIter
} // namespace __rw
_RWSTD_NAMESPACE (std) {
template <class _Facet>
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 <class _Facet>
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 <class _CharT, class _Traits, class _Allocator>
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;
}
} // namespace std
#endif // _RWSTD_LOC_LOCALE_INCLUDED