Facets.h
1/*
2 * Copyright (C) 2004-2013 Marc Boris Duerner
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * As a special exception, you may use this file as part of a free
10 * software library without restriction. Specifically, if other files
11 * instantiate templates or use macros or inline functions from this
12 * file, or you compile this file and link it with other files to
13 * produce an executable, this file does not by itself cause the
14 * resulting executable to be covered by the GNU General Public
15 * License. This exception does not however invalidate any other
16 * reasons why the executable file might be covered by the GNU Library
17 * General Public License.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#ifndef PT_FACETS_H
30#define PT_FACETS_H
31
32#include <Pt/Api.h>
33#include <Pt/String.h>
34#include <Pt/Locale.h>
35#include <iostream>
36#include <iterator>
37
38namespace std {
39
40// gcc 3.4.x requires a __numpunct_cache
41template <typename T>
42struct __numpunct_cache;
43
44
45template <>
46class PT_API numpunct<Pt::Char> : public locale::facet {
47 public:
48 typedef Pt::Char char_type;
49 typedef basic_string<Pt::Char> string_type;
50
51 // __GLIBCXX__ <= 20051201 && __GLIBCXX__ >= 20040419
52 typedef __numpunct_cache<Pt::Char> __cache_type;
53
54 static locale::id id;
55
56 // NOTE: rouguwave solaris
57 virtual locale::id& __get_id (void) const { return id; }
58
59 public:
60 explicit numpunct(std::size_t refs = 0);
61
62 char_type decimal_point() const;
63
64 char_type thousands_sep() const;
65
66 string grouping() const;
67
68 string_type truename() const;
69
70 string_type falsename() const;
71
72 protected:
73 virtual char_type do_decimal_point() const;
74
75 virtual char_type do_thousands_sep() const;
76
77 virtual string do_grouping() const;
78
79 virtual string_type do_truename() const;
80
81 virtual string_type do_falsename() const;
82};
83
84
85template <>
86class PT_API num_put< Pt::Char,
87 ostreambuf_iterator<Pt::Char> > : public locale::facet
88{
89 public:
90 typedef Pt::Char char_type;
91 typedef ostreambuf_iterator<Pt::Char> iter_type;
92 typedef basic_ostream<Pt::Char> stream_type;
93
94 explicit num_put(std::size_t refs = 0)
95 : locale::facet(refs)
96 { }
97
98 iter_type put(iter_type s, stream_type& f, char_type fill, bool val) const
99 { return this->do_put( s, f, fill, val ); }
100
101 // NOTE: rouguwave solaris
102 iter_type put(iter_type s, stream_type& f, char_type fill, int val) const
103 { return this->do_put( s, f, fill, long(val) ); }
104
105 // NOTE: rouguwave solaris
106 iter_type put(iter_type s, stream_type& f, char_type fill, unsigned val) const
107 { return this->do_put( s, f, fill, (unsigned long)(val) ); }
108
109 iter_type put(iter_type s, stream_type& f, char_type fill, long val) const
110 { return this->do_put( s, f, fill, val ); }
111
112 iter_type put(iter_type s, stream_type& f, char_type fill, unsigned long val) const
113 { return this->do_put( s, f, fill, val ); }
114
115 iter_type put(iter_type s, stream_type& f, char_type fill, long long val) const
116 { return this->do_put( s, f, fill, val ); }
117
118 iter_type put(iter_type s, stream_type& f, char_type fill, unsigned long long val) const
119 { return this->do_put( s, f, fill, val ); }
120
121 iter_type put(iter_type s, stream_type& f, char_type fill, double val) const
122 { return this->do_put( s, f, fill, val ); }
123
124 iter_type put(iter_type s, stream_type& f, char_type fill, long double val) const
125 { return this->do_put( s, f, fill, val ); }
126
127 iter_type put(iter_type s, stream_type& f, char_type fill, const void* val) const
128 { return this->do_put( s, f, fill, val ); }
129
130 static locale::id id;
131
132 // NOTE: rouguwave solaris
133 virtual locale::id& __get_id (void) const
134 { return id; }
135
136 protected:
137 virtual iter_type do_put(iter_type s, stream_type& f, char_type fill, bool val) const;
138
139 virtual iter_type do_put(iter_type s, stream_type& f, char_type fill, long val) const;
140
141 virtual iter_type do_put(iter_type s, stream_type& f, char_type fill, unsigned long val) const;
142
143 virtual iter_type do_put(iter_type s, stream_type& f, char_type fill, long long val) const;
144
145 virtual iter_type do_put(iter_type s, stream_type& f, char_type fill, unsigned long long val) const;
146
147 virtual iter_type do_put(iter_type s, stream_type& f, char_type fill, double val) const;
148
149 virtual iter_type do_put(iter_type s, stream_type& f, char_type fill, long double val) const;
150
151 virtual iter_type do_put(iter_type s, stream_type& f, char_type fill, const void*) const;
152};
153
154
155template<>
156class PT_API num_get< Pt::Char,
157 istreambuf_iterator<Pt::Char> > : public locale::facet
158{
159 public:
160 typedef Pt::Char char_type;
161 typedef istreambuf_iterator<Pt::Char> iter_type;
162 typedef basic_istream<Pt::Char> stream_type;
163
164 explicit num_get(std::size_t refs = 0)
165 : locale::facet(refs)
166 {}
167
168 iter_type get(iter_type it, iter_type end, stream_type& f, ios_base::iostate& s, bool& val) const
169 { return this->do_get(it, end, f, s, val); }
170
171 iter_type get(iter_type it, iter_type end, stream_type& f, ios_base::iostate& s, long& val) const
172 { return this->do_get(it, end, f, s, val); }
173
174 iter_type get(iter_type it, iter_type end, stream_type& f, ios_base::iostate& s, long long int& val) const
175 { return this->do_get(it, end, f, s, val); }
176
177 iter_type get(iter_type it, iter_type end, stream_type& f, ios_base::iostate& s, unsigned short& val) const
178 { return this->do_get(it, end, f, s, val); }
179
180 iter_type get(iter_type it, iter_type end, stream_type& f, ios_base::iostate& s, unsigned int& val) const
181 { return this->do_get(it, end, f, s, val); }
182
183 iter_type get(iter_type it, iter_type end, stream_type& f, ios_base::iostate& s, unsigned long& val) const
184 { return this->do_get(it, end, f, s, val); }
185
186 iter_type get(iter_type it, iter_type end, stream_type& f, ios_base::iostate& s, unsigned long long & val) const
187 { return this->do_get(it, end, f, s, val); }
188
189 iter_type get(iter_type it, iter_type end, stream_type& f, ios_base::iostate& s, float& val) const
190 { return this->do_get(it, end, f, s, val); }
191
192 iter_type get(iter_type it, iter_type end, stream_type& f, ios_base::iostate& s, double& val) const
193 { return this->do_get(it, end, f, s, val); }
194
195 iter_type get(iter_type it, iter_type end, stream_type& f, ios_base::iostate& s, long double& val) const
196 { return this->do_get(it, end, f, s, val); }
197
198 iter_type get(iter_type it, iter_type end, stream_type& f, ios_base::iostate& s, void*& val) const
199 { return this->do_get(it, end, f, s, val); }
200
201 static locale::id id;
202
203 // NOTE: rouguwave solaris
204 virtual locale::id& __get_id (void) const
205 { return id; }
206
207 protected:
208 virtual iter_type do_get(iter_type, iter_type, stream_type&, ios_base::iostate&, bool&) const;
209
210 virtual iter_type do_get(iter_type, iter_type, stream_type&, ios_base::iostate&, long&) const;
211
212 virtual iter_type do_get(iter_type, iter_type, stream_type&, ios_base::iostate&, long long&) const;
213
214 virtual iter_type do_get(iter_type, iter_type, stream_type&, ios_base::iostate&, unsigned short&) const;
215
216 virtual iter_type do_get(iter_type, iter_type, stream_type&, ios_base::iostate&, unsigned int&) const;
217
218 virtual iter_type do_get(iter_type, iter_type, stream_type&, ios_base::iostate&, unsigned long&) const;
219
220 virtual iter_type do_get(iter_type, iter_type, stream_type&, ios_base::iostate&, unsigned long long&) const;
221
222 virtual iter_type do_get(iter_type, iter_type, stream_type&, ios_base::iostate&, float&) const;
223
224 virtual iter_type do_get(iter_type, iter_type, stream_type&, ios_base::iostate&, double&) const;
225
226 virtual iter_type do_get(iter_type, iter_type, stream_type&, ios_base::iostate&, long double&) const;
227
228 virtual iter_type do_get(iter_type, iter_type, stream_type&, ios_base::iostate&, void*&) const;
229};
230
231#if (defined _MSC_VER || defined __QNX__ || defined __xlC__)
232 template <>
233 class PT_API ctype< Pt::Char > : public ctype_base {
234#else
235 template <>
236 class PT_API ctype<Pt::Char> : public ctype_base, public locale::facet {
237#endif
238
239 public:
240 typedef ctype_base::mask mask;
241
242 static locale::id id;
243
244 // NOTE: rouguwave solaris
245 virtual locale::id& __get_id (void) const { return id; }
246
247 public:
248 explicit ctype(std::size_t refs = 0);
249
250 bool is(mask m, Pt::Char c) const
251 { return this->do_is(m, c); }
252
253 const Pt::Char* is(const Pt::Char *lo, const Pt::Char *hi, mask *vec) const
254 { return this->do_is(lo, hi, vec); }
255
256 const Pt::Char* scan_is(mask m, const Pt::Char* lo, const Pt::Char* hi) const
257 { return this->do_scan_is(m, lo, hi); }
258
259 const Pt::Char* scan_not(mask m, const Pt::Char* lo, const Pt::Char* hi) const
260 { return this->do_scan_not(m, lo, hi); }
261
262 Pt::Char toupper(Pt::Char c) const
263 { return this->do_toupper(c); }
264
265 const Pt::Char* toupper(Pt::Char *lo, const Pt::Char* hi) const
266 { return this->do_toupper(lo, hi); }
267
268 Pt::Char tolower(Pt::Char c) const
269 { return this->do_tolower(c); }
270
271 const Pt::Char* tolower(Pt::Char* lo, const Pt::Char* hi) const
272 { return this->do_tolower(lo, hi); }
273
274 Pt::Char widen(char c) const
275 { return this->do_widen(c); }
276
277 const char* widen(const char* lo, const char* hi, Pt::Char* to) const
278 { return this->do_widen(lo, hi, to); }
279
280 char narrow(Pt::Char c, char dfault) const
281 { return this->do_narrow(c, dfault); }
282
283 const Pt::Char* narrow(const Pt::Char* lo, const Pt::Char* hi,
284 char dfault, char *to) const
285 { return this->do_narrow(lo, hi, dfault, to); }
286
287 protected:
288 virtual bool do_is(mask m, Pt::Char c) const;
289
290 virtual const Pt::Char* do_is(const Pt::Char* lo, const Pt::Char* hi,
291 mask* vec) const;
292
293 virtual const Pt::Char* do_scan_is(mask m, const Pt::Char* lo,
294 const Pt::Char* hi) const;
295
296 virtual const Pt::Char* do_scan_not(mask m, const Pt::Char* lo,
297 const Pt::Char* hi) const;
298
299 virtual Pt::Char do_toupper(Pt::Char) const;
300
301 virtual const Pt::Char* do_toupper(Pt::Char* lo, const Pt::Char* hi) const;
302
303 virtual Pt::Char do_tolower(Pt::Char) const;
304
305 virtual const Pt::Char* do_tolower(Pt::Char* lo, const Pt::Char* hi) const;
306
307 virtual Pt::Char do_widen(char) const;
308
309 virtual const char* do_widen(const char* lo, const char* hi,
310 Pt::Char* dest) const;
311
312 virtual char do_narrow(Pt::Char, char dfault) const;
313
314 virtual const Pt::Char* do_narrow(const Pt::Char* lo, const Pt::Char* hi,
315 char dfault, char* dest) const;
316};
317
318
319#if (defined _MSC_VER || defined __QNX__)
320 template<>
321 class PT_API codecvt<Pt::Char, char, Pt::MBState> : public codecvt_base {
322#else
323 template<>
324 class PT_API codecvt<Pt::Char, char, Pt::MBState> : public codecvt_base, public locale::facet {
325#endif
326
327 public:
328 static locale::id id;
329
330 // NOTE: rouguwave solaris
331 virtual locale::id& __get_id (void) const { return id; }
332
333 public:
334 explicit codecvt(std::size_t ref = 0);
335
336 codecvt_base::result out(Pt::MBState& state,
337 const Pt::Char* from,
338 const Pt::Char* from_end,
339 const Pt::Char*& from_next,
340 char* to,
341 char* to_end,
342 char*& to_next) const
343 { return this->do_out(state, from, from_end, from_next, to, to_end, to_next); }
344
345 codecvt_base::result unshift(Pt::MBState& state,
346 char* to,
347 char* to_end,
348 char*& to_next) const
349 { return this->do_unshift(state, to, to_end, to_next); }
350
351 codecvt_base::result in(Pt::MBState& state,
352 const char* from,
353 const char* from_end,
354 const char*& from_next,
355 Pt::Char* to,
356 Pt::Char* to_end,
357 Pt::Char*& to_next) const
358 { return this->do_in(state, from, from_end, from_next, to, to_end, to_next); }
359
360 int encoding() const
361 { return this->do_encoding(); }
362
363 bool always_noconv() const
364 { return this->do_always_noconv(); }
365
366 int length(Pt::MBState& state, const char* from,
367 const char* end, std::size_t max) const
368 { return this->do_length(state, from, end, max); }
369
370 int max_length() const
371 { return this->do_max_length(); }
372
373 protected:
374 virtual codecvt_base::result do_out(Pt::MBState& state,
375 const Pt::Char* from,
376 const Pt::Char* from_end,
377 const Pt::Char*& from_next,
378 char* to,
379 char* to_end,
380 char*& to_next) const = 0;
381
382 virtual codecvt_base::result do_unshift(Pt::MBState& state,
383 char* to,
384 char* to_end,
385 char*& to_next) const = 0;
386
387 virtual codecvt_base::result do_in(Pt::MBState& state,
388 const char* from,
389 const char* from_end,
390 const char*& from_next,
391 Pt::Char* to,
392 Pt::Char* to_end,
393 Pt::Char*& to_next) const = 0;
394
395 virtual int do_encoding() const throw() = 0;
396
397 virtual bool do_always_noconv() const throw() = 0;
398
399 virtual int do_length(Pt::MBState&,
400 const char* from,
401 const char* end,
402 std::size_t max) const = 0;
403
404 virtual int do_max_length() const throw() = 0;
405};
406
407#if (defined _MSC_VER || defined __QNX__)
408 template<>
409 class PT_API codecvt<char, char, Pt::MBState> : public codecvt_base {
410#else
411 template<>
412 class PT_API codecvt<char, char, Pt::MBState> : public codecvt_base, public locale::facet {
413#endif
414
415 public:
416 static locale::id id;
417
418 // NOTE: rouguwave solaris
419 virtual locale::id& __get_id (void) const { return id; }
420
421 public:
422 explicit codecvt(std::size_t ref = 0);
423
424 codecvt_base::result out(Pt::MBState& state,
425 const char* from,
426 const char* from_end,
427 const char*& from_next,
428 char* to,
429 char* to_end,
430 char*& to_next) const
431 { return this->do_out(state, from, from_end, from_next, to, to_end, to_next); }
432
433 codecvt_base::result unshift(Pt::MBState& state,
434 char* to,
435 char* to_end,
436 char*& to_next) const
437 { return this->do_unshift(state, to, to_end, to_next); }
438
439 codecvt_base::result in(Pt::MBState& state,
440 const char* from,
441 const char* from_end,
442 const char*& from_next,
443 char* to, char* to_end,
444 char*& to_next) const
445 { return this->do_in(state, from, from_end, from_next, to, to_end, to_next); }
446
447 int encoding() const
448 { return this->do_encoding(); }
449
450 bool always_noconv() const
451 { return this->do_always_noconv(); }
452
453 int length(Pt::MBState& state, const char* from,
454 const char* end, std::size_t max) const
455 { return this->do_length(state, from, end, max); }
456
457 int max_length() const
458 { return this->do_max_length(); }
459
460 protected:
461 virtual codecvt_base::result do_out(Pt::MBState& state,
462 const char* from,
463 const char* from_end,
464 const char*& from_next,
465 char* to,
466 char* to_end,
467 char*& to_next) const = 0;
468
469 virtual codecvt_base::result do_unshift(Pt::MBState& state,
470 char* to,
471 char* to_end,
472 char*& to_next) const = 0;
473
474 virtual codecvt_base::result do_in(Pt::MBState& state,
475 const char* from,
476 const char* from_end,
477 const char*& from_next,
478 char* to,
479 char* to_end,
480 char*& to_next) const = 0;
481
482 virtual int do_encoding() const throw() = 0;
483
484 virtual bool do_always_noconv() const throw() = 0;
485
486 virtual int do_length(Pt::MBState&,
487 const char* from,
488 const char* end,
489 std::size_t max) const = 0;
490
491 virtual int do_max_length() const throw() = 0;
492};
493
494} // namespace
495
496namespace Pt {
497
498PT_API const std::ctype<Pt::Char>& useCType(const std::locale& loc);
499
500PT_API const std::numpunct<Pt::Char>& useNumPunct(const std::locale& loc);
501
502PT_API const std::num_get<Pt::Char>& useNumGet(const std::locale& loc);
503
504PT_API const std::num_put<Pt::Char>& useNumPut(const std::locale& loc);
505
506} // namespace Pt
507
508namespace std {
509
510template<>
511inline bool has_facet< ctype<Pt::Char> >(const locale& /*loc*/) throw()
512{
513 return true;
514}
515
516template<>
517inline const ctype<Pt::Char>& use_facet(const locale& loc)
518{
519 return Pt::useCType(loc);
520}
521
522
523template<>
524inline bool has_facet< numpunct<Pt::Char> >(const locale& /*loc*/) throw()
525{
526 return true;
527}
528
529template<>
530inline const numpunct<Pt::Char>& use_facet(const locale& loc)
531{
532 return Pt::useNumPunct(loc);
533}
534
535
536template<>
537inline bool has_facet< num_get<Pt::Char> >(const locale& /*loc*/) throw()
538{
539 return true;
540}
541
542template<>
543inline const num_get<Pt::Char>& use_facet(const locale& loc)
544{
545 return Pt::useNumGet(loc);
546}
547
548
549template<>
550inline bool has_facet< num_put<Pt::Char> >(const locale& /*loc*/) throw()
551{
552 return true;
553}
554
555template<>
556inline const num_put<Pt::Char>& use_facet(const locale& loc)
557{
558 return Pt::useNumPut(loc);
559}
560
561} // namespace
562
563#endif
R narrow(T from)
Checked numeric conversion.
Definition Convert.h:112
Char toupper(const Char &ch)
Convert a character to upper case.
Char tolower(const Char &ch)
Convert a character to lower case.