📄 _locale.h
字号:
category __cat, __facet_maker_func) const;
facet* _C_get_facet (const id &__id) const {
return _RWSTD_STATIC_CAST (facet*, _C_imp->_C_get_facet (__id));
}
void _C_install_facet (_RW::__rw_facet_base*, const id&) const;
private:
friend class _RW::__rw_locale_imp;
// Construct a locale from an implementation object.
_EXPLICIT locale (_RW::__rw_locale_imp*);
// Create initial implementation objects.
static void _C_init ();
// remove all facets satisfying the given category
inline void _C_remove_facets (category);
static _RW::__rw_locale_imp *_C_classic; // the classic "C" locale
static _RW::__rw_locale_imp *_C_native; // the native "C++" locale
static _RW::__rw_locale_imp *_C_global; // the global locale
_RW::__rw_locale_imp *_C_imp; // pointer to a ref counted implementation
};
#if defined (_RWSTD_MULTI_THREAD) && !defined (_RWSTD_NO_STATIC_MUTEX_INIT)
_RWSTD_NAMESPACE_END // std
_RWSTD_NAMESPACE_BEGIN (__rw)
// explicitly instantiated to work around a g++ 2.95.2 bug on COFF systems
// (such as IBM AIX or DEC OSF1) where it "forgets" to do so implicitly for
// explicitly initialized static data members
_RWSTD_INSTANTIATE_1 (class _RWSTD_EXPORT __rw_static_mutex<_STD::locale>);
_RWSTD_NAMESPACE_END // __rw
_RWSTD_NAMESPACE_BEGIN (std)
#endif // _RWSTD_MULTI_THREAD && !_RWSTD_NO_STATIC_MUTEX_INIT
// ----------------------------
// Class locale inline members.
// ----------------------------
// Private constructor for use by implementation, constructs a locale from
// a __rw_locale_imp implementation object.
inline locale::locale (_RW::__rw_locale_imp *__rhs)
: _C_imp (__rhs)
{
_RWSTD_ASSERT (0 != __rhs);
if (!_C_global)
_C_init ();
// no lock here to prevent a deadlock, called only from guarded contexts
++_C_imp->_C_ref_count;
}
// Default constructor, returns a copy of the current global locale.
inline locale::locale () _THROWS (())
{
if (!_C_global)
_C_init ();
_C_imp = _C_global;
_RWSTD_ASSERT (0 != _C_imp);
_RWSTD_ATOMIC_PREINCREMENT (_C_imp->_C_ref_count, _C_imp->_C_mutex);
}
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
// Constructor to accrete or replace a single _Facet.
template <class _Facet>
inline locale::locale (const locale& __rhs, _Facet* __facet)
{
_RWSTD_ASSERT (0 != __rhs._C_imp);
_RWSTD_MT_GUARD (__rhs._C_imp->_C_mutex);
// Identical, EXCEPT no name -- so we can't just increment
// the ref count on the existing imp -- we need a new imp.
_C_imp = new _RW::__rw_locale_imp (*__rhs._C_imp, 0, 1);
if (__facet) {
_C_install_facet (__facet, _Facet::id);
}
}
// Operator () compares two strings according to the collate<_CharT> facet of
// the locale. It lets you use a locale object directly as a comparator
// predicate for strings in various algorithms. For instance, you can sort
// a vector<string> according to the collating sequence of a locale with an
// expression like: sort(v.begin(),v.end(),mylocale).
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
{
return _USE_FACET (_STD::collate<_CharT>, *this)
.compare (__x.data (), __x.data () + __x.length (),
__y.data (), __y.data () + __y.length ()) < 0;
}
#else // if defined (_RWSTD_NO_MEMBER_TEMPLATES)
inline locale::locale (const locale& __rhs, facet* __facet):
_C_imp (0)
{
_RWSTD_MT_GUARD (__rhs._C_imp->_C_mutex);
_C_imp = new _RW::__rw_locale_imp (*__rhs._C_imp, 0, 1);
if (__facet)
_C_install_facet (__facet, __facet->_C_get_id ());
}
#endif // _RWSTD_NO_MEMBER_TEMPLATES
#ifdef _INLINE_WITH_STATICS
_INLINE_WITH_STATICS void locale::id::_C_init () const
{
// implicit initialization used to prevent a g++ 2.95.2 warning
// on Tru64: sorry: semantics of inline function static data are
// wrong (you'll wind up with multiple copies)
static size_t _C_id_gen /* = 0 */;
if (!_C_id)
_C_id = _RWSTD_ATOMIC_PREINCREMENT (_C_id_gen, false);
}
#endif // _INLINE_WITH_STATICS
inline const locale::facet&
locale::_C_use_facet (const id &__id, bool __implicit, category __cat,
__facet_maker_func __maker) const
{
_RWSTD_ASSERT (0 != _C_imp);
// not guarded (heavily used in iostreams)
const facet *__facet = _C_get_facet (__id);
// If facet is not explicitly present in locale yet, use private function
// locale::_C_make_facet to construct it or retrieve it from a cache,
// and install it in the locale. This function can throw bad_cast or
// other exceptions.
if (!__facet) {
_RWSTD_MT_GUARD (_C_imp->_C_mutex);
__facet = _C_make_facet (__id, __implicit, __cat, __maker);
}
_RWSTD_ASSERT (__facet);
return *__facet;
}
// same as above but not guarded; called during initialization
// of the num_get<> and num_put<> facets (this is a hack)
inline const locale::facet&
locale::_C_unsafe_use_facet (const id &__id, bool __implicit, category __cat,
__facet_maker_func __maker) const
{
_RWSTD_ASSERT (0 != _C_imp);
const facet *__facet = _C_get_facet (__id);
if (!__facet)
__facet = _C_make_facet (__id, __implicit, __cat, __maker);
_RWSTD_ASSERT (__facet);
return *__facet;
}
_RWSTD_NAMESPACE_END // std
_RWSTD_NAMESPACE_BEGIN (__rw)
// -------------------------------------------------------
// Implementation function template -- create_named_facet.
// -------------------------------------------------------
//
// The default for facets with no derived byname version is to create a _Facet
// with classic ("C") behavior, ignoring the passed name.
template <class _Facet>
inline _Facet*
__rw_create_named_facet (_Facet*, const char *__name, _RWSTD_C::size_t __ref)
{
_RWSTD_UNUSED (__name);
// 22.1.1.1.2, p1: a facet class need not have a public copy
// constructor, assignment, default constructor, destructor, etc.
// this, of course, makes the assumption that a default
// ctor is available
_Facet *__facet = new _Facet ();
__facet->_C_set_ref (__ref);
return __facet;
}
// -----------------------------------------------------
// Implementation helper class -- __rw_use_c_lib_locale.
// -----------------------------------------------------
class _RWSTD_EXPORT __rw_use_c_lib_locale
{
int _C_saved_cat;
char *_C_previous_locale_name;
public:
__rw_use_c_lib_locale (const char* = 0, int = LC_ALL);
~__rw_use_c_lib_locale ();
operator bool () const {
return _C_previous_locale_name != NULL;
}
};
// ---------------------------------------
// Inline members of __rw_use_c_lib_locale
// ---------------------------------------
// Destructor restores the C library locale that was in effect when the object
// was constructed.
inline __rw_use_c_lib_locale::~__rw_use_c_lib_locale ()
{
if (_C_previous_locale_name) {
setlocale(_C_saved_cat, _C_previous_locale_name);
delete[] _C_previous_locale_name;
}
}
template <class _Facet>
inline _Facet*
__rw_create_native_facet (_Facet*)
{
return __rw_create_named_facet ((_Facet*)0, "", _RWSTD_C::size_t (1));
}
_RWSTD_NAMESPACE_END // __rw
// functions below are defined here as a hack to allow explicit instantiation
// with automatic template instantiation (and implicit file inclusion); needed
// to guarantee that definitions of all instantiated entities have been seen
_RWSTD_NAMESPACE_BEGIN (std)
// Template use_facet<>() returns a reference to a facet. Its result is
// guaranteed by locale's value semantics to last at least as long as the
// locale or any copy of the locale it came from.
#ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
# define _RWSTD_SELECT_FACET(ignore)
#else
# define _RWSTD_SELECT_FACET(type) , type*
#endif
#ifndef _RWSTD_INLINE_INSTANTIATION_HACK
template <class _Facet>
inline const _Facet&
use_facet (const locale &__loc _RWSTD_SELECT_FACET (_Facet))
{
const _Facet &__facet = _RWSTD_STATIC_CAST (const _Facet&,
__loc._C_use_facet (_Facet::id,
_Facet::_C_ok_implicit,
_Facet::_C_facet_cat,
_RW::__rw_facet_maker<_Facet>::_C_maker_func));
return __facet;
}
#endif // _RWSTD_INLINE_INSTANTIATION_HACK
template <class _Facet>
inline bool
has_facet (const locale &__loc _RWSTD_SELECT_FACET (_Facet)) _THROWS (())
{
return _Facet::_C_ok_implicit || __loc._C_get_facet (_Facet::id);
}
#undef _RWSTD_SELECT_FACET
_RWSTD_NAMESPACE_END // std
#endif // _RWSTD_LOCALE_H_INCLUDED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -