|
|
|
1 |
|
// locale standard header |
2 |
|
#pragma once |
3 |
|
#ifndef _LOCALE_ |
4 |
|
#define _LOCALE_ |
5 |
|
#ifndef RC_INVOKED |
6 |
|
#include <string> |
7 |
|
#include <xlocmes> |
8 |
|
#include <xlocmon> |
9 |
|
#include <xlocnum> |
10 |
|
#include <xloctime> |
11 |
|
|
12 |
|
#ifdef _MSC_VER |
13 |
|
#pragma pack(push,_CRT_PACKING) |
14 |
|
#pragma warning(push,3) |
15 |
|
#endif /* _MSC_VER */ |
16 |
|
|
17 |
|
_STD_BEGIN |
18 |
|
|
19 |
|
#pragma warning(push) |
20 |
|
#pragma warning(disable:4275) |
21 |
|
// TEMPLATE CLASS collate |
22 |
|
template<class _Elem> |
23 |
|
class collate |
24 |
|
: public locale::facet |
25 |
|
{ // facet for ordering sequences of elements |
26 |
|
public: |
27 |
|
typedef _Elem char_type; |
28 |
|
typedef basic_string<_Elem, char_traits<_Elem>, |
29 |
|
allocator<_Elem> > string_type; |
30 |
|
|
31 |
|
int __CLR_OR_THIS_CALL compare(const _Elem *_First1, const _Elem *_Last1, |
32 |
|
const _Elem *_First2, const _Elem *_Last2) const |
33 |
|
{ // compare [_First1, _Last1) to [_First2, _Last2) |
34 |
|
return (do_compare(_First1, _Last1, _First2, _Last2)); |
35 |
|
} |
36 |
|
|
37 |
|
string_type __CLR_OR_THIS_CALL transform(const _Elem *_First, const _Elem *_Last) const |
38 |
|
{ // transform [_First, _Last) to key string |
39 |
|
return (do_transform(_First, _Last)); |
40 |
|
} |
41 |
|
|
42 |
|
long __CLR_OR_THIS_CALL hash(const _Elem *_First, const _Elem *_Last) const |
43 |
|
{ // compute hash code for [_First, _Last) |
44 |
|
return (do_hash(_First, _Last)); |
45 |
|
} |
46 |
|
|
47 |
|
__PURE_APPDOMAIN_GLOBAL static locale::id id; // unique facet id |
48 |
|
|
49 |
|
explicit __CLR_OR_THIS_CALL collate(size_t _Refs = 0) |
50 |
|
: locale::facet(_Refs) |
51 |
|
{ // construct from current locale |
52 |
|
_BEGIN_LOCINFO(_Lobj) |
53 |
|
_Init(_Lobj); |
54 |
|
_END_LOCINFO() |
55 |
|
} |
56 |
|
|
57 |
|
__CLR_OR_THIS_CALL collate(const _Locinfo& _Lobj, size_t _Refs = 0) |
58 |
|
: locale::facet(_Refs) |
59 |
|
{ // construct from specified locale |
60 |
|
_Init(_Lobj); |
61 |
|
} |
62 |
|
|
63 |
|
static size_t __CLRCALL_OR_CDECL _Getcat(const locale::facet **_Ppf = 0, |
64 |
|
const locale *_Ploc = 0) |
65 |
|
{ // return locale category mask and construct standard facet |
66 |
|
if (_Ppf != 0 && *_Ppf == 0) |
67 |
|
*_Ppf = _NEW_CRT collate<_Elem>( |
68 |
|
_Locinfo(_Ploc->name())); |
69 |
|
return (_X_COLLATE); |
80 |
|
{ // construct from specified locale |
81 |
|
_BEGIN_LOCINFO(_Lobj(_Locname)) |
82 |
|
_Init(_Lobj); |
83 |
|
_END_LOCINFO() |
84 |
|
} |
85 |
|
|
86 |
|
void __CLR_OR_THIS_CALL _Init(const _Locinfo& _Lobj) |
87 |
|
{ // initialize from _Lobj |
88 |
|
_Coll = _Lobj._Getcoll(); |
89 |
|
} |
90 |
|
|
91 |
|
virtual int __CLR_OR_THIS_CALL do_compare(const _Elem *_First1, const _Elem *_Last1, |
92 |
|
const _Elem *_First2, const _Elem *_Last2) const |
93 |
|
{ // compare [_First1, _Last1) to [_First2, _Last2) |
94 |
|
_DEBUG_RANGE(_First1, _Last1); |
95 |
|
_DEBUG_RANGE(_First2, _Last2); |
96 |
|
return (_LStrcoll(_First1, _Last1, _First2, _Last2, &_Coll)); |
97 |
|
} |
98 |
|
|
99 |
|
virtual string_type __CLR_OR_THIS_CALL do_transform(const _Elem *_First, |
100 |
|
const _Elem *_Last) const |
101 |
|
{ // transform [_First, _Last) to key string |
102 |
|
_DEBUG_RANGE(_First, _Last); |
103 |
|
size_t _Count; |
104 |
|
string_type _Str; |
105 |
|
|
106 |
|
for (_Count = _Last - _First; 0 < _Count; ) |
107 |
|
{ // grow string if locale-specific strxfrm fails |
108 |
|
_Str.resize(_Count); |
109 |
|
if ((_Count = _LStrxfrm(&*_Str.begin(), |
110 |
|
&*_Str.begin() + _Str.size(), |
111 |
|
_First, _Last, &_Coll)) <= _Str.size()) |
112 |
|
break; |
113 |
|
} |
114 |
|
_Str.resize(_Count); |
115 |
|
return (_Str); |
116 |
|
} |
117 |
|
|
118 |
|
virtual long __CLR_OR_THIS_CALL do_hash(const _Elem *_First, |
119 |
|
const _Elem *_Last) const |
120 |
|
{ // compute hash code for [_First, _Last) |
121 |
|
_DEBUG_RANGE(_First, _Last); |
122 |
|
unsigned long _Val = 0; |
123 |
|
for (; _First != _Last; ++_First) |
124 |
|
_Val = (_Val << 8 | _Val >> 24) + *_First; |
125 |
|
return ((long)_Val); |
126 |
|
} |
127 |
|
|
128 |
|
private: |
129 |
|
_Locinfo::_Collvec _Coll; // used by _LStrcoll and _XStrxfrm |
130 |
|
}; |
131 |
|
#pragma warning(pop) |
132 |
|
|
133 |
|
// STATIC collate::id OBJECT |
134 |
|
template<class _Elem> |
135 |
|
__PURE_APPDOMAIN_GLOBAL locale::id collate<_Elem>::id; |
136 |
|
|
137 |
|
#if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE) |
138 |
|
template class _CRTIMP2_PURE collate<char>; |
139 |
|
template class _CRTIMP2_PURE collate<wchar_t>; |
140 |
|
|
141 |
|
|
142 |
|
|
143 |
|
#endif /* _DLL_CPPLIB */ |
144 |
|
|
145 |
|
// TEMPLATE CLASS collate_byname |
146 |
|
template<class _Elem> |
147 |
|
class collate_byname |
148 |
|
: public collate<_Elem> |
149 |
|
{ // collate for named locale |
150 |
|
public: |
151 |
|
explicit __CLR_OR_THIS_CALL collate_byname(const char *_Locname, size_t _Refs = 0) |
152 |
|
: collate<_Elem>(_Locname, _Refs) |
153 |
|
{ // construct for named locale |
154 |
|
} |
155 |
|
|
156 |
|
_PROTECTED: |
157 |
|
virtual __CLR_OR_THIS_CALL ~collate_byname() |
158 |
|
{ // destroy the object |
159 |
|
} |
160 |
|
}; |
161 |
|
|
162 |
|
// locale SUPPORT TEMPLATES |
163 |
|
|
164 |
|
#define _HAS(loc, fac) has_facet<fac>(loc) |
165 |
|
|
166 |
|
template<class _Facet> inline |
167 |
|
bool __CLRCALL_OR_CDECL has_facet(const locale& _Loc) _THROW0() |
168 |
|
{ // test if facet is in locale |
169 |
|
_BEGIN_LOCK(_LOCK_LOCALE) // the thread lock, make get atomic |
170 |
|
size_t _Id = _Facet::id; |
171 |
|
return (_Loc._Getfacet(_Id) != 0 || _Facet::_Getcat() != (size_t)(-1)); |
172 |
|
_END_LOCK() |
173 |
|
} |
174 |
|
|
175 |
|
template<class _Facet> inline _DEPRECATED |
176 |
|
bool __CLRCALL_OR_CDECL has_facet(const locale& _Loc, const _Facet *) _THROW0() |
177 |
|
{ // test if facet is in locale -- retained, two arg version |
178 |
|
return (has_facet<_Facet>(_Loc)); |
179 |
|
} |
180 |
|
|
181 |
|
// ctype TEMPLATE FUNCTIONS |
182 |
|
template<class _Elem> inline |
183 |
|
bool (__CLRCALL_OR_CDECL isalnum)(_Elem _Ch, const locale& _Loc) |
184 |
|
{ // test if character is alphanumeric, locale specific |
185 |
|
return (_USE(_Loc, ctype<_Elem>).is(ctype_base::alnum, _Ch)); |
186 |
|
} |
187 |
|
|
188 |
|
template<class _Elem> inline |
189 |
|
bool (__CLRCALL_OR_CDECL isalpha)(_Elem _Ch, const locale& _Loc) |
190 |
|
{ // test if character is alphabetic, locale specific |
191 |
|
return (_USE(_Loc, ctype<_Elem>).is(ctype_base::alpha, _Ch)); |
192 |
|
} |
193 |
|
|
194 |
|
template<class _Elem> inline |
195 |
|
bool (__CLRCALL_OR_CDECL iscntrl)(_Elem _Ch, const locale& _Loc) |
196 |
|
{ // test if character is control, locale specific |
197 |
|
return (_USE(_Loc, ctype<_Elem>).is(ctype_base::cntrl, _Ch)); |
198 |
|
} |
199 |
|
|
200 |
|
template<class _Elem> inline |
201 |
|
bool (__CLRCALL_OR_CDECL isdigit)(_Elem _Ch, const locale& _Loc) |
202 |
|
{ // test if character is digit, locale specific |
203 |
|
return (_USE(_Loc, ctype<_Elem>).is(ctype_base::digit, _Ch)); |
204 |
|
} |
205 |
|
|
206 |
|
template<class _Elem> inline |
207 |
|
bool (__CLRCALL_OR_CDECL isgraph)(_Elem _Ch, const locale& _Loc) |
208 |
|
{ // test if character is graphic, locale specific |
209 |
|
return (_USE(_Loc, ctype<_Elem>).is(ctype_base::graph, _Ch)); |
210 |
|
} |
211 |
|
|
212 |
|
template<class _Elem> inline |
213 |
|
bool (__CLRCALL_OR_CDECL islower)(_Elem _Ch, const locale& _Loc) |
214 |
|
{ // test if character is lower case, locale specific |
215 |
|
return (_USE(_Loc, ctype<_Elem>).is(ctype_base::lower, _Ch)); |
216 |
|
} |
217 |
|
|
218 |
|
template<class _Elem> inline |
219 |
|
bool (__CLRCALL_OR_CDECL isprint)(_Elem _Ch, const locale& _Loc) |
220 |
|
{ // test if character is printing, locale specific |
221 |
|
return (_USE(_Loc, ctype<_Elem>).is(ctype_base::print, _Ch)); |
222 |
|
} |
223 |
|
|
224 |
|
template<class _Elem> inline |
225 |
|
bool (__CLRCALL_OR_CDECL ispunct)(_Elem _Ch, const locale& _Loc) |
226 |
|
{ // test if character is punctuation, locale specific |
227 |
|
return (_USE(_Loc, ctype<_Elem>).is(ctype_base::punct, _Ch)); |
228 |
|
} |
229 |
|
|
230 |
|
template<class _Elem> inline |
231 |
|
bool (__CLRCALL_OR_CDECL isspace)(_Elem _Ch, const locale& _Loc) |
232 |
|
{ // test if character is whitespace, locale specific |
233 |
|
return (_USE(_Loc, ctype<_Elem>).is(ctype_base::space, _Ch)); |
234 |
|
} |
235 |
|
|
236 |
|
template<class _Elem> inline |
237 |
|
bool (__CLRCALL_OR_CDECL isupper)(_Elem _Ch, const locale& _Loc) |
238 |
|
{ // test if character is upper case, locale specific |
239 |
|
return (_USE(_Loc, ctype<_Elem>).is(ctype_base::upper, _Ch)); |
240 |
|
} |
241 |
|
|
242 |
|
template<class _Elem> inline |
243 |
|
bool (__CLRCALL_OR_CDECL isxdigit)(_Elem _Ch, const locale& _Loc) |
244 |
|
{ // test if character is hexadecimal digit, locale specific |
245 |
|
return (_USE(_Loc, ctype<_Elem>).is(ctype_base::xdigit, _Ch)); |
246 |
|
} |
247 |
|
|
248 |
|
template<class _Elem> inline |
249 |
|
_Elem (__CLRCALL_OR_CDECL tolower)(_Elem _Ch, const locale& _Loc) |
250 |
|
{ // convert character to lower case, locale specific |
251 |
|
return (_USE(_Loc, ctype<_Elem>).tolower(_Ch)); |
252 |
|
} |
253 |
|
|
254 |
|
template<class _Elem> inline |
255 |
|
_Elem (__CLRCALL_OR_CDECL toupper)(_Elem _Ch, const locale& _Loc) |
256 |
|
{ // convert character to upper case, locale specific |
257 |
|
return (_USE(_Loc, ctype<_Elem>).toupper(_Ch)); |
258 |
|
} |
259 |
|
_STD_END |
260 |
|
|
261 |
|
#ifdef _MSC_VER |
262 |
|
#pragma warning(pop) |
263 |
|
#pragma pack(pop) |
264 |
|
#endif /* _MSC_VER */ |
265 |
|
|
266 |
|
#endif /* RC_INVOKED */ |
267 |
|
#endif /* _LOCALE_ */ |
268 |
|
|
269 |
|
/* |
270 |
|
* Copyright (c) 1992-2007 by P.J. Plauger. ALL RIGHTS RESERVED. |
271 |
|
* Consult your license regarding permissions and restrictions. |
272 |
|
V5.03:0009 */ |
273 |
|
|
|
|
|