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

  1. // xlocale internal header (from <locale>)
  2.  
  3. #if     _MSC_VER > 1000
  4. #pragma once
  5. #endif
  6.  
  7. #ifndef _XLOCALE_
  8. #define _XLOCALE_
  9. #include <climits>
  10. #include <cstring>
  11. #include <stdexcept>
  12. #include <typeinfo>
  13. #include <xlocinfo>
  14.  
  15. #ifdef  _MSC_VER
  16. #pragma pack(push,8)
  17. #endif  /* _MSC_VER */
  18. _STD_BEGIN
  19.                 // CLASS locale
  20. class _CRTIMP locale {
  21. public:
  22.         enum _Category {collate = _M_COLLATE, ctype = _M_CTYPE,
  23.                 monetary = _M_MONETARY, numeric = _M_NUMERIC,
  24.                 time = _M_TIME, messages = _M_MESSAGE,
  25.                 all = _M_ALL, none = 0};
  26.         typedef int category;
  27.                         // CLASS id
  28.         class _CRTIMP id {
  29.         public:
  30.                 operator size_t()
  31.                         {_Lockit _Lk;
  32.                         if (_Id == 0)
  33.                                 _Id = ++_Id_cnt;
  34.                         return (_Id); }
  35.         private:
  36.                 size_t _Id;
  37.                 static int _Id_cnt;
  38.                 };
  39.         class _Locimp;
  40.                         // class facet
  41.         class _CRTIMP facet {
  42.                 friend class locale;
  43.                 friend class _Locimp;
  44.         public:
  45.                 static size_t __cdecl _Getcat()
  46.                         {return ((size_t)(-1)); }
  47.                 void _Incref()
  48.                         {_Lockit _Lk;
  49.                         if (_Refs < (size_t)(-1))
  50.                                 ++_Refs; }
  51.                 facet *_Decref()
  52.                         {_Lockit _Lk;
  53.                         if (0 < _Refs && _Refs < (size_t)(-1))
  54.                                 --_Refs;
  55.                         return (_Refs == 0 ? this : 0); }
  56.         _PROTECTED:
  57.                 virtual ~facet()
  58.                         {}
  59.         protected:
  60.                 explicit facet(size_t _R = 0)
  61.                         : _Refs(_R) {}
  62.         private:
  63.                 facet(const facet&);    // undefined
  64.                 const facet& operator=(const facet&);   // undefined
  65.                 size_t _Refs;
  66.                 };
  67.                         // CLASS _Locimp
  68.         class _Locimp : public facet {
  69.         _PROTECTED:
  70.                 ~_Locimp();
  71.         private:
  72.                 friend class locale;
  73.                 _Locimp(bool _Xp = false);
  74.                 _Locimp(const _Locimp&);
  75.                 void _Addfac(facet *, size_t);
  76.                 static _Locimp *__cdecl _Makeloc(const _Locinfo&,
  77.                         category, _Locimp *, const locale *);
  78.                 static void __cdecl _Makewloc(const _Locinfo&,
  79.                         category, _Locimp *, const locale *);
  80.                 static void __cdecl _Makexloc(const _Locinfo&,
  81.                         category, _Locimp *, const locale *);
  82.                 facet **_Fv;
  83.                 size_t _Nfv;
  84.                 category _Cat;
  85.                 bool _Xpar;
  86.                 string _Name;
  87.                 static _CRTIMP _Locimp *_Clocptr, *_Global;
  88.                 };
  89.         locale& _Addfac(facet *, size_t, size_t);
  90.         bool operator()(const string&, const string&) const;
  91.         locale() _THROW0()
  92.                 : _Ptr(_Init())
  93.                 {_Lockit _lk;
  94.                 _Locimp::_Global->_Incref(); }
  95.         locale(_Uninitialized)
  96.                 {}
  97.         locale(const locale& _X) _THROW0()
  98.                 : _Ptr(_X._Ptr)
  99.                 {_Ptr->_Incref(); }
  100.         locale(const locale&, const locale&, category);
  101.         explicit locale(const char *, category = all);
  102.         locale(const locale&, const char *, category);
  103.         ~locale() _THROW0()
  104.                 {if (_Ptr != 0)
  105.                         delete _Ptr->_Decref(); }
  106.         locale& operator=(const locale& _X) _THROW0()
  107.                 {if (_Ptr != _X._Ptr)
  108.                         {delete _Ptr->_Decref();
  109.                         _Ptr = _X._Ptr;
  110.                         _Ptr->_Incref(); }
  111.                 return (*this); }
  112.         string name() const
  113.                 {return (_Ptr->_Name); }
  114.         const facet *_Getfacet(size_t _Id, bool _Xp = false) const;
  115.         bool _Iscloc() const;
  116.         bool operator==(const locale& _X) const;
  117.         bool operator!=(const locale& _X) const
  118.                 {return (!(*this == _X)); }
  119.         static const locale& __cdecl classic();
  120.         static locale __cdecl global(const locale&);
  121.         static locale __cdecl empty();
  122. private:
  123.         locale(_Locimp *_P)
  124.                 : _Ptr(_P) {}
  125.         static _Locimp *__cdecl _Init();
  126.         static void __cdecl _Tidy();
  127.         _Locimp *_Ptr;
  128.         };
  129. _BITMASK_OPS(locale::_Category);
  130.                 // SUPPORT TEMPLATES
  131. template<class _F>
  132.         class _Tidyfac {
  133. public:
  134.         static _F *__cdecl _Save(_F *_Fac)
  135.                 {_Lockit _Lk;
  136.                 _Facsav = _Fac;
  137.                 _Facsav->_Incref();
  138.                 atexit(_Tidy);
  139.                 return (_Fac); }
  140.         static void __cdecl _Tidy()
  141.                 {_Lockit _Lk;
  142.                 delete _Facsav->_Decref();
  143.                 _Facsav = 0; }
  144. private:
  145.         static _F *_Facsav;
  146.         };
  147. template<class _F>
  148.         _F *_Tidyfac<_F>::_Facsav = 0;
  149.  #define _ADDFAC(loc, pfac) _Addfac(loc, pfac)
  150.  #define _USEFAC(loc, fac)      use_facet(loc, (fac *)0, false)
  151.  #define _USE(loc, fac)         use_facet(loc, (fac *)0, true)
  152. template<class _F> inline
  153.         locale _Addfac(locale _X, _F *_Fac)
  154.                 {_Lockit _Lk;
  155.                 return (_X._Addfac(_Fac, _F::id, _F::_Getcat())); }
  156. template<class _F> inline
  157.         const _F& __cdecl use_facet(const locale& _L, const _F *,
  158.                 bool _Cfacet)
  159.         {static const locale::facet *_Psave = 0;
  160.         _Lockit _Lk;
  161.         size_t _Id = _F::id;
  162.         const locale::facet *_Pf = _L._Getfacet(_Id, true);
  163.         if (_Pf != 0)
  164.                 ;
  165.         else if (!_Cfacet || !_L._Iscloc())
  166.                 _THROW(bad_cast, "missing locale facet");
  167.         else if (_Psave == 0)
  168.                 _Pf = _Psave = _Tidyfac<_F>::_Save(new _F);
  169.         else
  170.                 _Pf = _Psave;
  171.         return (*(const _F *)_Pf); }
  172.                 // TEMPLATE FUNCTION _Narrow
  173. #define _NARROW(T, V)   _Narrow((T)(V))
  174. template<class _E> inline
  175.         int _Narrow(_E _C)      // needs _E::operator char()
  176.         {return ((unsigned char)(char)_C); }
  177. inline int _Narrow(wchar_t _C)
  178.         {return (wctob(_C)); }
  179.                 // TEMPLATE FUNCTION _Widen
  180. #define _WIDEN(T, V)    _Widen(V, (T *)0)
  181. template<class _E> inline
  182.         _E _Widen(char _Ch, _E *)       // needs _E(char)
  183.         {return (_Ch); }
  184. inline wchar_t _Widen(char _Ch, wchar_t *)
  185.         {return (btowc(_Ch)); }
  186.                 // TEMPLATE FUNCTION _Getloctxt
  187. template<class _E, class _II> inline
  188.         int __cdecl _Getloctxt(_II& _F, _II& _L, size_t _N,
  189.                 const _E *_S)
  190.         {for (size_t _I = 0; _S[_I] != (_E)0; ++_I)
  191.                 if (_S[_I] == _S[0])
  192.                         ++_N;
  193.         string _Str(_N, '\0');
  194.         int _Ans = -2;
  195.         for (size_t _J = 1; ; ++_J, ++_F, _Ans = -1)
  196.                 {bool  _Pfx;
  197.                 size_t _I, _K;
  198.                 for (_I = 0, _K = 0, _Pfx = false; _K < _N; ++_K)
  199.                         {for (; _S[_I] != (_E)0 && _S[_I] != _S[0]; ++_I)
  200.                                 ;
  201.                         if (_Str[_K] != '\0')
  202.                                 _I += _Str[_K];
  203.                         else if (_S[_I += _J] == _S[0] || _S[_I] == (_E)0)
  204.                                 {_Str[_K] = _J < 127 ? _J : 127;
  205.                                 _Ans = _K; }
  206.                         else if (_F == _L || _S[_I] != *_F)
  207.                                 _Str[_K] = _J < 127 ? _J : 127;
  208.                         else
  209.                                 _Pfx = true; }
  210.                 if (!_Pfx || _F == _L)
  211.                         break; }
  212.         return (_Ans); }
  213.                 // TEMPLATE FUNCTION _Maklocstr
  214. #define _MAKLOCSTR(T, S)        _Maklocstr(S, (T *)0)
  215. template<class _E> inline
  216.         _E *__cdecl _Maklocstr(const char *_S, _E *)
  217.         {size_t _L = strlen(_S) + 1;
  218.         _E *_X = new _E[_L];
  219.         for (_E *_P = _X; 0 < _L; --_L, ++_P, ++_S)
  220.                 *_P = _WIDEN(_E, *_S);
  221.         return (_X); }
  222.                 // STRUCT codecvt_base
  223. class _CRTIMP codecvt_base : public locale::facet {
  224. public:
  225.         enum _Result {ok, partial, error, noconv};
  226.         _BITMASK(_Result, result);
  227.         codecvt_base(size_t _R = 0)
  228.                 : locale::facet(_R) {}
  229.         bool always_noconv() const _THROW0()
  230.                 {return (do_always_noconv()); }
  231.         int max_length() const _THROW0()
  232.                 {return (do_max_length()); }
  233.         int encoding() const _THROW0()
  234.                 {return (do_encoding()); }
  235. protected:
  236.         virtual bool do_always_noconv() const _THROW0()
  237.                 {return (true); }
  238.         virtual int do_max_length() const _THROW0()
  239.                 {return (1); }
  240.         virtual int do_encoding() const _THROW0()
  241.                 {return (1); }
  242.         };
  243. _BITMASK_OPS(codecvt_base::_Result);
  244.                 // TEMPLATE CLASS codecvt
  245. template<class _E, class _To, class _St>
  246.         class codecvt : public codecvt_base {
  247. public:
  248.         typedef _E from_type;
  249.         typedef _To to_type;
  250.         typedef _St state_type;
  251.         result in(_St& _State,
  252.                 const _To *_F1, const _To *_L1, const _To *& _Mid1,
  253.                 _E *_F2, _E *_L2, _E *& _Mid2) const
  254.                 {return (do_in(_State,
  255.                         _F1, _L1, _Mid1, _F2, _L2, _Mid2)); }
  256.         result out(_St& _State,
  257.                 const _E *_F1, const _E *_L1, const _E *& _Mid1,
  258.                 _To *_F2, _To *_L2, _To *& _Mid2) const
  259.                 {return (do_out(_State,
  260.                         _F1, _L1, _Mid1, _F2, _L2, _Mid2)); }
  261.         int length(_St& _State, const _E *_F1,
  262.                 const _E *_L1, size_t _N2) const _THROW0()
  263.                 {return (do_length(_State, _F1, _L1, _N2)); }
  264.         static locale::id id;
  265.         explicit codecvt(size_t _R = 0)
  266.                 : codecvt_base(_R) {_Init(_Locinfo()); }
  267.         codecvt(const _Locinfo& _Lobj, size_t _R = 0)
  268.                 : codecvt_base(_R) {_Init(_Lobj); }
  269.         static size_t __cdecl _Getcat()
  270.                 {return (_LC_CTYPE); }
  271. _PROTECTED:
  272.         virtual ~codecvt()
  273.                 {};
  274. protected:
  275.         void _Init(const _Locinfo& _Lobj)
  276.                 {_Cvt = _Lobj._Getcvt(); }
  277.         virtual result do_in(_St& _State,
  278.                 const _To *_F1, const _To *, const _To *& _Mid1,
  279.                 _E *_F2, _E *, _E *& _Mid2) const
  280.                 {_Mid1 = _F1, _Mid2 = _F2;
  281.                 return (noconv); }
  282.         virtual result do_out(_St& _State,
  283.                 const _E *_F1, const _E *, const _E *& _Mid1,
  284.                 _To *_F2, _To *, _To *& _Mid2) const
  285.                 {_Mid1 = _F1, _Mid2 = _F2;
  286.                 return (noconv); }
  287.         virtual int do_length(_St& _State, const _E *_F1,
  288.                 const _E *_L1, size_t _N2) const _THROW0()
  289.                 {return (_N2 < _L1 - _F1 ? _N2 : _L1 - _F1); }
  290. private:
  291.         _Locinfo::_Cvtvec _Cvt;
  292.         };
  293. template<class _E, class _To, class _St>
  294.         locale::id codecvt<_E, _To, _St>::id;
  295.                 // CLASS codecvt<wchar_t, char, mbstate_t>
  296. class _CRTIMP codecvt<wchar_t, char, mbstate_t> : public codecvt_base {
  297. public:
  298.         typedef wchar_t _E;
  299.         typedef char _To;
  300.         typedef mbstate_t _St;
  301.         typedef _E from_type;
  302.         typedef _To to_type;
  303.         typedef _St state_type;
  304.         result in(_St& _State,
  305.                 const _To *_F1, const _To *_L1, const _To *& _Mid1,
  306.                 _E *_F2, _E *_L2, _E *& _Mid2) const
  307.                 {return (do_in(_State,
  308.                         _F1, _L1, _Mid1, _F2, _L2, _Mid2)); }
  309.         result out(_St& _State,
  310.                 const _E *_F1, const _E *_L1, const _E *& _Mid1,
  311.                 _To *_F2, _To *_L2, _To *& _Mid2) const
  312.                 {return (do_out(_State,
  313.                         _F1, _L1, _Mid1, _F2, _L2, _Mid2)); }
  314.         int length(_St& _State, const _E *_F1,
  315.                 const _E *_L1, size_t _N2) const _THROW0()
  316.                 {return (do_length(_State, _F1, _L1, _N2)); }
  317.         static locale::id id;
  318.         explicit codecvt(size_t _R = 0)
  319.                 : codecvt_base(_R) {_Init(_Locinfo()); }
  320.         codecvt(const _Locinfo& _Lobj, size_t _R = 0)
  321.                 : codecvt_base(_R) {_Init(_Lobj); }
  322.         static size_t __cdecl _Getcat()
  323.                 {return (_LC_CTYPE); }
  324. _PROTECTED:
  325.         virtual ~codecvt()
  326.                 {};
  327. protected:
  328.         void _Init(const _Locinfo& _Lobj)
  329.                 {_Cvt = _Lobj._Getcvt(); }
  330.         virtual result do_in(_St& _State,
  331.                 const _To *_F1, const _To *_L1, const _To *& _Mid1,
  332.                 _E *_F2, _E *_L2, _E *& _Mid2) const
  333.                 {_Mid1 = _F1, _Mid2 = _F2;
  334.                 result _Ans = _Mid1 == _L1 ? ok : partial;
  335.                 int _N;
  336.                 while (_Mid1 != _L1 && _Mid2 != _L2)
  337.                         switch (_N =
  338.                                 _Mbrtowc(_Mid2, _Mid1, _L1 - _Mid1,
  339.                                         &_State, &_Cvt))
  340.                         {case -2:
  341.                                 _Mid1 = _L1;
  342.                                 return (_Ans);
  343.                         case -1:
  344.                                 return (error);
  345.                         case 0:
  346.                                 _N = strlen(_Mid1) + 1;
  347.                         default:        // fall through
  348.                                 _Mid1 += _N, ++_Mid2, _Ans = ok; }
  349.                 return (_Ans); }
  350.         virtual result do_out(_St& _State,
  351.                 const _E *_F1, const _E *_L1, const _E *& _Mid1,
  352.                 _To *_F2, _To *_L2, _To *& _Mid2) const
  353.                 {_Mid1 = _F1, _Mid2 = _F2;
  354.                 result _Ans = _Mid1 == _L1 ? ok : partial;
  355.                 int _N;
  356.                 while (_Mid1 != _L1 && _Mid2 != _L2)
  357.                         if (MB_CUR_MAX <= _L2 - _Mid2)
  358.                                 if ((_N =
  359.                                         _Wcrtomb(_Mid2, *_Mid1, &_State,
  360.                                                 &_Cvt)) <= 0)
  361.                                         return (error);
  362.                                 else
  363.                                         ++_Mid1, _Mid2 += _N, _Ans = ok;
  364.                         else
  365.                                 {_To _Buf[MB_LEN_MAX];
  366.                                 _St _Stsave = _State;
  367.                                 if ((_N =
  368.                                         _Wcrtomb(_Buf, *_Mid1, &_State,
  369.                                                 &_Cvt)) <= 0)
  370.                                         return (error);
  371.                                 else if (_L2 - _Mid2 < _N)
  372.                                         {_State = _Stsave;
  373.                                         return (_Ans); }
  374.                                 else
  375.                                         {memcpy(_Mid2, _Buf, _N);
  376.                                         ++_Mid1, _Mid2 += _N, _Ans = ok; }}
  377.                 return (_Ans); }
  378.         virtual int do_length(_St& _State, const _E *_F1,
  379.                 const _E *_L1, size_t _N2) const _THROW0()
  380.                 {const _E *_Mid1;
  381.                 _To _Buf[MB_LEN_MAX];
  382.                 int _N;
  383.                 for (_Mid1 = _F1; _Mid1 != _L1 && 0 < _N2;
  384.                         ++_Mid1, _N2 -= _N)
  385.                         if ((_N =
  386.                                 _Wcrtomb(_Buf, *_Mid1, &_State, &_Cvt)) <= 0
  387.                                         || _N2 < _N)
  388.                                 break;
  389.                 return (_Mid1 - _F1); }
  390.         virtual bool do_always_noconv() const _THROW0()
  391.                 {return (false); }
  392.         virtual int do_max_length() const _THROW0()
  393.                 {return (MB_LEN_MAX); }
  394.         virtual int do_encoding() const _THROW0()
  395.                 {return (0); }
  396. private:
  397.         _Locinfo::_Cvtvec _Cvt;
  398.         };
  399.                 // TEMPLATE CLASS codecvt_byname
  400. template<class _E, class _To, class _St>
  401.         class codecvt_byname : public codecvt<_E, _To, _St> {
  402. public:
  403.         explicit codecvt_byname(const char *_S, size_t _R = 0)
  404.                 : codecvt<_E, _To, _St>(_Locinfo(_S), _R) {}
  405. _PROTECTED:
  406.         virtual ~codecvt_byname()
  407.                 {}
  408.         };
  409.                 // STRUCT ctype_base
  410. struct _CRTIMP ctype_base : public locale::facet {
  411.         enum _Mask {alnum = _DI|_LO|_UP|_XA, alpha = _LO|_UP|_XA,
  412.                 cntrl = _BB, digit = _DI, graph = _DI|_LO|_PU|_UP|_XA,
  413.                 lower = _LO, print = _DI|_LO|_PU|_SP|_UP|_XA|_XD,
  414.                 punct = _PU, space = _CN|_SP|_XS, upper = _UP,
  415.                 xdigit = _XD};
  416. //      _BITMASK(_Mask, mask);
  417.         typedef short mask;     // to match <ctype.h>
  418.         ctype_base(size_t _R = 0)
  419.                 : locale::facet(_R) {}
  420.         };
  421.                 // TEMPLATE CLASS ctype
  422. template<class _E>
  423.         class ctype : public ctype_base {
  424. public:
  425.         typedef _E char_type;
  426.         bool is(mask _M, _E _C) const
  427.                 {return (do_is(_M, _C)); }
  428.         const _E *is(const _E *_F, const _E *_L, mask *_V) const
  429.                 {return (do_is(_F, _L, _V)); }
  430.         const _E *scan_is(mask _M, const _E *_F,
  431.                 const _E *_L) const
  432.                 {return (do_scan_is(_M, _F, _L)); }
  433.         const _E *scan_not(mask _M, const _E *_F,
  434.                 const _E *_L) const
  435.                 {return (do_scan_not(_M, _F, _L)); }
  436.         _E tolower(_E _C) const
  437.                 {return (do_tolower(_C)); }
  438.         const _E *tolower(_E *_F, const _E *_L) const
  439.                 {return (do_tolower(_F, _L)); }
  440.         _E toupper(_E _C) const
  441.                 {return (do_toupper(_C)); }
  442.         const _E *toupper(_E *_F, const _E *_L) const
  443.                 {return (do_toupper(_F, _L)); }
  444.         _E widen(char _X) const
  445.                 {return (do_widen(_X)); }
  446.         const char *widen(const char *_F, const char *_L,
  447.                 _E *_V) const
  448.                 {return (do_widen(_F, _L, _V)); }
  449.         char narrow(_E _C, char _D = '\0') const
  450.                 {return (do_narrow(_C, _D)); }
  451.         const _E *narrow(const _E *_F, const _E *_L, char _D,
  452.                 char *_V) const
  453.                 {return (do_narrow(_F, _L, _D, _V)); }
  454.         static locale::id id;
  455.         explicit ctype(size_t _R = 0)
  456.                 : ctype_base(_R) {_Init(_Locinfo()); }
  457.         ctype(const _Locinfo& _Lobj, size_t _R = 0)
  458.                 : ctype_base(_R) {_Init(_Lobj); }
  459.         static size_t __cdecl _Getcat()
  460.                 {return (_LC_CTYPE); }
  461. _PROTECTED:
  462.         virtual ~ctype()
  463.                 {if (_Ctype._Delfl)
  464.                         free((void *)_Ctype._Table); }
  465. protected:
  466.         void _Init(const _Locinfo& _Lobj)
  467.                 {_Ctype = _Lobj._Getctype(); }
  468.         virtual bool do_is(mask _M, _E _C) const
  469.                 {return ((_Ctype._Table[narrow(_C)] & _M) != 0); }
  470.         virtual const _E *do_is(const _E *_F, const _E *_L,
  471.                 mask *_V) const
  472.                 {for (; _F != _L; ++_F, ++_V)
  473.                         *_V = _Ctype._Table[narrow(*_F)];
  474.                 return (_F); }
  475.         virtual const _E *do_scan_is(mask _M, const _E *_F,
  476.                 const _E *_L) const
  477.                 {for (; _F != _L && !is(_M, *_F); ++_F)
  478.                         ;
  479.                 return (_F); }
  480.         virtual const _E *do_scan_not(mask _M, const _E *_F,
  481.                 const _E *_L) const
  482.                 {for (; _F != _L && is(_M, *_F); ++_F)
  483.                         ;
  484.                 return (_F); }
  485.         virtual _E do_tolower(_E _C) const
  486.                 {return ((_E)widen((char)_Tolower(narrow(_C), &_Ctype))); }
  487.         virtual const _E *do_tolower(_E *_F, const _E *_L) const
  488.                 {for (; _F != _L; ++_F)
  489.                         *_F = (_E)_Tolower(*_F, &_Ctype);
  490.                 return ((const _E *)_F); }
  491.         virtual _E do_toupper(_E _C) const
  492.                 {return ((_E)widen((char)_Toupper(narrow(_C), &_Ctype))); }
  493.         virtual const _E *do_toupper(_E *_F, const _E *_L) const
  494.                 {for (; _F != _L; ++_F)
  495.                         *_F = (_E)_Toupper(*_F, &_Ctype);
  496.                 return ((const _E *)_F); }
  497.         virtual _E do_widen(char _X) const
  498.                 {return (_WIDEN(_E, _X)); }
  499.         virtual const char *do_widen(const char *_F, const char *_L,
  500.                 _E *_V) const
  501.                 {for (; _F != _L; ++_F, ++_V)
  502.                         *_V = _WIDEN(_E, *_F);
  503.                 return (_F); }
  504.         virtual char do_narrow(_E _C, char) const
  505.                 {return ((char)_NARROW(_E, _C)); }
  506.         virtual const _E *do_narrow(const _E *_F, const _E *_L,
  507.                 char, char *_V) const
  508.                 {for (; _F != _L; ++_F, ++_V)
  509.                         *_V = (char)_NARROW(_E, *_F);
  510.                 return (_F); }
  511. private:
  512.         _Locinfo::_Ctypevec _Ctype;
  513.         };
  514.  
  515. template<class _E>
  516.         locale::id ctype<_E>::id;
  517.  
  518.                 // CLASS ctype<char>
  519. class _CRTIMP ctype<char> : public ctype_base {
  520. public:
  521.         typedef char _E;
  522.         typedef _E char_type;
  523.         bool is(mask _M, _E _C) const
  524.                 {return ((_Ctype._Table[(unsigned char)_C] & _M) != 0); }
  525.         const _E *is(const _E *_F, const _E *_L, mask *_V) const
  526.                 {for (; _F != _L; ++_F, ++_V)
  527.                         *_V = _Ctype._Table[(unsigned char)*_F];
  528.                 return (_F); }
  529.         const _E *scan_is(mask _M, const _E *_F,
  530.                 const _E *_L) const
  531.                 {for (; _F != _L && !is(_M, *_F); ++_F)
  532.                         ;
  533.                 return (_F); }
  534.         const _E *scan_not(mask _M, const _E *_F,
  535.                 const _E *_L) const
  536.                 {for (; _F != _L && is(_M, *_F); ++_F)
  537.                         ;
  538.                 return (_F); }
  539.         _E tolower(_E _C) const
  540.                 {return (do_tolower(_C)); }
  541.         const _E *tolower(_E *_F, const _E *_L) const
  542.                 {return (do_tolower(_F, _L)); }
  543.         _E toupper(_E _C) const
  544.                 {return (do_toupper(_C)); }
  545.         const _E *toupper(_E *_F, const _E *_L) const
  546.                 {return (do_toupper(_F, _L)); }
  547.         _E widen(char _X) const
  548.                 {return (_X); }
  549.         const _E *widen(const char *_F, const char *_L, _E *_V) const
  550.                 {memcpy(_V, _F, _L - _F);
  551.                 return (_L); }
  552.         _E narrow(_E _C, char _D = '\0') const
  553.                 {return (_C); }
  554.         const _E *narrow(const _E *_F, const _E *_L, char _D,
  555.                 char *_V) const
  556.                 {memcpy(_V, _F, _L - _F);
  557.                 return (_L); }
  558.         static locale::id id;
  559.         explicit ctype(const mask *_Tab = 0, bool _Df = false,
  560.                 size_t _R = 0)
  561.                 : ctype_base(_R)
  562.                 {_Lockit Lk;
  563.                 _Init(_Locinfo());
  564.                 if (_Ctype._Delfl)
  565.                         free((void *)_Ctype._Table), _Ctype._Delfl = false;
  566.                 if (_Tab == 0)
  567.                         _Ctype._Table = _Cltab;
  568.                 else
  569.                         _Ctype._Table = _Tab, _Ctype._Delfl = _Df; }
  570.         ctype(const _Locinfo& _Lobj, size_t _R = 0)
  571.                 : ctype_base(_R) {_Init(_Lobj); }
  572.         static size_t __cdecl _Getcat()
  573.                 {return (_LC_CTYPE); }
  574.         static const size_t table_size;
  575. _PROTECTED:
  576.         virtual ~ctype()
  577.                 {if (_Ctype._Delfl)
  578.                         free((void *)_Ctype._Table); }
  579. protected:
  580.         static void __cdecl _Term(void)
  581.                 {free((void *)_Cltab); }
  582.         void _Init(const _Locinfo& _Lobj)
  583.                 {_Lockit Lk;
  584.                 _Ctype = _Lobj._Getctype();
  585.                 if (_Cltab == 0)
  586.                         {_Cltab = _Ctype._Table;
  587.                         atexit(_Term);
  588.                         _Ctype._Delfl = false; }}
  589.         virtual _E do_tolower(_E _C) const
  590.                 {return (_E)(_Tolower((unsigned char)_C, &_Ctype)); }
  591.         virtual const _E *do_tolower(_E *_F, const _E *_L) const
  592.                 {for (; _F != _L; ++_F)
  593.                         *_F = (_E)_Tolower(*_F, &_Ctype);
  594.                 return ((const _E *)_F); }
  595.         virtual _E do_toupper(_E _C) const
  596.                 {return ((_E)_Toupper((unsigned char)_C, &_Ctype)); }
  597.         virtual const _E *do_toupper(_E *_F, const _E *_L) const
  598.                 {for (; _F != _L; ++_F)
  599.                         *_F = (_E)_Toupper(*_F, &_Ctype);
  600.                 return ((const _E *)_F); }
  601.         const mask *table() const _THROW0()
  602.                 {return (_Ctype._Table); }
  603.         static const mask * __cdecl classic_table() _THROW0()
  604.                 {_Lockit Lk;
  605.                 if (_Cltab == 0)
  606.                         locale::classic();      // force locale::_Init() call
  607.                 return (_Cltab); }
  608. private:
  609.         _Locinfo::_Ctypevec _Ctype;
  610.         static const mask *_Cltab;
  611.         };
  612.  
  613.  
  614.                 // TEMPLATE CLASS ctype_byname
  615. template<class _E>
  616.         class ctype_byname : public ctype<_E> {
  617. public:
  618.         explicit ctype_byname(const char *_S, size_t _R = 0)
  619.                 : ctype<_E>(_Locinfo(_S), _R) {}
  620. _PROTECTED:
  621.         virtual ~ctype_byname()
  622.                 {}
  623.         };
  624.  
  625. #ifdef  _DLL
  626. #pragma warning(disable:4231) /* the extern before template is a non-standard extension */
  627. extern template class _CRTIMP ctype<wchar_t>;
  628. extern template class _CRTIMP codecvt<char, char, int>;
  629. #pragma warning(default:4231) /* restore previous warning */
  630. #endif        // _DLL
  631.  
  632. _STD_END
  633. #ifdef  _MSC_VER
  634. #pragma pack(pop)
  635. #endif  /* _MSC_VER */
  636.  
  637. #endif /* _XLOCALE_ */
  638.  
  639. /*
  640.  * Copyright (c) 1995 by P.J. Plauger.  ALL RIGHTS RESERVED. 
  641.  * Consult your license regarding permissions and restrictions.
  642.  */
  643.