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.

1378 lines
39KB

  1. // Locale support -*- C++ -*-
  2. // Copyright (C) 1997-2020 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file bits/locale_facets.tcc
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{locale}
  23. */
  24. #ifndef _LOCALE_FACETS_TCC
  25. #define _LOCALE_FACETS_TCC 1
  26. #pragma GCC system_header
  27. namespace std _GLIBCXX_VISIBILITY(default)
  28. {
  29. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  30. // Routine to access a cache for the facet. If the cache didn't
  31. // exist before, it gets constructed on the fly.
  32. template<typename _Facet>
  33. struct __use_cache
  34. {
  35. const _Facet*
  36. operator() (const locale& __loc) const;
  37. };
  38. // Specializations.
  39. template<typename _CharT>
  40. struct __use_cache<__numpunct_cache<_CharT> >
  41. {
  42. const __numpunct_cache<_CharT>*
  43. operator() (const locale& __loc) const
  44. {
  45. const size_t __i = numpunct<_CharT>::id._M_id();
  46. const locale::facet** __caches = __loc._M_impl->_M_caches;
  47. if (!__caches[__i])
  48. {
  49. __numpunct_cache<_CharT>* __tmp = 0;
  50. __try
  51. {
  52. __tmp = new __numpunct_cache<_CharT>;
  53. __tmp->_M_cache(__loc);
  54. }
  55. __catch(...)
  56. {
  57. delete __tmp;
  58. __throw_exception_again;
  59. }
  60. __loc._M_impl->_M_install_cache(__tmp, __i);
  61. }
  62. return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]);
  63. }
  64. };
  65. template<typename _CharT>
  66. void
  67. __numpunct_cache<_CharT>::_M_cache(const locale& __loc)
  68. {
  69. const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
  70. char* __grouping = 0;
  71. _CharT* __truename = 0;
  72. _CharT* __falsename = 0;
  73. __try
  74. {
  75. const string& __g = __np.grouping();
  76. _M_grouping_size = __g.size();
  77. __grouping = new char[_M_grouping_size];
  78. __g.copy(__grouping, _M_grouping_size);
  79. _M_use_grouping = (_M_grouping_size
  80. && static_cast<signed char>(__grouping[0]) > 0
  81. && (__grouping[0]
  82. != __gnu_cxx::__numeric_traits<char>::__max));
  83. const basic_string<_CharT>& __tn = __np.truename();
  84. _M_truename_size = __tn.size();
  85. __truename = new _CharT[_M_truename_size];
  86. __tn.copy(__truename, _M_truename_size);
  87. const basic_string<_CharT>& __fn = __np.falsename();
  88. _M_falsename_size = __fn.size();
  89. __falsename = new _CharT[_M_falsename_size];
  90. __fn.copy(__falsename, _M_falsename_size);
  91. _M_decimal_point = __np.decimal_point();
  92. _M_thousands_sep = __np.thousands_sep();
  93. const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
  94. __ct.widen(__num_base::_S_atoms_out,
  95. __num_base::_S_atoms_out
  96. + __num_base::_S_oend, _M_atoms_out);
  97. __ct.widen(__num_base::_S_atoms_in,
  98. __num_base::_S_atoms_in
  99. + __num_base::_S_iend, _M_atoms_in);
  100. _M_grouping = __grouping;
  101. _M_truename = __truename;
  102. _M_falsename = __falsename;
  103. _M_allocated = true;
  104. }
  105. __catch(...)
  106. {
  107. delete [] __grouping;
  108. delete [] __truename;
  109. delete [] __falsename;
  110. __throw_exception_again;
  111. }
  112. }
  113. // Used by both numeric and monetary facets.
  114. // Check to make sure that the __grouping_tmp string constructed in
  115. // money_get or num_get matches the canonical grouping for a given
  116. // locale.
  117. // __grouping_tmp is parsed L to R
  118. // 1,222,444 == __grouping_tmp of "\1\3\3"
  119. // __grouping is parsed R to L
  120. // 1,222,444 == __grouping of "\3" == "\3\3\3"
  121. _GLIBCXX_PURE bool
  122. __verify_grouping(const char* __grouping, size_t __grouping_size,
  123. const string& __grouping_tmp) throw ();
  124. _GLIBCXX_BEGIN_NAMESPACE_LDBL
  125. template<typename _CharT, typename _InIter>
  126. _GLIBCXX_DEFAULT_ABI_TAG
  127. _InIter
  128. num_get<_CharT, _InIter>::
  129. _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
  130. ios_base::iostate& __err, string& __xtrc) const
  131. {
  132. typedef char_traits<_CharT> __traits_type;
  133. typedef __numpunct_cache<_CharT> __cache_type;
  134. __use_cache<__cache_type> __uc;
  135. const locale& __loc = __io._M_getloc();
  136. const __cache_type* __lc = __uc(__loc);
  137. const _CharT* __lit = __lc->_M_atoms_in;
  138. char_type __c = char_type();
  139. // True if __beg becomes equal to __end.
  140. bool __testeof = __beg == __end;
  141. // First check for sign.
  142. if (!__testeof)
  143. {
  144. __c = *__beg;
  145. const bool __plus = __c == __lit[__num_base::_S_iplus];
  146. if ((__plus || __c == __lit[__num_base::_S_iminus])
  147. && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  148. && !(__c == __lc->_M_decimal_point))
  149. {
  150. __xtrc += __plus ? '+' : '-';
  151. if (++__beg != __end)
  152. __c = *__beg;
  153. else
  154. __testeof = true;
  155. }
  156. }
  157. // Next, look for leading zeros.
  158. bool __found_mantissa = false;
  159. int __sep_pos = 0;
  160. while (!__testeof)
  161. {
  162. if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  163. || __c == __lc->_M_decimal_point)
  164. break;
  165. else if (__c == __lit[__num_base::_S_izero])
  166. {
  167. if (!__found_mantissa)
  168. {
  169. __xtrc += '0';
  170. __found_mantissa = true;
  171. }
  172. ++__sep_pos;
  173. if (++__beg != __end)
  174. __c = *__beg;
  175. else
  176. __testeof = true;
  177. }
  178. else
  179. break;
  180. }
  181. // Only need acceptable digits for floating point numbers.
  182. bool __found_dec = false;
  183. bool __found_sci = false;
  184. string __found_grouping;
  185. if (__lc->_M_use_grouping)
  186. __found_grouping.reserve(32);
  187. const char_type* __lit_zero = __lit + __num_base::_S_izero;
  188. if (!__lc->_M_allocated)
  189. // "C" locale
  190. while (!__testeof)
  191. {
  192. const int __digit = _M_find(__lit_zero, 10, __c);
  193. if (__digit != -1)
  194. {
  195. __xtrc += '0' + __digit;
  196. __found_mantissa = true;
  197. }
  198. else if (__c == __lc->_M_decimal_point
  199. && !__found_dec && !__found_sci)
  200. {
  201. __xtrc += '.';
  202. __found_dec = true;
  203. }
  204. else if ((__c == __lit[__num_base::_S_ie]
  205. || __c == __lit[__num_base::_S_iE])
  206. && !__found_sci && __found_mantissa)
  207. {
  208. // Scientific notation.
  209. __xtrc += 'e';
  210. __found_sci = true;
  211. // Remove optional plus or minus sign, if they exist.
  212. if (++__beg != __end)
  213. {
  214. __c = *__beg;
  215. const bool __plus = __c == __lit[__num_base::_S_iplus];
  216. if (__plus || __c == __lit[__num_base::_S_iminus])
  217. __xtrc += __plus ? '+' : '-';
  218. else
  219. continue;
  220. }
  221. else
  222. {
  223. __testeof = true;
  224. break;
  225. }
  226. }
  227. else
  228. break;
  229. if (++__beg != __end)
  230. __c = *__beg;
  231. else
  232. __testeof = true;
  233. }
  234. else
  235. while (!__testeof)
  236. {
  237. // According to 22.2.2.1.2, p8-9, first look for thousands_sep
  238. // and decimal_point.
  239. if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  240. {
  241. if (!__found_dec && !__found_sci)
  242. {
  243. // NB: Thousands separator at the beginning of a string
  244. // is a no-no, as is two consecutive thousands separators.
  245. if (__sep_pos)
  246. {
  247. __found_grouping += static_cast<char>(__sep_pos);
  248. __sep_pos = 0;
  249. }
  250. else
  251. {
  252. // NB: __convert_to_v will not assign __v and will
  253. // set the failbit.
  254. __xtrc.clear();
  255. break;
  256. }
  257. }
  258. else
  259. break;
  260. }
  261. else if (__c == __lc->_M_decimal_point)
  262. {
  263. if (!__found_dec && !__found_sci)
  264. {
  265. // If no grouping chars are seen, no grouping check
  266. // is applied. Therefore __found_grouping is adjusted
  267. // only if decimal_point comes after some thousands_sep.
  268. if (__found_grouping.size())
  269. __found_grouping += static_cast<char>(__sep_pos);
  270. __xtrc += '.';
  271. __found_dec = true;
  272. }
  273. else
  274. break;
  275. }
  276. else
  277. {
  278. const char_type* __q =
  279. __traits_type::find(__lit_zero, 10, __c);
  280. if (__q)
  281. {
  282. __xtrc += '0' + (__q - __lit_zero);
  283. __found_mantissa = true;
  284. ++__sep_pos;
  285. }
  286. else if ((__c == __lit[__num_base::_S_ie]
  287. || __c == __lit[__num_base::_S_iE])
  288. && !__found_sci && __found_mantissa)
  289. {
  290. // Scientific notation.
  291. if (__found_grouping.size() && !__found_dec)
  292. __found_grouping += static_cast<char>(__sep_pos);
  293. __xtrc += 'e';
  294. __found_sci = true;
  295. // Remove optional plus or minus sign, if they exist.
  296. if (++__beg != __end)
  297. {
  298. __c = *__beg;
  299. const bool __plus = __c == __lit[__num_base::_S_iplus];
  300. if ((__plus || __c == __lit[__num_base::_S_iminus])
  301. && !(__lc->_M_use_grouping
  302. && __c == __lc->_M_thousands_sep)
  303. && !(__c == __lc->_M_decimal_point))
  304. __xtrc += __plus ? '+' : '-';
  305. else
  306. continue;
  307. }
  308. else
  309. {
  310. __testeof = true;
  311. break;
  312. }
  313. }
  314. else
  315. break;
  316. }
  317. if (++__beg != __end)
  318. __c = *__beg;
  319. else
  320. __testeof = true;
  321. }
  322. // Digit grouping is checked. If grouping and found_grouping don't
  323. // match, then get very very upset, and set failbit.
  324. if (__found_grouping.size())
  325. {
  326. // Add the ending grouping if a decimal or 'e'/'E' wasn't found.
  327. if (!__found_dec && !__found_sci)
  328. __found_grouping += static_cast<char>(__sep_pos);
  329. if (!std::__verify_grouping(__lc->_M_grouping,
  330. __lc->_M_grouping_size,
  331. __found_grouping))
  332. __err = ios_base::failbit;
  333. }
  334. return __beg;
  335. }
  336. template<typename _CharT, typename _InIter>
  337. template<typename _ValueT>
  338. _GLIBCXX_DEFAULT_ABI_TAG
  339. _InIter
  340. num_get<_CharT, _InIter>::
  341. _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
  342. ios_base::iostate& __err, _ValueT& __v) const
  343. {
  344. typedef char_traits<_CharT> __traits_type;
  345. using __gnu_cxx::__add_unsigned;
  346. typedef typename __add_unsigned<_ValueT>::__type __unsigned_type;
  347. typedef __numpunct_cache<_CharT> __cache_type;
  348. __use_cache<__cache_type> __uc;
  349. const locale& __loc = __io._M_getloc();
  350. const __cache_type* __lc = __uc(__loc);
  351. const _CharT* __lit = __lc->_M_atoms_in;
  352. char_type __c = char_type();
  353. // NB: Iff __basefield == 0, __base can change based on contents.
  354. const ios_base::fmtflags __basefield = __io.flags()
  355. & ios_base::basefield;
  356. const bool __oct = __basefield == ios_base::oct;
  357. int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10);
  358. // True if __beg becomes equal to __end.
  359. bool __testeof = __beg == __end;
  360. // First check for sign.
  361. bool __negative = false;
  362. if (!__testeof)
  363. {
  364. __c = *__beg;
  365. __negative = __c == __lit[__num_base::_S_iminus];
  366. if ((__negative || __c == __lit[__num_base::_S_iplus])
  367. && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  368. && !(__c == __lc->_M_decimal_point))
  369. {
  370. if (++__beg != __end)
  371. __c = *__beg;
  372. else
  373. __testeof = true;
  374. }
  375. }
  376. // Next, look for leading zeros and check required digits
  377. // for base formats.
  378. bool __found_zero = false;
  379. int __sep_pos = 0;
  380. while (!__testeof)
  381. {
  382. if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  383. || __c == __lc->_M_decimal_point)
  384. break;
  385. else if (__c == __lit[__num_base::_S_izero]
  386. && (!__found_zero || __base == 10))
  387. {
  388. __found_zero = true;
  389. ++__sep_pos;
  390. if (__basefield == 0)
  391. __base = 8;
  392. if (__base == 8)
  393. __sep_pos = 0;
  394. }
  395. else if (__found_zero
  396. && (__c == __lit[__num_base::_S_ix]
  397. || __c == __lit[__num_base::_S_iX]))
  398. {
  399. if (__basefield == 0)
  400. __base = 16;
  401. if (__base == 16)
  402. {
  403. __found_zero = false;
  404. __sep_pos = 0;
  405. }
  406. else
  407. break;
  408. }
  409. else
  410. break;
  411. if (++__beg != __end)
  412. {
  413. __c = *__beg;
  414. if (!__found_zero)
  415. break;
  416. }
  417. else
  418. __testeof = true;
  419. }
  420. // At this point, base is determined. If not hex, only allow
  421. // base digits as valid input.
  422. const size_t __len = (__base == 16 ? __num_base::_S_iend
  423. - __num_base::_S_izero : __base);
  424. // Extract.
  425. typedef __gnu_cxx::__numeric_traits<_ValueT> __num_traits;
  426. string __found_grouping;
  427. if (__lc->_M_use_grouping)
  428. __found_grouping.reserve(32);
  429. bool __testfail = false;
  430. bool __testoverflow = false;
  431. const __unsigned_type __max =
  432. (__negative && __num_traits::__is_signed)
  433. ? -static_cast<__unsigned_type>(__num_traits::__min)
  434. : __num_traits::__max;
  435. const __unsigned_type __smax = __max / __base;
  436. __unsigned_type __result = 0;
  437. int __digit = 0;
  438. const char_type* __lit_zero = __lit + __num_base::_S_izero;
  439. if (!__lc->_M_allocated)
  440. // "C" locale
  441. while (!__testeof)
  442. {
  443. __digit = _M_find(__lit_zero, __len, __c);
  444. if (__digit == -1)
  445. break;
  446. if (__result > __smax)
  447. __testoverflow = true;
  448. else
  449. {
  450. __result *= __base;
  451. __testoverflow |= __result > __max - __digit;
  452. __result += __digit;
  453. ++__sep_pos;
  454. }
  455. if (++__beg != __end)
  456. __c = *__beg;
  457. else
  458. __testeof = true;
  459. }
  460. else
  461. while (!__testeof)
  462. {
  463. // According to 22.2.2.1.2, p8-9, first look for thousands_sep
  464. // and decimal_point.
  465. if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  466. {
  467. // NB: Thousands separator at the beginning of a string
  468. // is a no-no, as is two consecutive thousands separators.
  469. if (__sep_pos)
  470. {
  471. __found_grouping += static_cast<char>(__sep_pos);
  472. __sep_pos = 0;
  473. }
  474. else
  475. {
  476. __testfail = true;
  477. break;
  478. }
  479. }
  480. else if (__c == __lc->_M_decimal_point)
  481. break;
  482. else
  483. {
  484. const char_type* __q =
  485. __traits_type::find(__lit_zero, __len, __c);
  486. if (!__q)
  487. break;
  488. __digit = __q - __lit_zero;
  489. if (__digit > 15)
  490. __digit -= 6;
  491. if (__result > __smax)
  492. __testoverflow = true;
  493. else
  494. {
  495. __result *= __base;
  496. __testoverflow |= __result > __max - __digit;
  497. __result += __digit;
  498. ++__sep_pos;
  499. }
  500. }
  501. if (++__beg != __end)
  502. __c = *__beg;
  503. else
  504. __testeof = true;
  505. }
  506. // Digit grouping is checked. If grouping and found_grouping don't
  507. // match, then get very very upset, and set failbit.
  508. if (__found_grouping.size())
  509. {
  510. // Add the ending grouping.
  511. __found_grouping += static_cast<char>(__sep_pos);
  512. if (!std::__verify_grouping(__lc->_M_grouping,
  513. __lc->_M_grouping_size,
  514. __found_grouping))
  515. __err = ios_base::failbit;
  516. }
  517. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  518. // 23. Num_get overflow result.
  519. if ((!__sep_pos && !__found_zero && !__found_grouping.size())
  520. || __testfail)
  521. {
  522. __v = 0;
  523. __err = ios_base::failbit;
  524. }
  525. else if (__testoverflow)
  526. {
  527. if (__negative && __num_traits::__is_signed)
  528. __v = __num_traits::__min;
  529. else
  530. __v = __num_traits::__max;
  531. __err = ios_base::failbit;
  532. }
  533. else
  534. __v = __negative ? -__result : __result;
  535. if (__testeof)
  536. __err |= ios_base::eofbit;
  537. return __beg;
  538. }
  539. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  540. // 17. Bad bool parsing
  541. template<typename _CharT, typename _InIter>
  542. _InIter
  543. num_get<_CharT, _InIter>::
  544. do_get(iter_type __beg, iter_type __end, ios_base& __io,
  545. ios_base::iostate& __err, bool& __v) const
  546. {
  547. if (!(__io.flags() & ios_base::boolalpha))
  548. {
  549. // Parse bool values as long.
  550. // NB: We can't just call do_get(long) here, as it might
  551. // refer to a derived class.
  552. long __l = -1;
  553. __beg = _M_extract_int(__beg, __end, __io, __err, __l);
  554. if (__l == 0 || __l == 1)
  555. __v = bool(__l);
  556. else
  557. {
  558. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  559. // 23. Num_get overflow result.
  560. __v = true;
  561. __err = ios_base::failbit;
  562. if (__beg == __end)
  563. __err |= ios_base::eofbit;
  564. }
  565. }
  566. else
  567. {
  568. // Parse bool values as alphanumeric.
  569. typedef __numpunct_cache<_CharT> __cache_type;
  570. __use_cache<__cache_type> __uc;
  571. const locale& __loc = __io._M_getloc();
  572. const __cache_type* __lc = __uc(__loc);
  573. bool __testf = true;
  574. bool __testt = true;
  575. bool __donef = __lc->_M_falsename_size == 0;
  576. bool __donet = __lc->_M_truename_size == 0;
  577. bool __testeof = false;
  578. size_t __n = 0;
  579. while (!__donef || !__donet)
  580. {
  581. if (__beg == __end)
  582. {
  583. __testeof = true;
  584. break;
  585. }
  586. const char_type __c = *__beg;
  587. if (!__donef)
  588. __testf = __c == __lc->_M_falsename[__n];
  589. if (!__testf && __donet)
  590. break;
  591. if (!__donet)
  592. __testt = __c == __lc->_M_truename[__n];
  593. if (!__testt && __donef)
  594. break;
  595. if (!__testt && !__testf)
  596. break;
  597. ++__n;
  598. ++__beg;
  599. __donef = !__testf || __n >= __lc->_M_falsename_size;
  600. __donet = !__testt || __n >= __lc->_M_truename_size;
  601. }
  602. if (__testf && __n == __lc->_M_falsename_size && __n)
  603. {
  604. __v = false;
  605. if (__testt && __n == __lc->_M_truename_size)
  606. __err = ios_base::failbit;
  607. else
  608. __err = __testeof ? ios_base::eofbit : ios_base::goodbit;
  609. }
  610. else if (__testt && __n == __lc->_M_truename_size && __n)
  611. {
  612. __v = true;
  613. __err = __testeof ? ios_base::eofbit : ios_base::goodbit;
  614. }
  615. else
  616. {
  617. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  618. // 23. Num_get overflow result.
  619. __v = false;
  620. __err = ios_base::failbit;
  621. if (__testeof)
  622. __err |= ios_base::eofbit;
  623. }
  624. }
  625. return __beg;
  626. }
  627. template<typename _CharT, typename _InIter>
  628. _InIter
  629. num_get<_CharT, _InIter>::
  630. do_get(iter_type __beg, iter_type __end, ios_base& __io,
  631. ios_base::iostate& __err, float& __v) const
  632. {
  633. string __xtrc;
  634. __xtrc.reserve(32);
  635. __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
  636. std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
  637. if (__beg == __end)
  638. __err |= ios_base::eofbit;
  639. return __beg;
  640. }
  641. template<typename _CharT, typename _InIter>
  642. _InIter
  643. num_get<_CharT, _InIter>::
  644. do_get(iter_type __beg, iter_type __end, ios_base& __io,
  645. ios_base::iostate& __err, double& __v) const
  646. {
  647. string __xtrc;
  648. __xtrc.reserve(32);
  649. __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
  650. std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
  651. if (__beg == __end)
  652. __err |= ios_base::eofbit;
  653. return __beg;
  654. }
  655. #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
  656. template<typename _CharT, typename _InIter>
  657. _InIter
  658. num_get<_CharT, _InIter>::
  659. __do_get(iter_type __beg, iter_type __end, ios_base& __io,
  660. ios_base::iostate& __err, double& __v) const
  661. {
  662. string __xtrc;
  663. __xtrc.reserve(32);
  664. __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
  665. std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
  666. if (__beg == __end)
  667. __err |= ios_base::eofbit;
  668. return __beg;
  669. }
  670. #endif
  671. template<typename _CharT, typename _InIter>
  672. _InIter
  673. num_get<_CharT, _InIter>::
  674. do_get(iter_type __beg, iter_type __end, ios_base& __io,
  675. ios_base::iostate& __err, long double& __v) const
  676. {
  677. string __xtrc;
  678. __xtrc.reserve(32);
  679. __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
  680. std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
  681. if (__beg == __end)
  682. __err |= ios_base::eofbit;
  683. return __beg;
  684. }
  685. template<typename _CharT, typename _InIter>
  686. _InIter
  687. num_get<_CharT, _InIter>::
  688. do_get(iter_type __beg, iter_type __end, ios_base& __io,
  689. ios_base::iostate& __err, void*& __v) const
  690. {
  691. // Prepare for hex formatted input.
  692. typedef ios_base::fmtflags fmtflags;
  693. const fmtflags __fmt = __io.flags();
  694. __io.flags((__fmt & ~ios_base::basefield) | ios_base::hex);
  695. typedef __gnu_cxx::__conditional_type<(sizeof(void*)
  696. <= sizeof(unsigned long)),
  697. unsigned long, unsigned long long>::__type _UIntPtrType;
  698. _UIntPtrType __ul;
  699. __beg = _M_extract_int(__beg, __end, __io, __err, __ul);
  700. // Reset from hex formatted input.
  701. __io.flags(__fmt);
  702. __v = reinterpret_cast<void*>(__ul);
  703. return __beg;
  704. }
  705. // For use by integer and floating-point types after they have been
  706. // converted into a char_type string.
  707. template<typename _CharT, typename _OutIter>
  708. void
  709. num_put<_CharT, _OutIter>::
  710. _M_pad(_CharT __fill, streamsize __w, ios_base& __io,
  711. _CharT* __new, const _CharT* __cs, int& __len) const
  712. {
  713. // [22.2.2.2.2] Stage 3.
  714. // If necessary, pad.
  715. __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new,
  716. __cs, __w, __len);
  717. __len = static_cast<int>(__w);
  718. }
  719. _GLIBCXX_END_NAMESPACE_LDBL
  720. template<typename _CharT, typename _ValueT>
  721. int
  722. __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit,
  723. ios_base::fmtflags __flags, bool __dec)
  724. {
  725. _CharT* __buf = __bufend;
  726. if (__builtin_expect(__dec, true))
  727. {
  728. // Decimal.
  729. do
  730. {
  731. *--__buf = __lit[(__v % 10) + __num_base::_S_odigits];
  732. __v /= 10;
  733. }
  734. while (__v != 0);
  735. }
  736. else if ((__flags & ios_base::basefield) == ios_base::oct)
  737. {
  738. // Octal.
  739. do
  740. {
  741. *--__buf = __lit[(__v & 0x7) + __num_base::_S_odigits];
  742. __v >>= 3;
  743. }
  744. while (__v != 0);
  745. }
  746. else
  747. {
  748. // Hex.
  749. const bool __uppercase = __flags & ios_base::uppercase;
  750. const int __case_offset = __uppercase ? __num_base::_S_oudigits
  751. : __num_base::_S_odigits;
  752. do
  753. {
  754. *--__buf = __lit[(__v & 0xf) + __case_offset];
  755. __v >>= 4;
  756. }
  757. while (__v != 0);
  758. }
  759. return __bufend - __buf;
  760. }
  761. _GLIBCXX_BEGIN_NAMESPACE_LDBL
  762. template<typename _CharT, typename _OutIter>
  763. void
  764. num_put<_CharT, _OutIter>::
  765. _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep,
  766. ios_base&, _CharT* __new, _CharT* __cs, int& __len) const
  767. {
  768. _CharT* __p = std::__add_grouping(__new, __sep, __grouping,
  769. __grouping_size, __cs, __cs + __len);
  770. __len = __p - __new;
  771. }
  772. template<typename _CharT, typename _OutIter>
  773. template<typename _ValueT>
  774. _OutIter
  775. num_put<_CharT, _OutIter>::
  776. _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill,
  777. _ValueT __v) const
  778. {
  779. using __gnu_cxx::__add_unsigned;
  780. typedef typename __add_unsigned<_ValueT>::__type __unsigned_type;
  781. typedef __numpunct_cache<_CharT> __cache_type;
  782. __use_cache<__cache_type> __uc;
  783. const locale& __loc = __io._M_getloc();
  784. const __cache_type* __lc = __uc(__loc);
  785. const _CharT* __lit = __lc->_M_atoms_out;
  786. const ios_base::fmtflags __flags = __io.flags();
  787. // Long enough to hold hex, dec, and octal representations.
  788. const int __ilen = 5 * sizeof(_ValueT);
  789. _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  790. * __ilen));
  791. // [22.2.2.2.2] Stage 1, numeric conversion to character.
  792. // Result is returned right-justified in the buffer.
  793. const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
  794. const bool __dec = (__basefield != ios_base::oct
  795. && __basefield != ios_base::hex);
  796. const __unsigned_type __u = ((__v > 0 || !__dec)
  797. ? __unsigned_type(__v)
  798. : -__unsigned_type(__v));
  799. int __len = __int_to_char(__cs + __ilen, __u, __lit, __flags, __dec);
  800. __cs += __ilen - __len;
  801. // Add grouping, if necessary.
  802. if (__lc->_M_use_grouping)
  803. {
  804. // Grouping can add (almost) as many separators as the number
  805. // of digits + space is reserved for numeric base or sign.
  806. _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  807. * (__len + 1)
  808. * 2));
  809. _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size,
  810. __lc->_M_thousands_sep, __io, __cs2 + 2, __cs, __len);
  811. __cs = __cs2 + 2;
  812. }
  813. // Complete Stage 1, prepend numeric base or sign.
  814. if (__builtin_expect(__dec, true))
  815. {
  816. // Decimal.
  817. if (__v >= 0)
  818. {
  819. if (bool(__flags & ios_base::showpos)
  820. && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
  821. *--__cs = __lit[__num_base::_S_oplus], ++__len;
  822. }
  823. else
  824. *--__cs = __lit[__num_base::_S_ominus], ++__len;
  825. }
  826. else if (bool(__flags & ios_base::showbase) && __v)
  827. {
  828. if (__basefield == ios_base::oct)
  829. *--__cs = __lit[__num_base::_S_odigits], ++__len;
  830. else
  831. {
  832. // 'x' or 'X'
  833. const bool __uppercase = __flags & ios_base::uppercase;
  834. *--__cs = __lit[__num_base::_S_ox + __uppercase];
  835. // '0'
  836. *--__cs = __lit[__num_base::_S_odigits];
  837. __len += 2;
  838. }
  839. }
  840. // Pad.
  841. const streamsize __w = __io.width();
  842. if (__w > static_cast<streamsize>(__len))
  843. {
  844. _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  845. * __w));
  846. _M_pad(__fill, __w, __io, __cs3, __cs, __len);
  847. __cs = __cs3;
  848. }
  849. __io.width(0);
  850. // [22.2.2.2.2] Stage 4.
  851. // Write resulting, fully-formatted string to output iterator.
  852. return std::__write(__s, __cs, __len);
  853. }
  854. template<typename _CharT, typename _OutIter>
  855. void
  856. num_put<_CharT, _OutIter>::
  857. _M_group_float(const char* __grouping, size_t __grouping_size,
  858. _CharT __sep, const _CharT* __p, _CharT* __new,
  859. _CharT* __cs, int& __len) const
  860. {
  861. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  862. // 282. What types does numpunct grouping refer to?
  863. // Add grouping, if necessary.
  864. const int __declen = __p ? __p - __cs : __len;
  865. _CharT* __p2 = std::__add_grouping(__new, __sep, __grouping,
  866. __grouping_size,
  867. __cs, __cs + __declen);
  868. // Tack on decimal part.
  869. int __newlen = __p2 - __new;
  870. if (__p)
  871. {
  872. char_traits<_CharT>::copy(__p2, __p, __len - __declen);
  873. __newlen += __len - __declen;
  874. }
  875. __len = __newlen;
  876. }
  877. // The following code uses vsnprintf (or vsprintf(), when
  878. // _GLIBCXX_USE_C99_STDIO is not defined) to convert floating point
  879. // values for insertion into a stream. An optimization would be to
  880. // replace them with code that works directly on a wide buffer and
  881. // then use __pad to do the padding. It would be good to replace
  882. // them anyway to gain back the efficiency that C++ provides by
  883. // knowing up front the type of the values to insert. Also, sprintf
  884. // is dangerous since may lead to accidental buffer overruns. This
  885. // implementation follows the C++ standard fairly directly as
  886. // outlined in 22.2.2.2 [lib.locale.num.put]
  887. template<typename _CharT, typename _OutIter>
  888. template<typename _ValueT>
  889. _OutIter
  890. num_put<_CharT, _OutIter>::
  891. _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
  892. _ValueT __v) const
  893. {
  894. typedef __numpunct_cache<_CharT> __cache_type;
  895. __use_cache<__cache_type> __uc;
  896. const locale& __loc = __io._M_getloc();
  897. const __cache_type* __lc = __uc(__loc);
  898. // Use default precision if out of range.
  899. const streamsize __prec = __io.precision() < 0 ? 6 : __io.precision();
  900. const int __max_digits =
  901. __gnu_cxx::__numeric_traits<_ValueT>::__digits10;
  902. // [22.2.2.2.2] Stage 1, numeric conversion to character.
  903. int __len;
  904. // Long enough for the max format spec.
  905. char __fbuf[16];
  906. __num_base::_S_format_float(__io, __fbuf, __mod);
  907. #if _GLIBCXX_USE_C99_STDIO && !_GLIBCXX_HAVE_BROKEN_VSNPRINTF
  908. // Precision is always used except for hexfloat format.
  909. const bool __use_prec =
  910. (__io.flags() & ios_base::floatfield) != ios_base::floatfield;
  911. // First try a buffer perhaps big enough (most probably sufficient
  912. // for non-ios_base::fixed outputs)
  913. int __cs_size = __max_digits * 3;
  914. char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  915. if (__use_prec)
  916. __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
  917. __fbuf, __prec, __v);
  918. else
  919. __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
  920. __fbuf, __v);
  921. // If the buffer was not large enough, try again with the correct size.
  922. if (__len >= __cs_size)
  923. {
  924. __cs_size = __len + 1;
  925. __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  926. if (__use_prec)
  927. __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
  928. __fbuf, __prec, __v);
  929. else
  930. __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
  931. __fbuf, __v);
  932. }
  933. #else
  934. // Consider the possibility of long ios_base::fixed outputs
  935. const bool __fixed = __io.flags() & ios_base::fixed;
  936. const int __max_exp =
  937. __gnu_cxx::__numeric_traits<_ValueT>::__max_exponent10;
  938. // The size of the output string is computed as follows.
  939. // ios_base::fixed outputs may need up to __max_exp + 1 chars
  940. // for the integer part + __prec chars for the fractional part
  941. // + 3 chars for sign, decimal point, '\0'. On the other hand,
  942. // for non-fixed outputs __max_digits * 2 + __prec chars are
  943. // largely sufficient.
  944. const int __cs_size = __fixed ? __max_exp + __prec + 4
  945. : __max_digits * 2 + __prec;
  946. char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  947. __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, __fbuf,
  948. __prec, __v);
  949. #endif
  950. // [22.2.2.2.2] Stage 2, convert to char_type, using correct
  951. // numpunct.decimal_point() values for '.' and adding grouping.
  952. const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  953. _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  954. * __len));
  955. __ctype.widen(__cs, __cs + __len, __ws);
  956. // Replace decimal point.
  957. _CharT* __wp = 0;
  958. const char* __p = char_traits<char>::find(__cs, __len, '.');
  959. if (__p)
  960. {
  961. __wp = __ws + (__p - __cs);
  962. *__wp = __lc->_M_decimal_point;
  963. }
  964. // Add grouping, if necessary.
  965. // N.B. Make sure to not group things like 2e20, i.e., no decimal
  966. // point, scientific notation.
  967. if (__lc->_M_use_grouping
  968. && (__wp || __len < 3 || (__cs[1] <= '9' && __cs[2] <= '9'
  969. && __cs[1] >= '0' && __cs[2] >= '0')))
  970. {
  971. // Grouping can add (almost) as many separators as the
  972. // number of digits, but no more.
  973. _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  974. * __len * 2));
  975. streamsize __off = 0;
  976. if (__cs[0] == '-' || __cs[0] == '+')
  977. {
  978. __off = 1;
  979. __ws2[0] = __ws[0];
  980. __len -= 1;
  981. }
  982. _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size,
  983. __lc->_M_thousands_sep, __wp, __ws2 + __off,
  984. __ws + __off, __len);
  985. __len += __off;
  986. __ws = __ws2;
  987. }
  988. // Pad.
  989. const streamsize __w = __io.width();
  990. if (__w > static_cast<streamsize>(__len))
  991. {
  992. _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  993. * __w));
  994. _M_pad(__fill, __w, __io, __ws3, __ws, __len);
  995. __ws = __ws3;
  996. }
  997. __io.width(0);
  998. // [22.2.2.2.2] Stage 4.
  999. // Write resulting, fully-formatted string to output iterator.
  1000. return std::__write(__s, __ws, __len);
  1001. }
  1002. template<typename _CharT, typename _OutIter>
  1003. _OutIter
  1004. num_put<_CharT, _OutIter>::
  1005. do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
  1006. {
  1007. const ios_base::fmtflags __flags = __io.flags();
  1008. if ((__flags & ios_base::boolalpha) == 0)
  1009. {
  1010. const long __l = __v;
  1011. __s = _M_insert_int(__s, __io, __fill, __l);
  1012. }
  1013. else
  1014. {
  1015. typedef __numpunct_cache<_CharT> __cache_type;
  1016. __use_cache<__cache_type> __uc;
  1017. const locale& __loc = __io._M_getloc();
  1018. const __cache_type* __lc = __uc(__loc);
  1019. const _CharT* __name = __v ? __lc->_M_truename
  1020. : __lc->_M_falsename;
  1021. int __len = __v ? __lc->_M_truename_size
  1022. : __lc->_M_falsename_size;
  1023. const streamsize __w = __io.width();
  1024. if (__w > static_cast<streamsize>(__len))
  1025. {
  1026. const streamsize __plen = __w - __len;
  1027. _CharT* __ps
  1028. = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  1029. * __plen));
  1030. char_traits<_CharT>::assign(__ps, __plen, __fill);
  1031. __io.width(0);
  1032. if ((__flags & ios_base::adjustfield) == ios_base::left)
  1033. {
  1034. __s = std::__write(__s, __name, __len);
  1035. __s = std::__write(__s, __ps, __plen);
  1036. }
  1037. else
  1038. {
  1039. __s = std::__write(__s, __ps, __plen);
  1040. __s = std::__write(__s, __name, __len);
  1041. }
  1042. return __s;
  1043. }
  1044. __io.width(0);
  1045. __s = std::__write(__s, __name, __len);
  1046. }
  1047. return __s;
  1048. }
  1049. template<typename _CharT, typename _OutIter>
  1050. _OutIter
  1051. num_put<_CharT, _OutIter>::
  1052. do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
  1053. { return _M_insert_float(__s, __io, __fill, char(), __v); }
  1054. #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
  1055. template<typename _CharT, typename _OutIter>
  1056. _OutIter
  1057. num_put<_CharT, _OutIter>::
  1058. __do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
  1059. { return _M_insert_float(__s, __io, __fill, char(), __v); }
  1060. #endif
  1061. template<typename _CharT, typename _OutIter>
  1062. _OutIter
  1063. num_put<_CharT, _OutIter>::
  1064. do_put(iter_type __s, ios_base& __io, char_type __fill,
  1065. long double __v) const
  1066. { return _M_insert_float(__s, __io, __fill, 'L', __v); }
  1067. template<typename _CharT, typename _OutIter>
  1068. _OutIter
  1069. num_put<_CharT, _OutIter>::
  1070. do_put(iter_type __s, ios_base& __io, char_type __fill,
  1071. const void* __v) const
  1072. {
  1073. const ios_base::fmtflags __flags = __io.flags();
  1074. const ios_base::fmtflags __fmt = ~(ios_base::basefield
  1075. | ios_base::uppercase);
  1076. __io.flags((__flags & __fmt) | (ios_base::hex | ios_base::showbase));
  1077. typedef __gnu_cxx::__conditional_type<(sizeof(const void*)
  1078. <= sizeof(unsigned long)),
  1079. unsigned long, unsigned long long>::__type _UIntPtrType;
  1080. __s = _M_insert_int(__s, __io, __fill,
  1081. reinterpret_cast<_UIntPtrType>(__v));
  1082. __io.flags(__flags);
  1083. return __s;
  1084. }
  1085. _GLIBCXX_END_NAMESPACE_LDBL
  1086. // Construct correctly padded string, as per 22.2.2.2.2
  1087. // Assumes
  1088. // __newlen > __oldlen
  1089. // __news is allocated for __newlen size
  1090. // NB: Of the two parameters, _CharT can be deduced from the
  1091. // function arguments. The other (_Traits) has to be explicitly specified.
  1092. template<typename _CharT, typename _Traits>
  1093. void
  1094. __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill,
  1095. _CharT* __news, const _CharT* __olds,
  1096. streamsize __newlen, streamsize __oldlen)
  1097. {
  1098. const size_t __plen = static_cast<size_t>(__newlen - __oldlen);
  1099. const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
  1100. // Padding last.
  1101. if (__adjust == ios_base::left)
  1102. {
  1103. _Traits::copy(__news, __olds, __oldlen);
  1104. _Traits::assign(__news + __oldlen, __plen, __fill);
  1105. return;
  1106. }
  1107. size_t __mod = 0;
  1108. if (__adjust == ios_base::internal)
  1109. {
  1110. // Pad after the sign, if there is one.
  1111. // Pad after 0[xX], if there is one.
  1112. // Who came up with these rules, anyway? Jeeze.
  1113. const locale& __loc = __io._M_getloc();
  1114. const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  1115. if (__ctype.widen('-') == __olds[0]
  1116. || __ctype.widen('+') == __olds[0])
  1117. {
  1118. __news[0] = __olds[0];
  1119. __mod = 1;
  1120. ++__news;
  1121. }
  1122. else if (__ctype.widen('0') == __olds[0]
  1123. && __oldlen > 1
  1124. && (__ctype.widen('x') == __olds[1]
  1125. || __ctype.widen('X') == __olds[1]))
  1126. {
  1127. __news[0] = __olds[0];
  1128. __news[1] = __olds[1];
  1129. __mod = 2;
  1130. __news += 2;
  1131. }
  1132. // else Padding first.
  1133. }
  1134. _Traits::assign(__news, __plen, __fill);
  1135. _Traits::copy(__news + __plen, __olds + __mod, __oldlen - __mod);
  1136. }
  1137. template<typename _CharT>
  1138. _CharT*
  1139. __add_grouping(_CharT* __s, _CharT __sep,
  1140. const char* __gbeg, size_t __gsize,
  1141. const _CharT* __first, const _CharT* __last)
  1142. {
  1143. size_t __idx = 0;
  1144. size_t __ctr = 0;
  1145. while (__last - __first > __gbeg[__idx]
  1146. && static_cast<signed char>(__gbeg[__idx]) > 0
  1147. && __gbeg[__idx] != __gnu_cxx::__numeric_traits<char>::__max)
  1148. {
  1149. __last -= __gbeg[__idx];
  1150. __idx < __gsize - 1 ? ++__idx : ++__ctr;
  1151. }
  1152. while (__first != __last)
  1153. *__s++ = *__first++;
  1154. while (__ctr--)
  1155. {
  1156. *__s++ = __sep;
  1157. for (char __i = __gbeg[__idx]; __i > 0; --__i)
  1158. *__s++ = *__first++;
  1159. }
  1160. while (__idx--)
  1161. {
  1162. *__s++ = __sep;
  1163. for (char __i = __gbeg[__idx]; __i > 0; --__i)
  1164. *__s++ = *__first++;
  1165. }
  1166. return __s;
  1167. }
  1168. // Inhibit implicit instantiations for required instantiations,
  1169. // which are defined via explicit instantiations elsewhere.
  1170. #if _GLIBCXX_EXTERN_TEMPLATE
  1171. extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct<char>;
  1172. extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct_byname<char>;
  1173. extern template class _GLIBCXX_NAMESPACE_LDBL num_get<char>;
  1174. extern template class _GLIBCXX_NAMESPACE_LDBL num_put<char>;
  1175. extern template class ctype_byname<char>;
  1176. extern template
  1177. const ctype<char>&
  1178. use_facet<ctype<char> >(const locale&);
  1179. extern template
  1180. const numpunct<char>&
  1181. use_facet<numpunct<char> >(const locale&);
  1182. extern template
  1183. const num_put<char>&
  1184. use_facet<num_put<char> >(const locale&);
  1185. extern template
  1186. const num_get<char>&
  1187. use_facet<num_get<char> >(const locale&);
  1188. extern template
  1189. bool
  1190. has_facet<ctype<char> >(const locale&);
  1191. extern template
  1192. bool
  1193. has_facet<numpunct<char> >(const locale&);
  1194. extern template
  1195. bool
  1196. has_facet<num_put<char> >(const locale&);
  1197. extern template
  1198. bool
  1199. has_facet<num_get<char> >(const locale&);
  1200. #ifdef _GLIBCXX_USE_WCHAR_T
  1201. extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct<wchar_t>;
  1202. extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct_byname<wchar_t>;
  1203. extern template class _GLIBCXX_NAMESPACE_LDBL num_get<wchar_t>;
  1204. extern template class _GLIBCXX_NAMESPACE_LDBL num_put<wchar_t>;
  1205. extern template class ctype_byname<wchar_t>;
  1206. extern template
  1207. const ctype<wchar_t>&
  1208. use_facet<ctype<wchar_t> >(const locale&);
  1209. extern template
  1210. const numpunct<wchar_t>&
  1211. use_facet<numpunct<wchar_t> >(const locale&);
  1212. extern template
  1213. const num_put<wchar_t>&
  1214. use_facet<num_put<wchar_t> >(const locale&);
  1215. extern template
  1216. const num_get<wchar_t>&
  1217. use_facet<num_get<wchar_t> >(const locale&);
  1218. extern template
  1219. bool
  1220. has_facet<ctype<wchar_t> >(const locale&);
  1221. extern template
  1222. bool
  1223. has_facet<numpunct<wchar_t> >(const locale&);
  1224. extern template
  1225. bool
  1226. has_facet<num_put<wchar_t> >(const locale&);
  1227. extern template
  1228. bool
  1229. has_facet<num_get<wchar_t> >(const locale&);
  1230. #endif
  1231. #endif
  1232. _GLIBCXX_END_NAMESPACE_VERSION
  1233. } // namespace
  1234. #endif