Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

528 lines
16 KiB

  1. // xlocmon internal header (from <locale>)
  2. #ifndef _XLOCMON_
  3. #define _XLOCMON_
  4. #include <xiosbase>
  5. #ifdef _MSC_VER
  6. #pragma pack(push,8)
  7. #if 1200 <= _MSC_VER
  8. #pragma warning(push,3)
  9. #pragma warning(disable:4786)
  10. #endif
  11. #endif /* _MSC_VER */
  12. _STD_BEGIN
  13. // STRUCT money_base
  14. struct _CRTIMP2 money_base : public locale::facet {
  15. enum _Part {symbol = '$', sign = '+', space = ' ',
  16. value = 'v', none = 'x'};
  17. _BITMASK(_Part, part);
  18. struct pattern {
  19. char field[4];
  20. };
  21. money_base(size_t _R = 0)
  22. : locale::facet(_R) {}
  23. };
  24. _BITMASK_OPS(money_base::_Part);
  25. // TEMPLATE CLASS _Mpunct
  26. template<class _E>
  27. class _Mpunct : public money_base {
  28. public:
  29. typedef _E char_type;
  30. typedef basic_string<_E, char_traits<_E>, allocator<_E> >
  31. string_type;
  32. _E decimal_point() const
  33. {return (do_decimal_point()); }
  34. _E thousands_sep() const
  35. {return (do_thousands_sep()); }
  36. string grouping() const
  37. {return (do_grouping()); }
  38. string_type curr_symbol() const
  39. {return (do_curr_symbol()); }
  40. string_type positive_sign() const
  41. {return (do_positive_sign()); }
  42. string_type negative_sign() const
  43. {return (do_negative_sign()); }
  44. int frac_digits() const
  45. {return (do_frac_digits()); }
  46. pattern pos_format() const
  47. {return (do_pos_format()); }
  48. pattern neg_format() const
  49. {return (do_neg_format()); }
  50. explicit _Mpunct(size_t _R, bool _Intl)
  51. : money_base(_R), _Ifl(_Intl) {_Init(_Locinfo()); }
  52. _Mpunct(const _Locinfo& _Lobj, size_t _R, bool _Intl)
  53. : money_base(_R), _Ifl(_Intl) {_Init(_Lobj); }
  54. static size_t __cdecl _Getcat()
  55. {return (_LC_NUMERIC); }
  56. _PROTECTED:
  57. virtual ~_Mpunct()
  58. {delete[] _Mgr;
  59. delete[] _Mcs;
  60. delete[] _Mps;
  61. delete[] _Mns; }
  62. protected:
  63. void _Init(const _Locinfo& _Lobj)
  64. {const lconv *_P = _Lobj._Getlconv();
  65. _Mdp = _WIDEN(_E, _P->mon_decimal_point[0]);
  66. _Mks = _WIDEN(_E, _P->mon_thousands_sep[0]);
  67. _Mgr = _MAKLOCSTR(char, _P->mon_grouping);
  68. _Mcs = _MAKLOCSTR(_E, _Ifl ? _P->int_curr_symbol
  69. : _P->currency_symbol);
  70. _Mps = _MAKLOCSTR(_E, _P->p_sign_posn < 0
  71. || 4 < _P->p_sign_posn
  72. ? "" : _P->positive_sign);
  73. _Mns = _MAKLOCSTR(_E, _P->n_sign_posn < 0
  74. || 4 < _P->n_sign_posn
  75. ? "-" : _P->negative_sign);
  76. _Mfd = _Ifl ? _P->int_frac_digits
  77. : _P->frac_digits;
  78. if (_Mfd < 0 || CHAR_MAX <= _Mfd)
  79. _Mfd = 0;
  80. _Makpat(_Mpf, _P->p_sep_by_space,
  81. _P->p_cs_precedes, _P->p_sign_posn);
  82. _Makpat(_Mnf, _P->n_sep_by_space,
  83. _P->n_cs_precedes, _P->n_sign_posn); }
  84. virtual _E do_decimal_point() const
  85. {return (_Mdp); }
  86. virtual _E do_thousands_sep() const
  87. {return (_Mks); }
  88. virtual string do_grouping() const
  89. {return (string(_Mgr)); }
  90. virtual string_type do_curr_symbol() const
  91. {return (string_type(_Mcs)); }
  92. virtual string_type do_positive_sign() const
  93. {return (string_type(_Mps)); }
  94. virtual string_type do_negative_sign() const
  95. {return (string_type(_Mns)); }
  96. virtual int do_frac_digits() const
  97. {return (_Mfd); }
  98. virtual pattern do_pos_format() const
  99. {return (_Mpf); }
  100. virtual pattern do_neg_format() const
  101. {return (_Mnf); }
  102. private:
  103. void _Makpat(pattern& _Pat, char _Sep, char _Pre, char _Pos)
  104. {char *_S = _Ifl || (_Sep & ~1) != 0 || (_Pre & ~1) != 0
  105. || _Pos < 0 || 4 < _Pos ? "$+vx"
  106. : "+v$x" "+v$x" "v$+x" "v+$x" "v$+x"
  107. "+$vx" "+$vx" "$v+x" "+$vx" "$+vx"
  108. "+v $" "+v $" "v $+" "v+ $" "v $+"
  109. "+$ v" "+$ v" "$ v+" "+$ v" "$ +v" + (_Pos
  110. + (_Pre == 1 ? 20 : 0) + (_Sep == 1 ? 40 : 0));
  111. memcpy(_Pat.field, _S, 4); }
  112. char *_Mgr;
  113. _E _Mdp, _Mks, *_Mcs, *_Mps, *_Mns;
  114. int _Mfd;
  115. pattern _Mpf, _Mnf;
  116. bool _Ifl;
  117. };
  118. // TEMPLATE CLASS moneypunct
  119. template<class _E, bool _Intl = false>
  120. class moneypunct : public _Mpunct<_E> {
  121. public:
  122. static const bool intl;
  123. static locale::id id;
  124. explicit moneypunct(size_t _R = 0)
  125. : _Mpunct<_E>(_R, _Intl) {}
  126. moneypunct(const _Locinfo& _Lobj, size_t _R = 0)
  127. : _Mpunct<_E>(_Lobj, _R, _Intl) {}
  128. static size_t __cdecl _Getcat()
  129. {return (_LC_NUMERIC); }
  130. };
  131. template<class _E, bool _Intl>
  132. const bool moneypunct<_E, _Intl>::intl = _Intl;
  133. template<class _E, bool _Intl>
  134. locale::id moneypunct<_E, _Intl>::id;
  135. // TEMPLATE CLASS moneypunct_byname
  136. template<class _E, bool _Intl = false>
  137. class moneypunct_byname : public moneypunct<_E, _Intl> {
  138. public:
  139. explicit moneypunct_byname(const char *_S, size_t _R = 0)
  140. : moneypunct<_E, _Intl>(_Locinfo(_S), _R) {}
  141. _PROTECTED:
  142. virtual ~moneypunct_byname()
  143. {}
  144. };
  145. // TEMPLATE CLASS money_get
  146. template<class _E,
  147. class _II = istreambuf_iterator<_E, char_traits<_E> > >
  148. class money_get : public locale::facet {
  149. typedef moneypunct<_E, false> _Mypunct0;
  150. typedef moneypunct<_E, true> _Mypunct1;
  151. public:
  152. typedef _E char_type;
  153. typedef _II iter_type;
  154. typedef basic_string<_E, char_traits<_E>, allocator<_E> >
  155. string_type;
  156. _II get(_II _F, _II _L, bool _Intl, ios_base& _X,
  157. ios_base::iostate& _St, long double& _V) const
  158. {return (do_get(_F, _L, _Intl, _X, _St, _V)); }
  159. _II get(_II _F, _II _L, bool _Intl, ios_base& _X,
  160. ios_base::iostate& _St, string_type& _D) const
  161. {return (do_get(_F, _L, _Intl, _X, _St, _D)); }
  162. static locale::id id;
  163. explicit money_get(size_t _R = 0)
  164. : locale::facet(_R) {_Init(_Locinfo()); }
  165. money_get(const _Locinfo& _Lobj, size_t _R = 0)
  166. : locale::facet(_R) {_Init(_Lobj); }
  167. static size_t __cdecl _Getcat()
  168. {return (_LC_MONETARY); }
  169. _PROTECTED:
  170. virtual ~money_get()
  171. {}
  172. protected:
  173. void _Init(const _Locinfo& _Lobj)
  174. {}
  175. virtual _II do_get(_II _F, _II _L, bool _Intl, ios_base& _X,
  176. ios_base::iostate& _St, long double& _V) const
  177. {string_type _Str = _Getmfld(_F, _L, _Intl, _X);
  178. if (_F == _L)
  179. _St |= ios_base::eofbit;
  180. if (_Str.size() == 0)
  181. _St |= ios_base::failbit;
  182. else
  183. {string _Str2;
  184. _Str2.reserve(_Str.size());
  185. for (size_t _I = 0; _I < _Str.size(); ++_I)
  186. _Str2 += (char)_NARROW(_E, _Str[_I]);
  187. const char *_Eb = _Str2.c_str();
  188. char *_Ep;
  189. errno = 0;
  190. const long double _Ans = _Stold(_Eb, &_Ep, 0);
  191. if (_Ep == _Eb || errno != 0)
  192. _St |= ios_base::failbit;
  193. else
  194. _V = _Ans; }
  195. return (_F); }
  196. virtual _II do_get(_II _F, _II _L, bool _Intl, ios_base& _X,
  197. ios_base::iostate& _St, string_type& _D) const
  198. {string_type _Str = _Getmfld(_F, _L, _Intl, _X);
  199. if (_F == _L)
  200. _St |= ios_base::eofbit;
  201. if (_Str.size() == 0)
  202. _St |= ios_base::failbit;
  203. else
  204. _D = _Str;
  205. return (_F); }
  206. private:
  207. string_type _Getmfld(_II& _F, _II& _L, bool _Intl,
  208. ios_base& _X) const
  209. {const _Mpunct<_E> *_Pfac;
  210. if (_Intl)
  211. _Pfac = &_USE(_X.getloc(), _Mypunct1);
  212. else
  213. _Pfac = &_USE(_X.getloc(), _Mypunct0);
  214. const ctype<_E>& _Fac2 = _USE(_X.getloc(), ctype<_E>);
  215. bool _Bad = false, _Neg = false;
  216. string_type _Sg, _Str;
  217. const money_base::pattern _Pat = _Pfac->neg_format();
  218. for (size_t _N = 0; !_Bad && _N < 4; ++_N)
  219. switch (_Pat.field[_N])
  220. {case money_base::symbol:
  221. {string_type _Cs = _Pfac->curr_symbol();
  222. const _E *_S;
  223. if (_X.flags() & ios_base::showbase)
  224. ;
  225. else if (_N == 3 && _Sg.size() == 0
  226. || _F == _L || *_F != *_Cs.c_str())
  227. _Cs.erase();
  228. for (_S = _Cs.begin(); _F != _L && _S != _Cs.end()
  229. && *_F == *_S; ++_S, ++_F)
  230. ;
  231. if (_S != _Cs.end())
  232. _Bad = true; }
  233. break;
  234. case money_base::sign:
  235. {if (_F == _L)
  236. ;
  237. else if (0 < (_Pfac->positive_sign()).size()
  238. && _Pfac->positive_sign()[0] == *_F)
  239. ++_F, _Sg = _Pfac->positive_sign();
  240. else if (0 < (_Pfac->negative_sign()).size()
  241. && _Pfac->negative_sign()[0] == *_F)
  242. ++_F, _Sg = _Pfac->negative_sign(), _Neg = true;
  243. if (_Sg.size() == 1)
  244. _Sg.erase(); }
  245. break;
  246. case money_base::value:
  247. {int _Nfd = 0;
  248. int _Fd = _Pfac->frac_digits();
  249. const string _Gr = _Pfac->grouping();
  250. if (*_Gr.c_str() <= '\0')
  251. while (_F != _L
  252. && _Fac2.is(ctype_base::digit, *_F))
  253. _Str += *_F++;
  254. else
  255. {const _E _Ks = _Pfac->thousands_sep();
  256. string _Grin(1, '\0');
  257. size_t _I = 0;
  258. for (; _F != _L; ++_F)
  259. if (_Fac2.is(ctype_base::digit, *_F))
  260. {_Str += *_F;
  261. if (_Grin[_I] != CHAR_MAX)
  262. ++_Grin[_I]; }
  263. else if (_Grin[_I] == '\0' || *_F != _Ks)
  264. break;
  265. else
  266. _Grin.append(1, '\0'), ++_I;
  267. if (_I == 0)
  268. ;
  269. else if ('\0' < _Grin[_I])
  270. ++_I;
  271. else
  272. _Bad = true;
  273. for (const char *_Pg = _Gr.c_str();
  274. !_Bad && 0 < _I; --_I)
  275. if (*_Pg == CHAR_MAX)
  276. break;
  277. else if (0 < --_I && *_Pg != _Grin[_I]
  278. || 0 == _I && *_Pg < _Grin[_I])
  279. _Bad = true;
  280. else if ('\0' < _Pg[1])
  281. ++_Pg;
  282. if (_Bad)
  283. break; }
  284. if (_F != _L && *_F == _Pfac->decimal_point())
  285. {while (++_F != _L
  286. && _Fac2.is(ctype_base::digit, *_F))
  287. if (_Nfd < _Fd)
  288. _Str += *_F, ++_Nfd; }
  289. if (_Str.size() == 0)
  290. _Bad = true;
  291. else
  292. for (; _Nfd < _Fd; ++_Nfd)
  293. _Str += _WIDEN(_E, '0'); }
  294. break;
  295. default:
  296. {if (_N == 3)
  297. break;
  298. while (_F != _L && _Fac2.is(ctype_base::space, *_F))
  299. ++_F; }}
  300. if (!_Bad && 0 < _Sg.size())
  301. {const _E *_S;
  302. for (_S = _Sg.begin(); _F != _L
  303. && ++_S != _Sg.end() && *_F == *_S; ++_F)
  304. ;
  305. if (_S != _Sg.end())
  306. _Bad = true; }
  307. if (_Bad)
  308. _Str.erase();
  309. else if (_Neg)
  310. _Str.insert((size_t)0, (size_t)1, _WIDEN(_E, '-'));
  311. return (_Str); }
  312. };
  313. template<class _E, class _II>
  314. locale::id money_get<_E, _II>::id;
  315. // TEMPLATE CLASS money_put
  316. template<class _E,
  317. class _OI = ostreambuf_iterator<_E, char_traits<_E> > >
  318. class money_put : public locale::facet {
  319. typedef moneypunct<_E, false> _Mypunct0;
  320. typedef moneypunct<_E, true> _Mypunct1;
  321. public:
  322. typedef _E char_type;
  323. typedef _OI iter_type;
  324. typedef basic_string<_E, char_traits<_E>, allocator<_E> >
  325. string_type;
  326. _OI put(_OI _F, bool _Intl, ios_base& _X, _E _Fill,
  327. long double _V) const
  328. {return (do_put(_F, _Intl, _X, _Fill, _V)); }
  329. _OI put(_OI _F, bool _Intl, ios_base& _X, _E _Fill,
  330. const string_type& _D) const
  331. {return (do_put(_F, _Intl, _X, _Fill, _D)); }
  332. static locale::id id;
  333. explicit money_put(size_t _R = 0)
  334. : locale::facet(_R) {_Init(_Locinfo()); }
  335. money_put(const _Locinfo& _Lobj, size_t _R = 0)
  336. : locale::facet(_R) {_Init(_Lobj); }
  337. static size_t __cdecl _Getcat()
  338. {return (_LC_MONETARY); }
  339. _PROTECTED:
  340. virtual ~money_put()
  341. {}
  342. protected:
  343. void _Init(const _Locinfo& _Lobj)
  344. {}
  345. virtual _OI do_put(_OI _F, bool _Intl,
  346. ios_base& _X, _E _Fill, long double _V) const
  347. {bool _Neg = false;
  348. if (_V < 0)
  349. _Neg = true, _V = -_V;
  350. size_t _Exp;
  351. for (_Exp = 0; 1e35 <= _V && _Exp < 5000; _Exp += 10)
  352. _V /= 1e10;
  353. string_type _D2;
  354. char _Buf[40];
  355. int _N = sprintf(_Buf, "%.0Lf", _V);
  356. for (int _I = 0; _I < _N; ++_I)
  357. _D2.append(1, _WIDEN(_E, _Buf[_I]));
  358. _D2.append(_Exp, _WIDEN(_E, '0'));
  359. return (_Putmfld(_F, _Intl, _X, _Fill, _Neg, _D2)); }
  360. virtual _OI do_put(_OI _F, bool _Intl,
  361. ios_base& _X, _E _Fill, const string_type& _D) const
  362. {const ctype<_E>& _Fac = _USE(_X.getloc(), ctype<_E>);
  363. const _E *_S = _D.c_str();
  364. bool _Neg = false;
  365. if (*_S == _WIDEN(_E, '-'))
  366. _Neg = true, ++_S;
  367. size_t _N;
  368. for (_N = 0; _Fac.is(ctype_base::digit, _S[_N]); ++_N)
  369. ;
  370. string_type _D2(_S, _N);
  371. if (_N == 0)
  372. _D2.append(1, _WIDEN(_E, '0'));
  373. return (_Putmfld(_F, _Intl, _X, _Fill, _Neg, _D2)); }
  374. private:
  375. _OI _Putmfld(_OI _F, bool _Intl, ios_base& _X, _E _Fill,
  376. bool _Neg, string_type _D) const
  377. {const _Mpunct<_E> *_Pfac;
  378. if (_Intl)
  379. _Pfac = &_USE(_X.getloc(), _Mypunct1);
  380. else
  381. _Pfac = &_USE(_X.getloc(), _Mypunct0);
  382. size_t _Fd = _Pfac->frac_digits();
  383. const string _Gr = _Pfac->grouping();
  384. if (_Fd < _D.size() && '\0' < *_Gr.c_str())
  385. {const _E _Ks = _Pfac->thousands_sep();
  386. const char *_Pg = _Gr.c_str();
  387. size_t _I = _D.size() - _Fd;
  388. while (*_Pg != CHAR_MAX && '\0' < *_Pg && *_Pg < _I)
  389. {_D.insert(_I -= *_Pg, (size_t)1, _Ks);
  390. if ('\0' < _Pg[1])
  391. ++_Pg; }}
  392. money_base::pattern _Pat;
  393. string_type _Sg;
  394. if (_Neg)
  395. {_Pat = _Pfac->neg_format();
  396. _Sg = _Pfac->negative_sign(); }
  397. else
  398. {_Pat = _Pfac->pos_format();
  399. _Sg = _Pfac->positive_sign(); }
  400. string_type _Cs;
  401. if (_X.flags() & ios_base::showbase)
  402. _Cs = _Pfac->curr_symbol();
  403. bool _Intern = false;
  404. size_t _M, _N;
  405. for (_M = 0, _N = 0; _N < 4; ++_N)
  406. switch (_Pat.field[_N])
  407. {case money_base::symbol:
  408. _M += _Cs.size();
  409. break;
  410. case money_base::sign:
  411. _M += _Sg.size();
  412. break;
  413. case money_base::value:
  414. _M += _D.size() + (0 < _Fd ? 1 : 0)
  415. + (_D.size() <= _Fd ? _Fd - _D.size() + 1 : 0);
  416. break;
  417. case money_base::space:
  418. _Intern = true; }
  419. _M = _X.width() <= 0 || _X.width() <= _M
  420. ? 0 : _X.width() - _M;
  421. ios_base::fmtflags _Afl =
  422. _X.flags() & ios_base::adjustfield;
  423. if (_Afl != ios_base::left
  424. && (_Afl != ios_base::internal || !_Intern))
  425. _F = _Rep(_F, _Fill, _M), _M = 0;
  426. for (_N = 0; _N < 4; ++_N)
  427. switch (_Pat.field[_N])
  428. {case money_base::symbol:
  429. _F = _Put(_F, _Cs.begin(), _Cs.size());
  430. break;
  431. case money_base::sign:
  432. if (0 < _Sg.size())
  433. _F = _Put(_F, _Sg.begin(), 1);
  434. break;
  435. case money_base::value:
  436. if (_Fd == 0)
  437. _F = _Put(_F, _D.begin(), _D.size());
  438. else if (_D.size() <= _Fd)
  439. {*_F++ = _WIDEN(_E, '0');
  440. *_F++ = _Pfac->decimal_point();
  441. _F = _Rep(_F, _WIDEN(_E, '0'), _Fd - _D.size());
  442. _F = _Put(_F, _D.begin(), _D.size()); }
  443. else
  444. {_F = _Put(_F, _D.begin(), _D.size() - _Fd);
  445. *_F++ = _Pfac->decimal_point();
  446. _F = _Put(_F, _D.end() - _Fd, _Fd); }
  447. break;
  448. case money_base::space:
  449. if (_Afl == ios_base::internal)
  450. _F = _Rep(_F, _Fill, _M), _M = 0; }
  451. if (1 < _Sg.size())
  452. _F = _Put(_F, _Sg.begin() + 1, _Sg.size() - 1);
  453. _X.width(0);
  454. return (_Rep(_F, _Fill, _M)); }
  455. static _OI _Put(_OI _F, const _E *_S, size_t _N)
  456. {for (; 0 < _N; --_N, ++_F, ++_S)
  457. *_F = *_S;
  458. return (_F); }
  459. static _OI _Rep(_OI _F, _E _C, size_t _N)
  460. {for (; 0 < _N; --_N, ++_F)
  461. *_F = _C;
  462. return (_F); }
  463. };
  464. template<class _E, class _OI>
  465. locale::id money_put<_E, _OI>::id;
  466. #ifdef _DLL
  467. #ifdef __FORCE_INSTANCE
  468. template class _CRTIMP2 _Mpunct<char>;
  469. template class _CRTIMP2 _Mpunct<wchar_t>;
  470. template class _CRTIMP2 moneypunct<char, true>;
  471. template class _CRTIMP2 moneypunct<char, false>;
  472. template class _CRTIMP2 moneypunct<wchar_t, true>;
  473. template class _CRTIMP2 moneypunct<wchar_t, false>;
  474. template class _CRTIMP2 money_get<char,
  475. istreambuf_iterator<char, char_traits<char> > >;
  476. template class _CRTIMP2 money_get<wchar_t,
  477. istreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
  478. template class _CRTIMP2 money_put<char,
  479. ostreambuf_iterator<char, char_traits<char> > >;
  480. template class _CRTIMP2 money_put<wchar_t,
  481. ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
  482. #else // __FORCE_INSTANCE
  483. #pragma warning(disable:4231) /* the extern before template is a non-standard extension */
  484. extern template class _CRTIMP2 _Mpunct<char>;
  485. extern template class _CRTIMP2 _Mpunct<wchar_t>;
  486. extern template class _CRTIMP2 moneypunct<char, true>;
  487. extern template class _CRTIMP2 moneypunct<char, false>;
  488. extern template class _CRTIMP2 moneypunct<wchar_t, true>;
  489. extern template class _CRTIMP2 moneypunct<wchar_t, false>;
  490. extern template class _CRTIMP2 money_get<char,
  491. istreambuf_iterator<char, char_traits<char> > >;
  492. extern template class _CRTIMP2 money_get<wchar_t,
  493. istreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
  494. extern template class _CRTIMP2 money_put<char,
  495. ostreambuf_iterator<char, char_traits<char> > >;
  496. extern template class _CRTIMP2 money_put<wchar_t,
  497. ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
  498. #pragma warning(default:4231) /* restore previous warning */
  499. #endif // __FORCE_INSTANCE
  500. #endif // _DLL
  501. _STD_END
  502. #ifdef _MSC_VER
  503. #if 1200 <= _MSC_VER
  504. #pragma warning(pop)
  505. #endif
  506. #pragma pack(pop)
  507. #endif /* _MSC_VER */
  508. #endif /* _XLOCMON_ */
  509. /*
  510. * Copyright (c) 1995 by P.J. Plauger. ALL RIGHTS RESERVED.
  511. * Consult your license regarding permissions and restrictions.
  512. */