xlocmon

来自「C语言库函数的原型,有用的拿去」· 代码 · 共 972 行 · 第 1/2 页

TXT
972
字号
					;	// assume no sign
				else if (0 < (_Ppunct_fac->positive_sign()).size()
					&& _Ppunct_fac->positive_sign()[0] == *_First)
					{	// match positive sign
					++_First;
					_Sign = _Ppunct_fac->positive_sign();
					}
				else if (0 < (_Ppunct_fac->negative_sign()).size()
					&& _Ppunct_fac->negative_sign()[0] == *_First)
					{	// match negative sign
					++_First;
					_Sign = _Ppunct_fac->negative_sign();
					_Neg = true;
					}
				else if (0 == (_Ppunct_fac->positive_sign()).size())
					;
				else if (0 == (_Ppunct_fac->negative_sign()).size())
					_Neg = true;
				break;	// sign match can't fail

			case money_base::value:
				{	// parse value field
				int _Fracdigseen = 0;
				int _Fracdigits = _Ppunct_fac->frac_digits();
				const _Elem _E0 = _MAKLOCCHR(_Elem, '0', _Cvt);
				const string _Grouping = _Ppunct_fac->grouping();
				const _Elem _Kseparator = _Grouping.size() == 0
					? (_Elem)0 : _Ppunct_fac->thousands_sep();

				if (_Kseparator == (_Elem)0
					|| CHAR_MAX <= (unsigned char)*_Grouping.c_str())
					for (; _First != _Last
						&& _E0 <= *_First && *_First <= _E0 + 9; ++_First)
					_Val += *_First;	// no grouping, just gather digits
				else
					{	// grouping specified, gather digits and group sizes
					string _Groups((size_t)1, '\0');
					size_t _Group = 0;

					for (; _First != _Last; ++_First)
						if ( _E0 <= *_First && *_First <= _E0 + 9)
							{	// got a digit, add to group size
							_Val += *_First;
							if (_Groups[_Group] != CHAR_MAX)
								++_Groups[_Group];
							}
						else if (_Groups[_Group] == '\0'
							|| *_First != _Kseparator)
							break;	// not a group separator, done
						else
							{	// add a new group to _Groups string
							_Groups.append((size_t)1, '\0');
							++_Group;
							}

					if (_Group == 0)
						;	// no thousands separators seen
					else if ('\0' < _Groups[_Group])
						++_Group;	// add trailing group to group count
					else
						_Bad = true;	// trailing separator, fail

					for (const char *_Pg = _Grouping.c_str();
						!_Bad && 0 < _Group; )
						if (*_Pg == CHAR_MAX)
							break;	// end of grouping constraints to check
						else if (0 < --_Group && *_Pg != _Groups[_Group]
							|| 0 == _Group && *_Pg < _Groups[_Group])
							_Bad = true;	// bad group size, fail
						else if ('\0' < _Pg[1])
							++_Pg;	// group size okay, advance to next test
					if (_Bad)
						break;	// bad grouping, give up
					}

				const _Elem _Point = _Ppunct_fac->decimal_point();
				if (_First != _Last
					&& _Point != (_Elem)0
					&& *_First == _Point)
					{	// seen decimal point, gather fraction digits
					while (++_First != _Last
						&& _Fracdigseen < _Fracdigits
						&& _E0 <= *_First && *_First <= _E0 + 9)
						_Val += *_First, ++_Fracdigseen;

					if (_Fracdigseen < _Fracdigits)
						_Bad = true;	// short fraction
					}

				if (_Val.size() == 0)
					_Bad = true;	// fail if no elements parsed
				else
					for (; _Fracdigseen < _Fracdigits; ++_Fracdigseen)
						_Val += _E0;	// pad out fraction
				break;
				}

			case money_base::space:
			case money_base::none:
				{	// parse optional space
				if (_Off == 3)
					break;	// ignore space at end

				const ctype<_Elem>& _Ctype_fac =
					_USE(_Iosbase.getloc(), ctype<_Elem>);
				while (_First != _Last
					&& _Ctype_fac.is(ctype_base::space, *_First))
					++_First;	// skip any space
				}
				}

		if (!_Bad && 1 < _Sign.size())
			{	// match rest of sign string
			typename string_type::const_iterator _Source;

			for (_Source = _Sign.begin(); ++_Source != _Sign.end()
				&& _First != _Last && *_First == *_Source; ++_First)
				;
			if (_Source != _Sign.end())
				_Bad = true;	// rest of sign doesn't match, fail
			}

		if (_Bad)
			_Val.erase();	// bad input, return empty string
		else if (_Neg)
			_Val.insert((size_t)0, (size_t)1, _MAKLOCCHR(_Elem, '-', _Cvt));
		return (_Val);
		}

	_Locinfo::_Cvtvec _Cvt;		// conversion information
	};

		// STATIC money_get::id OBJECT
template<class _Elem,
	class _InIt>
	__PURE_APPDOMAIN_GLOBAL locale::id money_get<_Elem, _InIt>::id;

		// TEMPLATE CLASS money_put
template<class _Elem,
	class _OutIt = ostreambuf_iterator<_Elem, char_traits<_Elem> > >
	class money_put
		: public locale::facet
	{	// facet for converting encoded monetary amounts to text
	typedef moneypunct<_Elem, false> _Mypunct0;
	typedef moneypunct<_Elem, true> _Mypunct1;

public:
	typedef _Elem char_type;
	typedef _OutIt iter_type;
	typedef basic_string<_Elem, char_traits<_Elem>, allocator<_Elem> >
		string_type;

	_OutIt put(_OutIt _Dest,
		bool _Intl, ios_base& _Iosbase, _Elem _Fill,
			long double _Val) const
		{	// put long double to _Dest
		return (do_put(_Dest, _Intl, _Iosbase, _Fill, _Val));
		}

	_OutIt put(_OutIt _Dest,
		bool _Intl, ios_base& _Iosbase, _Elem _Fill,
			const string_type& _Val) const
		{	// put string_type to _Dest
		return (do_put(_Dest, _Intl, _Iosbase, _Fill, _Val));
		}

	__PURE_APPDOMAIN_GLOBAL _CRTIMP2_PURE static locale::id id;	// unique facet id

	explicit money_put(size_t _Refs = 0)
		: locale::facet(_Refs)
		{	// construct from current locale
		_BEGIN_LOCINFO(_Lobj)
			_Init(_Lobj);
		_END_LOCINFO()
		}

	money_put(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_put<_Elem, _OutIt>(
				_Locinfo(_Ploc->c_str()));
		return (_X_MONETARY);
		}

protected:
	virtual __CLR_OR_THIS_CALL ~money_put()
		{	// destroy the object
		}

	void _Init(const _Locinfo& _Lobj)
		{	// initialize from _Locinfo object
		_Cvt = _Lobj._Getcvt();
		}

	virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest,
		bool _Intl, ios_base& _Iosbase, _Elem _Fill,
			long double _Val) const
		{	// put long double to _Dest
		bool _Negative = false;
		if (_Val < 0)
			_Negative = true, _Val = -_Val;

		size_t _Exp;
		for (_Exp = 0; 1e35 <= _Val && _Exp < 5000; _Exp += 10)
			_Val /= 1e10;	// drop 10 zeros before decimal point

		string_type _Val2;
		char _Buf[40];

		int _Count = _CSTD sprintf_s(_Buf, sizeof (_Buf), "%.0Lf",
			_Val);	// convert to chars

		for (int _Off = 0; _Off < _Count; ++_Off)
			_Val2.append((typename string_type::size_type)1,
				_MAKLOCCHR(_Elem, _Buf[_Off], _Cvt));	// convert chars
		_Val2.append(_Exp,
			_MAKLOCCHR(_Elem, '0', _Cvt));	// scale by trailing zeros

		return (_Putmfld(_Dest, _Intl, _Iosbase, _Fill, _Negative, _Val2));
		}

	virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest,
		bool _Intl, ios_base& _Iosbase, _Elem _Fill,
			const string_type& _Val) const
		{	// put string_type to _Dest
		const _Elem _E0 = _MAKLOCCHR(_Elem, '0', _Cvt);
		const _Elem *_Ptr = _Val.c_str();
		bool _Negative = false;
		if (*_Ptr == _MAKLOCCHR(_Elem, '-', _Cvt))
			_Negative = true, ++_Ptr;

		size_t _Count;
		for (_Count = 0; _E0 <= _Ptr[_Count] && _Ptr[_Count] <= _E0 + 9;
			++_Count)
			;	// count digits
		string_type _Val2(_Ptr, _Count);
		if (_Count == 0)	// replace empty digit string with '0'
			_Val2.append((typename string_type::size_type)1, _E0);

		return (_Putmfld(_Dest, _Intl, _Iosbase, _Fill, _Negative, _Val2));
		}

private:
	_OutIt _Putmfld(_OutIt _Dest,
		bool _Intl, ios_base& _Iosbase, _Elem _Fill,
			bool _Neg, string_type _Val) const
		{	// put string_type with just digits to _Dest
		_DEBUG_POINTER(_Dest);
		const _Mpunct<_Elem> *_Ppunct_fac;
		if (_Intl)
			_Ppunct_fac =
				&_USE(_Iosbase.getloc(), _Mypunct1);	// international
		else
			_Ppunct_fac =
				&_USE(_Iosbase.getloc(), _Mypunct0);	// local
		const _Elem _E0 = _MAKLOCCHR(_Elem, '0', _Cvt);

		const string _Grouping = _Ppunct_fac->grouping();
		int _Ifracdigits = _Ppunct_fac->frac_digits();
		unsigned int _Fracdigits = _Ifracdigits < 0 ? -_Ifracdigits
			: _Ifracdigits;

		if (_Val.size() <= _Fracdigits)
			_Val.insert((size_t)0, _Fracdigits - _Val.size() + 1, _E0);
		else if (*_Grouping.c_str() != CHAR_MAX && '\0' < *_Grouping.c_str())
			{	// grouping specified, add thousands separators
			const _Elem _Kseparator = _Ppunct_fac->thousands_sep();
			const char *_Pg = _Grouping.c_str();
			size_t _Off = _Val.size() - _Fracdigits;	// start of fraction

			while (*_Pg != CHAR_MAX && '\0' < *_Pg
				&& (size_t)*_Pg < _Off)
				{	// add a thousands separator, right to left
				_Val.insert(_Off -= *_Pg, (size_t)1, _Kseparator);
				if ('\0' < _Pg[1])
					++_Pg;	// not last group, advance
				}
			}

		money_base::pattern _Pattern;
		string_type _Sign;
		if (_Neg)
			{	// negative value, choose appropriate format and sign
			_Pattern = _Ppunct_fac->neg_format();
			_Sign = _Ppunct_fac->negative_sign();
			}
		else
			{	// positive value, choose appropriate format and sign
			_Pattern = _Ppunct_fac->pos_format();
			_Sign = _Ppunct_fac->positive_sign();
			}

		string_type _Symbol;
		if (_Iosbase.flags() & ios_base::showbase)
			_Symbol = _Ppunct_fac->curr_symbol();	// showbase ==> show $

		bool _Intern = false;
		size_t _Fillcount, _Off;
		for (_Fillcount = 0, _Off = 0; _Off < 4; ++_Off)
			switch (_Pattern.field[_Off])
			{	// accumulate total length in _Fillcount
			case money_base::symbol:	// count currency symbol size
				_Fillcount += _Symbol.size();
				break;

			case money_base::sign:	// count sign size
				_Fillcount += _Sign.size();
				break;

			case money_base::value:	// count value field size
				_Fillcount += _Val.size() + (0 < _Fracdigits ? 1 : 0)
					+ (_Val.size() <= _Fracdigits
						? _Fracdigits - _Val.size() + 1 : 0);
				break;

			case money_base::space:	// count space size
				++_Fillcount;	// at least one space
				// fall through

			case money_base::none:	// count space size
				if (_Off != 3)
					_Intern = true;	// optional internal fill
				break;
			}

		_Fillcount = _Iosbase.width() <= 0
			|| (size_t)_Iosbase.width() <= _Fillcount
				? 0 : (size_t)_Iosbase.width() - _Fillcount;

		ios_base::fmtflags _Afl =
			_Iosbase.flags() & ios_base::adjustfield;
		if (_Afl != ios_base::left
			&& (_Afl != ios_base::internal || !_Intern))
			{	// put leading fill
			_Dest = _Rep(_Dest, _Fill, _Fillcount);
			_Fillcount = 0;
			}

		for (_Off = 0; _Off < 4; ++_Off)
			switch (_Pattern.field[_Off])
				{	// put components as specified by _Pattern
			case money_base::symbol:	// put currency symbol
				_Dest = _Put(_Dest, _Symbol.begin(), _Symbol.size());
				break;

			case money_base::sign:	// put sign
				if (0 < _Sign.size())
					_Dest = _Put(_Dest, _Sign.begin(), 1);
				break;

			case money_base::value:	// put value field
				if (_Fracdigits == 0)
					_Dest = _Put(_Dest, _Val.begin(),
						_Val.size());	// no fraction part
				else if (_Val.size() <= _Fracdigits)
					{	// put leading zero, all fraction digits
					*_Dest++ = _E0;
					*_Dest++ = _Ppunct_fac->decimal_point();
					_Dest = _Rep(_Dest, _E0,
						_Fracdigits - _Val.size());	// insert zeros
					_Dest = _Put(_Dest, _Val.begin(), _Val.size());
					}
				else
					{	// put both integer and fraction parts
					_Dest = _Put(_Dest, _Val.begin(),
						_Val.size() - _Fracdigits);	// put integer part
					*_Dest++ = _Ppunct_fac->decimal_point();
					_Dest = _Put(_Dest, _Val.end() - _Fracdigits,
						_Fracdigits);	// put fraction part
					}
				break;

			case money_base::space:	// put any internal fill
				_Dest = _Rep(_Dest, _Fill, 1);
				// fall through

			case money_base::none:	// put any internal fill
				if (_Afl == ios_base::internal)
					{	// put internal fill
					_Dest = _Rep(_Dest, _Fill, _Fillcount);
					_Fillcount = 0;
					}
				}

		if (1 < _Sign.size())
			_Dest = _Put(_Dest, _Sign.begin() + 1,
				_Sign.size() - 1);	// put remainder of sign
		_Iosbase.width(0);
		return (_Rep(_Dest, _Fill, _Fillcount));	// put trailing fill
		}

	static _OutIt _Put(_OutIt _Dest,
		typename string_type::const_iterator _Source, size_t _Count)
		{	// put [_Source, _Source + _Count) to _Dest
		for (; 0 < _Count; --_Count, ++_Dest, ++_Source)
			*_Dest = *_Source;
		return (_Dest);
		}

	static _OutIt _Rep(_OutIt _Dest,
		_Elem _Ch, size_t _Count)
		{	// put _Count * _Ch to _Dest
		for (; 0 < _Count; --_Count, ++_Dest)
			*_Dest = _Ch;
		return (_Dest);
		}

	_Locinfo::_Cvtvec _Cvt;		// conversion information
	};

		// STATIC money_put::id OBJECT
template<class _Elem,
	class _OutIt>
	__PURE_APPDOMAIN_GLOBAL locale::id money_put<_Elem, _OutIt>::id;

 #if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE)

  #ifdef __FORCE_INSTANCE

template _PGLOBAL const bool moneypunct<char, true>::intl;
template _PGLOBAL const bool moneypunct<char, false>::intl;
template __PURE_APPDOMAIN_GLOBAL locale::id
	moneypunct<char, true>::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
	moneypunct<char, false>::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
	money_get<char, istreambuf_iterator<char,
		char_traits<char> > >::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
	money_put<char, ostreambuf_iterator<char,
		char_traits<char> > >::id;

template _PGLOBAL const bool moneypunct<wchar_t, true>::intl;
template _PGLOBAL const bool moneypunct<wchar_t, false>::intl;
template __PURE_APPDOMAIN_GLOBAL locale::id
	moneypunct<wchar_t, true>::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
	moneypunct<wchar_t, false>::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
	money_get<wchar_t, istreambuf_iterator<wchar_t,
		char_traits<wchar_t> > >::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
	money_put<wchar_t, ostreambuf_iterator<wchar_t,
		char_traits<wchar_t> > >::id;

   #ifdef _CRTBLD_NATIVE_WCHAR_T

template _PGLOBAL const bool moneypunct<unsigned short, true>::intl;
template _PGLOBAL const bool moneypunct<unsigned short, false>::intl;
template __PURE_APPDOMAIN_GLOBAL locale::id
	moneypunct<unsigned short, true>::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
	moneypunct<unsigned short, false>::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
	money_get<unsigned short, istreambuf_iterator<unsigned short,
		char_traits<unsigned short> > >::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
	money_put<unsigned short, ostreambuf_iterator<unsigned short,
		char_traits<unsigned short> > >::id;

   #endif /* _CRTBLD_NATIVE_WCHAR_T */
  #endif /* __FORCE_INSTANCE */

 #endif /* defined(_DLL_CPPLIB) etc. */
_STD_END

 #pragma pop_macro("new")

 #pragma warning(pop)
 #pragma pack(pop)

#endif /* RC_INVOKED */
#endif /* _XLOCMON_ */

/*
 * Copyright (c) 1992-2009 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
V5.20:0009 */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?