Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Locale support -*- C++ -*-
  2.  
  3. // Copyright (C) 1997, 1998, 1999, 2000, 2001 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 2, 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. // You should have received a copy of the GNU General Public License along
  17. // with this library; see the file COPYING.  If not, write to the Free
  18. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  19. // USA.
  20.  
  21. // As a special exception, you may use this file as part of a free software
  22. // library without restriction.  Specifically, if other files instantiate
  23. // templates or use macros or inline functions from this file, or you compile
  24. // this file and link it with other files to produce an executable, this
  25. // file does not by itself cause the resulting executable to be covered by
  26. // the GNU General Public License.  This exception does not however
  27. // invalidate any other reasons why the executable file might be covered by
  28. // the GNU General Public License.
  29.  
  30. // Warning: this file is not meant for user inclusion.  Use <locale>.
  31.  
  32. #ifndef _CPP_BITS_LOCFACETS_TCC
  33. #define _CPP_BITS_LOCFACETS_TCC 1
  34.  
  35. #include <bits/std_cerrno.h>
  36. #include <bits/std_clocale.h>   // For localeconv
  37. #include <bits/std_cstdlib.h>   // For strof, strtold
  38. #include <bits/std_limits.h>    // For numeric_limits
  39. #include <bits/std_memory.h>    // For auto_ptr
  40. #include <bits/sbuf_iter.h>     // For streambuf_iterators
  41. #include <bits/std_cctype.h>    // For isspace
  42. #include <typeinfo>             // For bad_cast
  43. #include <bits/std_vector.h>   
  44.  
  45.  
  46. namespace std
  47. {
  48.   template<typename _Facet>
  49.     locale
  50.     locale::combine(const locale& __other)
  51.     {
  52.       locale __copy(*this);
  53.       __copy._M_impl->_M_replace_facet(__other._M_impl, &_Facet::id);
  54.       return __copy;
  55.     }
  56.  
  57.   template<typename _CharT, typename _Traits, typename _Alloc>
  58.     bool
  59.     locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
  60.                        const basic_string<_CharT, _Traits, _Alloc>& __s2) const
  61.     {
  62.       typedef std::collate<_CharT> __collate_type;
  63.       const __collate_type* __fcoll = &use_facet<__collate_type>(*this);
  64.       return (__fcoll->compare(__s1.data(), __s1.data() + __s1.length(),
  65.                                __s2.data(), __s2.data() + __s2.length()) < 0);
  66.     }
  67.  
  68.   template<typename _Facet>
  69.     const _Facet&
  70.     use_facet(const locale& __loc)
  71.     {
  72.       typedef locale::_Impl::__vec_facet        __vec_facet;
  73.       size_t __i = _Facet::id._M_index;
  74.       __vec_facet* __facet = __loc._M_impl->_M_facets;
  75.       const locale::facet* __fp = (*__facet)[__i];
  76.       if (__fp == 0 || __i >= __facet->size())
  77.         __throw_bad_cast();
  78.       return static_cast<const _Facet&>(*__fp);
  79.     }
  80.  
  81.   template<typename _Facet>
  82.     bool
  83.     has_facet(const locale& __loc) throw()
  84.     {
  85.       typedef locale::_Impl::__vec_facet        __vec_facet;
  86.       size_t __i = _Facet::id._M_index;
  87.       __vec_facet* __facet = __loc._M_impl->_M_facets;
  88.       return (__i < __facet->size() && (*__facet)[__i] != 0);
  89.     }
  90.  
  91.   // __match_parallel
  92.   // matches input __s against a set of __ntargs strings in __targets,
  93.   // placing in __matches a vector of indices into __targets which
  94.   // match, and in __remain the number of such matches. If it hits
  95.   // end of sequence before it minimizes the set, sets __eof.
  96.   // Empty strings are never matched.
  97.   template<typename _InIter, typename _CharT>
  98.     _InIter
  99.     __match_parallel(_InIter __s, _InIter __end, int __ntargs,
  100.                      const basic_string<_CharT>* __targets,
  101.                      int* __matches, int& __remain, bool& __eof)
  102.     {
  103.       typedef basic_string<_CharT> __string_type;
  104.       __eof = false;
  105.       for (int __ti = 0; __ti < __ntargs; ++__ti)
  106.         __matches[__ti] = __ti;
  107.       __remain = __ntargs;
  108.       size_t __pos = 0;
  109.       do
  110.         {
  111.           int __ti = 0;
  112.           while (__ti < __remain && __pos == __targets[__matches[__ti]].size())
  113.             ++__ti;
  114.           if (__ti == __remain)
  115.             {
  116.               if (__pos == 0) __remain = 0;
  117.               return __s;
  118.             }
  119.           if (__s == __end)
  120.             __eof = true;
  121.           bool __matched = false;
  122.           for (int __ti2 = 0; __ti2 < __remain; )
  123.             {
  124.               const __string_type& __target = __targets[__matches[__ti2]];
  125.               if (__pos < __target.size())
  126.                 {
  127.                   if (__eof || __target[__pos] != *__s)
  128.                     {
  129.                       __matches[__ti2] = __matches[--__remain];
  130.                       continue;
  131.                     }
  132.                   __matched = true;
  133.                 }
  134.               ++__ti2;
  135.             }
  136.           if (__matched)
  137.             {
  138.               ++__s;
  139.               ++__pos;
  140.             }
  141.           for (int __ti3 = 0; __ti3 < __remain;)
  142.             {
  143.               if (__pos > __targets[__matches[__ti3]].size())
  144.                 {
  145.                   __matches[__ti3] = __matches[--__remain];
  146.                   continue;
  147.                 }
  148.               ++__ti3;
  149.             }
  150.         }
  151.       while (__remain);
  152.       return __s;
  153.     }
  154.  
  155.   template<typename _CharT>
  156.     _Format_cache<_CharT>::_Format_cache()
  157.     : _M_valid(true), _M_use_grouping(false)
  158.     { }
  159.  
  160.   template<>
  161.     _Format_cache<char>::_Format_cache();
  162.  
  163.   template<>
  164.     _Format_cache<wchar_t>::_Format_cache();
  165.  
  166.   template<typename _CharT>
  167.     void
  168.     _Format_cache<_CharT>::_M_populate(ios_base& __io)
  169.     {
  170.       locale __loc = __io.getloc ();
  171.       numpunct<_CharT> const& __np = use_facet<numpunct<_CharT> >(__loc);
  172.       _M_truename = __np.truename();
  173.       _M_falsename = __np.falsename();
  174.       _M_thousands_sep = __np.thousands_sep();
  175.       _M_decimal_point = __np.decimal_point();
  176.       _M_grouping = __np.grouping();
  177.       _M_use_grouping = _M_grouping.size() != 0 && _M_grouping.data()[0] != 0;
  178.       _M_valid = true;
  179.     }
  180.  
  181.   // This function is always called via a pointer installed in
  182.   // an ios_base by ios_base::register_callback.
  183.   template<typename _CharT>
  184.     void
  185.     _Format_cache<_CharT>::
  186.     _S_callback(ios_base::event __ev, ios_base& __ios, int __ix) throw()
  187.     {
  188.       void*& __p = __ios.pword(__ix);
  189.       switch (__ev)
  190.         {
  191.         case ios_base::erase_event:
  192.           delete static_cast<_Format_cache<_CharT>*>(__p);
  193.           __p = 0;
  194.           break;
  195.         case ios_base::copyfmt_event:
  196.           // If just stored zero, the callback would get registered again.
  197.           try
  198.             { __p = new _Format_cache<_CharT>; }
  199.           catch(...)
  200.             { }
  201.           break;
  202.         case ios_base::imbue_event:
  203.           static_cast<_Format_cache<_CharT>*>(__p)->_M_valid = false;
  204.           break;
  205.         }
  206.     }
  207.  
  208.   template<typename _CharT>
  209.     _Format_cache<_CharT>*
  210.     _Format_cache<_CharT>::_S_get(ios_base& __ios)
  211.     {
  212.       if (!_S_pword_ix)
  213.         _S_pword_ix = ios_base::xalloc();  // XXX MT
  214.       void*& __p = __ios.pword(_S_pword_ix);
  215.  
  216.       // XXX What if pword fails? must check failbit, throw.
  217.       if (__p == 0)  // XXX MT?  maybe sentry takes care of it
  218.         {
  219.           auto_ptr<_Format_cache<_CharT> > __ap(new _Format_cache<_CharT>);
  220.           __ios.register_callback(&_Format_cache<_CharT>::_S_callback,
  221.                                   _S_pword_ix);
  222.           __p = __ap.release();
  223.         }
  224.       _Format_cache<_CharT>* __ncp = static_cast<_Format_cache<_CharT>*>(__p);
  225.       if (!__ncp->_M_valid)
  226.         __ncp->_M_populate(__ios);
  227.  
  228.       return __ncp;
  229.     }
  230.  
  231.   // This member function takes an (w)istreambuf_iterator object and
  232.   // parses it into a generic char array suitable for parsing with
  233.   // strto[l,ll,f,d]. The thought was to encapsulate the conversion
  234.   // into this one function, and thus the num_get::do_get member
  235.   // functions can just adjust for the type of the overloaded
  236.   // argument and process the char array returned from _M_extract.
  237.   // Other things were also considered, including a fused
  238.   // multiply-add loop that would obviate the need for any call to
  239.   // strto... at all: however, it would b e a bit of a pain, because
  240.   // you'd have to be able to return either floating or integral
  241.   // types, etc etc. The current approach seems to be smack dab in
  242.   // the middle between an unoptimized approach using sscanf, and
  243.   // some kind of hyper-optimized approach alluded to above.
  244.  
  245.   // XXX
  246.   // Need to do partial specialization to account for differences
  247.   // between character sets. For char, this is pretty
  248.   // straightforward, but for wchar_t, the conversion to a plain-jane
  249.   // char type is a bit more involved.
  250.   template<typename _CharT, typename _InIter>
  251.     void
  252.     num_get<_CharT, _InIter>::
  253.     _M_extract(_InIter /*__beg*/, _InIter /*__end*/, ios_base& /*__io*/,
  254.                ios_base::iostate& /*__err*/, char* /*__xtrc*/,
  255.                int& /*__base*/, bool /*__fp*/) const
  256.     {
  257.       // XXX Not currently done: need to expand upon char version below.
  258.     }
  259.  
  260.   template<>
  261.     void
  262.     num_get<char, istreambuf_iterator<char> >::
  263.     _M_extract(istreambuf_iterator<char> __beg,
  264.                istreambuf_iterator<char> __end, ios_base& __io,
  265.                ios_base::iostate& __err, char* __xtrc, int& __base,
  266.                bool __fp) const;
  267.  
  268. #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
  269.   // NB: This is an unresolved library defect #17
  270.   template<typename _CharT, typename _InIter>
  271.     _InIter
  272.     num_get<_CharT, _InIter>::
  273.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  274.            ios_base::iostate& __err, bool& __v) const
  275.     {
  276.       // Parse bool values as long
  277.       if (!(__io.flags() & ios_base::boolalpha))
  278.         {
  279.           // NB: We can't just call do_get(long) here, as it might
  280.           // refer to a derived class.
  281.  
  282.           // Stage 1: extract and determine the conversion specifier.
  283.           // Assuming leading zeros eliminated, thus the size of 32 for
  284.           // integral types.
  285.           char __xtrc[32] = {'\0'};
  286.           int __base;
  287.           _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
  288.  
  289.           // Stage 2: convert and store results.
  290.           char* __sanity;
  291.           errno = 0;
  292.           long __l = strtol(__xtrc, &__sanity, __base);
  293.           if (!(__err & ios_base::failbit)
  294.               && __l <= 1
  295.               && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
  296.             __v = __l;
  297.           else
  298.             __err |= ios_base::failbit;
  299.         }
  300.  
  301.       // Parse bool values as alphanumeric
  302.       else
  303.         {
  304.           typedef _Format_cache<char_type> __fcache_type;
  305.           __fcache_type* __fmt = __fcache_type::_S_get(__io);
  306.           const char_type* __true = __fmt->_M_truename.c_str();
  307.           const char_type* __false = __fmt->_M_falsename.c_str();
  308.           const size_t __truelen =  __traits_type::length(__true) - 1;
  309.           const size_t __falselen =  __traits_type::length(__false) - 1;
  310.  
  311.           for (size_t __pos = 0; __beg != __end; ++__pos)
  312.             {
  313.               char_type __c = *__beg++;
  314.               bool __testf = __c == __false[__pos];
  315.               bool __testt = __c == __true[__pos];
  316.               if (!(__testf || __testt))
  317.                 {
  318.                   __err |= ios_base::failbit;
  319.                   break;
  320.                 }
  321.               else if (__testf && __pos == __falselen)
  322.                 {
  323.                   __v = 0;
  324.                   break;
  325.                 }
  326.               else if (__testt && __pos == __truelen)
  327.                 {
  328.                   __v = 1;
  329.                   break;
  330.                 }
  331.             }
  332.           if (__beg == __end)
  333.             __err |= ios_base::eofbit;
  334.         }
  335.  
  336.       return __beg;
  337.     }
  338. #endif
  339.  
  340. #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
  341.   template<typename _CharT, typename _InIter>
  342.     _InIter
  343.     num_get<_CharT, _InIter>::
  344.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  345.            ios_base::iostate& __err, short& __v) const
  346.     {
  347.       // Stage 1: extract and determine the conversion specifier.
  348.       // Assuming leading zeros eliminated, thus the size of 32 for
  349.       // integral types.
  350.       char __xtrc[32]= {'\0'};
  351.       int __base;
  352.       _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
  353.  
  354.       // Stage 2: convert and store results.
  355.       char* __sanity;
  356.       errno = 0;
  357.       long __l = strtol(__xtrc, &__sanity, __base);
  358.       if (!(__err & ios_base::failbit)
  359.           && __sanity != __xtrc && *__sanity == '\0' && errno == 0
  360.           && __l >= SHRT_MIN && __l <= SHRT_MAX)
  361.         __v = static_cast<short>(__l);
  362.       else
  363.         __err |= ios_base::failbit;
  364.  
  365.       return __beg;
  366.     }
  367.  
  368.   template<typename _CharT, typename _InIter>
  369.     _InIter
  370.     num_get<_CharT, _InIter>::
  371.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  372.            ios_base::iostate& __err, int& __v) const
  373.     {
  374.       // Stage 1: extract and determine the conversion specifier.
  375.       // Assuming leading zeros eliminated, thus the size of 32 for
  376.       // integral types.
  377.       char __xtrc[32] = {'\0'};
  378.       int __base;
  379.       _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
  380.  
  381.       // Stage 2: convert and store results.
  382.       char* __sanity;
  383.       errno = 0;
  384.       long __l = strtol(__xtrc, &__sanity, __base);
  385.       if (!(__err & ios_base::failbit)
  386.           && __sanity != __xtrc && *__sanity == '\0' && errno == 0
  387.           && __l >= INT_MIN && __l <= INT_MAX)
  388.         __v = static_cast<int>(__l);
  389.       else
  390.         __err |= ios_base::failbit;
  391.  
  392.       return __beg;
  393.     }
  394. #endif
  395.  
  396.   template<typename _CharT, typename _InIter>
  397.     _InIter
  398.     num_get<_CharT, _InIter>::
  399.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  400.            ios_base::iostate& __err, long& __v) const
  401.     {
  402.       // Stage 1: extract and determine the conversion specifier.
  403.       // Assuming leading zeros eliminated, thus the size of 32 for
  404.       // integral types.
  405.       char __xtrc[32]= {'\0'};
  406.       int __base;
  407.       _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
  408.  
  409.       // Stage 2: convert and store results.
  410.       char* __sanity;
  411.       errno = 0;
  412.       long __l = strtol(__xtrc, &__sanity, __base);
  413.       if (!(__err & ios_base::failbit)
  414.           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
  415.         __v = __l;
  416.       else
  417.         __err |= ios_base::failbit;
  418.  
  419.       return __beg;
  420.     }
  421.  
  422. #ifdef _GLIBCPP_USE_LONG_LONG
  423.   template<typename _CharT, typename _InIter>
  424.     _InIter
  425.     num_get<_CharT, _InIter>::
  426.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  427.            ios_base::iostate& __err, long long& __v) const
  428.     {
  429.       // Stage 1: extract and determine the conversion specifier.
  430.       // Assuming leading zeros eliminated, thus the size of 32 for
  431.       // integral types.
  432.       char __xtrc[32]= {'\0'};
  433.       int __base;
  434.       _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
  435.  
  436.       // Stage 2: convert and store results.
  437.       char* __sanity;
  438.       errno = 0;
  439.       long long __ll = strtoll(__xtrc, &__sanity, __base);
  440.       if (!(__err & ios_base::failbit)
  441.           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
  442.         __v = __ll;
  443.       else
  444.         __err |= ios_base::failbit;
  445.  
  446.       return __beg;
  447.     }
  448. #endif
  449.  
  450.   template<typename _CharT, typename _InIter>
  451.     _InIter
  452.     num_get<_CharT, _InIter>::
  453.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  454.            ios_base::iostate& __err, unsigned short& __v) const
  455.     {
  456.       // Stage 1: extract and determine the conversion specifier.
  457.       // Assuming leading zeros eliminated, thus the size of 32 for
  458.       // integral types.
  459.       char __xtrc[32]= {'\0'};
  460.       int __base;
  461.       _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
  462.  
  463.       // Stage 2: convert and store results.
  464.       char* __sanity;
  465.       errno = 0;
  466.       unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
  467.       if (!(__err & ios_base::failbit)
  468.           && __sanity != __xtrc && *__sanity == '\0' && errno == 0
  469.           && __ul <= USHRT_MAX)
  470.         __v = static_cast<unsigned short>(__ul);
  471.       else
  472.         __err |= ios_base::failbit;
  473.  
  474.       return __beg;
  475.     }
  476.  
  477.   template<typename _CharT, typename _InIter>
  478.     _InIter
  479.     num_get<_CharT, _InIter>::
  480.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  481.            ios_base::iostate& __err, unsigned int& __v) const
  482.     {
  483.       // Stage 1: extract and determine the conversion specifier.
  484.       // Assuming leading zeros eliminated, thus the size of 32 for
  485.       // integral types.
  486.       char __xtrc[32]= {'\0'};
  487.       int __base;
  488.       _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
  489.  
  490.       // Stage 2: convert and store results.
  491.       char* __sanity;
  492.       errno = 0;
  493.       unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
  494.       if (!(__err & ios_base::failbit)
  495.           && __sanity != __xtrc && *__sanity == '\0' && errno == 0
  496.           && __ul <= UINT_MAX)
  497.         __v = static_cast<unsigned int>(__ul);
  498.       else
  499.         __err |= ios_base::failbit;
  500.  
  501.       return __beg;
  502.     }
  503.  
  504.   template<typename _CharT, typename _InIter>
  505.     _InIter
  506.     num_get<_CharT, _InIter>::
  507.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  508.            ios_base::iostate& __err, unsigned long& __v) const
  509.     {
  510.       // Stage 1: extract and determine the conversion specifier.
  511.       // Assuming leading zeros eliminated, thus the size of 32 for
  512.       // integral types.
  513.       char __xtrc[32] = {'\0'};
  514.       int __base;
  515.       _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
  516.  
  517.       // Stage 2: convert and store results.
  518.       char* __sanity;
  519.       errno = 0;
  520.       unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
  521.       if (!(__err & ios_base::failbit)
  522.           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
  523.         __v = __ul;
  524.       else
  525.         __err |= ios_base::failbit;
  526.  
  527.       return __beg;
  528.     }
  529.  
  530. #ifdef _GLIBCPP_USE_LONG_LONG
  531.   template<typename _CharT, typename _InIter>
  532.     _InIter
  533.     num_get<_CharT, _InIter>::
  534.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  535.            ios_base::iostate& __err, unsigned long long& __v) const
  536.     {
  537.       // Stage 1: extract and determine the conversion specifier.
  538.       // Assuming leading zeros eliminated, thus the size of 32 for
  539.       // integral types.
  540.       char __xtrc[32]= {'\0'};
  541.       int __base;
  542.       _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
  543.  
  544.       // Stage 2: convert and store results.
  545.       char* __sanity;
  546.       errno = 0;
  547.       unsigned long long __ull = strtoull(__xtrc, &__sanity, __base);
  548.       if (!(__err & ios_base::failbit)
  549.           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
  550.         __v = __ull;
  551.       else
  552.         __err |= ios_base::failbit;
  553.  
  554.       return __beg;
  555.     }
  556. #endif
  557.  
  558.   template<typename _CharT, typename _InIter>
  559.     _InIter
  560.     num_get<_CharT, _InIter>::
  561.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  562.            ios_base::iostate& __err, float& __v) const
  563.     {
  564.       // Stage 1: extract and determine the conversion specifier.
  565.       // Assuming leading zeros eliminated, thus the size of 256 for
  566.       // floating-point types.
  567.       char __xtrc[32]= {'\0'};
  568.       int __base;
  569.       _M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
  570.  
  571.       // Stage 2: convert and store results.
  572.       char* __sanity;
  573.       errno = 0;
  574. #ifdef _GLIBCPP_USE_C99
  575.       float __f = strtof(__xtrc, &__sanity);
  576. #else
  577.       float __f = static_cast<float>(strtod(__xtrc, &__sanity));
  578. #endif
  579.       if (!(__err & ios_base::failbit)
  580.           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
  581.         __v = __f;
  582.       else
  583.         __err |= ios_base::failbit;
  584.  
  585.       return __beg;
  586.     }
  587.  
  588.   template<typename _CharT, typename _InIter>
  589.     _InIter
  590.     num_get<_CharT, _InIter>::
  591.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  592.            ios_base::iostate& __err, double& __v) const
  593.     {
  594.       // Stage 1: extract and determine the conversion specifier.
  595.       // Assuming leading zeros eliminated, thus the size of 256 for
  596.       // floating-point types.
  597.       char __xtrc[32]= {'\0'};
  598.       int __base;
  599.       _M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
  600.  
  601.       // Stage 2: convert and store results.
  602.       char* __sanity;
  603.       errno = 0;
  604.       double __d = strtod(__xtrc, &__sanity);
  605.       if (!(__err & ios_base::failbit)
  606.           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
  607.         __v = __d;
  608.       else
  609.         __err |= ios_base::failbit;
  610.  
  611.       return __beg;
  612.     }
  613.  
  614. #if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
  615.   template<typename _CharT, typename _InIter>
  616.     _InIter
  617.     num_get<_CharT, _InIter>::
  618.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  619.            ios_base::iostate& __err, long double& __v) const
  620.     {
  621.       // Stage 1: extract and determine the conversion specifier.
  622.       // Assuming leading zeros eliminated, thus the size of 256 for
  623.       // floating-point types.
  624.       char __xtrc[32]= {'\0'};
  625.       int __base;
  626.       _M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
  627.  
  628.       // Stage 2: convert and store results.
  629.       char* __sanity;
  630.       errno = 0;
  631.       long double __ld = strtold(__xtrc, &__sanity);
  632.       if (!(__err & ios_base::failbit)
  633.           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
  634.         __v = __ld;
  635.       else
  636.         __err |= ios_base::failbit;
  637.  
  638.       return __beg;
  639.     }
  640. #else
  641.   template<typename _CharT, typename _InIter>
  642.     _InIter
  643.     num_get<_CharT, _InIter>::
  644.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  645.            ios_base::iostate& __err, long double& __v) const
  646.     {
  647.       // Stage 1: extract
  648.       char __xtrc[32]= {'\0'};
  649.       int __base;
  650.       _M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
  651.  
  652.       // Stage 2: determine a conversion specifier.
  653.       ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
  654.       const char* __conv;
  655.       if (__basefield == ios_base::oct)
  656.         __conv = "%Lo";
  657.       else if (__basefield == ios_base::hex)
  658.         __conv = "%LX";
  659.       else if (__basefield == 0)
  660.         __conv = "%Li";
  661.       else
  662.         __conv = "%Lg";
  663.  
  664.       // Stage 3: store results.
  665.       long double __ld;
  666.       int __p = sscanf(__xtrc, __conv, &__ld);
  667.       if (__p
  668.           && static_cast<typename __traits_type::int_type>(__p)
  669.         != __traits_type::eof())
  670.         __v = __ld;
  671.       else
  672.         __err |= ios_base::failbit;
  673.  
  674.       return __beg;
  675.     }
  676. #endif
  677.  
  678.   template<typename _CharT, typename _InIter>
  679.     _InIter
  680.     num_get<_CharT, _InIter>::
  681.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  682.            ios_base::iostate& __err, void*& __v) const
  683.     {
  684.       // Prepare for hex formatted input
  685.       typedef ios_base::fmtflags        fmtflags;
  686.       fmtflags __fmt = __io.flags();
  687.       fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield
  688.                              | ios_base::uppercase | ios_base::internal);
  689.       __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
  690.  
  691.       // Stage 1: extract and determine the conversion specifier.
  692.       // Assuming leading zeros eliminated, thus the size of 32 for
  693.       // integral types.
  694.       char __xtrc[32]= {'\0'};
  695.       int __base;
  696.       _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
  697.  
  698.       // Stage 2: convert and store results.
  699.       char* __sanity;
  700.       errno = 0;
  701.       void* __vp = reinterpret_cast<void*>(strtoul(__xtrc, &__sanity, __base));
  702.       if (!(__err & ios_base::failbit)
  703.           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
  704.         __v = __vp;
  705.       else
  706.         __err |= ios_base::failbit;
  707.  
  708.       // Reset from hex formatted input
  709.       __io.flags(__fmt);
  710.       return __beg;
  711.     }
  712.  
  713.   // __pad is specialized for ostreambuf_iterator, random access iterator.
  714.   template <typename _CharT, typename _OutIter>
  715.     inline _OutIter
  716.     __pad(_OutIter __s, _CharT __fill, int __padding);
  717.  
  718.   template <typename _CharT, typename _RaIter>
  719.     _RaIter
  720.     __pad(_RaIter __s, _CharT __fill, int __padding,
  721.           random_access_iterator_tag)
  722.     {
  723.       fill_n(__s, __fill);
  724.       return __s + __padding;
  725.     }
  726.  
  727.   template <typename _CharT, typename _OutIter, typename _Tag>
  728.     _OutIter
  729.     __pad(_OutIter __s, _CharT __fill, int __padding, _Tag)
  730.     {
  731.       while (--__padding >= 0) { *__s = __fill; ++__s; }
  732.       return __s;
  733.     }
  734.  
  735.   template <typename _CharT, typename _OutIter>
  736.     inline _OutIter
  737.     __pad(_OutIter __s, _CharT __fill, int __padding)
  738.     {
  739.       return __pad(__s, __fill, __padding,
  740.                    typename iterator_traits<_OutIter>::iterator_category());
  741.     }
  742.  
  743.   template <typename _CharT, typename _OutIter>
  744.     _OutIter
  745.     __pad_numeric(_OutIter __s, ios_base::fmtflags /*__flags*/,
  746.                   _CharT /*__fill*/, int /*__width*/,
  747.                   _CharT const* /*__first*/, _CharT const* /*__middle*/,
  748.                   _CharT const* /*__last*/)
  749.   {
  750.       // XXX Not currently done: non streambuf_iterator
  751.       return __s;
  752.     }
  753.  
  754.   // Partial specialization for ostreambuf_iterator.
  755.   template <typename _CharT>  
  756.     ostreambuf_iterator<_CharT>
  757.     __pad_numeric(ostreambuf_iterator<_CharT> __s, ios_base::fmtflags __flags,
  758.                   _CharT __fill, int __width, _CharT const* __first,
  759.                   _CharT const* __middle, _CharT const* __last)
  760.     {
  761.       typedef ostreambuf_iterator<_CharT>       __out_iter;
  762.       int __padding = __width - (__last - __first);
  763.       if (__padding < 0)
  764.         __padding = 0;
  765.       ios_base::fmtflags __aflags = __flags & ios_base::adjustfield;
  766.       bool __testfield = __padding == 0 || __aflags == ios_base::left
  767.                          || __aflags == ios_base::internal;
  768.  
  769.       // This was needlessly complicated.
  770.       if (__first != __middle)
  771.         {
  772.           if (!__testfield)
  773.             {
  774.               __pad(__s, __fill, __padding);
  775.               __padding = 0;
  776.             }
  777.           copy(__first, __middle, __s);
  778.         }
  779.       __out_iter __s2 = __s;
  780.  
  781.       if (__padding && __aflags != ios_base::left)
  782.         {
  783.           __pad(__s2, __fill, __padding);
  784.           __padding = 0;
  785.         }
  786.       __out_iter __s3 = copy(__middle, __last, __s2);
  787.       if (__padding)
  788.         __pad(__s3, __fill, __padding);
  789.       return __s3;
  790.     }
  791.  
  792.   template <typename _CharT, typename _OutIter>
  793.     _OutIter
  794.     num_put<_CharT, _OutIter>::
  795.     do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
  796.     {
  797.       const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io);
  798.       ios_base::fmtflags __flags = __io.flags();
  799.  
  800.       if ((__flags & ios_base::boolalpha) == 0)
  801.         {
  802.           unsigned long __uv = __v;
  803.           return __output_integer(__s, __io, __fill, false, __uv);
  804.         }
  805.       else
  806.         {
  807.           const char_type* __first;
  808.           const char_type* __last;
  809.           if (__v)
  810.             {
  811.               __first = __fmt->_M_truename.data();
  812.               __last = __first + __fmt->_M_truename.size();
  813.             }
  814.           else
  815.             {
  816.               __first = __fmt->_M_falsename.data();
  817.               __last = __first + __fmt->_M_falsename.size();
  818.             }
  819.           copy(__first, __last, __s);
  820.         }
  821.       return __s;
  822.     }
  823.  
  824.   // __group_digits inserts "group separator" characters into an array
  825.   // of characters.  It's recursive, one iteration per group.  It moves
  826.   // the characters in the buffer this way: "xxxx12345" -> "12,345xxx".
  827.   // Call this only with __grouping != __grend.
  828.   template <typename _CharT>
  829.     _CharT*
  830.     __group_digits(_CharT* __s, _CharT __grsep,  char const* __grouping,
  831.                     char const* __grend, _CharT const* __first,
  832.                     _CharT const* __last)
  833.     {
  834.       if (__last - __first > *__grouping)
  835.         {
  836.           __s = __group_digits(__s,  __grsep,
  837.               (__grouping + 1 == __grend ? __grouping : __grouping + 1),
  838.               __grend, __first, __last - *__grouping);
  839.           __first = __last - *__grouping;
  840.           *__s++ = __grsep;
  841.         }
  842.       do
  843.         {
  844.           *__s++ = *__first++;
  845.         }
  846.       while (__first != __last);
  847.       return __s;
  848.     }
  849.  
  850.   template <typename _CharT, typename _OutIter, typename _ValueT>
  851.     _OutIter
  852.     __output_integer(_OutIter __s, ios_base& __io, _CharT __fill, bool __neg,
  853.               _ValueT __v)
  854.     {
  855.       // Leave room for "+/-," "0x," and commas.
  856.       const long _M_room = numeric_limits<_ValueT>::digits10 * 2 + 4;
  857.       _CharT __digits[_M_room];
  858.       _CharT* __front = __digits + _M_room;
  859.       ios_base::fmtflags __flags = __io.flags();
  860.       const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io);
  861.       char const* __table = __fmt->_S_literals + __fmt->_S_digits;
  862.  
  863.       ios_base::fmtflags __basefield = (__flags & __io.basefield);
  864.       _CharT* __sign_end = __front;
  865.       if (__basefield == ios_base::hex)
  866.         {
  867.           if (__flags & ios_base::uppercase)
  868.             __table += 16;  // use ABCDEF
  869.           do
  870.             *--__front = __table[__v & 15];
  871.           while ((__v >>= 4) != 0);
  872.           __sign_end = __front;
  873.           if (__flags & ios_base::showbase)
  874.             {
  875.               *--__front = __fmt->_S_literals[__fmt->_S_x +
  876.                        ((__flags & ios_base::uppercase) ? 1 : 0)];
  877.               *--__front = __table[0];
  878.             }
  879.         }
  880.       else if (__basefield == ios_base::oct)
  881.         {
  882.           do
  883.             *--__front = __table[__v & 7];
  884.           while ((__v >>= 3) != 0);
  885.           if (__flags & ios_base::showbase
  886.               && static_cast<char>(*__front) != __table[0])
  887.             *--__front = __table[0];
  888.           __sign_end = __front;
  889.         }
  890.       else
  891.         {
  892.           // NB: This is _lots_ faster than using ldiv.
  893.           do
  894.             *--__front = __table[__v % 10];
  895.           while ((__v /= 10) != 0);
  896.           __sign_end = __front;
  897.           // NB: ios_base:hex || ios_base::oct assumed to be unsigned.
  898.           if (__neg || (__flags & ios_base::showpos))
  899.             *--__front = __fmt->_S_literals[__fmt->_S_plus - __neg];
  900.         }
  901.  
  902.       // XXX should specialize!
  903.       if (!__fmt->_M_use_grouping && !__io.width())
  904.         return copy(__front, __digits + _M_room, __s);
  905.  
  906.       if (!__fmt->_M_use_grouping)
  907.         return __pad_numeric(__s, __flags, __fill, __io.width(0),
  908.                              __front, __sign_end, __digits + _M_room);
  909.  
  910.       _CharT* __p = __digits;
  911.       while (__front < __sign_end)
  912.         *__p++ = *__front++;
  913.       const char* __gr = __fmt->_M_grouping.data();
  914.       __front = __group_digits(__p, __fmt->_M_thousands_sep, __gr,
  915.         __gr + __fmt->_M_grouping.size(), __sign_end, __digits + _M_room);
  916.       return __pad_numeric(__s, __flags, __fill, __io.width(0),
  917.                            __digits, __p, __front);
  918.     }
  919.  
  920.   template <typename _CharT, typename _OutIter>
  921.     _OutIter
  922.     num_put<_CharT, _OutIter>::
  923.     do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
  924.     {
  925.       unsigned long __uv = __v;
  926.       bool __neg = false;
  927.       if (__v < 0)
  928.         {
  929.           __neg = true;
  930.           __uv = -__uv;
  931.         }
  932.       return __output_integer(__s, __io, __fill, __neg, __uv);
  933.     }
  934.  
  935.   template <typename _CharT, typename _OutIter>
  936.     _OutIter
  937.     num_put<_CharT, _OutIter>::
  938.     do_put(iter_type __s, ios_base& __io, char_type __fill,
  939.            unsigned long __v) const
  940.     { return __output_integer(__s, __io, __fill, false, __v); }
  941.  
  942. #ifdef _GLIBCPP_USE_LONG_LONG
  943.   template <typename _CharT, typename _OutIter>
  944.     _OutIter
  945.     num_put<_CharT, _OutIter>::
  946.     do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const
  947.     {
  948.       unsigned long long __uv = __v;
  949.       bool __neg = false;
  950.       if (__v < 0)
  951.         {
  952.           __neg = true;
  953.           __uv = -__uv;
  954.         }
  955.       return __output_integer(__s, __b, __fill, __neg, __uv);
  956.     }
  957.  
  958.   template <typename _CharT, typename _OutIter>
  959.     _OutIter
  960.     num_put<_CharT, _OutIter>::
  961.     do_put(iter_type __s, ios_base& __io, char_type __fill,
  962.            unsigned long long __v) const
  963.     { return __output_integer(__s, __io, __fill, false, __v); }
  964. #endif
  965.  
  966.   // Generic helper function
  967.   template<typename _CharT, typename _Traits, typename _OutIter>
  968.     _OutIter
  969.     __output_float(_OutIter __s, ios_base& __io, _CharT __fill,
  970.                     const char* __sptr, size_t __slen)
  971.     {
  972.       // XXX Not currently done: non streambuf_iterator
  973.       return __s;
  974.     }
  975.  
  976.   // Partial specialization for ostreambuf_iterator.
  977.   template<typename _CharT, typename _Traits>
  978.     ostreambuf_iterator<_CharT, _Traits>
  979.     __output_float(ostreambuf_iterator<_CharT, _Traits> __s, ios_base& __io,
  980.                    _CharT __fill, const char* __sptr, size_t __slen)
  981.     {
  982.       size_t __padding = __io.width() > streamsize(__slen) ?
  983.                          __io.width() -__slen : 0;
  984.       locale __loc = __io.getloc();
  985.       ctype<_CharT> const& __ct = use_facet<ctype<_CharT> >(__loc);
  986.       ios_base::fmtflags __adjfield = __io.flags() & ios_base::adjustfield;
  987.       const char* const __eptr = __sptr + __slen;
  988.       // [22.2.2.2.2.19] Table 61
  989.       if (__adjfield == ios_base::internal)
  990.        {
  991.          // [22.2.2.2.2.14]; widen()
  992.          if (__sptr < __eptr && (*__sptr == '+' || *__sptr == '-'))
  993.            {
  994.              __s = __ct.widen(*__sptr);
  995.              ++__s;
  996.              ++__sptr;
  997.            }
  998.          __s = __pad(__s, __fill, __padding);
  999.          __padding = 0;
  1000.        }
  1001.       else if (__adjfield != ios_base::left)
  1002.         {
  1003.           __s = __pad(__s, __fill, __padding);
  1004.           __padding = 0;
  1005.         }
  1006.       // the "C" locale decimal character
  1007.       char __decimal_point = *(localeconv()->decimal_point);
  1008.       const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io);
  1009.       for (; __sptr != __eptr; ++__s, ++__sptr)
  1010.        {
  1011.          // [22.2.2.2.2.17]; decimal point conversion
  1012.          if (*__sptr == __decimal_point)
  1013.            __s = __fmt->_M_decimal_point;
  1014.          // [22.2.2.2.2.14]; widen()
  1015.          else
  1016.            __s = __ct.widen(*__sptr);
  1017.        }
  1018.       // [22.2.2.2.2.19] Table 61
  1019.       if (__padding)
  1020.         __pad(__s, __fill, __padding);
  1021.       __io.width(0);
  1022.       return __s;
  1023.     }
  1024.  
  1025.   bool
  1026.   __build_float_format(ios_base& __io, char* __fptr, char __modifier,
  1027.                        streamsize __prec);
  1028.  
  1029.   template <typename _CharT, typename _OutIter>
  1030.     _OutIter
  1031.     num_put<_CharT, _OutIter>::
  1032.     do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
  1033.     {
  1034.       const streamsize __max_prec = numeric_limits<double>::digits10 + 3;
  1035.       streamsize __prec = __io.precision();
  1036.       // Protect against sprintf() buffer overflows.
  1037.       if (__prec > __max_prec)
  1038.         __prec = __max_prec;
  1039.       // The *2 provides for signs, exp, 'E', and pad.
  1040.       char __sbuf[__max_prec * 2];
  1041.       size_t __slen;
  1042.       // Long enough for the max format spec.
  1043.       char __fbuf[16];
  1044.       if (__build_float_format(__io, __fbuf, 0, __prec))
  1045.         __slen = sprintf(__sbuf, __fbuf, __prec, __v);
  1046.       else
  1047.         __slen = sprintf(__sbuf, __fbuf, __v);
  1048.       // [22.2.2.2.2] Stages 2-4.
  1049.       return __output_float(__s, __io, __fill, __sbuf, __slen);
  1050.     }
  1051.  
  1052.   template <typename _CharT, typename _OutIter>
  1053.     _OutIter
  1054.     num_put<_CharT, _OutIter>::
  1055.     do_put(iter_type __s, ios_base& __io, char_type __fill,
  1056.            long double __v) const
  1057.     {
  1058.       const streamsize __max_prec = numeric_limits<long double>::digits10 + 3;
  1059.       streamsize __prec = __io.precision();
  1060.       // Protect against sprintf() buffer overflows.
  1061.       if (__prec > __max_prec)
  1062.         __prec = __max_prec;
  1063.       // The *2 provides for signs, exp, 'E', and pad.
  1064.       char __sbuf[__max_prec * 2];
  1065.       size_t __slen;
  1066.       // Long enough for the max format spec.
  1067.       char __fbuf[16];
  1068.       // 'L' as per [22.2.2.2.2] Table 59
  1069.       if (__build_float_format(__io, __fbuf, 'L', __prec))
  1070.         __slen = sprintf(__sbuf, __fbuf, __prec, __v);
  1071.       else
  1072.         __slen = sprintf(__sbuf, __fbuf, __v);
  1073.       // [22.2.2.2.2] Stages 2-4
  1074.       return __output_float(__s, __io, __fill, __sbuf, __slen);
  1075.     }
  1076.  
  1077.   template <typename _CharT, typename _OutIter>
  1078.     _OutIter
  1079.     num_put<_CharT, _OutIter>::
  1080.     do_put(iter_type __s, ios_base& __io, char_type __fill,
  1081.            const void* __v) const
  1082.     {
  1083.       typedef ios_base::fmtflags        fmtflags;
  1084.       fmtflags __fmt = __io.flags();
  1085.       fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield
  1086.                              | ios_base::uppercase | ios_base::internal);
  1087.       __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
  1088.       try {
  1089.         _OutIter __s2 = __output_integer(__s, __io, __fill, false,
  1090.                                   reinterpret_cast<unsigned long>(__v));
  1091.         __io.flags(__fmt);
  1092.         return __s2;
  1093.       }
  1094.       catch (...) {
  1095.         __io.flags(__fmt);
  1096.         __throw_exception_again;
  1097.       }
  1098.     }
  1099.  
  1100.   // Support for time_get:
  1101.   // Note that these partial specializations could, and maybe should,
  1102.   // be changed to full specializations (by eliminating the _Dummy
  1103.   // argument) and moved to a .cc file.
  1104.   template<typename _CharT, typename _Dummy = int>
  1105.     struct _Weekdaynames;
  1106.  
  1107.   template<typename _Dummy>
  1108.     struct _Weekdaynames<char, _Dummy>
  1109.     { static const char* const _S_names[14]; };
  1110.  
  1111.   template<typename _Dummy>
  1112.     const char* const
  1113.     _Weekdaynames<char, _Dummy>::_S_names[14] =
  1114.     {
  1115.       "Sun", "Sunday",
  1116.       "Mon", "Monday",   "Tue", "Tuesday", "Wed", "Wednesday",
  1117.       "Thu", "Thursday", "Fri", "Friday",  "Sat", "Saturday"
  1118.     };
  1119.  
  1120. #ifdef _GLIBCPP_USE_WCHAR_T
  1121.   template<typename _Dummy>
  1122.     struct _Weekdaynames<wchar_t, _Dummy>
  1123.     { static const wchar_t* const _S_names[14]; };
  1124.  
  1125.   template<typename _Dummy>
  1126.     const wchar_t* const
  1127.     _Weekdaynames<wchar_t, _Dummy>::_S_names[14] =
  1128.     {
  1129.       L"Sun", L"Sunday",
  1130.       L"Mon", L"Monday",   L"Tue", L"Tuesday", L"Wed", L"Wednesday",
  1131.       L"Thu", L"Thursday", L"Fri", L"Friday",  L"Sat", L"Saturday"
  1132.     };
  1133. #endif
  1134.  
  1135.   template<typename _CharT, typename _Dummy = int>
  1136.     struct _Monthnames;
  1137.  
  1138.   template<typename _Dummy>
  1139.     struct _Monthnames<char,_Dummy>
  1140.     { static const char* const _S_names[24]; };
  1141.  
  1142.   template<typename _Dummy>
  1143.     const char* const
  1144.     _Monthnames<char,_Dummy>::_S_names[24] =
  1145.     {
  1146.       "Jan", "January", "Feb", "February", "Mar", "March",
  1147.       "Apr", "April",   "May", "May",      "Jun", "June",
  1148.       "Jul", "July",    "Aug", "August",   "Sep", "September",
  1149.       "Oct", "October", "Nov", "November", "Dec", "December"
  1150.     };
  1151.  
  1152. #ifdef _GLIBCPP_USE_WCHAR_T
  1153.   template<typename _Dummy>
  1154.     struct _Monthnames<wchar_t, _Dummy>
  1155.     { static const wchar_t* const _S_names[24]; };
  1156.  
  1157.   template<typename _Dummy>
  1158.     const wchar_t* const
  1159.     _Monthnames<wchar_t,_Dummy>::_S_names[24] =
  1160.     {
  1161.       L"Jan", L"January", L"Feb", L"February", L"Mar", L"March",
  1162.       L"Apr", L"April",   L"May", L"May",      L"Jun", L"June",
  1163.       L"Jul", L"July",    L"Aug", L"August",   L"Sep", L"September",
  1164.       L"Oct", L"October", L"Nov", L"November", L"Dec", L"December"
  1165.     };
  1166. #endif
  1167.  
  1168.   template<typename _CharT, typename _InIter>
  1169.     _InIter
  1170.     time_get<_CharT, _InIter>::
  1171.     do_get_weekday(iter_type __s, iter_type __end,
  1172.                    ios_base& __io, ios_base::iostate& __err, tm* __t) const
  1173.     {
  1174.       if (!_M_daynames)
  1175.         {
  1176.           _M_daynames = new basic_string<_CharT>[14];
  1177.           for (int __i = 0; __i < 14; ++__i)
  1178.             _M_daynames[__i] = _Weekdaynames<_CharT>::_S_names[__i];
  1179.         }
  1180.       bool __at_eof = false;
  1181.       int __remain = 0;
  1182.       int __matches[14];
  1183.       iter_type __out = __match_parallel(__s, __end, 14, _M_daynames,
  1184.                                          __matches, __remain, __at_eof);
  1185.       __err = ios_base::iostate(0);
  1186.       if (__at_eof) __err |= __io.eofbit;
  1187.       if (__remain == 1 ||
  1188.           __remain == 2 && (__matches[0]>>1) == (__matches[1]>>1))
  1189.         __t->tm_wday = (__matches[0]>>1);
  1190.       else
  1191.         __err |= __io.failbit;
  1192.       return __out;
  1193.     }
  1194.  
  1195.   template<typename _CharT, typename _InIter>
  1196.     _InIter
  1197.     time_get<_CharT, _InIter>::
  1198.     do_get_monthname(iter_type __s, iter_type __end,
  1199.                      ios_base& __io, ios_base::iostate& __err, tm* __t) const
  1200.     {
  1201.       if (!_M_monthnames)
  1202.         {
  1203.           _M_monthnames = new basic_string<_CharT>[24];
  1204.           for (int __i = 0; __i < 24; ++__i)
  1205.             _M_monthnames[__i] = _Monthnames<_CharT>::_S_names[__i];
  1206.         }
  1207.       bool __at_eof = false;
  1208.       int __remain = 0;
  1209.       int __matches[24];
  1210.       iter_type __out = __match_parallel( __s, __end, 24, _M_monthnames,
  1211.                                           __matches, __remain, __at_eof);
  1212.       __err = ios_base::iostate(0);
  1213.       if (__at_eof) __err |= __io.eofbit;
  1214.       if (__remain == 1 ||
  1215.           __remain == 2 && (__matches[0]>>1) == (__matches[1]>>1))
  1216.         __t->tm_mon = (__matches[0]>>1);
  1217.       else
  1218.         __err |= __io.failbit;
  1219.       return __out;
  1220.     }
  1221. } // std::
  1222.  
  1223. #endif /* _CPP_BITS_LOCFACETS_TCC */
  1224.  
  1225. // Local Variables:
  1226. // mode:c++
  1227. // End:
  1228.