home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / include / xlocnum < prev    next >
Text File  |  1998-06-16  |  21KB  |  671 lines

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