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 
38 namespace std {
39 
40 // gcc 3.4.x requires a __numpunct_cache
41 template <typename T>
42 struct __numpunct_cache;
43 
44 
45 template <>
46 class 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 
85 template <>
86 class 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 
155 template<>
156 class 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 
496 namespace Pt {
497 
498 PT_API const std::ctype<Pt::Char>& useCType(const std::locale& loc);
499 
500 PT_API const std::numpunct<Pt::Char>& useNumPunct(const std::locale& loc);
501 
502 PT_API const std::num_get<Pt::Char>& useNumGet(const std::locale& loc);
503 
504 PT_API const std::num_put<Pt::Char>& useNumPut(const std::locale& loc);
505 
506 } // namespace Pt
507 
508 namespace std {
509 
510 template<>
511 inline bool has_facet< ctype<Pt::Char> >(const locale& /*loc*/) throw()
512 {
513  return true;
514 }
515 
516 template<>
517 inline const ctype<Pt::Char>& use_facet(const locale& loc)
518 {
519  return Pt::useCType(loc);
520 }
521 
522 
523 template<>
524 inline bool has_facet< numpunct<Pt::Char> >(const locale& /*loc*/) throw()
525 {
526  return true;
527 }
528 
529 template<>
530 inline const numpunct<Pt::Char>& use_facet(const locale& loc)
531 {
532  return Pt::useNumPunct(loc);
533 }
534 
535 
536 template<>
537 inline bool has_facet< num_get<Pt::Char> >(const locale& /*loc*/) throw()
538 {
539  return true;
540 }
541 
542 template<>
543 inline const num_get<Pt::Char>& use_facet(const locale& loc)
544 {
545  return Pt::useNumGet(loc);
546 }
547 
548 
549 template<>
550 inline bool has_facet< num_put<Pt::Char> >(const locale& /*loc*/) throw()
551 {
552  return true;
553 }
554 
555 template<>
556 inline 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
Unicode character type.
Definition: String.h:66