Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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