📄 xlocale
字号:
// xlocale internal header (from <locale>)
#pragma once
#ifndef _XLOCALE_
#define _XLOCALE_
#ifndef RC_INVOKED
#include <climits>
#include <cstring>
#include <stdexcept>
#include <typeinfo>
#include <xlocinfo>
#include <xdebug>
#pragma pack(push,_CRT_PACKING)
#pragma warning(push,3)
#pragma push_macro("new")
#undef new
#pragma warning(disable: 4412)
_STD_BEGIN
// TEMPLATE CLASS _Locbase
template<class _Dummy>
class _Locbase
{ // define templatized category constants, instantiate on demand
public:
_PGLOBAL static const int collate = _M_COLLATE;
_PGLOBAL static const int ctype = _M_CTYPE;
_PGLOBAL static const int monetary = _M_MONETARY;
_PGLOBAL static const int numeric = _M_NUMERIC;
_PGLOBAL static const int time = _M_TIME;
_PGLOBAL static const int messages = _M_MESSAGES;
_PGLOBAL static const int all = _M_ALL;
_PGLOBAL static const int none = 0;
};
template<class _Dummy>
const int _Locbase<_Dummy>::collate;
template<class _Dummy>
const int _Locbase<_Dummy>::ctype;
template<class _Dummy>
const int _Locbase<_Dummy>::monetary;
template<class _Dummy>
const int _Locbase<_Dummy>::numeric;
template<class _Dummy>
const int _Locbase<_Dummy>::time;
template<class _Dummy>
const int _Locbase<_Dummy>::messages;
template<class _Dummy>
const int _Locbase<_Dummy>::all;
template<class _Dummy>
const int _Locbase<_Dummy>::none;
// CLASS locale
class locale;
template<class _Facet>
const _Facet& __CRTDECL use_facet(const locale&);
class locale
: public _Locbase<int>
{ // nonmutable collection of facets that describe a locale
public:
typedef int category;
// CLASS id
class _CRTIMP2_PURE id
{ // identifier stamp, unique for each distinct kind of facet
public:
__CLR_OR_THIS_CALL id(size_t _Val = 0)
: _Id(_Val)
{ // construct with specified stamp value
}
__CLR_OR_THIS_CALL operator size_t()
{ // get stamp, with lazy allocation
if (_Id == 0)
{ // still zero, allocate stamp
_BEGIN_LOCK(_LOCK_LOCALE)
if (_Id == 0)
_Id = ++_Id_cnt;
_END_LOCK()
}
return (_Id);
}
private:
size_t _Id; // the identifier stamp
__PURE_APPDOMAIN_GLOBAL static int _Id_cnt;
__CLR_OR_THIS_CALL id(const id&); // not defined
id& __CLR_OR_THIS_CALL operator=(const id&); // not defined
};
class _Locimp;
// class facet
class facet
{ // base class for all locale facets, performs reference counting
friend class locale;
friend class _Locimp;
public:
_CRTIMP2_PURE static size_t __CLRCALL_OR_CDECL _Getcat(const facet ** = 0,
const locale * = 0)
{ // get category value, or -1 if no corresponding C category
return ((size_t)(-1));
}
_CRTIMP2_PURE void __CLR_OR_THIS_CALL _Incref()
{ // safely increment the reference count
_BEGIN_LOCK(_LOCK_LOCALE)
if (_Refs < (size_t)(-1))
++_Refs;
_END_LOCK()
}
_CRTIMP2_PURE facet *__CLR_OR_THIS_CALL _Decref()
{ // safely decrement the reference count, return this when dead
_BEGIN_LOCK(_LOCK_LOCALE)
if (0 < _Refs && _Refs < (size_t)(-1))
--_Refs;
return (_Refs == 0 ? this : 0);
_END_LOCK()
}
void __CLR_OR_THIS_CALL _Register()
{ // queue lazy facet destruction
#if defined(_M_CEE)
_Facet_Register_m(this);
#else /* defined(_M_CEE) */
_Facet_Register(this);
#endif /* defined(_M_CEE) */
}
#if defined(_DEBUG) && !defined(_M_X64)
_CRTIMP2_PURE void *__CLRCALL_OR_CDECL operator new(size_t _Size)
{ // replace operator new
return (operator new(_Size, _DebugHeapTag_func(),
__FILE__, __LINE__));
}
_CRTIMP2_PURE void *__CLRCALL_OR_CDECL operator new(size_t _Size,
const _DebugHeapTag_t& _Tag, char *_File, int _Line)
{ // replace debugging operator new
return (::operator new(_Size, _Tag, _File, _Line));
}
_CRTIMP2_PURE void __CLRCALL_OR_CDECL operator delete(void *_Ptr,
const _DebugHeapTag_t&, char *, int)
{ // replace debugging operator delete
operator delete(_Ptr);
}
_CRTIMP2_PURE void __CLRCALL_OR_CDECL operator delete(void *_Ptr)
{ // replace operator delete
_DebugHeapDelete((facet *)_Ptr);
}
#endif /* defined(_DEBUG) etc. */
// protected:
_CRTIMP2_PURE virtual __CLR_OR_THIS_CALL ~facet()
{ // destroy the object
}
protected:
_CRTIMP2_PURE explicit __CLR_OR_THIS_CALL facet(size_t _Initrefs = 0)
: _Refs(_Initrefs)
{ // construct with initial reference count
}
private:
size_t _Refs; // the reference count
__CLR_OR_THIS_CALL facet(const facet&); // not defined
facet& __CLR_OR_THIS_CALL operator=(const facet&); // not defined
#if defined(_M_CEE)
static void __CLRCALL_OR_CDECL _Facet_Register_m(facet *);
#else /* defined(_M_CEE) */
static void __CLRCALL_OR_CDECL _Facet_Register(facet *);
#endif /* defined(_M_CEE) */
};
// CLASS _Locimp
#pragma warning(push)
#pragma warning(disable: 4275)
class _CRTIMP2_PURE _Locimp
: public facet
{ // reference-counted actual implementation of a locale
protected:
__CLR_OR_THIS_CALL ~_Locimp()
{ // destroy the object
_Locimp_dtor(this);
}
private:
static _MRTIMP2_PURE_NPURE void __CLRCALL_PURE_OR_CDECL _Locimp_dtor(_Locimp *);
static _MRTIMP2_PURE_NPURE void __CLRCALL_PURE_OR_CDECL _Locimp_Addfac(_Locimp *, facet *,
size_t); // add a facet
static void __CLRCALL_PURE_OR_CDECL _Locimp_ctor(_Locimp *, const _Locimp&);
friend class locale;
__CLR_OR_THIS_CALL _Locimp(bool _Transparent = false)
: locale::facet(1), _Facetvec(0), _Facetcount(0),
_Catmask(none), _Xparent(_Transparent),
_Name("*")
{ // construct an empty _Locimp
}
__CLR_OR_THIS_CALL _Locimp(const _Locimp& _Right)
: locale::facet(1), _Facetvec(0), _Facetcount(_Right._Facetcount),
_Catmask(_Right._Catmask), _Xparent(_Right._Xparent),
_Name(_Right._Name.c_str())
{ // construct by copying
_Locimp_ctor(this, _Right);
}
void __CLR_OR_THIS_CALL _Addfac(facet *_Pfacet, size_t _Id)
{ // add a facet
_Locimp_Addfac(this, _Pfacet, _Id);
}
static _Locimp *__CLRCALL_OR_CDECL _Makeloc(const _Locinfo&,
category, _Locimp *, const locale *); // make essential facets
static void __CLRCALL_OR_CDECL _Makewloc(const _Locinfo&,
category, _Locimp *, const locale *); // make wchar_t facets
#ifdef _NATIVE_WCHAR_T_DEFINED
static void __CLRCALL_OR_CDECL _Makeushloc(const _Locinfo&,
category, _Locimp *, const locale *); // make ushort facets
#endif /* _NATIVE_WCHAR_T_DEFINED */
static void __CLRCALL_OR_CDECL _Makexloc(const _Locinfo&,
category, _Locimp *, const locale *); // make remaining facets
facet **_Facetvec; // pointer to vector of facets
size_t _Facetcount; // size of vector of facets
category _Catmask; // mask describing implemented categories
bool _Xparent; // true if locale is transparent
_Yarn<char> _Name; // locale name, or "*" if not known
__PURE_APPDOMAIN_GLOBAL static _Locimp *_Clocptr;
private:
_Locimp& __CLR_OR_THIS_CALL operator=(const _Locimp&); // not defined
};
#pragma warning(pop)
template<class _Elem,
class _Traits,
class _Alloc>
bool operator()(const basic_string<_Elem, _Traits, _Alloc>& _Left,
const basic_string<_Elem, _Traits, _Alloc>& _Right) const
{ // compare _Left and _Right strings using collate facet in locale
const _STD collate<_Elem>& _Coll_fac =
_STD use_facet<_STD collate<_Elem> >(*this);
return (_Coll_fac.compare(_Left.c_str(), _Left.c_str() + _Left.size(),
_Right.c_str(), _Right.c_str() + _Right.size()) < 0);
}
template<class _Facet>
locale combine(const locale& _Loc) const
{ // combine two locales
_Facet *_Facptr;
_TRY_BEGIN
_Facptr = (_Facet *)&_STD use_facet<_Facet>(_Loc);
_CATCH_ALL
_Xruntime_error("locale::combine facet missing");
_CATCH_END
_Locimp *_Newimp = _NEW_CRT _Locimp(*_Ptr);
_Newimp->_Addfac(_Facptr, _Facet::id);
_Newimp->_Catmask = 0;
_Newimp->_Name = "*";
return (locale(_Newimp));
}
template<class _Facet>
locale(const locale& _Loc, const _Facet *_Facptr)
: _Ptr(_NEW_CRT _Locimp(*_Loc._Ptr))
{ // construct from _Loc, replacing facet with *_Facptr
if (_Facptr != 0)
{ // replace facet
_Ptr->_Addfac((_Facet *)_Facptr, _Facet::id);
if (_Facet::_Getcat() != (size_t)(-1))
{ // no C category
_Ptr->_Catmask = 0;
_Ptr->_Name = "*";
}
}
}
locale(_Uninitialized)
{ // defer construction
}
locale(const locale& _Right) _THROW0()
: _Ptr(_Right._Ptr)
{ // construct by copying
_Ptr->_Incref();
}
locale() _THROW0()
: _Ptr(_Init())
{ // construct from current locale
_Getgloballocale()->_Incref();
}
#ifndef MRTDLL
locale(const locale& _Loc, const locale& _Other,
category _Cat)
: _Ptr(_NEW_CRT _Locimp(*_Loc._Ptr))
{ // construct a locale by copying named facets
_TRY_BEGIN
_BEGIN_LOCINFO(_Lobj(_Loc._Ptr->_Catmask, _Loc._Ptr->_Name.c_str()))
_Locimp::_Makeloc(_Lobj._Addcats(_Cat & _Other._Ptr->_Catmask,
_Other._Ptr->_Name.c_str()), _Cat, _Ptr, &_Other);
_END_LOCINFO()
_CATCH_ALL
_DELETE_CRT(_Ptr->_Decref());
_RERAISE;
_CATCH_END
}
explicit locale(const char *_Locname,
category _Cat = all) // construct from named locale for category
: _Ptr(_NEW_CRT _Locimp)
{ // construct a locale with named facets
_TRY_BEGIN
_Init();
_BEGIN_LOCINFO(_Lobj(_Cat, _Locname))
if (_Badname(_Lobj))
_Xruntime_error("bad locale name");
_Locimp::_Makeloc(_Lobj, _Cat, _Ptr, 0);
_END_LOCINFO()
_CATCH_ALL
_DELETE_CRT(_Ptr->_Decref());
_RERAISE;
_CATCH_END
}
locale(const locale& _Loc, const char *_Locname,
category _Cat)
: _Ptr(_NEW_CRT _Locimp(*_Loc._Ptr))
{ // construct a locale by copying, replacing named facets
_TRY_BEGIN
_BEGIN_LOCINFO(_Lobj(_Loc._Ptr->_Catmask, _Loc._Ptr->_Name.c_str()))
bool _Hadname = !_Badname(_Lobj);
_Lobj._Addcats(_Cat, _Locname);
if (_Hadname && _Badname(_Lobj))
_Xruntime_error("bad locale name");
_Locimp::_Makeloc(_Lobj, _Cat, _Ptr, 0);
_END_LOCINFO()
_CATCH_ALL
_DELETE_CRT(_Ptr->_Decref());
_RERAISE;
_CATCH_END
}
#if _HAS_CPP0X
explicit locale(const string& _Str,
category _Cat = all)
: _Ptr(_NEW_CRT _Locimp)
{ // construct a locale with named facets
_TRY_BEGIN
_Init();
_Locinfo _Lobj(_Cat, _Str.c_str());
if (_Badname(_Lobj))
_Xruntime_error("bad locale name");
_Locimp::_Makeloc(_Lobj, _Cat, _Ptr, 0);
_CATCH_ALL
_DELETE_CRT(_Ptr->_Decref());
_RERAISE;
_CATCH_END
}
locale(const locale& _Loc, const string& _Str,
category _Cat)
: _Ptr(_NEW_CRT _Locimp(*_Loc._Ptr))
{ // construct a locale by copying, replacing named facets
_TRY_BEGIN
_Locinfo _Lobj(_Loc._Ptr->_Catmask, _Loc._Ptr->_Name.c_str());
bool _Hadname = !_Badname(_Lobj);
_Lobj._Addcats(_Cat, _Str.c_str());
if (_Hadname && _Badname(_Lobj))
_Xruntime_error("bad locale name");
_Locimp::_Makeloc(_Lobj, _Cat, _Ptr, 0);
_CATCH_ALL
_DELETE_CRT(_Ptr->_Decref());
_RERAISE;
_CATCH_END
}
#endif /* _HAS_CPP0X */
#endif /* MRTDLL */
~locale() _THROW0()
{ // destroy the object
if (_Ptr != 0)
_DELETE_CRT(_Ptr->_Decref());
}
locale& operator=(const locale& _Right) _THROW0()
{ // assign a locale
if (_Ptr != _Right._Ptr)
{ // different implementation, point at new one
_DELETE_CRT(_Ptr->_Decref());
_Ptr = _Right._Ptr;
_Ptr->_Incref();
}
return (*this);
}
string name() const
{ // return locale name
return (_Ptr->_Name.c_str());
}
const char *c_str() const
{ // return locale name as NTBS
return (_Ptr->_Name.c_str());
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -