]>
Commit | Line | Data |
---|---|---|
725dc051 BK |
1 | // Locale support -*- C++ -*- |
2 | ||
0214010c | 3 | // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. |
725dc051 BK |
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 | // | |
31 | // ISO C++ 14882: 22.1 Locales | |
32 | // | |
33 | ||
34 | #ifndef _CPP_BITS_LOCCORE_H | |
35 | #define _CPP_BITS_LOCCORE_H 1 | |
36 | ||
37 | #include <bits/c++config.h> | |
38 | #include <bits/std_climits.h> // For CHAR_BIT | |
39 | #include <bits/std_string.h> // For string | |
40 | #include <bits/std_cctype.h> // For isspace, etc. | |
0214010c | 41 | #include <bits/c++locale.h> // Defines __c_locale. |
725dc051 BK |
42 | |
43 | namespace std | |
44 | { | |
0214010c BK |
45 | // NB: Don't instantiate required wchar_t facets if no wchar_t support. |
46 | #ifdef _GLIBCPP_USE_WCHAR_T | |
47 | # define _GLIBCPP_NUM_FACETS 26 | |
48 | #else | |
49 | # define _GLIBCPP_NUM_FACETS 13 | |
50 | #endif | |
725dc051 BK |
51 | |
52 | // _Count_ones: compile-time computation of number of 1-bits in a value N | |
53 | // This takes only 5 (or 6) instantiations, doing recursive descent | |
54 | // in parallel -- ncm | |
55 | template<unsigned int _Num, int _Shift = (sizeof(unsigned) * CHAR_BIT)/2, | |
56 | unsigned int _Mask = (~0u >> _Shift) > | |
57 | struct _Count_ones; | |
58 | ||
982b8443 GDR |
59 | // It is preferable to use enumerators instead of integral static data |
60 | // members to avoid emission of superflous variables -- gdr. | |
725dc051 BK |
61 | template<unsigned int _Num, unsigned int _Mask> |
62 | struct _Count_ones<_Num, 0, _Mask> | |
982b8443 GDR |
63 | { |
64 | enum | |
65 | { | |
0a31609b | 66 | _M_count = _Num |
982b8443 GDR |
67 | }; |
68 | }; | |
725dc051 BK |
69 | |
70 | template<unsigned int _Num, int _Shift, unsigned int _Mask> | |
71 | struct _Count_ones | |
72 | { | |
982b8443 GDR |
73 | enum |
74 | { | |
0a31609b BK |
75 | _M_halfcount = _Count_ones<_Num, _Shift/2, |
76 | (_Mask^((~_Mask)>>(_Shift/2))) >::_M_count, | |
77 | _M_count = (_M_halfcount&_Mask) + ((_M_halfcount>>_Shift)&_Mask) | |
982b8443 | 78 | }; |
725dc051 BK |
79 | }; |
80 | ||
725dc051 BK |
81 | // 22.1.1 Locale |
82 | template<typename _Tp> class allocator; | |
83 | template<typename _Tp, typename _Alloc> class vector; | |
84 | class locale; | |
85 | ||
86 | // 22.1.3 Convenience interfaces | |
87 | template<typename _CharT> | |
88 | inline bool | |
89 | isspace(_CharT, const locale&); | |
90 | ||
91 | template<typename _CharT> | |
92 | inline bool | |
93 | isprint(_CharT, const locale&); | |
94 | ||
95 | template<typename _CharT> | |
96 | inline bool | |
97 | iscntrl(_CharT, const locale&); | |
98 | ||
99 | template<typename _CharT> | |
100 | inline bool | |
101 | isupper(_CharT, const locale&); | |
102 | ||
103 | template<typename _CharT> | |
104 | inline bool | |
105 | islower(_CharT, const locale&); | |
106 | ||
107 | template<typename _CharT> | |
108 | inline bool | |
109 | isalpha(_CharT, const locale&); | |
110 | ||
111 | template<typename _CharT> | |
112 | inline bool | |
113 | isdigit(_CharT, const locale&); | |
114 | ||
115 | template<typename _CharT> | |
116 | inline bool | |
117 | ispunct(_CharT, const locale&); | |
118 | ||
119 | template<typename _CharT> | |
120 | inline bool | |
121 | isxdigit(_CharT, const locale&); | |
122 | ||
123 | template<typename _CharT> | |
124 | inline bool | |
125 | isalnum(_CharT, const locale&); | |
126 | ||
127 | template<typename _CharT> | |
128 | inline bool | |
129 | isgraph(_CharT, const locale&); | |
130 | ||
131 | template<typename _CharT> | |
132 | inline _CharT | |
133 | toupper(_CharT, const locale&); | |
134 | ||
135 | template<typename _CharT> | |
136 | inline _CharT | |
137 | tolower(_CharT, const locale&); | |
138 | ||
139 | ||
140 | // 22.2.1 and 22.2.1.3 ctype | |
141 | class ctype_base; | |
142 | template<typename _CharT> | |
143 | class ctype; | |
144 | template<> class ctype<char>; | |
145 | #ifdef _GLIBCPP_USE_WCHAR_T | |
146 | template<> class ctype<wchar_t>; | |
147 | #endif | |
725dc051 BK |
148 | template<typename _CharT> |
149 | class ctype_byname; | |
697649ea | 150 | // NB: Specialized for char and wchar_t in locale_facets.h. |
725dc051 BK |
151 | |
152 | class codecvt_base; | |
153 | template<typename _InternT, typename _ExternT, typename _StateT> | |
154 | class codecvt; | |
155 | template<> class codecvt<char, char, mbstate_t>; | |
156 | #ifdef _GLIBCPP_USE_WCHAR_T | |
157 | template<> class codecvt<wchar_t, char, mbstate_t>; | |
158 | #endif | |
725dc051 BK |
159 | template<typename _InternT, typename _ExternT, typename _StateT> |
160 | class codecvt_byname; | |
725dc051 BK |
161 | |
162 | // 22.2.2 and 22.2.3 numeric | |
163 | template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > | |
164 | class num_get; | |
165 | template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > | |
166 | class num_put; | |
167 | template<typename _CharT> class numpunct; | |
168 | template<typename _CharT> class numpunct_byname; | |
169 | ||
170 | // 22.2.4 collation | |
171 | template<typename _CharT> | |
172 | class collate; | |
725dc051 BK |
173 | template<typename _CharT> class |
174 | collate_byname; | |
175 | ||
176 | // 22.2.5 date and time | |
177 | class time_base; | |
178 | template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > | |
179 | class time_get; | |
180 | template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > | |
181 | class time_get_byname; | |
182 | template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > | |
183 | class time_put; | |
184 | template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > | |
185 | class time_put_byname; | |
186 | ||
187 | // 22.2.6 money | |
188 | class money_base; | |
189 | template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > | |
190 | class money_get; | |
191 | template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > | |
192 | class money_put; | |
193 | template<typename _CharT, bool _Intl = false> | |
194 | class moneypunct; | |
195 | template<typename _CharT, bool _Intl = false> | |
196 | class moneypunct_byname; | |
197 | ||
198 | // 22.2.7 message retrieval | |
199 | class messages_base; | |
200 | template<typename _CharT> | |
201 | class messages; | |
202 | template<typename _CharT> | |
203 | class messages_byname; | |
204 | ||
725dc051 BK |
205 | // 22.1.1 Class locale |
206 | class locale | |
207 | { | |
208 | public: | |
209 | // Types: | |
0214010c | 210 | typedef unsigned int category; |
725dc051 BK |
211 | |
212 | // Forward decls and friends: | |
213 | class facet; | |
214 | class id; | |
215 | class _Impl; | |
216 | ||
0214010c | 217 | friend class facet; |
725dc051 BK |
218 | friend class _Impl; |
219 | ||
220 | template<typename _Facet> | |
221 | friend const _Facet& | |
222 | use_facet(const locale&); | |
223 | ||
224 | template<typename _Facet> | |
225 | friend bool | |
226 | has_facet(const locale&) throw(); | |
227 | ||
228 | // Category values: | |
0214010c | 229 | // NB: Order must match _S_facet_categories definition in locale.cc |
725dc051 | 230 | static const category none = 0; |
0a31609b BK |
231 | static const category ctype = 1 << 0; |
232 | static const category numeric = 1 << 1; | |
233 | static const category collate = 1 << 2; | |
234 | static const category time = 1 << 3; | |
235 | static const category monetary = 1 << 4; | |
236 | static const category messages = 1 << 5; | |
725dc051 BK |
237 | static const category all = (collate | ctype | monetary | |
238 | numeric | time | messages); | |
239 | ||
240 | // Construct/copy/destroy: | |
725dc051 BK |
241 | locale() throw(); |
242 | ||
725dc051 BK |
243 | locale(const locale& __other) throw(); |
244 | ||
245 | explicit | |
246 | locale(const char* __std_name); | |
247 | ||
0214010c | 248 | locale(const locale& __base, const char* __s, category __cat); |
725dc051 | 249 | |
0214010c | 250 | locale(const locale& __base, const locale& __add, category __cat); |
725dc051 BK |
251 | |
252 | template<typename _Facet> | |
253 | locale(const locale& __other, _Facet* __f); | |
254 | ||
725dc051 BK |
255 | ~locale() throw(); |
256 | ||
257 | const locale& | |
258 | operator=(const locale& __other) throw(); | |
259 | ||
260 | template<typename _Facet> | |
261 | locale | |
262 | combine(const locale& __other); | |
263 | ||
264 | // Locale operations: | |
265 | string | |
266 | name() const; | |
267 | ||
268 | bool | |
269 | operator==(const locale& __other) const throw (); | |
270 | ||
271 | inline bool | |
272 | operator!=(const locale& __other) const throw () | |
d358ecd0 | 273 | { return !(this->operator==(__other)); } |
725dc051 BK |
274 | |
275 | template<typename _Char, typename _Traits, typename _Alloc> | |
276 | bool | |
277 | operator()(const basic_string<_Char, _Traits, _Alloc>& __s1, | |
278 | const basic_string<_Char, _Traits, _Alloc>& __s2) const; | |
279 | ||
280 | // Global locale objects: | |
281 | static locale | |
282 | global(const locale&); | |
283 | ||
284 | static const locale& | |
285 | classic(); | |
286 | ||
287 | private: | |
288 | // The (shared) implementation | |
289 | _Impl* _M_impl; | |
290 | ||
291 | // The "C" reference locale | |
292 | static _Impl* _S_classic; | |
293 | ||
294 | // Current global reference locale | |
295 | static _Impl* _S_global; | |
296 | ||
0214010c BK |
297 | static const size_t _S_num_categories = _Count_ones<all>::_M_count; |
298 | static const size_t _S_num_facets = _GLIBCPP_NUM_FACETS; | |
725dc051 BK |
299 | |
300 | explicit | |
301 | locale(_Impl*) throw(); | |
302 | ||
303 | static inline void | |
304 | _S_initialize() | |
305 | { if (!_S_classic) classic(); } | |
306 | ||
0214010c BK |
307 | static category |
308 | _S_normalize_category(category); | |
309 | ||
310 | void | |
311 | _M_coalesce(const locale& __base, const locale& __add, category __cat); | |
725dc051 BK |
312 | }; |
313 | ||
314 | ||
315 | // locale implementation object | |
316 | class locale::_Impl | |
317 | { | |
318 | public: | |
319 | // Types. | |
0214010c | 320 | typedef vector<facet*, allocator<facet*> > __vec_facet; |
725dc051 BK |
321 | |
322 | // Friends. | |
323 | friend class locale; | |
324 | friend class locale::facet; | |
325 | ||
326 | template<typename _Facet> | |
327 | friend const _Facet& | |
328 | use_facet(const locale&); | |
329 | ||
330 | template<typename _Facet> | |
331 | friend bool | |
332 | has_facet(const locale&) throw(); | |
333 | ||
e63a5d07 | 334 | private: |
725dc051 BK |
335 | // Data Members. |
336 | size_t _M_references; | |
337 | __vec_facet* _M_facets; | |
0214010c BK |
338 | string _M_names[_S_num_categories]; |
339 | __c_locale _M_c_locale; | |
725dc051 | 340 | static const locale::id* const _S_id_ctype[]; |
725dc051 | 341 | static const locale::id* const _S_id_numeric[]; |
0a31609b | 342 | static const locale::id* const _S_id_collate[]; |
725dc051 | 343 | static const locale::id* const _S_id_time[]; |
0a31609b | 344 | static const locale::id* const _S_id_monetary[]; |
725dc051 BK |
345 | static const locale::id* const _S_id_messages[]; |
346 | static const locale::id* const* const _S_facet_categories[]; | |
347 | ||
348 | inline void | |
349 | _M_add_reference() throw() | |
350 | { ++_M_references; } // XXX MT | |
351 | ||
352 | inline void | |
353 | _M_remove_reference() throw() | |
354 | { | |
355 | if (_M_references-- == 0) // XXX MT | |
356 | { | |
0214010c BK |
357 | try |
358 | { delete this; } | |
359 | catch(...) | |
360 | { } | |
725dc051 BK |
361 | } |
362 | } | |
363 | ||
d358ecd0 | 364 | _Impl(const _Impl&, size_t); |
0214010c | 365 | _Impl(string __name, size_t); |
725dc051 BK |
366 | ~_Impl() throw(); |
367 | ||
0214010c BK |
368 | bool |
369 | _M_check_same_name() | |
370 | { | |
371 | bool __ret = true; | |
372 | for (size_t i = 0; i < _S_num_categories - 1; ++i) | |
373 | __ret &= _M_names[i] == _M_names[i + 1]; | |
374 | return __ret; | |
375 | } | |
725dc051 BK |
376 | void |
377 | _M_replace_categories(const _Impl*, category); | |
378 | ||
379 | void | |
380 | _M_replace_category(const _Impl*, const locale::id* const*); | |
381 | ||
382 | void | |
383 | _M_replace_facet(const _Impl*, const locale::id*); | |
384 | ||
385 | void | |
386 | _M_install_facet(const locale::id*, facet*); | |
387 | ||
388 | template<typename _Facet> | |
389 | inline void | |
0214010c | 390 | _M_init_facet(_Facet* __facet) |
725dc051 | 391 | { _M_install_facet(&_Facet::id, __facet); } |
725dc051 BK |
392 | }; |
393 | ||
725dc051 BK |
394 | template<typename _Facet> |
395 | locale::locale(const locale& __other, _Facet* __f) | |
396 | { | |
397 | _M_impl = new _Impl(*__other._M_impl, 1); | |
398 | _M_impl->_M_install_facet(&_Facet::id, __f); | |
0214010c BK |
399 | for (int __i = 0; __i < _S_num_categories; ++__i) |
400 | _M_impl->_M_names[__i] = "*"; | |
725dc051 BK |
401 | } |
402 | ||
725dc051 BK |
403 | // 22.1.1.1.2 Class locale::facet |
404 | class locale::facet | |
405 | { | |
406 | friend class locale; | |
407 | friend class locale::_Impl; | |
408 | ||
409 | protected: | |
410 | explicit | |
411 | facet(size_t __refs = 0) throw(); | |
412 | ||
413 | virtual | |
414 | ~facet() { }; | |
415 | ||
0214010c BK |
416 | static void |
417 | _S_create_c_locale(__c_locale& __cloc, const char* __s); | |
418 | ||
419 | static void | |
420 | _S_destroy_c_locale(__c_locale& __cloc); | |
421 | ||
725dc051 BK |
422 | private: |
423 | size_t _M_references; | |
424 | ||
425 | void | |
426 | _M_add_reference() throw(); | |
427 | ||
428 | void | |
429 | _M_remove_reference() throw(); | |
430 | ||
431 | facet(const facet&); // not defined | |
432 | ||
433 | void | |
434 | operator=(const facet&); // not defined | |
435 | }; | |
436 | ||
437 | ||
438 | // 22.1.1.1.3 Class locale::id | |
439 | class locale::id | |
440 | { | |
0214010c | 441 | private: |
725dc051 BK |
442 | friend class locale; |
443 | friend class locale::_Impl; | |
444 | template<typename _Facet> | |
445 | friend const _Facet& | |
446 | use_facet(const locale&); | |
447 | template<typename _Facet> | |
448 | friend bool | |
449 | has_facet(const locale&) throw (); | |
0214010c | 450 | |
725dc051 BK |
451 | // NB: There is no accessor for _M_index because it may be used |
452 | // before the constructor is run; the effect of calling a member | |
453 | // function (even an inline) would be undefined. | |
454 | mutable size_t _M_index; | |
455 | ||
456 | // Last id number assigned | |
457 | static size_t _S_highwater; | |
458 | ||
459 | void | |
460 | operator=(const id&); // not defined | |
461 | ||
462 | id(const id&); // not defined | |
0214010c BK |
463 | |
464 | public: | |
465 | // NB: This class is always a static data member, and thus can be | |
466 | // counted on to be zero-initialized. | |
467 | // XXX id() : _M_index(0) { } | |
468 | id() { } | |
725dc051 BK |
469 | }; |
470 | ||
471 | template<typename _Facet> | |
472 | const _Facet& | |
473 | use_facet(const locale& __loc); | |
474 | ||
475 | template<typename _Facet> | |
476 | bool | |
477 | has_facet(const locale& __loc) throw(); | |
725dc051 BK |
478 | } // namespace std |
479 | ||
480 | #endif /* _CPP_BITS_LOCCORE_H */ | |
481 | ||
482 | // Local Variables: | |
483 | // mode:c++ | |
484 | // End: | |
485 |