Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Locale support -*- C++ -*-
  2.  
  3. // Copyright (C) 2007-2015 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /** @file bits/locale_facets_nonio.tcc
  26.  *  This is an internal header file, included by other library headers.
  27.  *  Do not attempt to use it directly. @headername{locale}
  28.  */
  29.  
  30. #ifndef _LOCALE_FACETS_NONIO_TCC
  31. #define _LOCALE_FACETS_NONIO_TCC 1
  32.  
  33. #pragma GCC system_header
  34.  
  35. namespace std _GLIBCXX_VISIBILITY(default)
  36. {
  37. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  38.  
  39.   template<typename _CharT, bool _Intl>
  40.     struct __use_cache<__moneypunct_cache<_CharT, _Intl> >
  41.     {
  42.       const __moneypunct_cache<_CharT, _Intl>*
  43.       operator() (const locale& __loc) const
  44.       {
  45.         const size_t __i = moneypunct<_CharT, _Intl>::id._M_id();
  46.         const locale::facet** __caches = __loc._M_impl->_M_caches;
  47.         if (!__caches[__i])
  48.           {
  49.             __moneypunct_cache<_CharT, _Intl>* __tmp = 0;
  50.             __try
  51.               {
  52.                 __tmp = new __moneypunct_cache<_CharT, _Intl>;
  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<
  63.           const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]);
  64.       }
  65.     };
  66.  
  67.   template<typename _CharT, bool _Intl>
  68.     void
  69.     __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc)
  70.     {
  71.       const moneypunct<_CharT, _Intl>& __mp =
  72.         use_facet<moneypunct<_CharT, _Intl> >(__loc);
  73.  
  74.       _M_decimal_point = __mp.decimal_point();
  75.       _M_thousands_sep = __mp.thousands_sep();
  76.       _M_frac_digits = __mp.frac_digits();
  77.  
  78.       char* __grouping = 0;
  79.       _CharT* __curr_symbol = 0;
  80.       _CharT* __positive_sign = 0;
  81.       _CharT* __negative_sign = 0;    
  82.       __try
  83.         {
  84.           const string& __g = __mp.grouping();
  85.           _M_grouping_size = __g.size();
  86.           __grouping = new char[_M_grouping_size];
  87.           __g.copy(__grouping, _M_grouping_size);
  88.           _M_use_grouping = (_M_grouping_size
  89.                              && static_cast<signed char>(__grouping[0]) > 0
  90.                              && (__grouping[0]
  91.                                  != __gnu_cxx::__numeric_traits<char>::__max));
  92.  
  93.           const basic_string<_CharT>& __cs = __mp.curr_symbol();
  94.           _M_curr_symbol_size = __cs.size();
  95.           __curr_symbol = new _CharT[_M_curr_symbol_size];
  96.           __cs.copy(__curr_symbol, _M_curr_symbol_size);
  97.  
  98.           const basic_string<_CharT>& __ps = __mp.positive_sign();
  99.           _M_positive_sign_size = __ps.size();
  100.           __positive_sign = new _CharT[_M_positive_sign_size];
  101.           __ps.copy(__positive_sign, _M_positive_sign_size);
  102.  
  103.           const basic_string<_CharT>& __ns = __mp.negative_sign();
  104.           _M_negative_sign_size = __ns.size();
  105.           __negative_sign = new _CharT[_M_negative_sign_size];
  106.           __ns.copy(__negative_sign, _M_negative_sign_size);
  107.  
  108.           _M_pos_format = __mp.pos_format();
  109.           _M_neg_format = __mp.neg_format();
  110.  
  111.           const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
  112.           __ct.widen(money_base::_S_atoms,
  113.                      money_base::_S_atoms + money_base::_S_end, _M_atoms);
  114.  
  115.           _M_grouping = __grouping;
  116.           _M_curr_symbol = __curr_symbol;
  117.           _M_positive_sign = __positive_sign;
  118.           _M_negative_sign = __negative_sign;
  119.           _M_allocated = true;
  120.         }
  121.       __catch(...)
  122.         {
  123.           delete [] __grouping;
  124.           delete [] __curr_symbol;
  125.           delete [] __positive_sign;
  126.           delete [] __negative_sign;
  127.           __throw_exception_again;
  128.         }
  129.     }
  130.  
  131. _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
  132.  
  133.   template<typename _CharT, typename _InIter>
  134.     template<bool _Intl>
  135.       _InIter
  136.       money_get<_CharT, _InIter>::
  137.       _M_extract(iter_type __beg, iter_type __end, ios_base& __io,
  138.                  ios_base::iostate& __err, string& __units) const
  139.       {
  140.         typedef char_traits<_CharT>                       __traits_type;
  141.         typedef typename string_type::size_type           size_type;   
  142.         typedef money_base::part                          part;
  143.         typedef __moneypunct_cache<_CharT, _Intl>         __cache_type;
  144.        
  145.         const locale& __loc = __io._M_getloc();
  146.         const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  147.  
  148.         __use_cache<__cache_type> __uc;
  149.         const __cache_type* __lc = __uc(__loc);
  150.         const char_type* __lit = __lc->_M_atoms;
  151.  
  152.         // Deduced sign.
  153.         bool __negative = false;
  154.         // Sign size.
  155.         size_type __sign_size = 0;
  156.         // True if sign is mandatory.
  157.         const bool __mandatory_sign = (__lc->_M_positive_sign_size
  158.                                        && __lc->_M_negative_sign_size);
  159.         // String of grouping info from thousands_sep plucked from __units.
  160.         string __grouping_tmp;
  161.         if (__lc->_M_use_grouping)
  162.           __grouping_tmp.reserve(32);
  163.         // Last position before the decimal point.
  164.         int __last_pos = 0;
  165.         // Separator positions, then, possibly, fractional digits.
  166.         int __n = 0;
  167.         // If input iterator is in a valid state.
  168.         bool __testvalid = true;
  169.         // Flag marking when a decimal point is found.
  170.         bool __testdecfound = false;
  171.  
  172.         // The tentative returned string is stored here.
  173.         string __res;
  174.         __res.reserve(32);
  175.  
  176.         const char_type* __lit_zero = __lit + money_base::_S_zero;
  177.         const money_base::pattern __p = __lc->_M_neg_format;
  178.         for (int __i = 0; __i < 4 && __testvalid; ++__i)
  179.           {
  180.             const part __which = static_cast<part>(__p.field[__i]);
  181.             switch (__which)
  182.               {
  183.               case money_base::symbol:
  184.                 // According to 22.2.6.1.2, p2, symbol is required
  185.                 // if (__io.flags() & ios_base::showbase), otherwise
  186.                 // is optional and consumed only if other characters
  187.                 // are needed to complete the format.
  188.                 if (__io.flags() & ios_base::showbase || __sign_size > 1
  189.                     || __i == 0
  190.                     || (__i == 1 && (__mandatory_sign
  191.                                      || (static_cast<part>(__p.field[0])
  192.                                          == money_base::sign)
  193.                                      || (static_cast<part>(__p.field[2])
  194.                                          == money_base::space)))
  195.                     || (__i == 2 && ((static_cast<part>(__p.field[3])
  196.                                       == money_base::value)
  197.                                      || (__mandatory_sign
  198.                                          && (static_cast<part>(__p.field[3])
  199.                                              == money_base::sign)))))
  200.                   {
  201.                     const size_type __len = __lc->_M_curr_symbol_size;
  202.                     size_type __j = 0;
  203.                     for (; __beg != __end && __j < __len
  204.                            && *__beg == __lc->_M_curr_symbol[__j];
  205.                          ++__beg, ++__j);
  206.                     if (__j != __len
  207.                         && (__j || __io.flags() & ios_base::showbase))
  208.                       __testvalid = false;
  209.                   }
  210.                 break;
  211.               case money_base::sign:
  212.                 // Sign might not exist, or be more than one character long.
  213.                 if (__lc->_M_positive_sign_size && __beg != __end
  214.                     && *__beg == __lc->_M_positive_sign[0])
  215.                   {
  216.                     __sign_size = __lc->_M_positive_sign_size;
  217.                     ++__beg;
  218.                   }
  219.                 else if (__lc->_M_negative_sign_size && __beg != __end
  220.                          && *__beg == __lc->_M_negative_sign[0])
  221.                   {
  222.                     __negative = true;
  223.                     __sign_size = __lc->_M_negative_sign_size;
  224.                     ++__beg;
  225.                   }
  226.                 else if (__lc->_M_positive_sign_size
  227.                          && !__lc->_M_negative_sign_size)
  228.                   // "... if no sign is detected, the result is given the sign
  229.                   // that corresponds to the source of the empty string"
  230.                   __negative = true;
  231.                 else if (__mandatory_sign)
  232.                   __testvalid = false;
  233.                 break;
  234.               case money_base::value:
  235.                 // Extract digits, remove and stash away the
  236.                 // grouping of found thousands separators.
  237.                 for (; __beg != __end; ++__beg)
  238.                   {
  239.                     const char_type __c = *__beg;
  240.                     const char_type* __q = __traits_type::find(__lit_zero,
  241.                                                                10, __c);
  242.                     if (__q != 0)
  243.                       {
  244.                         __res += money_base::_S_atoms[__q - __lit];
  245.                         ++__n;
  246.                       }
  247.                     else if (__c == __lc->_M_decimal_point
  248.                              && !__testdecfound)
  249.                       {
  250.                         if (__lc->_M_frac_digits <= 0)
  251.                           break;
  252.  
  253.                         __last_pos = __n;
  254.                         __n = 0;
  255.                         __testdecfound = true;
  256.                       }
  257.                     else if (__lc->_M_use_grouping
  258.                              && __c == __lc->_M_thousands_sep
  259.                              && !__testdecfound)
  260.                       {
  261.                         if (__n)
  262.                           {
  263.                             // Mark position for later analysis.
  264.                             __grouping_tmp += static_cast<char>(__n);
  265.                             __n = 0;
  266.                           }
  267.                         else
  268.                           {
  269.                             __testvalid = false;
  270.                             break;
  271.                           }
  272.                       }
  273.                     else
  274.                       break;
  275.                   }
  276.                 if (__res.empty())
  277.                   __testvalid = false;
  278.                 break;
  279.               case money_base::space:
  280.                 // At least one space is required.
  281.                 if (__beg != __end && __ctype.is(ctype_base::space, *__beg))
  282.                   ++__beg;
  283.                 else
  284.                   __testvalid = false;
  285.               case money_base::none:
  286.                 // Only if not at the end of the pattern.
  287.                 if (__i != 3)
  288.                   for (; __beg != __end
  289.                          && __ctype.is(ctype_base::space, *__beg); ++__beg);
  290.                 break;
  291.               }
  292.           }
  293.  
  294.         // Need to get the rest of the sign characters, if they exist.
  295.         if (__sign_size > 1 && __testvalid)
  296.           {
  297.             const char_type* __sign = __negative ? __lc->_M_negative_sign
  298.                                                  : __lc->_M_positive_sign;
  299.             size_type __i = 1;
  300.             for (; __beg != __end && __i < __sign_size
  301.                    && *__beg == __sign[__i]; ++__beg, ++__i);
  302.            
  303.             if (__i != __sign_size)
  304.               __testvalid = false;
  305.           }
  306.  
  307.         if (__testvalid)
  308.           {
  309.             // Strip leading zeros.
  310.             if (__res.size() > 1)
  311.               {
  312.                 const size_type __first = __res.find_first_not_of('0');
  313.                 const bool __only_zeros = __first == string::npos;
  314.                 if (__first)
  315.                   __res.erase(0, __only_zeros ? __res.size() - 1 : __first);
  316.               }
  317.  
  318.             // 22.2.6.1.2, p4
  319.             if (__negative && __res[0] != '0')
  320.               __res.insert(__res.begin(), '-');
  321.            
  322.             // Test for grouping fidelity.
  323.             if (__grouping_tmp.size())
  324.               {
  325.                 // Add the ending grouping.
  326.                 __grouping_tmp += static_cast<char>(__testdecfound ? __last_pos
  327.                                                                    : __n);
  328.                 if (!std::__verify_grouping(__lc->_M_grouping,
  329.                                             __lc->_M_grouping_size,
  330.                                             __grouping_tmp))
  331.                   __err |= ios_base::failbit;
  332.               }
  333.            
  334.             // Iff not enough digits were supplied after the decimal-point.
  335.             if (__testdecfound && __n != __lc->_M_frac_digits)
  336.               __testvalid = false;
  337.           }
  338.  
  339.         // Iff valid sequence is not recognized.
  340.         if (!__testvalid)
  341.           __err |= ios_base::failbit;
  342.         else
  343.           __units.swap(__res);
  344.        
  345.         // Iff no more characters are available.
  346.         if (__beg == __end)
  347.           __err |= ios_base::eofbit;
  348.         return __beg;
  349.       }
  350.  
  351. #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
  352.       && _GLIBCXX_USE_CXX11_ABI == 0
  353.   template<typename _CharT, typename _InIter>
  354.     _InIter
  355.     money_get<_CharT, _InIter>::
  356.     __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
  357.              ios_base::iostate& __err, double& __units) const
  358.     {
  359.       string __str;
  360.       __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
  361.                      : _M_extract<false>(__beg, __end, __io, __err, __str);
  362.       std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
  363.       return __beg;
  364.     }
  365. #endif
  366.  
  367.   template<typename _CharT, typename _InIter>
  368.     _InIter
  369.     money_get<_CharT, _InIter>::
  370.     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
  371.            ios_base::iostate& __err, long double& __units) const
  372.     {
  373.       string __str;
  374.       __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
  375.                      : _M_extract<false>(__beg, __end, __io, __err, __str);
  376.       std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
  377.       return __beg;
  378.     }
  379.  
  380.   template<typename _CharT, typename _InIter>
  381.     _InIter
  382.     money_get<_CharT, _InIter>::
  383.     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
  384.            ios_base::iostate& __err, string_type& __digits) const
  385.     {
  386.       typedef typename string::size_type                  size_type;
  387.  
  388.       const locale& __loc = __io._M_getloc();
  389.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  390.  
  391.       string __str;
  392.       __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
  393.                      : _M_extract<false>(__beg, __end, __io, __err, __str);
  394.       const size_type __len = __str.size();
  395.       if (__len)
  396.         {
  397.           __digits.resize(__len);
  398.           __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]);
  399.         }
  400.       return __beg;
  401.     }
  402.  
  403.   template<typename _CharT, typename _OutIter>
  404.     template<bool _Intl>
  405.       _OutIter
  406.       money_put<_CharT, _OutIter>::
  407.       _M_insert(iter_type __s, ios_base& __io, char_type __fill,
  408.                 const string_type& __digits) const
  409.       {
  410.         typedef typename string_type::size_type           size_type;
  411.         typedef money_base::part                          part;
  412.         typedef __moneypunct_cache<_CharT, _Intl>         __cache_type;
  413.      
  414.         const locale& __loc = __io._M_getloc();
  415.         const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  416.  
  417.         __use_cache<__cache_type> __uc;
  418.         const __cache_type* __lc = __uc(__loc);
  419.         const char_type* __lit = __lc->_M_atoms;
  420.  
  421.         // Determine if negative or positive formats are to be used, and
  422.         // discard leading negative_sign if it is present.
  423.         const char_type* __beg = __digits.data();
  424.  
  425.         money_base::pattern __p;
  426.         const char_type* __sign;
  427.         size_type __sign_size;
  428.         if (!(*__beg == __lit[money_base::_S_minus]))
  429.           {
  430.             __p = __lc->_M_pos_format;
  431.             __sign = __lc->_M_positive_sign;
  432.             __sign_size = __lc->_M_positive_sign_size;
  433.           }
  434.         else
  435.           {
  436.             __p = __lc->_M_neg_format;
  437.             __sign = __lc->_M_negative_sign;
  438.             __sign_size = __lc->_M_negative_sign_size;
  439.             if (__digits.size())
  440.               ++__beg;
  441.           }
  442.        
  443.         // Look for valid numbers in the ctype facet within input digits.
  444.         size_type __len = __ctype.scan_not(ctype_base::digit, __beg,
  445.                                            __beg + __digits.size()) - __beg;
  446.         if (__len)
  447.           {
  448.             // Assume valid input, and attempt to format.
  449.             // Break down input numbers into base components, as follows:
  450.             //   final_value = grouped units + (decimal point) + (digits)
  451.             string_type __value;
  452.             __value.reserve(2 * __len);
  453.  
  454.             // Add thousands separators to non-decimal digits, per
  455.             // grouping rules.
  456.             long __paddec = __len - __lc->_M_frac_digits;
  457.             if (__paddec > 0)
  458.               {
  459.                 if (__lc->_M_frac_digits < 0)
  460.                   __paddec = __len;
  461.                 if (__lc->_M_grouping_size)
  462.                   {
  463.                     __value.assign(2 * __paddec, char_type());
  464.                     _CharT* __vend =
  465.                       std::__add_grouping(&__value[0], __lc->_M_thousands_sep,
  466.                                           __lc->_M_grouping,
  467.                                           __lc->_M_grouping_size,
  468.                                           __beg, __beg + __paddec);
  469.                     __value.erase(__vend - &__value[0]);
  470.                   }
  471.                 else
  472.                   __value.assign(__beg, __paddec);
  473.               }
  474.  
  475.             // Deal with decimal point, decimal digits.
  476.             if (__lc->_M_frac_digits > 0)
  477.               {
  478.                 __value += __lc->_M_decimal_point;
  479.                 if (__paddec >= 0)
  480.                   __value.append(__beg + __paddec, __lc->_M_frac_digits);
  481.                 else
  482.                   {
  483.                     // Have to pad zeros in the decimal position.
  484.                     __value.append(-__paddec, __lit[money_base::_S_zero]);
  485.                     __value.append(__beg, __len);
  486.                   }
  487.               }
  488.  
  489.             // Calculate length of resulting string.
  490.             const ios_base::fmtflags __f = __io.flags()
  491.                                            & ios_base::adjustfield;
  492.             __len = __value.size() + __sign_size;
  493.             __len += ((__io.flags() & ios_base::showbase)
  494.                       ? __lc->_M_curr_symbol_size : 0);
  495.  
  496.             string_type __res;
  497.             __res.reserve(2 * __len);
  498.            
  499.             const size_type __width = static_cast<size_type>(__io.width());  
  500.             const bool __testipad = (__f == ios_base::internal
  501.                                      && __len < __width);
  502.             // Fit formatted digits into the required pattern.
  503.             for (int __i = 0; __i < 4; ++__i)
  504.               {
  505.                 const part __which = static_cast<part>(__p.field[__i]);
  506.                 switch (__which)
  507.                   {
  508.                   case money_base::symbol:
  509.                     if (__io.flags() & ios_base::showbase)
  510.                       __res.append(__lc->_M_curr_symbol,
  511.                                    __lc->_M_curr_symbol_size);
  512.                     break;
  513.                   case money_base::sign:
  514.                     // Sign might not exist, or be more than one
  515.                     // character long. In that case, add in the rest
  516.                     // below.
  517.                     if (__sign_size)
  518.                       __res += __sign[0];
  519.                     break;
  520.                   case money_base::value:
  521.                     __res += __value;
  522.                     break;
  523.                   case money_base::space:
  524.                     // At least one space is required, but if internal
  525.                     // formatting is required, an arbitrary number of
  526.                     // fill spaces will be necessary.
  527.                     if (__testipad)
  528.                       __res.append(__width - __len, __fill);
  529.                     else
  530.                       __res += __fill;
  531.                     break;
  532.                   case money_base::none:
  533.                     if (__testipad)
  534.                       __res.append(__width - __len, __fill);
  535.                     break;
  536.                   }
  537.               }
  538.            
  539.             // Special case of multi-part sign parts.
  540.             if (__sign_size > 1)
  541.               __res.append(__sign + 1, __sign_size - 1);
  542.            
  543.             // Pad, if still necessary.
  544.             __len = __res.size();
  545.             if (__width > __len)
  546.               {
  547.                 if (__f == ios_base::left)
  548.                   // After.
  549.                   __res.append(__width - __len, __fill);
  550.                 else
  551.                   // Before.
  552.                   __res.insert(0, __width - __len, __fill);
  553.                 __len = __width;
  554.               }
  555.            
  556.             // Write resulting, fully-formatted string to output iterator.
  557.             __s = std::__write(__s, __res.data(), __len);
  558.           }
  559.         __io.width(0);
  560.         return __s;    
  561.       }
  562.  
  563. #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
  564.       && _GLIBCXX_USE_CXX11_ABI == 0
  565.   template<typename _CharT, typename _OutIter>
  566.     _OutIter
  567.     money_put<_CharT, _OutIter>::
  568.     __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
  569.              double __units) const
  570.     { return this->do_put(__s, __intl, __io, __fill, (long double) __units); }
  571. #endif
  572.  
  573.   template<typename _CharT, typename _OutIter>
  574.     _OutIter
  575.     money_put<_CharT, _OutIter>::
  576.     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
  577.            long double __units) const
  578.     {
  579.       const locale __loc = __io.getloc();
  580.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  581. #ifdef _GLIBCXX_USE_C99
  582.       // First try a buffer perhaps big enough.
  583.       int __cs_size = 64;
  584.       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  585.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  586.       // 328. Bad sprintf format modifier in money_put<>::do_put()
  587.       int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
  588.                                         "%.*Lf", 0, __units);
  589.       // If the buffer was not large enough, try again with the correct size.
  590.       if (__len >= __cs_size)
  591.         {
  592.           __cs_size = __len + 1;
  593.           __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  594.           __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
  595.                                         "%.*Lf", 0, __units);
  596.         }
  597. #else
  598.       // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
  599.       const int __cs_size =
  600.         __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 3;
  601.       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  602.       int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf",
  603.                                         0, __units);
  604. #endif
  605.       string_type __digits(__len, char_type());
  606.       __ctype.widen(__cs, __cs + __len, &__digits[0]);
  607.       return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
  608.                     : _M_insert<false>(__s, __io, __fill, __digits);
  609.     }
  610.  
  611.   template<typename _CharT, typename _OutIter>
  612.     _OutIter
  613.     money_put<_CharT, _OutIter>::
  614.     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
  615.            const string_type& __digits) const
  616.     { return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
  617.                     : _M_insert<false>(__s, __io, __fill, __digits); }
  618.  
  619. _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
  620.  
  621.   // NB: Not especially useful. Without an ios_base object or some
  622.   // kind of locale reference, we are left clawing at the air where
  623.   // the side of the mountain used to be...
  624.   template<typename _CharT, typename _InIter>
  625.     time_base::dateorder
  626.     time_get<_CharT, _InIter>::do_date_order() const
  627.     { return time_base::no_order; }
  628.  
  629.   // Expand a strftime format string and parse it.  E.g., do_get_date() may
  630.   // pass %m/%d/%Y => extracted characters.
  631.   template<typename _CharT, typename _InIter>
  632.     _InIter
  633.     time_get<_CharT, _InIter>::
  634.     _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
  635.                           ios_base::iostate& __err, tm* __tm,
  636.                           const _CharT* __format) const
  637.     {
  638.       const locale& __loc = __io._M_getloc();
  639.       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
  640.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  641.       const size_t __len = char_traits<_CharT>::length(__format);
  642.  
  643.       ios_base::iostate __tmperr = ios_base::goodbit;
  644.       size_t __i = 0;
  645.       for (; __beg != __end && __i < __len && !__tmperr; ++__i)
  646.         {
  647.           if (__ctype.narrow(__format[__i], 0) == '%')
  648.             {
  649.               // Verify valid formatting code, attempt to extract.
  650.               char __c = __ctype.narrow(__format[++__i], 0);
  651.               int __mem = 0;
  652.               if (__c == 'E' || __c == 'O')
  653.                 __c = __ctype.narrow(__format[++__i], 0);
  654.               switch (__c)
  655.                 {
  656.                   const char* __cs;
  657.                   _CharT __wcs[10];
  658.                 case 'a':
  659.                   // Abbreviated weekday name [tm_wday]
  660.                   const char_type*  __days1[7];
  661.                   __tp._M_days_abbreviated(__days1);
  662.                   __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1,
  663.                                           7, __io, __tmperr);
  664.                   break;
  665.                 case 'A':
  666.                   // Weekday name [tm_wday].
  667.                   const char_type*  __days2[7];
  668.                   __tp._M_days(__days2);
  669.                   __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2,
  670.                                           7, __io, __tmperr);
  671.                   break;
  672.                 case 'h':
  673.                 case 'b':
  674.                   // Abbreviated month name [tm_mon]
  675.                   const char_type*  __months1[12];
  676.                   __tp._M_months_abbreviated(__months1);
  677.                   __beg = _M_extract_name(__beg, __end, __tm->tm_mon,
  678.                                           __months1, 12, __io, __tmperr);
  679.                   break;
  680.                 case 'B':
  681.                   // Month name [tm_mon].
  682.                   const char_type*  __months2[12];
  683.                   __tp._M_months(__months2);
  684.                   __beg = _M_extract_name(__beg, __end, __tm->tm_mon,
  685.                                           __months2, 12, __io, __tmperr);
  686.                   break;
  687.                 case 'c':
  688.                   // Default time and date representation.
  689.                   const char_type*  __dt[2];
  690.                   __tp._M_date_time_formats(__dt);
  691.                   __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
  692.                                                 __tm, __dt[0]);
  693.                   break;
  694.                 case 'd':
  695.                   // Day [01, 31]. [tm_mday]
  696.                   __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
  697.                                          __io, __tmperr);
  698.                   break;
  699.                 case 'e':
  700.                   // Day [1, 31], with single digits preceded by
  701.                   // space. [tm_mday]
  702.                   if (__ctype.is(ctype_base::space, *__beg))
  703.                     __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9,
  704.                                            1, __io, __tmperr);
  705.                   else
  706.                     __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31,
  707.                                            2, __io, __tmperr);
  708.                   break;
  709.                 case 'D':
  710.                   // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
  711.                   __cs = "%m/%d/%y";
  712.                   __ctype.widen(__cs, __cs + 9, __wcs);
  713.                   __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
  714.                                                 __tm, __wcs);
  715.                   break;
  716.                 case 'H':
  717.                   // Hour [00, 23]. [tm_hour]
  718.                   __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
  719.                                          __io, __tmperr);
  720.                   break;
  721.                 case 'I':
  722.                   // Hour [01, 12]. [tm_hour]
  723.                   __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
  724.                                          __io, __tmperr);
  725.                   break;
  726.                 case 'm':
  727.                   // Month [01, 12]. [tm_mon]
  728.                   __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2,
  729.                                          __io, __tmperr);
  730.                   if (!__tmperr)
  731.                     __tm->tm_mon = __mem - 1;
  732.                   break;
  733.                 case 'M':
  734.                   // Minute [00, 59]. [tm_min]
  735.                   __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
  736.                                          __io, __tmperr);
  737.                   break;
  738.                 case 'n':
  739.                   if (__ctype.narrow(*__beg, 0) == '\n')
  740.                     ++__beg;
  741.                   else
  742.                     __tmperr |= ios_base::failbit;
  743.                   break;
  744.                 case 'R':
  745.                   // Equivalent to (%H:%M).
  746.                   __cs = "%H:%M";
  747.                   __ctype.widen(__cs, __cs + 6, __wcs);
  748.                   __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
  749.                                                 __tm, __wcs);
  750.                   break;
  751.                 case 'S':
  752.                   // Seconds. [tm_sec]
  753.                   // [00, 60] in C99 (one leap-second), [00, 61] in C89.
  754. #ifdef _GLIBCXX_USE_C99
  755.                   __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2,
  756. #else
  757.                   __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2,
  758. #endif
  759.                                          __io, __tmperr);
  760.                   break;
  761.                 case 't':
  762.                   if (__ctype.narrow(*__beg, 0) == '\t')
  763.                     ++__beg;
  764.                   else
  765.                     __tmperr |= ios_base::failbit;
  766.                   break;
  767.                 case 'T':
  768.                   // Equivalent to (%H:%M:%S).
  769.                   __cs = "%H:%M:%S";
  770.                   __ctype.widen(__cs, __cs + 9, __wcs);
  771.                   __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
  772.                                                 __tm, __wcs);
  773.                   break;
  774.                 case 'x':
  775.                   // Locale's date.
  776.                   const char_type*  __dates[2];
  777.                   __tp._M_date_formats(__dates);
  778.                   __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
  779.                                                 __tm, __dates[0]);
  780.                   break;
  781.                 case 'X':
  782.                   // Locale's time.
  783.                   const char_type*  __times[2];
  784.                   __tp._M_time_formats(__times);
  785.                   __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
  786.                                                 __tm, __times[0]);
  787.                   break;
  788.                 case 'y':
  789.                 case 'C': // C99
  790.                   // Two digit year.
  791.                 case 'Y':
  792.                   // Year [1900).
  793.                   // NB: We parse either two digits, implicitly years since
  794.                   // 1900, or 4 digits, full year.  In both cases we can
  795.                   // reconstruct [tm_year].  See also libstdc++/26701.
  796.                   __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4,
  797.                                          __io, __tmperr);
  798.                   if (!__tmperr)
  799.                     __tm->tm_year = __mem < 0 ? __mem + 100 : __mem - 1900;
  800.                   break;
  801.                 case 'Z':
  802.                   // Timezone info.
  803.                   if (__ctype.is(ctype_base::upper, *__beg))
  804.                     {
  805.                       int __tmp;
  806.                       __beg = _M_extract_name(__beg, __end, __tmp,
  807.                                        __timepunct_cache<_CharT>::_S_timezones,
  808.                                               14, __io, __tmperr);
  809.  
  810.                       // GMT requires special effort.
  811.                       if (__beg != __end && !__tmperr && __tmp == 0
  812.                           && (*__beg == __ctype.widen('-')
  813.                               || *__beg == __ctype.widen('+')))
  814.                         {
  815.                           __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
  816.                                                  __io, __tmperr);
  817.                           __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
  818.                                                  __io, __tmperr);
  819.                         }
  820.                     }
  821.                   else
  822.                     __tmperr |= ios_base::failbit;
  823.                   break;
  824.                 default:
  825.                   // Not recognized.
  826.                   __tmperr |= ios_base::failbit;
  827.                 }
  828.             }
  829.           else
  830.             {
  831.               // Verify format and input match, extract and discard.
  832.               if (__format[__i] == *__beg)
  833.                 ++__beg;
  834.               else
  835.                 __tmperr |= ios_base::failbit;
  836.             }
  837.         }
  838.  
  839.       if (__tmperr || __i != __len)
  840.         __err |= ios_base::failbit;
  841.  
  842.       return __beg;
  843.     }
  844.  
  845.   template<typename _CharT, typename _InIter>
  846.     _InIter
  847.     time_get<_CharT, _InIter>::
  848.     _M_extract_num(iter_type __beg, iter_type __end, int& __member,
  849.                    int __min, int __max, size_t __len,
  850.                    ios_base& __io, ios_base::iostate& __err) const
  851.     {
  852.       const locale& __loc = __io._M_getloc();
  853.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  854.  
  855.       // As-is works for __len = 1, 2, 4, the values actually used.
  856.       int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1);
  857.  
  858.       ++__min;
  859.       size_t __i = 0;
  860.       int __value = 0;
  861.       for (; __beg != __end && __i < __len; ++__beg, ++__i)
  862.         {
  863.           const char __c = __ctype.narrow(*__beg, '*');
  864.           if (__c >= '0' && __c <= '9')
  865.             {
  866.               __value = __value * 10 + (__c - '0');
  867.               const int __valuec = __value * __mult;
  868.               if (__valuec > __max || __valuec + __mult < __min)
  869.                 break;
  870.               __mult /= 10;
  871.             }
  872.           else
  873.             break;
  874.         }
  875.       if (__i == __len)
  876.         __member = __value;
  877.       // Special encoding for do_get_year, 'y', and 'Y' above.
  878.       else if (__len == 4 && __i == 2)
  879.         __member = __value - 100;
  880.       else
  881.         __err |= ios_base::failbit;
  882.  
  883.       return __beg;
  884.     }
  885.  
  886.   // Assumptions:
  887.   // All elements in __names are unique.
  888.   template<typename _CharT, typename _InIter>
  889.     _InIter
  890.     time_get<_CharT, _InIter>::
  891.     _M_extract_name(iter_type __beg, iter_type __end, int& __member,
  892.                     const _CharT** __names, size_t __indexlen,
  893.                     ios_base& __io, ios_base::iostate& __err) const
  894.     {
  895.       typedef char_traits<_CharT>               __traits_type;
  896.       const locale& __loc = __io._M_getloc();
  897.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  898.  
  899.       int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int)
  900.                                                           * __indexlen));
  901.       size_t __nmatches = 0;
  902.       size_t __pos = 0;
  903.       bool __testvalid = true;
  904.       const char_type* __name;
  905.  
  906.       // Look for initial matches.
  907.       // NB: Some of the locale data is in the form of all lowercase
  908.       // names, and some is in the form of initially-capitalized
  909.       // names. Look for both.
  910.       if (__beg != __end)
  911.         {
  912.           const char_type __c = *__beg;
  913.           for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
  914.             if (__c == __names[__i1][0]
  915.                 || __c == __ctype.toupper(__names[__i1][0]))
  916.               __matches[__nmatches++] = __i1;
  917.         }
  918.  
  919.       while (__nmatches > 1)
  920.         {
  921.           // Find smallest matching string.
  922.           size_t __minlen = __traits_type::length(__names[__matches[0]]);
  923.           for (size_t __i2 = 1; __i2 < __nmatches; ++__i2)
  924.             __minlen = std::min(__minlen,
  925.                               __traits_type::length(__names[__matches[__i2]]));
  926.           ++__beg, ++__pos;
  927.           if (__pos < __minlen && __beg != __end)
  928.             for (size_t __i3 = 0; __i3 < __nmatches;)
  929.               {
  930.                 __name = __names[__matches[__i3]];
  931.                 if (!(__name[__pos] == *__beg))
  932.                   __matches[__i3] = __matches[--__nmatches];
  933.                 else
  934.                   ++__i3;
  935.               }
  936.           else
  937.             break;
  938.         }
  939.  
  940.       if (__nmatches == 1)
  941.         {
  942.           // Make sure found name is completely extracted.
  943.           ++__beg, ++__pos;
  944.           __name = __names[__matches[0]];
  945.           const size_t __len = __traits_type::length(__name);
  946.           while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
  947.             ++__beg, ++__pos;
  948.  
  949.           if (__len == __pos)
  950.             __member = __matches[0];
  951.           else
  952.             __testvalid = false;
  953.         }
  954.       else
  955.         __testvalid = false;
  956.       if (!__testvalid)
  957.         __err |= ios_base::failbit;
  958.  
  959.       return __beg;
  960.     }
  961.  
  962.   template<typename _CharT, typename _InIter>
  963.     _InIter
  964.     time_get<_CharT, _InIter>::
  965.     _M_extract_wday_or_month(iter_type __beg, iter_type __end, int& __member,
  966.                              const _CharT** __names, size_t __indexlen,
  967.                              ios_base& __io, ios_base::iostate& __err) const
  968.     {
  969.       typedef char_traits<_CharT>               __traits_type;
  970.       const locale& __loc = __io._M_getloc();
  971.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  972.  
  973.       int* __matches = static_cast<int*>(__builtin_alloca(2 * sizeof(int)
  974.                                                           * __indexlen));
  975.       size_t __nmatches = 0;
  976.       size_t* __matches_lengths = 0;
  977.       size_t __pos = 0;
  978.  
  979.       if (__beg != __end)
  980.         {
  981.           const char_type __c = *__beg;
  982.           for (size_t __i = 0; __i < 2 * __indexlen; ++__i)
  983.             if (__c == __names[__i][0]
  984.                 || __c == __ctype.toupper(__names[__i][0]))
  985.               __matches[__nmatches++] = __i;
  986.         }
  987.  
  988.       if (__nmatches)
  989.         {
  990.           ++__beg, ++__pos;
  991.  
  992.           __matches_lengths
  993.             = static_cast<size_t*>(__builtin_alloca(sizeof(size_t)
  994.                                                     * __nmatches));
  995.           for (size_t __i = 0; __i < __nmatches; ++__i)
  996.             __matches_lengths[__i]
  997.               = __traits_type::length(__names[__matches[__i]]);
  998.         }
  999.  
  1000.       for (; __beg != __end; ++__beg, ++__pos)
  1001.         {
  1002.           size_t __nskipped = 0;
  1003.           const char_type __c = *__beg;
  1004.           for (size_t __i = 0; __i < __nmatches;)
  1005.             {
  1006.               const char_type* __name = __names[__matches[__i]];
  1007.               if (__pos >= __matches_lengths[__i])
  1008.                 ++__nskipped, ++__i;
  1009.               else if (!(__name[__pos] == __c))
  1010.                 {
  1011.                   --__nmatches;
  1012.                   __matches[__i] = __matches[__nmatches];
  1013.                   __matches_lengths[__i] = __matches_lengths[__nmatches];
  1014.                 }
  1015.               else
  1016.                 ++__i;
  1017.             }
  1018.           if (__nskipped == __nmatches)
  1019.             break;
  1020.         }
  1021.  
  1022.       if ((__nmatches == 1 && __matches_lengths[0] == __pos)
  1023.           || (__nmatches == 2 && (__matches_lengths[0] == __pos
  1024.                                   || __matches_lengths[1] == __pos)))
  1025.         __member = (__matches[0] >= __indexlen
  1026.                     ? __matches[0] - __indexlen : __matches[0]);
  1027.       else
  1028.         __err |= ios_base::failbit;
  1029.  
  1030.       return __beg;
  1031.     }
  1032.  
  1033.   template<typename _CharT, typename _InIter>
  1034.     _InIter
  1035.     time_get<_CharT, _InIter>::
  1036.     do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
  1037.                 ios_base::iostate& __err, tm* __tm) const
  1038.     {
  1039.       const locale& __loc = __io._M_getloc();
  1040.       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
  1041.       const char_type*  __times[2];
  1042.       __tp._M_time_formats(__times);
  1043.       __beg = _M_extract_via_format(__beg, __end, __io, __err,
  1044.                                     __tm, __times[0]);
  1045.       if (__beg == __end)
  1046.         __err |= ios_base::eofbit;
  1047.       return __beg;
  1048.     }
  1049.  
  1050.   template<typename _CharT, typename _InIter>
  1051.     _InIter
  1052.     time_get<_CharT, _InIter>::
  1053.     do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
  1054.                 ios_base::iostate& __err, tm* __tm) const
  1055.     {
  1056.       const locale& __loc = __io._M_getloc();
  1057.       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
  1058.       const char_type*  __dates[2];
  1059.       __tp._M_date_formats(__dates);
  1060.       __beg = _M_extract_via_format(__beg, __end, __io, __err,
  1061.                                     __tm, __dates[0]);
  1062.       if (__beg == __end)
  1063.         __err |= ios_base::eofbit;
  1064.       return __beg;
  1065.     }
  1066.  
  1067.   template<typename _CharT, typename _InIter>
  1068.     _InIter
  1069.     time_get<_CharT, _InIter>::
  1070.     do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
  1071.                    ios_base::iostate& __err, tm* __tm) const
  1072.     {
  1073.       const locale& __loc = __io._M_getloc();
  1074.       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
  1075.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  1076.       const char_type* __days[14];
  1077.       __tp._M_days_abbreviated(__days);
  1078.       __tp._M_days(__days + 7);
  1079.       int __tmpwday;
  1080.       ios_base::iostate __tmperr = ios_base::goodbit;
  1081.  
  1082.       __beg = _M_extract_wday_or_month(__beg, __end, __tmpwday, __days, 7,
  1083.                                        __io, __tmperr);
  1084.       if (!__tmperr)
  1085.         __tm->tm_wday = __tmpwday;
  1086.       else
  1087.         __err |= ios_base::failbit;
  1088.  
  1089.       if (__beg == __end)
  1090.         __err |= ios_base::eofbit;
  1091.       return __beg;
  1092.      }
  1093.  
  1094.   template<typename _CharT, typename _InIter>
  1095.     _InIter
  1096.     time_get<_CharT, _InIter>::
  1097.     do_get_monthname(iter_type __beg, iter_type __end,
  1098.                      ios_base& __io, ios_base::iostate& __err, tm* __tm) const
  1099.     {
  1100.       const locale& __loc = __io._M_getloc();
  1101.       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
  1102.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  1103.       const char_type*  __months[24];
  1104.       __tp._M_months_abbreviated(__months);
  1105.       __tp._M_months(__months + 12);
  1106.       int __tmpmon;
  1107.       ios_base::iostate __tmperr = ios_base::goodbit;
  1108.  
  1109.       __beg = _M_extract_wday_or_month(__beg, __end, __tmpmon, __months, 12,
  1110.                                        __io, __tmperr);
  1111.       if (!__tmperr)
  1112.         __tm->tm_mon = __tmpmon;
  1113.       else
  1114.         __err |= ios_base::failbit;
  1115.  
  1116.       if (__beg == __end)
  1117.         __err |= ios_base::eofbit;
  1118.       return __beg;
  1119.     }
  1120.  
  1121.   template<typename _CharT, typename _InIter>
  1122.     _InIter
  1123.     time_get<_CharT, _InIter>::
  1124.     do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
  1125.                 ios_base::iostate& __err, tm* __tm) const
  1126.     {
  1127.       const locale& __loc = __io._M_getloc();
  1128.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  1129.       int __tmpyear;
  1130.       ios_base::iostate __tmperr = ios_base::goodbit;
  1131.  
  1132.       __beg = _M_extract_num(__beg, __end, __tmpyear, 0, 9999, 4,
  1133.                              __io, __tmperr);
  1134.       if (!__tmperr)
  1135.         __tm->tm_year = __tmpyear < 0 ? __tmpyear + 100 : __tmpyear - 1900;
  1136.       else
  1137.         __err |= ios_base::failbit;
  1138.  
  1139.       if (__beg == __end)
  1140.         __err |= ios_base::eofbit;
  1141.       return __beg;
  1142.     }
  1143.  
  1144. #if __cplusplus >= 201103L
  1145.   template<typename _CharT, typename _InIter>
  1146.     inline
  1147.     _InIter
  1148.     time_get<_CharT, _InIter>::
  1149.     get(iter_type __s, iter_type __end, ios_base& __io,
  1150.         ios_base::iostate& __err, tm* __tm, const char_type* __fmt,
  1151.         const char_type* __fmtend) const
  1152.     {
  1153.       const locale& __loc = __io._M_getloc();
  1154.       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
  1155.       __err = ios_base::goodbit;
  1156.       while (__fmt != __fmtend &&
  1157.              __err == ios_base::goodbit)
  1158.         {
  1159.           if (__s == __end)
  1160.             {
  1161.               __err = ios_base::eofbit | ios_base::failbit;
  1162.               break;
  1163.             }
  1164.           else if (__ctype.narrow(*__fmt, 0) == '%')
  1165.             {
  1166.               char __format;
  1167.               char __mod = 0;
  1168.               if (++__fmt == __fmtend)
  1169.                 {
  1170.                   __err = ios_base::failbit;
  1171.                   break;
  1172.                 }
  1173.               const char __c = __ctype.narrow(*__fmt, 0);
  1174.               if (__c != 'E' && __c != 'O')
  1175.                 __format = __c;
  1176.               else if (++__fmt != __fmtend)
  1177.                 {
  1178.                   __mod = __c;
  1179.                   __format = __ctype.narrow(*__fmt, 0);
  1180.                 }
  1181.               else
  1182.                 {
  1183.                   __err = ios_base::failbit;
  1184.                   break;
  1185.                 }
  1186.               __s = this->do_get(__s, __end, __io, __err, __tm, __format,
  1187.                                  __mod);
  1188.               ++__fmt;
  1189.             }
  1190.           else if (__ctype.is(ctype_base::space, *__fmt))
  1191.             {
  1192.               ++__fmt;
  1193.               while (__fmt != __fmtend &&
  1194.                      __ctype.is(ctype_base::space, *__fmt))
  1195.                 ++__fmt;
  1196.  
  1197.               while (__s != __end &&
  1198.                      __ctype.is(ctype_base::space, *__s))
  1199.                 ++__s;
  1200.             }
  1201.           // TODO real case-insensitive comparison
  1202.           else if (__ctype.tolower(*__s) == __ctype.tolower(*__fmt) ||
  1203.                    __ctype.toupper(*__s) == __ctype.toupper(*__fmt))
  1204.             {
  1205.               ++__s;
  1206.               ++__fmt;
  1207.             }
  1208.           else
  1209.             {
  1210.               __err = ios_base::failbit;
  1211.               break;
  1212.             }
  1213.         }
  1214.       return __s;
  1215.     }
  1216.  
  1217.   template<typename _CharT, typename _InIter>
  1218.     inline
  1219.     _InIter
  1220.     time_get<_CharT, _InIter>::
  1221.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  1222.            ios_base::iostate& __err, tm* __tm,
  1223.            char __format, char __mod) const
  1224.     {
  1225.       const locale& __loc = __io._M_getloc();
  1226.       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
  1227.       __err = ios_base::goodbit;
  1228.  
  1229.       char_type __fmt[4];
  1230.       __fmt[0] = __ctype.widen('%');
  1231.       if (!__mod)
  1232.         {
  1233.           __fmt[1] = __format;
  1234.           __fmt[2] = char_type();
  1235.         }
  1236.       else
  1237.         {
  1238.           __fmt[1] = __mod;
  1239.           __fmt[2] = __format;
  1240.           __fmt[3] = char_type();
  1241.         }
  1242.  
  1243.       __beg = _M_extract_via_format(__beg, __end, __io, __err, __tm, __fmt);
  1244.       if (__beg == __end)
  1245.         __err |= ios_base::eofbit;
  1246.       return __beg;
  1247.     }
  1248.  
  1249. #endif // __cplusplus >= 201103L
  1250.  
  1251.   template<typename _CharT, typename _OutIter>
  1252.     _OutIter
  1253.     time_put<_CharT, _OutIter>::
  1254.     put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
  1255.         const _CharT* __beg, const _CharT* __end) const
  1256.     {
  1257.       const locale& __loc = __io._M_getloc();
  1258.       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
  1259.       for (; __beg != __end; ++__beg)
  1260.         if (__ctype.narrow(*__beg, 0) != '%')
  1261.           {
  1262.             *__s = *__beg;
  1263.             ++__s;
  1264.           }
  1265.         else if (++__beg != __end)
  1266.           {
  1267.             char __format;
  1268.             char __mod = 0;
  1269.             const char __c = __ctype.narrow(*__beg, 0);
  1270.             if (__c != 'E' && __c != 'O')
  1271.               __format = __c;
  1272.             else if (++__beg != __end)
  1273.               {
  1274.                 __mod = __c;
  1275.                 __format = __ctype.narrow(*__beg, 0);
  1276.               }
  1277.             else
  1278.               break;
  1279.             __s = this->do_put(__s, __io, __fill, __tm, __format, __mod);
  1280.           }
  1281.         else
  1282.           break;
  1283.       return __s;
  1284.     }
  1285.  
  1286.   template<typename _CharT, typename _OutIter>
  1287.     _OutIter
  1288.     time_put<_CharT, _OutIter>::
  1289.     do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
  1290.            char __format, char __mod) const
  1291.     {
  1292.       const locale& __loc = __io._M_getloc();
  1293.       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
  1294.       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
  1295.  
  1296.       // NB: This size is arbitrary. Should this be a data member,
  1297.       // initialized at construction?
  1298.       const size_t __maxlen = 128;
  1299.       char_type __res[__maxlen];
  1300.  
  1301.       // NB: In IEE 1003.1-200x, and perhaps other locale models, it
  1302.       // is possible that the format character will be longer than one
  1303.       // character. Possibilities include 'E' or 'O' followed by a
  1304.       // format character: if __mod is not the default argument, assume
  1305.       // it's a valid modifier.
  1306.       char_type __fmt[4];
  1307.       __fmt[0] = __ctype.widen('%');
  1308.       if (!__mod)
  1309.         {
  1310.           __fmt[1] = __format;
  1311.           __fmt[2] = char_type();
  1312.         }
  1313.       else
  1314.         {
  1315.           __fmt[1] = __mod;
  1316.           __fmt[2] = __format;
  1317.           __fmt[3] = char_type();
  1318.         }
  1319.  
  1320.       __tp._M_put(__res, __maxlen, __fmt, __tm);
  1321.  
  1322.       // Write resulting, fully-formatted string to output iterator.
  1323.       return std::__write(__s, __res, char_traits<char_type>::length(__res));
  1324.     }
  1325.  
  1326.  
  1327.   // Inhibit implicit instantiations for required instantiations,
  1328.   // which are defined via explicit instantiations elsewhere.
  1329. #if _GLIBCXX_EXTERN_TEMPLATE
  1330.   extern template class moneypunct<char, false>;
  1331.   extern template class moneypunct<char, true>;
  1332.   extern template class moneypunct_byname<char, false>;
  1333.   extern template class moneypunct_byname<char, true>;
  1334.   extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get<char>;
  1335.   extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put<char>;
  1336.   extern template class __timepunct<char>;
  1337.   extern template class time_put<char>;
  1338.   extern template class time_put_byname<char>;
  1339.   extern template class time_get<char>;
  1340.   extern template class time_get_byname<char>;
  1341.   extern template class messages<char>;
  1342.   extern template class messages_byname<char>;
  1343.  
  1344.   extern template
  1345.     const moneypunct<char, true>&
  1346.     use_facet<moneypunct<char, true> >(const locale&);
  1347.  
  1348.   extern template
  1349.     const moneypunct<char, false>&
  1350.     use_facet<moneypunct<char, false> >(const locale&);
  1351.  
  1352.   extern template
  1353.     const money_put<char>&
  1354.     use_facet<money_put<char> >(const locale&);
  1355.  
  1356.   extern template
  1357.     const money_get<char>&
  1358.     use_facet<money_get<char> >(const locale&);
  1359.  
  1360.   extern template
  1361.     const __timepunct<char>&
  1362.     use_facet<__timepunct<char> >(const locale&);
  1363.  
  1364.   extern template
  1365.     const time_put<char>&
  1366.     use_facet<time_put<char> >(const locale&);
  1367.  
  1368.   extern template
  1369.     const time_get<char>&
  1370.     use_facet<time_get<char> >(const locale&);
  1371.  
  1372.   extern template
  1373.     const messages<char>&
  1374.     use_facet<messages<char> >(const locale&);
  1375.  
  1376.   extern template
  1377.     bool
  1378.     has_facet<moneypunct<char> >(const locale&);
  1379.  
  1380.   extern template
  1381.     bool
  1382.     has_facet<money_put<char> >(const locale&);
  1383.  
  1384.   extern template
  1385.     bool
  1386.     has_facet<money_get<char> >(const locale&);
  1387.  
  1388.   extern template
  1389.     bool
  1390.     has_facet<__timepunct<char> >(const locale&);
  1391.  
  1392.   extern template
  1393.     bool
  1394.     has_facet<time_put<char> >(const locale&);
  1395.  
  1396.   extern template
  1397.     bool
  1398.     has_facet<time_get<char> >(const locale&);
  1399.  
  1400.   extern template
  1401.     bool
  1402.     has_facet<messages<char> >(const locale&);
  1403.  
  1404. #ifdef _GLIBCXX_USE_WCHAR_T
  1405.   extern template class moneypunct<wchar_t, false>;
  1406.   extern template class moneypunct<wchar_t, true>;
  1407.   extern template class moneypunct_byname<wchar_t, false>;
  1408.   extern template class moneypunct_byname<wchar_t, true>;
  1409.   extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get<wchar_t>;
  1410.   extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put<wchar_t>;
  1411.   extern template class __timepunct<wchar_t>;
  1412.   extern template class time_put<wchar_t>;
  1413.   extern template class time_put_byname<wchar_t>;
  1414.   extern template class time_get<wchar_t>;
  1415.   extern template class time_get_byname<wchar_t>;
  1416.   extern template class messages<wchar_t>;
  1417.   extern template class messages_byname<wchar_t>;
  1418.  
  1419.   extern template
  1420.     const moneypunct<wchar_t, true>&
  1421.     use_facet<moneypunct<wchar_t, true> >(const locale&);
  1422.  
  1423.   extern template
  1424.     const moneypunct<wchar_t, false>&
  1425.     use_facet<moneypunct<wchar_t, false> >(const locale&);
  1426.  
  1427.   extern template
  1428.     const money_put<wchar_t>&
  1429.     use_facet<money_put<wchar_t> >(const locale&);
  1430.  
  1431.   extern template
  1432.     const money_get<wchar_t>&
  1433.     use_facet<money_get<wchar_t> >(const locale&);
  1434.  
  1435.   extern template
  1436.     const __timepunct<wchar_t>&
  1437.     use_facet<__timepunct<wchar_t> >(const locale&);
  1438.  
  1439.   extern template
  1440.     const time_put<wchar_t>&
  1441.     use_facet<time_put<wchar_t> >(const locale&);
  1442.  
  1443.   extern template
  1444.     const time_get<wchar_t>&
  1445.     use_facet<time_get<wchar_t> >(const locale&);
  1446.  
  1447.   extern template
  1448.     const messages<wchar_t>&
  1449.     use_facet<messages<wchar_t> >(const locale&);
  1450.  
  1451.   extern template
  1452.     bool
  1453.     has_facet<moneypunct<wchar_t> >(const locale&);
  1454.  
  1455.   extern template
  1456.     bool
  1457.     has_facet<money_put<wchar_t> >(const locale&);
  1458.  
  1459.   extern template
  1460.     bool
  1461.     has_facet<money_get<wchar_t> >(const locale&);
  1462.  
  1463.   extern template
  1464.     bool
  1465.     has_facet<__timepunct<wchar_t> >(const locale&);
  1466.  
  1467.   extern template
  1468.     bool
  1469.     has_facet<time_put<wchar_t> >(const locale&);
  1470.  
  1471.   extern template
  1472.     bool
  1473.     has_facet<time_get<wchar_t> >(const locale&);
  1474.  
  1475.   extern template
  1476.     bool
  1477.     has_facet<messages<wchar_t> >(const locale&);
  1478. #endif
  1479. #endif
  1480.  
  1481. _GLIBCXX_END_NAMESPACE_VERSION
  1482. } // namespace std
  1483.  
  1484. #endif
  1485.