📄 xlocale
字号:
const facet *_Getfacet(size_t _Id) const
{ // look up a facet in locale object
const facet *_Facptr = _Id < _Ptr->_Facetcount
? _Ptr->_Facetvec[_Id] : 0; // null if id off end
if (_Facptr != 0 || !_Ptr->_Xparent)
return (_Facptr); // found facet or not transparent
else
{ // look in current locale
locale::_Locimp *_Ptr = _Getgloballocale();
return (_Id < _Ptr->_Facetcount
? _Ptr->_Facetvec[_Id] // get from current locale
: 0); // no entry in current locale
}
}
bool operator==(const locale& _Loc) const
{ // compare locales for equality
return (_Ptr == _Loc._Ptr
|| name().compare("*") != 0 && name().compare(_Loc.name()) == 0);
}
bool operator!=(const locale& _Right) const
{ // test for locale inequality
return (!(*this == _Right));
}
static _MRTIMP2_PURE const locale& __CLRCALL_PURE_OR_CDECL classic(); // classic "C" locale
static _MRTIMP2_PURE locale __CLRCALL_PURE_OR_CDECL global(const locale&); // current locale
static _MRTIMP2_PURE locale __CLRCALL_PURE_OR_CDECL empty(); // empty (transparent) locale
private:
locale(_Locimp *_Ptrimp)
: _Ptr(_Ptrimp)
{ // construct from _Locimp pointer
}
static _MRTIMP2_PURE _Locimp *__CLRCALL_PURE_OR_CDECL _Init(); // initialize locale
static _MRTIMP2_PURE _Locimp *__CLRCALL_PURE_OR_CDECL _Getgloballocale();
static _MRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _Setgloballocale(void *);
bool _Badname(const _Locinfo& _Lobj)
{ // test if name is "*"
return (_CSTD strcmp(_Lobj._Getname(), "*") == 0);
}
_Locimp *_Ptr; // pointer to locale implementation object
};
// SUPPORT TEMPLATES
template<class _Facet>
struct _Facetptr
{ // store pointer to lazy facet for use_facet
__PURE_APPDOMAIN_GLOBAL static const locale::facet *_Psave;
};
template<class _Facet>
__PURE_APPDOMAIN_GLOBAL const locale::facet *_Facetptr<_Facet>::
_Psave = 0;
#define _ADDFAC(loc, pfac) locale(loc, pfac) /* add facet to locale */
#define _USE(loc, fac) \
use_facet< fac >(loc) /* get facet reference from locale */
template<class _Facet> inline
const _Facet& __CRTDECL use_facet(const locale& _Loc)
{ // get facet reference from locale
_BEGIN_LOCK(_LOCK_LOCALE) // the thread lock, make get atomic
const locale::facet *_Psave =
_Facetptr<_Facet>::_Psave; // static pointer to lazy facet
size_t _Id = _Facet::id;
const locale::facet *_Pf = _Loc._Getfacet(_Id);
if (_Pf != 0)
; // got facet from locale
else if (_Psave != 0)
_Pf = _Psave; // lazy facet already allocated
else if (_Facet::_Getcat(&_Psave, &_Loc) == (size_t)(-1))
#if _HAS_EXCEPTIONS
_THROW_NCEE(bad_cast, _EMPTY_ARGUMENT); // lazy disallowed
#else /* _HAS_EXCEPTIONS */
abort(); // lazy disallowed
#endif /* _HAS_EXCEPTIONS */
else
{ // queue up lazy facet for destruction
_Pf = _Psave;
_Facetptr<_Facet>::_Psave = _Psave;
locale::facet *_Pfmod = (_Facet *)_Psave;
_Pfmod->_Incref();
_Pfmod->_Register();
}
return ((const _Facet&)(*_Pf)); // should be dynamic_cast
_END_LOCK()
}
// TEMPLATE FUNCTION _Getloctxt
template<class _Elem,
class _InIt> inline
int __CRTDECL _Getloctxt(_InIt& _First, _InIt& _Last, size_t _Numfields,
const _Elem *_Ptr)
{ // find field at _Ptr that matches longest in [_First, _Last)
for (size_t _Off = 0; _Ptr[_Off] != (_Elem)0; ++_Off)
if (_Ptr[_Off] == _Ptr[0])
++_Numfields; // add fields with leading mark to initial count
string _Str(_Numfields, '\0'); // one column counter for each field
int _Ans = -2; // no candidates so far
for (size_t _Column = 1; ; ++_Column, ++_First, _Ans = -1)
{ // test each element against all viable fields
bool _Prefix = false; // seen at least one valid prefix
size_t _Off = 0; // offset into fields
size_t _Field = 0; // current field number
for (; _Field < _Numfields; ++_Field)
{ // test element at _Column in field _Field
for (; _Ptr[_Off] != (_Elem)0 && _Ptr[_Off] != _Ptr[0]; ++_Off)
; // find beginning of field
if (_Str[_Field] != '\0')
_Off += _Str[_Field]; // skip tested columns in field
else if (_Ptr[_Off += _Column] == _Ptr[0]
|| _Ptr[_Off] == (_Elem)0)
{ // matched all of field, save as possible answer
_Str[_Field] = (char)(_Column < 127
? _Column : 127); // save skip count if small enough
_Ans = (int)_Field; // save answer
}
else if (_First == _Last || _Ptr[_Off] != *_First)
_Str[_Field] = (char)(_Column < 127
? _Column : 127); // no match, just save skip count
else
_Prefix = true; // still a valid prefix
}
if (!_Prefix || _First == _Last)
break; // no pending prefixes or no input, give up
}
return (_Ans); // return field number or negative value on failure
}
// TEMPLATE FUNCTION _Maklocbyte
#define _MAKLOCBYTE(Elem, chr, cvt) \
_Maklocbyte((_Elem)chr, cvt) /* convert Elem to char */
template<class _Elem> inline
char __CRTDECL _Maklocbyte(_Elem _Char,
const _Locinfo::_Cvtvec&)
{ // convert _Elem to char using _Cvtvec
return ((char)(unsigned char)_Char);
}
template<> inline
char __CRTDECL _Maklocbyte(wchar_t _Char,
const _Locinfo::_Cvtvec& _Cvt)
{ // convert wchar_t to char using _Cvtvec
char _Byte = '\0';
_Mbstinit(_Mbst1);
_Wcrtomb(&_Byte, _Char, &_Mbst1, &_Cvt);
return (_Byte);
}
#ifdef _NATIVE_WCHAR_T_DEFINED
template<> inline
char __CRTDECL _Maklocbyte(unsigned short _Char,
const _Locinfo::_Cvtvec &_Cvt)
{ // convert unsigned short to char using _Cvtvec
char _Byte = '\0';
_Mbstinit(_Mbst1);
_Wcrtomb(&_Byte, (wchar_t)_Char, &_Mbst1, &_Cvt);
return (_Byte);
}
#endif /* _NATIVE_WCHAR_T_DEFINED */
// TEMPLATE FUNCTION _Maklocchr
#define _MAKLOCCHR(Elem, chr, cvt) \
_Maklocchr(chr, (Elem *)0, cvt) /* convert char to Elem */
template<class _Elem> inline
_Elem __CRTDECL _Maklocchr(char _Byte, _Elem *,
const _Locinfo::_Cvtvec&)
{ // convert char to _Elem using _Cvtvec
return ((_Elem)(unsigned char)_Byte);
}
template<> inline
wchar_t __CRTDECL _Maklocchr(char _Byte, wchar_t *,
const _Locinfo::_Cvtvec& _Cvt)
{ // convert char to wchar_t using _Cvtvec
wchar_t _Wc = L'\0';
_Mbstinit(_Mbst1);
_Mbrtowc(&_Wc, &_Byte, 1, &_Mbst1, &_Cvt);
return (_Wc);
}
#ifdef _NATIVE_WCHAR_T_DEFINED
template<> inline
unsigned short __CRTDECL _Maklocchr(char _Byte, unsigned short *,
const _Locinfo::_Cvtvec &_Cvt)
{ // convert char to unsigned short using _Cvtvec
unsigned short _Wc = (unsigned short)0;
_Mbstinit(_Mbst1);
_Mbrtowc((wchar_t *)&_Wc, &_Byte, 1, &_Mbst1, &_Cvt);
return (_Wc);
}
#endif /* _NATIVE_WCHAR_T_DEFINED */
// TEMPLATE FUNCTION _Maklocstr
#define _MAKLOCSTR(Elem, str, cvt) \
_Maklocstr(str, (Elem *)0, cvt) /* convert C string to Elem sequence */
template<class _Elem> inline
_Elem *__CRTDECL _Maklocstr(const char *_Ptr, _Elem *,
const _Locinfo::_Cvtvec&)
{ // convert C string to _Elem sequence using _Cvtvec
size_t _Count = _CSTD strlen(_Ptr) + 1;
_Elem *_Ptrdest = _NEW_CRT _Elem[_Count];
#pragma warning(push)
#pragma warning(disable: 6011) /* quiet prefast noise */
for (_Elem *_Ptrnext = _Ptrdest; 0 < _Count; --_Count, ++_Ptrnext, ++_Ptr)
*_Ptrnext = (_Elem)(unsigned char)*_Ptr;
#pragma warning(pop)
return (_Ptrdest);
}
template<> inline
wchar_t *__CRTDECL _Maklocstr(const char *_Ptr, wchar_t *,
const _Locinfo::_Cvtvec& _Cvt)
{ // convert C string to wchar_t sequence using _Cvtvec
size_t _Count, _Count1;
size_t _Wchars;
const char *_Ptr1;
int _Bytes;
wchar_t _Wc;
_Mbstinit(_Mbst1);
_Count1 = _CSTD strlen(_Ptr) + 1;
for (_Count = _Count1, _Wchars = 0, _Ptr1 = _Ptr; 0 < _Count;
_Count -= _Bytes, _Ptr1 += _Bytes, ++_Wchars)
if ((_Bytes = _Mbrtowc(&_Wc, _Ptr1, _Count, &_Mbst1, &_Cvt)) <= 0)
break;
++_Wchars; // count terminating nul
wchar_t *_Ptrdest = _NEW_CRT wchar_t[_Wchars];
wchar_t *_Ptrnext = _Ptrdest;
_Mbstinit(_Mbst2);
#pragma warning(push)
#pragma warning(disable: 6011) /* quiet prefast noise */
for (; 0 < _Wchars;
_Count -= _Bytes, _Ptr += _Bytes, --_Wchars, ++_Ptrnext)
if ((_Bytes = _Mbrtowc(_Ptrnext, _Ptr, _Count1, &_Mbst2, &_Cvt)) <= 0)
break;
*_Ptrnext = L'\0';
#pragma warning(pop)
return (_Ptrdest);
}
#ifdef _NATIVE_WCHAR_T_DEFINED
template<> inline
unsigned short *__CRTDECL _Maklocstr(const char *_Ptr, unsigned short *,
const _Locinfo::_Cvtvec &_Cvt)
{ // convert C string to unsigned short sequence using _Cvtvec
size_t _Count, _Count1;
size_t _Wchars;
const char *_Ptr1;
int _Bytes;
unsigned short _Wc;
_Mbstinit(_Mbst1);
_Count1 = _CSTD strlen(_Ptr) + 1;
for (_Count = _Count1, _Wchars = 0, _Ptr1 = _Ptr; 0 < _Count;
_Count -= _Bytes, _Ptr1 += _Bytes, ++_Wchars)
if ((_Bytes =
_Mbrtowc((wchar_t *)&_Wc, _Ptr1, _Count, &_Mbst1, &_Cvt)) <= 0)
break;
++_Wchars; // count terminating nul
wchar_t *_Ptrdest = _NEW_CRT wchar_t[_Wchars];
wchar_t *_Ptrnext = _Ptrdest;
_Mbstinit(_Mbst2);
for (; 0 < _Wchars;
_Count -= _Bytes, _Ptr += _Bytes, --_Wchars, ++_Ptrnext)
if ((_Bytes = _Mbrtowc(_Ptrnext, _Ptr, _Count1, &_Mbst2, &_Cvt)) <= 0)
break;
*_Ptrnext = L'\0';
return ((unsigned short *)_Ptrdest);
}
#endif /* _NATIVE_WCHAR_T_DEFINED */
// STRUCT codecvt_base
#pragma warning(push)
#pragma warning(disable: 4275)
class _CRTIMP2_PURE codecvt_base
: public locale::facet
{ // base class for codecvt
public:
enum
{ // constants for different parse states
ok, partial, error, noconv};
typedef int result;
__CLR_OR_THIS_CALL codecvt_base(size_t _Refs = 0)
: locale::facet(_Refs)
{ // default constructor
}
bool __CLR_OR_THIS_CALL always_noconv() const _THROW0()
{ // return true if conversions never change input (from codecvt)
return (do_always_noconv());
}
int __CLR_OR_THIS_CALL max_length() const _THROW0()
{ // return maximum length required for a conversion (from codecvt)
return (do_max_length());
}
int __CLR_OR_THIS_CALL encoding() const _THROW0()
{ // return length of code sequence (from codecvt)
return (do_encoding());
}
__CLR_OR_THIS_CALL ~codecvt_base()
{ // destroy the object
}
protected:
virtual bool __CLR_OR_THIS_CALL do_always_noconv() const _THROW0()
{ // return true if conversions never change input (from codecvt)
return (true);
}
virtual int __CLR_OR_THIS_CALL do_max_length() const _THROW0()
{ // return maximum length required for a conversion (from codecvt)
return (1);
}
virtual int __CLR_OR_THIS_CALL do_encoding() const _THROW0()
{ // return length of code sequence (from codecvt)
return (1); // -1 ==> state dependent, 0 ==> varying length
}
};
#pragma warning(pop)
// TEMPLATE CLASS codecvt
template<class _Elem,
class _Byte,
class _Statype>
class codecvt
: public codecvt_base
{ // facet for converting between _Elem and char (_Byte) sequences
public:
typedef _Elem intern_type;
typedef _Byte extern_type;
typedef _Statype state_type;
result __CLR_OR_THIS_CALL in(_Statype& _State,
const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
_Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
{ // convert bytes [_First1, _Last1) to [_First2, _Last)
return (do_in(_State,
_First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
}
result __CLR_OR_THIS_CALL out(_Statype& _State,
const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
{ // convert [_First1, _Last1) to bytes [_First2, _Last2)
return (do_out(_State,
_First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
}
result __CLR_OR_THIS_CALL unshift(_Statype& _State,
_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
{ // generate bytes to return to default shift state
return (do_unshift(_State, _First2, _Last2, _Mid2));
}
int __CLR_OR_THIS_CALL length(const _Statype& _State, const _Byte *_First1,
const _Byte *_Last1, size_t _Count) const
{ // return min(_Count, converted length of bytes [_First1, _Last1))
return (do_length(_State, _First1, _Last1, _Count));
}
__PURE_APPDOMAIN_GLOBAL static locale::id id; // unique facet id
explicit __CLR_OR_THIS_CALL codecvt(size_t _Refs = 0)
: codecvt_base(_Refs)
{ // construct from current locale
_Init(_Locinfo());
}
__CLR_OR_THIS_CALL codecvt(const _Locinfo& _Lobj, size_t _Refs = 0)
: codecvt_base(_Refs)
{ // construct from specified locale
_Init(_Lobj);
}
static size_t __CLRCALL_OR_CDECL _Getcat(const locale::facet **_Ppf = 0,
const locale *_Ploc = 0)
{ // return locale category mask and construct standard facet
if (_Ppf != 0 && *_Ppf == 0)
*_Ppf = _NEW_CRT codecvt<_Elem, _Byte, _Statype>(
_Locinfo(_Ploc->c_str()));
return (_X_CTYPE);
}
protected:
virtual __CLR_OR_THIS_CALL ~codecvt()
{ // destroy the object
}
void __CLR_OR_THIS_CALL _Init(const _Locinfo&)
{ // initialize from _Locinfo object
}
virtual result __CLR_OR_THIS_CALL do_in(_Statype&,
const _Byte *_First1, const _Byte *, const _Byte *& _Mid1,
_Elem *_First2, _Elem *, _Elem *& _Mid2) const
{ // convert bytes [_First1, _Last1) to [_First2, _Last)
_Mid1 = _First1, _Mid2 = _First2;
return (noconv); // convert nothing
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -