📄 xlocmon
字号:
// xlocmon internal header (from <locale>)
#pragma once
#ifndef _XLOCMON_
#define _XLOCMON_
#ifndef RC_INVOKED
#include <xlocnum>
#pragma pack(push,_CRT_PACKING)
#pragma warning(push,3)
#pragma push_macro("new")
#undef new
#pragma warning(disable: 4275)
_STD_BEGIN
// STRUCT money_base
struct money_base
: public locale::facet
{ // ultimate base class for moneypunct
enum
{ // constants for different format codes
symbol = '$', sign = '+', space = ' ', value = 'v', none = 'x'};
typedef int part;
struct pattern
{ // four-part formats for monetary text
char field[4];
};
money_base(size_t _Refs = 0)
: locale::facet(_Refs)
{ // default constructor
}
};
// TEMPLATE CLASS _Mpunct
template<class _Elem>
class _Mpunct
: public money_base
{ // common base class for moneypunct<_Elem, false/true>
public:
typedef _Elem char_type;
typedef basic_string<_Elem, char_traits<_Elem>, allocator<_Elem> >
string_type;
_Elem decimal_point() const
{ // return decimal point
return (do_decimal_point());
}
_Elem thousands_sep() const
{ // return thousands separator
return (do_thousands_sep());
}
string grouping() const
{ // return grouping string
return (do_grouping());
}
string_type curr_symbol() const
{ // return currency symbol string
return (do_curr_symbol());
}
string_type positive_sign() const
{ // return plus sign
return (do_positive_sign());
}
string_type negative_sign() const
{ // return minus sign
return (do_negative_sign());
}
int frac_digits() const
{ // return number of fraction digits
return (do_frac_digits());
}
pattern pos_format() const
{ // return format for positive values
return (do_pos_format());
}
pattern neg_format() const
{ // return format for negative values
return (do_neg_format());
}
explicit _Mpunct(size_t _Refs, bool _Intl)
: money_base(_Refs), _International(_Intl)
{ // construct from current locale
_BEGIN_LOCINFO(_Lobj)
_Init(_Lobj);
_END_LOCINFO()
}
_Mpunct(const _Locinfo& _Lobj, size_t _Refs, bool _Intl,
bool _Isdef = false)
: money_base(_Refs), _International(_Intl)
{ // construct from specified locale
_Init(_Lobj, _Isdef);
}
protected:
_Mpunct(const char *_Locname, size_t _Refs,
bool _Intl, bool _Isdef = false)
: money_base(_Refs), _International(_Intl)
{ // construct from specified locale
_BEGIN_LOCINFO(_Lobj(_Locname))
_Init(_Lobj, _Isdef);
_END_LOCINFO()
}
virtual __CLR_OR_THIS_CALL ~_Mpunct()
{ // destroy the object
_Tidy();
}
void _Init(const _Locinfo& _Lobj, bool _Isdef = false)
{ // initialize from _Lobj
_Cvt = _Lobj._Getcvt();
const lconv *_Ptr = _Lobj._Getlconv();
_Grouping = 0;
_Currencysign = 0;
_Plussign = 0;
_Minussign = 0;
_TRY_BEGIN
_Grouping = _MAKLOCSTR(char, _Ptr->mon_grouping, _Cvt);
_Currencysign = _MAKLOCSTR(_Elem, _International
? _Ptr->int_curr_symbol : _Ptr->currency_symbol, _Cvt);
_Plussign = _MAKLOCSTR(_Elem, 4 < (unsigned int)_Ptr->p_sign_posn
? "" : _Ptr->positive_sign, _Cvt);
_Minussign = _MAKLOCSTR(_Elem, 4 < (unsigned int)_Ptr->n_sign_posn
? "-" : _Ptr->negative_sign, _Cvt);
_CATCH_ALL
_Tidy();
_RERAISE;
_CATCH_END
_Decimalpoint = _MAKLOCCHR(_Elem, _Ptr->mon_decimal_point[0], _Cvt);
_Kseparator = _MAKLOCCHR(_Elem, _Ptr->mon_thousands_sep[0], _Cvt);
_Fracdigits = _International ? _Ptr->int_frac_digits
: _Ptr->frac_digits;
if (_Fracdigits < 0 || CHAR_MAX <= _Fracdigits)
_Fracdigits = 0;
_Makpat(_Plusformat, _Ptr->p_sep_by_space,
_Ptr->p_cs_precedes, _Ptr->p_sign_posn);
_Makpat(_Minusformat, _Ptr->n_sep_by_space,
_Ptr->n_cs_precedes, _Ptr->n_sign_posn);
if (_Isdef)
{ // apply defaults for required facets
memcpy(&_Plusformat, "$+xv", 4);
memcpy(&_Minusformat, "$+xv", 4);
}
}
virtual _Elem __CLR_OR_THIS_CALL do_decimal_point() const
{ // return decimal point
return (_Decimalpoint);
}
virtual _Elem __CLR_OR_THIS_CALL do_thousands_sep() const
{ // return thousands separator
return (_Kseparator);
}
virtual string __CLR_OR_THIS_CALL do_grouping() const
{ // return grouping string
return (string(_Grouping));
}
virtual string_type __CLR_OR_THIS_CALL do_curr_symbol() const
{ // return currency symbol string
return (string_type(_Currencysign));
}
virtual string_type __CLR_OR_THIS_CALL do_positive_sign() const
{ // return plus sign
return (string_type(_Plussign));
}
virtual string_type __CLR_OR_THIS_CALL do_negative_sign() const
{ // return minus sign
return (string_type(_Minussign));
}
virtual int __CLR_OR_THIS_CALL do_frac_digits() const
{ // return number of fraction digits
return (_Fracdigits);
}
virtual pattern __CLR_OR_THIS_CALL do_pos_format() const
{ // return format for positive values
return (_Plusformat);
}
virtual pattern __CLR_OR_THIS_CALL do_neg_format() const
{ // return format for negative values
return (_Minusformat);
}
private:
void _Makpat(pattern& _Pattern, unsigned int _Sepbyspace,
unsigned int _Symbolprecedes, unsigned int _Signposition)
{ // make format pattern from locale information
const char *_Ptr = _International || 2 < _Sepbyspace
|| 1 < _Symbolprecedes || 4 < _Signposition
? "$+xv" // international or bad parameters
: &(
"+v$x" "+v$x" "v$+x" "v+$x" "v$+x"
"+$vx" "+$vx" "$v+x" "+$vx" "$+vx"
"+v $" "+v $" "v $+" "v +$" "v $+"
"+$ v" "+$ v" "$ v+" "+$ v" "$+ v"
"+xv$" "+ v$" "v$ +" "v+ $" "v$ +"
"+x$v" "+ $v" "$v +" "+ $v" "$ +v")
[_Signposition * 4 // pick even/odd column
+ _Symbolprecedes * 20 // pick even/odd row
+ _Sepbyspace * 40]; // pick first/second/third group
_CRT_SECURE_MEMCPY(_Pattern.field, sizeof (_Pattern.field), _Ptr, 4);
}
void _Tidy()
{ // free all storage
_DELETE_CRT_VEC((void *)_Grouping);
_DELETE_CRT_VEC((void *)_Currencysign);
_DELETE_CRT_VEC((void *)_Plussign);
_DELETE_CRT_VEC((void *)_Minussign);
}
const char *_Grouping; // grouping string, "" for "C" locale
_Elem _Decimalpoint; // decimal point, '\0' for "C" locale
_Elem _Kseparator; // thousands separator, '\0' for "C" locale
const _Elem *_Currencysign; // currency symbol, "" for "C" locale
const _Elem *_Plussign; // plus sign, "" for "C" locale
const _Elem *_Minussign; // minus sign, "-" for "C" locale
int _Fracdigits; // number of fraction digits, 0 for "C" locale
pattern _Plusformat; // positive format, "$+vx" for "C" locale
pattern _Minusformat; // negative format, "$+vx" for "C" locale
bool _International; // true if international format
_Locinfo::_Cvtvec _Cvt; // conversion information
};
// TEMPLATE CLASS moneypunct
template<class _Elem,
bool _Intl = false>
class moneypunct
: public _Mpunct<_Elem>
{ // facet for defining monetary punctuation text
public:
_PGLOBAL _CRTIMP2_PURE static const bool intl; // true if international
__PURE_APPDOMAIN_GLOBAL _CRTIMP2_PURE static locale::id id; // unique facet id
explicit moneypunct(size_t _Refs = 0)
: _Mpunct<_Elem>(_Refs, _Intl)
{ // construct from current locale
}
moneypunct(const _Locinfo& _Lobj, size_t _Refs = 0, bool _Isdef = false)
: _Mpunct<_Elem>(_Lobj, _Refs, _Intl, _Isdef)
{ // construct from specified locale
}
static size_t _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 moneypunct<_Elem, _Intl>(
_Locinfo(_Ploc->c_str()), 0, true);
return (_X_MONETARY);
}
protected:
moneypunct(const char *_Locname, size_t _Refs = 0)
: _Mpunct<_Elem>(_Locname, _Refs, _Intl)
{ // construct from specified locale
}
virtual __CLR_OR_THIS_CALL ~moneypunct()
{ // destroy the object
}
};
// STATIC moneypunct::intl OBJECT
template<class _Elem,
bool _Intl>
_PGLOBAL const bool moneypunct<_Elem, _Intl>::intl = _Intl;
// STATIC moneypunct::id OBJECT
template<class _Elem,
bool _Intl>
__PURE_APPDOMAIN_GLOBAL locale::id moneypunct<_Elem, _Intl>::id;
// TEMPLATE CLASS moneypunct_byname
template<class _Elem,
bool _Intl = false>
class moneypunct_byname
: public moneypunct<_Elem, _Intl>
{ // moneypunct for named locale
public:
explicit moneypunct_byname(const char *_Locname, size_t _Refs = 0)
: moneypunct<_Elem, _Intl>(_Locname, _Refs)
{ // construct for named locale
}
#if _HAS_CPP0X
explicit moneypunct_byname(const string& _Str, size_t _Refs = 0)
: moneypunct<_Elem, _Intl>(_Str.c_str(), _Refs)
{ // construct for named locale
}
#endif /* _HAS_CPP0X */
protected:
virtual __CLR_OR_THIS_CALL ~moneypunct_byname()
{ // destroy the object
}
};
// TEMPLATE CLASS money_get
template<class _Elem,
class _InIt = istreambuf_iterator<_Elem, char_traits<_Elem> > >
class money_get
: public locale::facet
{ // facet for converting text to encoded monetary amounts
typedef moneypunct<_Elem, false> _Mypunct0;
typedef moneypunct<_Elem, true> _Mypunct1;
public:
typedef _Elem char_type;
typedef _InIt iter_type;
typedef basic_string<_Elem, char_traits<_Elem>, allocator<_Elem> >
string_type;
_InIt get(_InIt _First, _InIt _Last,
bool _Intl, ios_base& _Iosbase, ios_base::iostate& _State,
long double& _Val) const
{ // get long double from [_First, _Last) into _Val
return (do_get(_First, _Last, _Intl, _Iosbase, _State, _Val));
}
_InIt get(_InIt _First, _InIt _Last,
bool _Intl, ios_base& _Iosbase, ios_base::iostate& _State,
string_type& _Val) const
{ // get string_type from [_First, _Last) into _Val
return (do_get(_First, _Last, _Intl, _Iosbase, _State, _Val));
}
__PURE_APPDOMAIN_GLOBAL _CRTIMP2_PURE static locale::id id; // unique facet id
explicit money_get(size_t _Refs = 0)
: locale::facet(_Refs)
{ // construct from current locale
_BEGIN_LOCINFO(_Lobj)
_Init(_Lobj);
_END_LOCINFO()
}
money_get(const _Locinfo& _Lobj, size_t _Refs = 0)
: locale::facet(_Refs)
{ // construct from specified locale
_Init(_Lobj);
}
static size_t _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 money_get<_Elem, _InIt>(
_Locinfo(_Ploc->c_str()));
return (_X_MONETARY);
}
protected:
virtual __CLR_OR_THIS_CALL ~money_get()
{ // destroy the object
}
void _Init(const _Locinfo& _Lobj)
{ // initialize from _Locinfo object
_Cvt = _Lobj._Getcvt();
}
virtual _InIt __CLR_OR_THIS_CALL do_get(_InIt _First, _InIt _Last,
bool _Intl, ios_base& _Iosbase, ios_base::iostate& _State,
long double& _Val) const
{ // get long double from [_First, _Last) into _Val
string_type _Str = _Getmfld(_First, _Last, _Intl, _Iosbase);
if (_First == _Last)
_State |= ios_base::eofbit;
if (_Str.size() == 0)
_State |= ios_base::failbit; // _Getmfld failed
else
{ // convert to char string, then to long double
const _Elem _E0 = _MAKLOCCHR(_Elem, '0', _Cvt);
string _Str2;
_Str2.reserve(_Str.size());
size_t _Off = 0;
if (_Str[0] < _E0 || _E0 + 9 < _Str[0])
_Str2 += '-', ++_Off;
for (; _Off < _Str.size(); ++_Off)
_Str2 += (char)(_Str[_Off] - _E0 + '0');
const char *_Eb = _Str2.c_str();
char *_Ep;
int _Errno = 0;
const long double _Ans =
_CSTD _Stoldx(_Eb, &_Ep, 0, &_Errno); // convert
if (_Ep == _Eb || _Errno != 0)
_State |= ios_base::failbit;
else
_Val = _Ans; // deliver value
}
return (_First);
}
virtual _InIt __CLR_OR_THIS_CALL do_get(_InIt _First, _InIt _Last,
bool _Intl, ios_base& _Iosbase, ios_base::iostate& _State,
string_type& _Val) const
{ // get string_type from [_First, _Last) into _Val
string_type _Str = _Getmfld(_First, _Last, _Intl, _Iosbase);
if (_First == _Last)
_State |= ios_base::eofbit;
if (_Str.size() == 0)
_State |= ios_base::failbit; // _Getmfld failed
else
_Val = _Str; // deliver value
return (_First);
}
private:
string_type _Getmfld(_InIt& _First, _InIt& _Last,
bool _Intl, ios_base& _Iosbase) const
{ // get monetary field from [_First, _Last) into string_type
_DEBUG_RANGE(_First, _Last);
const _Mpunct<_Elem> *_Ppunct_fac;
if (_Intl)
_Ppunct_fac =
&_USE(_Iosbase.getloc(), _Mypunct1); // international
else
_Ppunct_fac =
&_USE(_Iosbase.getloc(), _Mypunct0); // local
bool _Bad = false, _Neg = false;
string_type _Sign, _Val;
const money_base::pattern _Pattern = _Ppunct_fac->neg_format();
for (size_t _Off = 0; !_Bad && _Off < 4; ++_Off)
switch (_Pattern.field[_Off])
{ // parse a format component
case money_base::symbol:
{ // parse currency symbol
string_type _Symbol = _Ppunct_fac->curr_symbol();
typename string_type::const_iterator _Source;
if (!(_Iosbase.flags() & ios_base::showbase)
&& _First != _Last && *_First != *_Symbol.c_str())
_Symbol.erase(); // showbase ==> mandatory symbol
else if (_Off == 3 && _Sign.size() <= 1
&& (_First == _Last || *_First != *_Symbol.c_str()))
_Symbol.erase(); // currency symbol optional at end
for (_Source = _Symbol.begin();
_First != _Last && _Source != _Symbol.end()
&& *_First == *_Source; ++_Source, ++_First)
; // still matching currency symbol
if (_Source != _Symbol.end())
_Bad = true; // currency symbol match failed
break;
}
case money_base::sign: // parse sign
if (_First == _Last)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -