// TEMPLATE CLASS money_put template<class _E, class _OI = ostreambuf_iterator<_E, char_traits<_E> > > class money_put : public locale::facet { typedef moneypunct<_E, false> _Mypunct0; typedef moneypunct<_E, true> _Mypunct1; public: typedef _E char_type; typedef _OI iter_type; typedef basic_string<_E, char_traits<_E>, allocator<_E> > string_type; _OI put(_OI _F, bool _Intl, ios_base& _X, _E _Fill, long double _V) const {return (do_put(_F, _Intl, _X, _Fill, _V)); } _OI put(_OI _F, bool _Intl, ios_base& _X, _E _Fill, const string_type& _D) const {return (do_put(_F, _Intl, _X, _Fill, _D)); } static locale::id id; explicit money_put(size_t _R = 0); protected: virtual ~money_put(); virtual _OI do_put(_OI _F, bool _Intl, ios_base& _X, _E _Fill, long double _V) const {bool _Neg = false; if (_V < 0) _Neg = true, _V = -_V; size_t _Exp; for (_Exp = 0; 1e35 <= _V && _Exp < 5000; _Exp += 10) _V /= 1e10; string_type _D2; char _Buf[40]; int _N = sprintf(_Buf, "%.0Lf", _V); for (int _I = 0; _I < _N; ++_I) _D2.append((typename string_type::size_type)1, _WIDEN(_E, _Buf[_I])); _D2.append(_Exp, _WIDEN(_E, '0')); return (_Putmfld(_F, _Intl, _X, _Fill, _Neg, _D2)); } virtual _OI do_put(_OI _F, bool _Intl, ios_base& _X, _E _Fill, const string_type& _D) const {const ctype<_E>& _Fac = _USE(_X.getloc(), ctype<_E>); const _E *_S = _D.c_str(); bool _Neg = false; if (*_S == _WIDEN(_E, '-')) _Neg = true, ++_S; size_t _N; for (_N = 0; _Fac.is(ctype_base::digit, _S[_N]); ++_N) ; string_type _D2(_S, _N); if (_N == 0) _D2.append((typename string_type::size_type)1, _WIDEN(_E, '0')); return (_Putmfld(_F, _Intl, _X, _Fill, _Neg, _D2)); } private: _OI _Putmfld(_OI _F, bool _Intl, ios_base& _X, _E _Fill, bool _Neg, string_type _D) const {const _Mpunct<_E> *_Pfac; if (_Intl) _Pfac = &_USE(_X.getloc(), _Mypunct1); else _Pfac = &_USE(_X.getloc(), _Mypunct0); size_t _Fd = _Pfac->frac_digits(); const string _Gr = _Pfac->grouping(); if (_Fd < _D.size() && '\0' < *_Gr.c_str()) {const _E _Ks = _Pfac->thousands_sep(); const char *_Pg = _Gr.c_str(); size_t _I = _D.size() - _Fd; while (*_Pg != CHAR_MAX && '\0' < *_Pg && *_Pg < _I) {_D.insert(_I -= *_Pg, (size_t)1, _Ks); if ('\0' < _Pg[1]) ++_Pg; }} money_base::pattern _Pat; string_type _Sg; if (_Neg) {_Pat = _Pfac->neg_format(); _Sg = _Pfac->negative_sign(); } else {_Pat = _Pfac->pos_format(); _Sg = _Pfac->positive_sign(); } string_type _Cs; if (_X.flags() & ios_base::showbase) _Cs = _Pfac->curr_symbol(); bool _Intern = false; size_t _M, _N; for (_M = 0, _N = 0; _N < 4; ++_N) switch (_Pat.field[_N]) {case money_base::symbol: _M += _Cs.size(); break; case money_base::sign: _M += _Sg.size(); break; case money_base::value: _M += _D.size() + (0 < _Fd ? 1 : 0) + (_D.size() <= _Fd ? _Fd - _D.size() + 1 : 0); break; case money_base::space: _Intern = true; } _M = _X.width() <= 0 || _X.width() <= _M ? 0 : _X.width() - _M; ios_base::fmtflags _Afl = _X.flags() & ios_base::adjustfield; if (_Afl != ios_base::left && (_Afl != ios_base::internal || !_Intern)) _F = _Rep(_F, _Fill, _M), _M = 0; for (_N = 0; _N < 4; ++_N) switch (_Pat.field[_N]) {case money_base::symbol: _F = _Put(_F, _Cs.begin(), _Cs.size()); break; case money_base::sign: if (0 < _Sg.size()) _F = _Put(_F, _Sg.begin(), 1); break; case money_base::value: if (_Fd == 0) _F = _Put(_F, _D.begin(), _D.size()); else if (_D.size() <= _Fd) {*_F++ = _WIDEN(_E, '0'); *_F++ = _Pfac->decimal_point(); _F = _Rep(_F, _WIDEN(_E, '0'), _Fd - _D.size()); _F = _Put(_F, _D.begin(), _D.size()); } else {_F = _Put(_F, _D.begin(), _D.size() - _Fd); *_F++ = _Pfac->decimal_point(); _F = _Put(_F, _D.end() - _Fd, _Fd); } break; case money_base::space: if (_Afl == ios_base::internal) _F = _Rep(_F, _Fill, _M), _M = 0; } if (1 < _Sg.size()) _F = _Put(_F, _Sg.begin() + 1, _Sg.size() - 1); _X.width(0); return (_Rep(_F, _Fill, _M)); } static _OI _Put(_OI _F, string_type::const_iterator _S, size_t _N) {for (; 0 < _N; --_N, ++_F, ++_S) *_F = *_S; return (_F); } static _OI _Rep(_OI _F, _E _C, size_t _N) {for (; 0 < _N; --_N, ++_F) *_F = _C; return (_F); } }; template<class _E, class _OI> locale::id money_put<_E, _OI>::id; //End of File