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.

751 lines
23 KiB

  1. // xlocnum internal header (from <locale>)
  2. #ifndef _XLOCNUM_
  3. #define _XLOCNUM_
  4. #include <cerrno>
  5. #include <climits>
  6. #include <cstdio>
  7. #include <cstdlib>
  8. #include <xiosbase>
  9. #ifdef _MSC_VER
  10. #pragma pack(push,8)
  11. #endif /* _MSC_VER */
  12. _STD_BEGIN
  13. // TEMPLATE CLASS numpunct
  14. template<class _E>
  15. class numpunct : public locale::facet {
  16. public:
  17. typedef basic_string<_E, char_traits<_E>, allocator<_E> >
  18. string_type;
  19. typedef _E char_type;
  20. static locale::id id;
  21. _E decimal_point() const
  22. {return (do_decimal_point()); }
  23. _E thousands_sep() const
  24. {return (do_thousands_sep()); }
  25. string grouping() const
  26. {return (do_grouping()); }
  27. string_type falsename() const
  28. {return (do_falsename()); }
  29. string_type truename() const
  30. {return (do_truename()); }
  31. explicit numpunct(size_t _R = 0)
  32. : locale::facet(_R) {_Init(_Locinfo()); }
  33. numpunct(const _Locinfo& _Lobj, size_t _R = 0)
  34. : locale::facet(_R) {_Init(_Lobj); }
  35. static size_t __cdecl _Getcat()
  36. {return (_LC_NUMERIC); }
  37. _PROTECTED:
  38. virtual ~numpunct()
  39. {delete[] _Gr;
  40. delete[] _Nf;
  41. delete[] _Nt; }
  42. protected:
  43. void _Init(const _Locinfo& _Lobj)
  44. {const lconv *_P = _Lobj._Getlconv();
  45. _Dp = _WIDEN(_E, _P->decimal_point[0]);
  46. _Ks = _WIDEN(_E, _P->thousands_sep[0]);
  47. _Gr = _MAKLOCSTR(char, _P->grouping);
  48. _Nf = _MAKLOCSTR(_E, _Lobj._Getfalse());
  49. _Nt = _MAKLOCSTR(_E, _Lobj._Gettrue()); }
  50. virtual _E do_decimal_point() const
  51. {return (_Dp); }
  52. virtual _E do_thousands_sep() const
  53. {return (_Ks); }
  54. virtual string do_grouping() const
  55. {return (string(_Gr)); }
  56. virtual string_type do_falsename() const
  57. {return (string_type(_Nf)); }
  58. virtual string_type do_truename() const
  59. {return (string_type(_Nt)); }
  60. private:
  61. char *_Gr;
  62. _E _Dp, _Ks, *_Nf, *_Nt;
  63. };
  64. typedef numpunct<char> _Npc;
  65. typedef numpunct<wchar_t> _Npwc;
  66. // TEMPLATE CLASS numpunct_byname
  67. template<class _E>
  68. class numpunct_byname : public numpunct<_E> {
  69. public:
  70. explicit numpunct_byname(const char *_S, size_t _R = 0)
  71. : numpunct<_E>(_Locinfo(_S), _R) {}
  72. _PROTECTED:
  73. virtual ~numpunct_byname()
  74. {}
  75. };
  76. template<class _E>
  77. locale::id numpunct<_E>::id;
  78. #define _VIRTUAL virtual
  79. template<class _E> inline
  80. bool (isdigit)(_E _C, const locale& _L)
  81. {return (_USE(_L, ctype<_E>).is(ctype_base::digit, _C)); }
  82. // TEMPLATE CLASS num_get
  83. template<class _E,
  84. class _II = istreambuf_iterator<_E, char_traits<_E> > >
  85. class num_get : public locale::facet {
  86. public:
  87. typedef numpunct<_E> _Mypunct;
  88. typedef basic_string<_E, char_traits<_E>, allocator<_E> >
  89. _Mystr;
  90. static size_t __cdecl _Getcat()
  91. {return (_LC_NUMERIC); }
  92. static locale::id id;
  93. _PROTECTED:
  94. virtual ~num_get()
  95. {}
  96. protected:
  97. void _Init(const _Locinfo& _Lobj)
  98. {}
  99. public:
  100. explicit num_get(size_t _R = 0)
  101. : locale::facet(_R) {_Init(_Locinfo()); }
  102. num_get(const _Locinfo& _Lobj, size_t _R = 0)
  103. : locale::facet(_R) {_Init(_Lobj); }
  104. typedef _E char_type;
  105. typedef _II iter_type;
  106. _II get(_II _F, _II _L, ios_base& _X, ios_base::iostate& _St,
  107. _Bool& _V) const
  108. {return (do_get(_F, _L, _X, _St, _V)); }
  109. _II get(_II _F, _II _L, ios_base& _X, ios_base::iostate& _St,
  110. unsigned short& _V) const
  111. {return (do_get(_F, _L, _X, _St, _V)); }
  112. _II get(_II _F, _II _L, ios_base& _X, ios_base::iostate& _St,
  113. unsigned int& _V) const
  114. {return (do_get(_F, _L, _X, _St, _V)); }
  115. _II get(_II _F, _II _L, ios_base& _X, ios_base::iostate& _St,
  116. long& _V) const
  117. {return (do_get(_F, _L, _X, _St, _V)); }
  118. _II get(_II _F, _II _L, ios_base& _X, ios_base::iostate& _St,
  119. unsigned long& _V) const
  120. {return (do_get(_F, _L, _X, _St, _V)); }
  121. #ifdef _WIN64
  122. _II get(_II _F, _II _L, ios_base& _X, ios_base::iostate& _St,
  123. __int64& _V) const
  124. {return (do_get(_F, _L, _X, _St, _V)); }
  125. _II get(_II _F, _II _L, ios_base& _X, ios_base::iostate& _St,
  126. unsigned __int64& _V) const
  127. {return (do_get(_F, _L, _X, _St, _V)); }
  128. #endif // _WIN64
  129. _II get(_II _F, _II _L, ios_base& _X, ios_base::iostate& _St,
  130. float& _V) const
  131. {return (do_get(_F, _L, _X, _St, _V)); }
  132. _II get(_II _F, _II _L, ios_base& _X, ios_base::iostate& _St,
  133. double& _V) const
  134. {return (do_get(_F, _L, _X, _St, _V)); }
  135. _II get(_II _F, _II _L, ios_base& _X, ios_base::iostate& _St,
  136. long double& _V) const
  137. {return (do_get(_F, _L, _X, _St, _V)); }
  138. _II get(_II _F, _II _L, ios_base& _X, ios_base::iostate& _St,
  139. void *& _V) const
  140. {return (do_get(_F, _L, _X, _St, _V)); }
  141. protected:
  142. _VIRTUAL _II do_get(_II _F, _II _L, ios_base& _X,
  143. ios_base::iostate& _St, _Bool& _V) const
  144. {int _Ans = -1;
  145. if (_X.flags() & ios_base::boolalpha)
  146. {const _Mypunct& _Fac = _USE(_X.getloc(), _Mypunct);
  147. _Mystr _Str(1, (_E)0);
  148. _Str += _Fac.falsename();
  149. _Str += (_E)0;
  150. _Str += _Fac.truename();
  151. _Ans = _Getloctxt(_F, _L, (size_t)2, _Str.c_str()); }
  152. else
  153. {char _Ac[_MAX_INT_DIG], *_Ep;
  154. errno = 0;
  155. const unsigned long _Ulo = strtoul(_Ac, &_Ep,
  156. _Getifld(_Ac, _F, _L, _X.flags(), _X.getloc()));
  157. if (_Ep != _Ac && errno == 0 && _Ulo <= 1)
  158. _Ans = _Ulo; }
  159. if (_F == _L)
  160. _St |= ios_base::eofbit;
  161. if (_Ans < 0)
  162. _St |= ios_base::failbit;
  163. else
  164. _V = _Ans != 0;
  165. return (_F); }
  166. _VIRTUAL _II do_get(_II _F, _II _L, ios_base& _X,
  167. ios_base::iostate& _St, unsigned short& _V) const
  168. {char _Ac[_MAX_INT_DIG], *_Ep;
  169. errno = 0;
  170. int _Base =
  171. _Getifld(_Ac, _F, _L, _X.flags(), _X.getloc());
  172. char *_S = _Ac[0] == '-' ? _Ac + 1 : _Ac;
  173. const unsigned long _Ans = strtoul(_S, &_Ep, _Base);
  174. if (_F == _L)
  175. _St |= ios_base::eofbit;
  176. if (_Ep == _S || errno != 0 || USHRT_MAX < _Ans)
  177. _St |= ios_base::failbit;
  178. else
  179. _V = (unsigned short)(_Ac[0] == '-' ? -_Ans : _Ans);
  180. return (_F); }
  181. _VIRTUAL _II do_get(_II _F, _II _L, ios_base& _X,
  182. ios_base::iostate& _St, unsigned int& _V) const
  183. {char _Ac[_MAX_INT_DIG], *_Ep;
  184. errno = 0;
  185. int _Base =
  186. _Getifld(_Ac, _F, _L, _X.flags(), _X.getloc());
  187. char *_S = _Ac[0] == '-' ? _Ac + 1 : _Ac;
  188. const unsigned long _Ans = strtoul(_S, &_Ep, _Base);
  189. if (_F == _L)
  190. _St |= ios_base::eofbit;
  191. if (_Ep == _S || errno != 0 || UINT_MAX < _Ans)
  192. _St |= ios_base::failbit;
  193. else
  194. _V = _Ac[0] == '-' ? -_Ans : _Ans;
  195. return (_F); }
  196. _VIRTUAL _II do_get(_II _F, _II _L, ios_base& _X,
  197. ios_base::iostate& _St, long& _V) const
  198. {char _Ac[_MAX_INT_DIG], *_Ep;
  199. errno = 0;
  200. const long _Ans = strtol(_Ac, &_Ep,
  201. _Getifld(_Ac, _F, _L, _X.flags(), _X.getloc()));
  202. if (_F == _L)
  203. _St |= ios_base::eofbit;
  204. if (_Ep == _Ac || errno != 0)
  205. _St |= ios_base::failbit;
  206. else
  207. _V = _Ans;
  208. return (_F); }
  209. _VIRTUAL _II do_get(_II _F, _II _L, ios_base& _X,
  210. ios_base::iostate& _St, unsigned long& _V) const
  211. {char _Ac[_MAX_INT_DIG], *_Ep;
  212. errno = 0;
  213. const unsigned long _Ans = strtoul(_Ac, &_Ep,
  214. _Getifld(_Ac, _F, _L, _X.flags(), _X.getloc()));
  215. if (_F == _L)
  216. _St |= ios_base::eofbit;
  217. if (_Ep == _Ac || errno != 0)
  218. _St |= ios_base::failbit;
  219. else
  220. _V = _Ans;
  221. return (_F); }
  222. #ifdef _WIN64
  223. _VIRTUAL _II do_get(_II _F, _II _L, ios_base& _X,
  224. ios_base::iostate& _St, __int64& _V) const
  225. {char _Ac[_MAX_INT_DIG];
  226. errno = 0;
  227. _Getifld(_Ac, _F, _L, _X.flags(), _X.getloc());
  228. const __int64 _Ans = _atoi64(_Ac);
  229. if (_F == _L)
  230. _St |= ios_base::eofbit;
  231. if (errno != 0)
  232. _St |= ios_base::failbit;
  233. else
  234. _V = _Ans;
  235. return (_F); }
  236. _VIRTUAL _II do_get(_II _F, _II _L, ios_base& _X,
  237. ios_base::iostate& _St, unsigned __int64& _V) const
  238. {char _Ac[_MAX_INT_DIG];
  239. errno = 0;
  240. _Getifld(_Ac, _F, _L, _X.flags(), _X.getloc());
  241. const unsigned __int64 _Ans = _atoi64(_Ac);
  242. if (_F == _L)
  243. _St |= ios_base::eofbit;
  244. if (errno != 0)
  245. _St |= ios_base::failbit;
  246. else
  247. _V = _Ans;
  248. return (_F); }
  249. #endif // _WIN64
  250. _VIRTUAL _II do_get(_II _F, _II _L, ios_base& _X,
  251. ios_base::iostate& _St, float& _V) const
  252. {char _Ac[_MAX_EXP_DIG + _MAX_SIG_DIG + 16], *_Ep;
  253. errno = 0;
  254. const float _Ans = _Stof(_Ac, &_Ep,
  255. _Getffld(_Ac, _F, _L, _X.getloc()));
  256. if (_F == _L)
  257. _St |= ios_base::eofbit;
  258. if (_Ep == _Ac || errno != 0)
  259. _St |= ios_base::failbit;
  260. else
  261. _V = _Ans;
  262. return (_F); }
  263. _VIRTUAL _II do_get(_II _F, _II _L, ios_base& _X,
  264. ios_base::iostate& _St, double& _V) const
  265. {char _Ac[_MAX_EXP_DIG + _MAX_SIG_DIG + 16], *_Ep;
  266. errno = 0;
  267. const double _Ans = _Stod(_Ac, &_Ep,
  268. _Getffld(_Ac, _F, _L, _X.getloc()));
  269. if (_F == _L)
  270. _St |= ios_base::eofbit;
  271. if (_Ep == _Ac || errno != 0)
  272. _St |= ios_base::failbit;
  273. else
  274. _V = _Ans;
  275. return (_F); }
  276. _VIRTUAL _II do_get(_II _F, _II _L, ios_base& _X,
  277. ios_base::iostate& _St, long double& _V) const
  278. {char _Ac[_MAX_EXP_DIG + _MAX_SIG_DIG + 16], *_Ep;
  279. errno = 0;
  280. const long double _Ans = _Stold(_Ac, &_Ep,
  281. _Getffld(_Ac, _F, _L, _X.getloc()));
  282. if (_F == _L)
  283. _St |= ios_base::eofbit;
  284. if (_Ep == _Ac || errno != 0)
  285. _St |= ios_base::failbit;
  286. else
  287. _V = _Ans;
  288. return (_F); }
  289. _VIRTUAL _II do_get(_II _F, _II _L, ios_base& _X,
  290. ios_base::iostate& _St, void *& _V) const
  291. {union _Pvlo {
  292. void *_Pv;
  293. unsigned long _Lo[1 +
  294. (sizeof (void *) - 1) / sizeof (unsigned long)];
  295. } _U;
  296. const int _NL = sizeof (_U._Lo) / sizeof (unsigned long);
  297. for (int _I = 0; ; ++_F)
  298. {char _Ac[_MAX_INT_DIG], *_Ep;
  299. errno = 0;
  300. _U._Lo[_I] = strtoul(_Ac, &_Ep,
  301. _Getifld(_Ac, _F, _L,
  302. ios_base::hex, _X.getloc()));
  303. if (_F == _L)
  304. _St |= ios_base::eofbit;
  305. if (_Ep == _Ac || errno != 0)
  306. {_St |= ios_base::failbit;
  307. break; }
  308. if (_NL <= ++_I)
  309. break;
  310. if (_F == _L || *_F != _WIDEN(_E, ':'))
  311. {_St |= ios_base::failbit;
  312. break; }}
  313. if (!(_St & ios_base::failbit))
  314. _V = _U._Pv;
  315. return (_F); }
  316. private:
  317. static int __cdecl _Getifld(char *_Ac, _II& _F, _II& _L,
  318. ios_base::fmtflags _Bfl, const locale& _Loc)
  319. {const _E _E0 = _WIDEN(_E, '0');
  320. const _Mypunct& _Fac = _USE(_Loc, _Mypunct);
  321. const string _Gr = _Fac.grouping();
  322. const _E _Ks = _Fac.thousands_sep();
  323. char *_P = _Ac;
  324. if (_F == _L)
  325. ;
  326. else if (*_F == _WIDEN(_E, '+'))
  327. *_P++ = '+', ++_F;
  328. else if (*_F == _WIDEN(_E, '-'))
  329. *_P++ = '-', ++_F;
  330. _Bfl &= ios_base::basefield;
  331. int _Base = _Bfl == ios_base::oct ? 8
  332. : _Bfl == ios_base::hex ? 16
  333. : _Bfl == ios_base::_Fmtzero ? 0 : 10;
  334. bool _Sd = false, _Snz = false;
  335. if (_F != _L && *_F == _E0)
  336. {_Sd = true, ++_F;
  337. if (_F != _L && (*_F == _WIDEN(_E, 'x')
  338. || *_F == _WIDEN(_E, 'X'))
  339. && (_Base == 0 || _Base == 16))
  340. _Base = 16, _Sd = false, ++_F;
  341. else if (_Base == 0)
  342. _Base = 8; }
  343. int _Dlen = _Base == 0 || _Base == 10 ? 10
  344. : _Base == 8 ? 8 : 16 + 6;
  345. string _Grin(1, _Sd ? '\1' : '\0');
  346. size_t _I = 0;
  347. for (char *const _Pe = &_Ac[_MAX_INT_DIG - 1];
  348. _F != _L; ++_F)
  349. if (memchr("0123456789abcdefABCDEF",
  350. *_P = (char)_NARROW(_E, *_F), _Dlen) != 0)
  351. {if ((_Snz || *_P != '0') && _P < _Pe)
  352. ++_P, _Snz = true;
  353. _Sd = true;
  354. if (_Grin[_I] != CHAR_MAX)
  355. ++_Grin[_I]; }
  356. else if (_Grin[_I] == '\0' || _Ks == (_E)0
  357. || *_F != _Ks)
  358. break;
  359. else
  360. _Grin.append(1, '\0'), ++_I;
  361. if (_I == 0)
  362. ;
  363. else if ('\0' < _Grin[_I])
  364. ++_I;
  365. else
  366. _Sd = false;
  367. for (const char *_Pg = _Gr.c_str(); _Sd && 0 < _I; --_I)
  368. if (*_Pg == CHAR_MAX)
  369. break;
  370. else if (0 < --_I && *_Pg != _Grin[_I]
  371. || 0 == _I && *_Pg < _Grin[_I])
  372. _Sd = false;
  373. else if ('\0' < _Pg[1])
  374. ++_Pg;
  375. if (_Sd && !_Snz)
  376. *_P++ = '0';
  377. else if (!_Sd)
  378. _P = _Ac;
  379. *_P = '\0';
  380. return (_Base);
  381. }
  382. static int __cdecl _Getffld(char *_Ac, _II& _F, _II &_L,
  383. const locale& _Loc)
  384. {const _E _E0 = _WIDEN(_E, '0');
  385. const _Mypunct& _Fac = _USE(_Loc, _Mypunct);
  386. char *_P = _Ac;
  387. if (_F == _L)
  388. ;
  389. else if (*_F == _WIDEN(_E, '+'))
  390. *_P++ = '+', ++_F;
  391. else if (*_F == _WIDEN(_E, '-'))
  392. *_P++ = '-', ++_F;
  393. bool _Sd = false;
  394. for (; _F != _L && *_F == _E0; _Sd = true, ++_F)
  395. ;
  396. if (_Sd)
  397. *_P++ = '0';
  398. int _Ns = 0;
  399. int _Pten = 0;
  400. for (; _F != _L && isdigit(*_P = (char)_NARROW(_E, *_F), _Loc);
  401. _Sd = true, ++_F)
  402. if (_Ns < _MAX_SIG_DIG)
  403. ++_P, ++_Ns;
  404. else
  405. ++_Pten;
  406. if (_F != _L && *_F == _Fac.decimal_point())
  407. *_P++ = localeconv()->decimal_point[0], ++_F;
  408. if (_Ns == 0)
  409. {for (; _F != _L && *_F == _E0; _Sd = true, ++_F)
  410. --_Pten;
  411. if (_Pten < 0)
  412. *_P++ = '0', ++_Pten; }
  413. for (; _F != _L && isdigit(*_P = (char)_NARROW(_E, *_F), _Loc);
  414. _Sd = true, ++_F)
  415. if (_Ns < _MAX_SIG_DIG)
  416. ++_P, ++_Ns;
  417. if (_Sd && _F != _L
  418. && (*_F == _WIDEN(_E, 'e') || *_F == _WIDEN(_E, 'E')))
  419. {*_P++ = 'e', ++_F;
  420. _Sd = false, _Ns = 0;
  421. if (_F == _L)
  422. ;
  423. else if (*_F == _WIDEN(_E, '+'))
  424. *_P++ = '+', ++_F;
  425. else if (*_F == _WIDEN(_E, '-'))
  426. *_P++ = '-', ++_F;
  427. for (; _F != _L && *_F == _E0; _Sd = true, ++_F)
  428. ;
  429. if (_Sd)
  430. *_P++ = '0';
  431. for (; _F != _L && isdigit(*_P = (char)_NARROW(_E, *_F), _Loc);
  432. _Sd = true, ++_F)
  433. if (_Ns < _MAX_EXP_DIG)
  434. ++_P, ++_Ns; }
  435. if (!_Sd)
  436. _P = _Ac;
  437. *_P = '\0';
  438. return (_Pten);
  439. };
  440. };
  441. template<class _E, class _II>
  442. locale::id num_get<_E, _II>::id;
  443. // TEMPLATE CLASS num_put
  444. template<class _E,
  445. class _OI = ostreambuf_iterator<_E, char_traits<_E> > >
  446. class num_put : public locale::facet {
  447. public:
  448. typedef numpunct<_E> _Mypunct;
  449. typedef basic_string<_E, char_traits<_E>, allocator<_E> >
  450. _Mystr;
  451. static size_t __cdecl _Getcat()
  452. {return (_LC_NUMERIC); }
  453. static locale::id id;
  454. _PROTECTED:
  455. virtual ~num_put()
  456. {}
  457. protected:
  458. void _Init(const _Locinfo& _Lobj)
  459. {}
  460. public:
  461. explicit num_put(size_t _R = 0)
  462. : locale::facet(_R) {_Init(_Locinfo()); }
  463. num_put(const _Locinfo& _Lobj, size_t _R = 0)
  464. : locale::facet(_R) {_Init(_Lobj); }
  465. typedef _E char_type;
  466. typedef _OI iter_type;
  467. _OI put(_OI _F, ios_base& _X, _E _Fill,
  468. _Bool _V) const
  469. {return (do_put(_F, _X, _Fill, _V)); }
  470. _OI put(_OI _F, ios_base& _X, _E _Fill,
  471. long _V) const
  472. {return (do_put(_F, _X, _Fill, _V)); }
  473. _OI put(_OI _F, ios_base& _X, _E _Fill,
  474. unsigned long _V) const
  475. {return (do_put(_F, _X, _Fill, _V)); }
  476. #ifdef _WIN64
  477. _OI put(_OI _F, ios_base& _X, _E _Fill,
  478. __int64 _V) const
  479. {return (do_put(_F, _X, _Fill, _V)); }
  480. _OI put(_OI _F, ios_base& _X, _E _Fill,
  481. unsigned __int64 _V) const
  482. {return (do_put(_F, _X, _Fill, _V)); }
  483. #endif // _WIN64
  484. _OI put(_OI _F, ios_base& _X, _E _Fill,
  485. double _V) const
  486. {return (do_put(_F, _X, _Fill, _V)); }
  487. _OI put(_OI _F, ios_base& _X, _E _Fill,
  488. long double _V) const
  489. {return (do_put(_F, _X, _Fill, _V)); }
  490. _OI put(_OI _F, ios_base& _X, _E _Fill,
  491. const void *_V) const
  492. {return (do_put(_F, _X, _Fill, _V)); }
  493. protected:
  494. virtual _OI do_put(_OI _F, ios_base& _X, _E _Fill,
  495. _Bool _V) const
  496. {const _Mypunct& _Fac = _USE(_X.getloc(), _Mypunct);
  497. _Mystr _Str;
  498. if (!(_X.flags() & ios_base::boolalpha))
  499. _Str.append(1, _WIDEN(_E, _V ? '1' : '0'));
  500. else if (_V)
  501. _Str = _Fac.truename();
  502. else
  503. _Str = _Fac.falsename();
  504. size_t _M = _X.width() <= 0 || _X.width() <= _Str.size()
  505. ? 0 : _X.width() - _Str.size();
  506. ios_base::fmtflags _Afl =
  507. _X.flags() & ios_base::adjustfield;
  508. if (_Afl != ios_base::left)
  509. _F = _Rep(_F, _Fill, _M), _M = 0;
  510. _F = _Put(_F, _Str.c_str(), _Str.size());
  511. _X.width(0);
  512. return (_Rep(_F, _Fill, _M)); }
  513. virtual _OI do_put(_OI _F, ios_base& _X, _E _Fill,
  514. long _V) const
  515. {char _Buf[2 * _MAX_INT_DIG], _Fmt[6];
  516. return (_Iput(_F, _X, _Fill, _Buf,
  517. sprintf(_Buf, _Ifmt(_Fmt, 'd', _X.flags()), _V))); }
  518. virtual _OI do_put(_OI _F, ios_base& _X, _E _Fill,
  519. unsigned long _V) const
  520. {char _Buf[2 * _MAX_INT_DIG], _Fmt[6];
  521. return (_Iput(_F, _X, _Fill, _Buf,
  522. sprintf(_Buf, _Ifmt(_Fmt, 'u', _X.flags()), _V))); }
  523. #ifdef _WIN64
  524. virtual _OI do_put(_OI _F, ios_base& _X, _E _Fill,
  525. __int64 _V) const
  526. {char _Buf[2 * _MAX_INT_DIG], _Fmt[6];
  527. return (_Iput(_F, _X, _Fill, _Buf,
  528. sprintf(_Buf, _Ifmt(_Fmt, "Id", _X.flags()), _V))); }
  529. virtual _OI do_put(_OI _F, ios_base& _X, _E _Fill,
  530. unsigned __int64 _V) const
  531. {char _Buf[2 * _MAX_INT_DIG], _Fmt[6];
  532. return (_Iput(_F, _X, _Fill, _Buf,
  533. sprintf(_Buf, _Ifmt(_Fmt, "Iu", _X.flags()), _V))); }
  534. #endif // _WIN64
  535. virtual _OI do_put(_OI _F, ios_base& _X, _E _Fill,
  536. double _V) const
  537. {char _Buf[_MAX_EXP_DIG + _MAX_SIG_DIG + 16], _Fmt[8];
  538. streamsize _Prec = _X.precision() <= 0
  539. && !(_X.flags() & ios_base::fixed) ? 6
  540. : _X.precision();
  541. int _Mpr = _MAX_SIG_DIG < _Prec ? _MAX_SIG_DIG : _Prec;
  542. return (_Fput(_F, _X, _Fill, _Buf, _Prec - _Mpr,
  543. sprintf(_Buf, _Ffmt(_Fmt, 0, _X.flags()),
  544. _Mpr, _V))); }
  545. virtual _OI do_put(_OI _F, ios_base& _X, _E _Fill,
  546. long double _V) const
  547. {char _Buf[_MAX_EXP_DIG + _MAX_SIG_DIG + 16], _Fmt[8];
  548. streamsize _Prec = _X.precision() <= 0
  549. && !(_X.flags() & ios_base::fixed) ? 6
  550. : _X.precision();
  551. int _Mpr = _MAX_SIG_DIG < _Prec ? _MAX_SIG_DIG : _Prec;
  552. return (_Fput(_F, _X, _Fill, _Buf, _Prec - _Mpr,
  553. sprintf(_Buf, _Ffmt(_Fmt, 'L', _X.flags()),
  554. _Mpr, _V))); }
  555. virtual _OI do_put(_OI _F, ios_base& _X, _E _Fill,
  556. const void *_V) const
  557. {
  558. const int _NL = 1
  559. + (sizeof (void *) - 1) / sizeof (unsigned long);
  560. char _Buf[(_NL + 1) * (_MAX_INT_DIG + 1)];
  561. int _N = sprintf(_Buf, "%p", _V);
  562. size_t _M = _X.width() <= 0 || _X.width() <= _N
  563. ? 0 : _X.width() - _N;
  564. ios_base::fmtflags _Afl =
  565. _X.flags() & ios_base::adjustfield;
  566. if (_Afl != ios_base::left)
  567. _F = _Rep(_F, _Fill, _M), _M = 0;
  568. _F = _Putc(_F, _Buf, _N);
  569. _X.width(0);
  570. return (_Rep(_F, _Fill, _M)); }
  571. static char *_Ffmt(char *_Fmt, char _Spec,
  572. ios_base::fmtflags _Fl)
  573. {char *_S = _Fmt;
  574. *_S++ = '%';
  575. if (_Fl & ios_base::showpos)
  576. *_S++ = '+';
  577. if (_Fl & ios_base::showpoint)
  578. *_S++ = '#';
  579. *_S++ = '.';
  580. *_S++ = '*';
  581. if (_Spec != 0)
  582. *_S++ = _Spec; // 'L' for long double only
  583. ios_base::fmtflags _Ffl = _Fl & ios_base::floatfield;
  584. *_S++ = _Ffl == ios_base::fixed ? 'f'
  585. : _Ffl == ios_base::scientific ? 'e' : 'g';
  586. *_S = '\0';
  587. return (_Fmt); }
  588. static _OI __cdecl _Fput(_OI _F, ios_base& _X, _E _Fill,
  589. const char *_S, size_t _Nz, size_t _N)
  590. {size_t _M = _X.width() <= 0 || _X.width() <= _N + _Nz
  591. ? 0 : _X.width() - _N - _Nz;
  592. ios_base::fmtflags _Afl =
  593. _X.flags() & ios_base::adjustfield;
  594. if (_Afl != ios_base::left && _Afl != ios_base::internal)
  595. _F = _Rep(_F, _Fill, _M), _M = 0;
  596. else if (_Afl == ios_base::internal)
  597. {if (0 < _N && (*_S == '+' || *_S == '-'))
  598. _F = _Putc(_F, _S, 1), ++_S, --_N;
  599. _F = _Rep(_F, _Fill, _M), _M = 0; }
  600. const char *_P = (const char *)memchr(_S,
  601. localeconv()->decimal_point[0], _N);
  602. if (_P != 0)
  603. {const _Mypunct& _Fac = _USE(_X.getloc(), _Mypunct);
  604. size_t _Nf = (size_t) (_P - _S + 1);
  605. _F = _Putc(_F, _S, _Nf - 1);
  606. _F = _Rep(_F, _Fac.decimal_point(), 1);
  607. _S += _Nf, _N -= _Nf; }
  608. if ((_P = (const char *)memchr(_S, 'e', _N)) != 0)
  609. {size_t _Nm = (size_t) (_P - _S + 1);
  610. _F = _Putc(_F, _S, _Nm - 1);
  611. _F = _Rep(_F, _WIDEN(_E, '0'), _Nz), _Nz = 0;
  612. _F = _Putc(_F, _X.flags() & ios_base::uppercase
  613. ? "E" : "e", 1);
  614. _S += _Nm, _N -= _Nm; }
  615. _F = _Putc(_F, _S, _N);
  616. _F = _Rep(_F, _WIDEN(_E, '0'), _Nz);
  617. _X.width(0);
  618. return (_Rep(_F, _Fill, _M)); }
  619. static char *__cdecl _Ifmt(char *_Fmt, char _Spec,
  620. ios_base::fmtflags _Fl)
  621. {char *_S = _Fmt;
  622. *_S++ = '%';
  623. if (_Fl & ios_base::showpos)
  624. *_S++ = '+';
  625. if (_Fl & ios_base::showbase)
  626. *_S++ = '#';
  627. *_S++ = 'l';
  628. ios_base::fmtflags _Bfl = _Fl & ios_base::basefield;
  629. *_S++ = _Bfl == ios_base::oct ? 'o'
  630. : _Bfl != ios_base::hex ? _Spec // 'd' or 'u'
  631. : _Fl & ios_base::uppercase ? 'X' : 'x';
  632. *_S = '\0';
  633. return (_Fmt); }
  634. #ifdef _WIN64
  635. static char *__cdecl _Ifmt(char *_Fmt, const char *_Spec,
  636. ios_base::fmtflags _Fl)
  637. {char *_S = _Fmt;
  638. *_S++ = '%';
  639. if (_Fl & ios_base::showpos)
  640. *_S++ = '+';
  641. if (_Fl & ios_base::showbase)
  642. *_S++ = '#';
  643. *_S++ = _Spec[0];
  644. ios_base::fmtflags _Bfl = _Fl & ios_base::basefield;
  645. *_S++ = _Bfl == ios_base::oct ? 'o'
  646. : _Bfl != ios_base::hex ? _Spec[1] // 'd' or 'u'
  647. : _Fl & ios_base::uppercase ? 'X' : 'x';
  648. *_S = '\0';
  649. return (_Fmt); }
  650. #endif // _WIN64
  651. static _OI __cdecl _Iput(_OI _F, ios_base& _X, _E _Fill,
  652. char *_S, size_t _N)
  653. {const size_t _Np = *_S == '+' || *_S == '-' ? 1
  654. : *_S == '0' && (_S[1] == 'x' || _S[1] == 'X') ? 2
  655. : 0;
  656. const _Mypunct& _Fac = _USE(_X.getloc(), _Mypunct);
  657. const string _Gr = _Fac.grouping();
  658. const _E _Ks = _Fac.thousands_sep();
  659. bool _Grp = '\0' < *_Gr.c_str();
  660. if (_Grp)
  661. {const char *_Pg = _Gr.c_str();
  662. size_t _I = _N;
  663. for (_Grp = false; *_Pg != CHAR_MAX && '\0' < *_Pg
  664. && *_Pg < _I - _Np; _Grp = true)
  665. {_I -= *_Pg;
  666. memmove(&_S[_I + 1], &_S[_I], _N + 1 - _I);
  667. _S[_I] = ',', ++_N;
  668. if ('\0' < _Pg[1])
  669. ++_Pg; }}
  670. size_t _M = _X.width() <= 0 || _X.width() <= _N
  671. ? 0 : _X.width() - _N;
  672. ios_base::fmtflags _Afl =
  673. _X.flags() & ios_base::adjustfield;
  674. if (_Afl != ios_base::left && _Afl != ios_base::internal)
  675. _F = _Rep(_F, _Fill, _M), _M = 0;
  676. else if (_Afl == ios_base::internal)
  677. {_F = _Putc(_F, _S, _Np), _S += _Np, _N -= _Np;
  678. _F = _Rep(_F, _Fill, _M), _M = 0; }
  679. if (!_Grp)
  680. _F = _Putc(_F, _S, _N);
  681. else
  682. for (; ; ++_S, --_N)
  683. {size_t _Nd = strcspn(_S, ",");
  684. _F = _Putc(_F, _S, _Nd);
  685. _S += _Nd, _N -= _Nd;
  686. if (_N == 0)
  687. break;
  688. if (_Ks != (_E)0)
  689. _F = _Rep(_F, _Ks, 1); }
  690. _X.width(0);
  691. return (_Rep(_F, _Fill, _M)); }
  692. static _OI _Put(_OI _F, const _E *_S, size_t _N)
  693. {for (; 0 < _N; --_N, ++_F, ++_S)
  694. *_F = *_S;
  695. return (_F); }
  696. static _OI _Putc(_OI _F, const char *_S, size_t _N)
  697. {for (; 0 < _N; --_N, ++_F, ++_S)
  698. *_F = _WIDEN(_E, *_S);
  699. return (_F); }
  700. static _OI _Rep(_OI _F, _E _C, size_t _N)
  701. {for (; 0 < _N; --_N, ++_F)
  702. *_F = _C;
  703. return (_F); }
  704. };
  705. template<class _E, class _OI>
  706. locale::id num_put<_E, _OI>::id;
  707. #ifdef _DLL
  708. #ifdef __FORCE_INSTANCE
  709. template class _CRTIMP2 numpunct<char>;
  710. template class _CRTIMP2 numpunct<wchar_t>;
  711. template class _CRTIMP2 num_get<char,
  712. istreambuf_iterator<char, char_traits<char> > >;
  713. template class _CRTIMP2 num_get<wchar_t,
  714. istreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
  715. template class _CRTIMP2 num_put<char,
  716. ostreambuf_iterator<char, char_traits<char> > >;
  717. template class _CRTIMP2 num_put<wchar_t,
  718. ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
  719. #else // __FORCE_INSTANCE
  720. #pragma warning(disable:4231) /* the extern before template is a non-standard extension */
  721. extern template class _CRTIMP2 numpunct<char>;
  722. extern template class _CRTIMP2 numpunct<wchar_t>;
  723. extern template class _CRTIMP2 num_get<char,
  724. istreambuf_iterator<char, char_traits<char> > >;
  725. extern template class _CRTIMP2 num_get<wchar_t,
  726. istreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
  727. extern template class _CRTIMP2 num_put<char,
  728. ostreambuf_iterator<char, char_traits<char> > >;
  729. extern template class _CRTIMP2 num_put<wchar_t,
  730. ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
  731. #pragma warning(default:4231) /* restore previous warning */
  732. #endif // __FORCE_INSTANCE
  733. #endif // _DLL
  734. _STD_END
  735. #ifdef _MSC_VER
  736. #pragma pack(pop)
  737. #endif /* _MSC_VER */
  738. #endif /* _XLOCNUM_ */
  739. /*
  740. * Copyright (c) 1995 by P.J. Plauger. ALL RIGHTS RESERVED.
  741. * Consult your license regarding permissions and restrictions.
  742. */