Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

642 lines
25 KiB

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