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 #ifndef PT_FACETS_H
29 #define PT_FACETS_H
30 
31 #include <Pt/Api.h>
32 #include <Pt/String.h>
33 #include <Pt/Locale.h>
34 #include <iostream>
35 #include <iterator>
36 
37 namespace std {
38 
39 // gcc 3.4.x requires a __numpunct_cache
40 template <typename T>
41 struct __numpunct_cache;
42 
43 
44 template <>
45 class PT_API numpunct<Pt::Char> : public locale::facet {
46  public:
47  typedef Pt::Char char_type;
48  typedef basic_string<Pt::Char> string_type;
49 
50  // __GLIBCXX__ <= 20051201 && __GLIBCXX__ >= 20040419
51  typedef __numpunct_cache<Pt::Char> __cache_type;
52 
53  static locale::id id;
54 
55  // NOTE: rouguwave solaris
56  virtual locale::id& __get_id (void) const { return id; }
57 
58  public:
59  explicit numpunct(std::size_t refs = 0);
60 
61  virtual ~numpunct();
62 
63  char_type decimal_point() const;
64 
65  char_type thousands_sep() const;
66 
67  string grouping() const;
68 
69  string_type truename() const;
70 
71  string_type falsename() const;
72 
73  protected:
74  virtual char_type do_decimal_point() const;
75 
76  virtual char_type do_thousands_sep() const;
77 
78  virtual string do_grouping() const;
79 
80  virtual string_type do_truename() const;
81 
82  virtual string_type do_falsename() const;
83 };
84 
85 
86 template <>
87 class PT_API num_put< Pt::Char,
88  ostreambuf_iterator<Pt::Char> > : public locale::facet
89 {
90  public:
91  typedef Pt::Char char_type;
92  typedef ostreambuf_iterator<Pt::Char> iter_type;
93 
94  explicit num_put(std::size_t refs = 0)
95  : locale::facet(refs)
96  { }
97 
98  iter_type put(iter_type s, ios_base& 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, ios_base& 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, ios_base& 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, ios_base& f, char_type fill, long val) const
110  { return this->do_put( s, f, fill, val ); }
111 
112  iter_type put(iter_type s, ios_base& 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, ios_base& 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, ios_base& 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, ios_base& f, char_type fill, double val) const
122  { return this->do_put( s, f, fill, val ); }
123 
124  iter_type put(iter_type s, ios_base& 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, ios_base& 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 ~num_put()
138  {}
139 
140  virtual iter_type do_put(iter_type s, ios_base& f, char_type fill, bool val) const;
141 
142  virtual iter_type do_put(iter_type s, ios_base& f, char_type fill, long val) const;
143 
144  virtual iter_type do_put(iter_type s, ios_base& f, char_type fill, unsigned long val) const;
145 
146  virtual iter_type do_put(iter_type s, ios_base& f, char_type fill, long long val) const;
147 
148  virtual iter_type do_put(iter_type s, ios_base& f, char_type fill, unsigned long long val) const;
149 
150  virtual iter_type do_put(iter_type s, ios_base& f, char_type fill, double val) const;
151 
152  virtual iter_type do_put(iter_type s, ios_base& f, char_type fill, long double val) const;
153 
154  virtual iter_type do_put(iter_type s, ios_base& f, char_type fill, const void*) const;
155 };
156 
157 
158 template<>
159 class PT_API num_get< Pt::Char,
160  istreambuf_iterator<Pt::Char> > : public locale::facet
161 {
162  public:
163  typedef Pt::Char char_type;
164  typedef istreambuf_iterator<Pt::Char> iter_type;
165 
166  explicit num_get(std::size_t refs = 0)
167  : locale::facet(refs)
168  {}
169 
170  iter_type get(iter_type it, iter_type end, ios_base& f, ios_base::iostate& s, bool& val) const
171  { return this->do_get(it, end, f, s, val); }
172 
173  iter_type get(iter_type it, iter_type end, ios_base& f, ios_base::iostate& s, long& val) const
174  { return this->do_get(it, end, f, s, val); }
175 
176  iter_type get(iter_type it, iter_type end, ios_base& f, ios_base::iostate& s, long long int& val) const
177  { return this->do_get(it, end, f, s, val); }
178 
179  iter_type get(iter_type it, iter_type end, ios_base& f, ios_base::iostate& s, unsigned short& val) const
180  { return this->do_get(it, end, f, s, val); }
181 
182  iter_type get(iter_type it, iter_type end, ios_base& f, ios_base::iostate& s, unsigned int& val) const
183  { return this->do_get(it, end, f, s, val); }
184 
185  iter_type get(iter_type it, iter_type end, ios_base& f, ios_base::iostate& s, unsigned long& val) const
186  { return this->do_get(it, end, f, s, val); }
187 
188  iter_type get(iter_type it, iter_type end, ios_base& f, ios_base::iostate& s, unsigned long long & val) const
189  { return this->do_get(it, end, f, s, val); }
190 
191  iter_type get(iter_type it, iter_type end, ios_base& f, ios_base::iostate& s, float& val) const
192  { return this->do_get(it, end, f, s, val); }
193 
194  iter_type get(iter_type it, iter_type end, ios_base& f, ios_base::iostate& s, double& val) const
195  { return this->do_get(it, end, f, s, val); }
196 
197  iter_type get(iter_type it, iter_type end, ios_base& f, ios_base::iostate& s, long double& val) const
198  { return this->do_get(it, end, f, s, val); }
199 
200  iter_type get(iter_type it, iter_type end, ios_base& f, ios_base::iostate& s, void*& val) const
201  { return this->do_get(it, end, f, s, val); }
202 
203  static locale::id id;
204 
205  // NOTE: rouguwave solaris
206  virtual locale::id& __get_id (void) const
207  { return id; }
208 
209  protected:
210  virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
211 
212  virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
213 
214  virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long long&) const;
215 
216  virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, unsigned short&) const;
217 
218  virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, unsigned int&) const;
219 
220  virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, unsigned long&) const;
221 
222  virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, unsigned long long&) const;
223 
224  virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, float&) const;
225 
226  virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, double&) const;
227 
228  virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long double&) const;
229 
230  virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, void*&) const;
231 };
232 
233 
234 #if (defined _MSC_VER || defined __QNX__ || defined __xlC__)
235  template <>
236  class PT_API ctype< Pt::Char > : public ctype_base {
237 #else
238  template <>
239  class PT_API ctype<Pt::Char> : public ctype_base, public locale::facet {
240 #endif
241 
242  public:
243  typedef ctype_base::mask mask;
244 
245  static locale::id id;
246 
247  // NOTE: rouguwave solaris
248  virtual locale::id& __get_id (void) const { return id; }
249 
250  public:
251  explicit ctype(std::size_t refs = 0);
252 
253  virtual ~ctype();
254 
255  bool is(mask m, Pt::Char c) const
256  { return this->do_is(m, c); }
257 
258  const Pt::Char* is(const Pt::Char *lo, const Pt::Char *hi, mask *vec) const
259  { return this->do_is(lo, hi, vec); }
260 
261  const Pt::Char* scan_is(mask m, const Pt::Char* lo, const Pt::Char* hi) const
262  { return this->do_scan_is(m, lo, hi); }
263 
264  const Pt::Char* scan_not(mask m, const Pt::Char* lo, const Pt::Char* hi) const
265  { return this->do_scan_not(m, lo, hi); }
266 
267  Pt::Char toupper(Pt::Char c) const
268  { return this->do_toupper(c); }
269 
270  const Pt::Char* toupper(Pt::Char *lo, const Pt::Char* hi) const
271  { return this->do_toupper(lo, hi); }
272 
273  Pt::Char tolower(Pt::Char c) const
274  { return this->do_tolower(c); }
275 
276  const Pt::Char* tolower(Pt::Char* lo, const Pt::Char* hi) const
277  { return this->do_tolower(lo, hi); }
278 
279  Pt::Char widen(char c) const
280  { return this->do_widen(c); }
281 
282  const char* widen(const char* lo, const char* hi, Pt::Char* to) const
283  { return this->do_widen(lo, hi, to); }
284 
285  char narrow(Pt::Char c, char dfault) const
286  { return this->do_narrow(c, dfault); }
287 
288  const Pt::Char* narrow(const Pt::Char* lo, const Pt::Char* hi,
289  char dfault, char *to) const
290  { return this->do_narrow(lo, hi, dfault, to); }
291 
292  protected:
293  virtual bool do_is(mask m, Pt::Char c) const;
294 
295  virtual const Pt::Char* do_is(const Pt::Char* lo, const Pt::Char* hi,
296  mask* vec) const;
297 
298  virtual const Pt::Char* do_scan_is(mask m, const Pt::Char* lo,
299  const Pt::Char* hi) const;
300 
301  virtual const Pt::Char* do_scan_not(mask m, const Pt::Char* lo,
302  const Pt::Char* hi) const;
303 
304  virtual Pt::Char do_toupper(Pt::Char) const;
305 
306  virtual const Pt::Char* do_toupper(Pt::Char* lo, const Pt::Char* hi) const;
307 
308  virtual Pt::Char do_tolower(Pt::Char) const;
309 
310  virtual const Pt::Char* do_tolower(Pt::Char* lo, const Pt::Char* hi) const;
311 
312  virtual Pt::Char do_widen(char) const;
313 
314  virtual const char* do_widen(const char* lo, const char* hi,
315  Pt::Char* dest) const;
316 
317  virtual char do_narrow(Pt::Char, char dfault) const;
318 
319  virtual const Pt::Char* do_narrow(const Pt::Char* lo, const Pt::Char* hi,
320  char dfault, char* dest) const;
321 };
322 
323 
324 #if (defined _MSC_VER || defined __QNX__)
325  template<>
326  class PT_API codecvt<Pt::Char, char, Pt::MBState> : public codecvt_base {
327 #else
328  template<>
329  class PT_API codecvt<Pt::Char, char, Pt::MBState> : public codecvt_base, public locale::facet {
330 #endif
331 
332  public:
333  static locale::id id;
334 
335  // NOTE: rouguwave solaris
336  virtual locale::id& __get_id (void) const { return id; }
337 
338  public:
339  explicit codecvt(std::size_t ref = 0);
340 
341  virtual ~codecvt();
342 
343  codecvt_base::result out(Pt::MBState& state,
344  const Pt::Char* from,
345  const Pt::Char* from_end,
346  const Pt::Char*& from_next,
347  char* to,
348  char* to_end,
349  char*& to_next) const
350  { return this->do_out(state, from, from_end, from_next, to, to_end, to_next); }
351 
352  codecvt_base::result unshift(Pt::MBState& state,
353  char* to,
354  char* to_end,
355  char*& to_next) const
356  { return this->do_unshift(state, to, to_end, to_next); }
357 
358  codecvt_base::result in(Pt::MBState& state,
359  const char* from,
360  const char* from_end,
361  const char*& from_next,
362  Pt::Char* to,
363  Pt::Char* to_end,
364  Pt::Char*& to_next) const
365  { return this->do_in(state, from, from_end, from_next, to, to_end, to_next); }
366 
367  int encoding() const
368  { return this->do_encoding(); }
369 
370  bool always_noconv() const
371  { return this->do_always_noconv(); }
372 
373  int length(Pt::MBState& state, const char* from,
374  const char* end, std::size_t max) const
375  { return this->do_length(state, from, end, max); }
376 
377  int max_length() const
378  { return this->do_max_length(); }
379 
380  protected:
381  virtual codecvt_base::result do_out(Pt::MBState& state,
382  const Pt::Char* from,
383  const Pt::Char* from_end,
384  const Pt::Char*& from_next,
385  char* to,
386  char* to_end,
387  char*& to_next) const = 0;
388 
389  virtual codecvt_base::result do_unshift(Pt::MBState& state,
390  char* to,
391  char* to_end,
392  char*& to_next) const = 0;
393 
394  virtual codecvt_base::result do_in(Pt::MBState& state,
395  const char* from,
396  const char* from_end,
397  const char*& from_next,
398  Pt::Char* to,
399  Pt::Char* to_end,
400  Pt::Char*& to_next) const = 0;
401 
402  virtual int do_encoding() const throw() = 0;
403 
404  virtual bool do_always_noconv() const throw() = 0;
405 
406  virtual int do_length(Pt::MBState&,
407  const char* from,
408  const char* end,
409  std::size_t max) const = 0;
410 
411  virtual int do_max_length() const throw() = 0;
412 };
413 
414 #if (defined _MSC_VER || defined __QNX__)
415  template<>
416  class PT_API codecvt<char, char, Pt::MBState> : public codecvt_base {
417 #else
418  template<>
419  class PT_API codecvt<char, char, Pt::MBState> : public codecvt_base, public locale::facet {
420 #endif
421 
422  public:
423  static locale::id id;
424 
425  // NOTE: rouguwave solaris
426  virtual locale::id& __get_id (void) const { return id; }
427 
428  public:
429  explicit codecvt(std::size_t ref = 0);
430 
431  virtual ~codecvt();
432 
433  codecvt_base::result out(Pt::MBState& state,
434  const char* from,
435  const char* from_end,
436  const char*& from_next,
437  char* to,
438  char* to_end,
439  char*& to_next) const
440  { return this->do_out(state, from, from_end, from_next, to, to_end, to_next); }
441 
442  codecvt_base::result unshift(Pt::MBState& state,
443  char* to,
444  char* to_end,
445  char*& to_next) const
446  { return this->do_unshift(state, to, to_end, to_next); }
447 
448  codecvt_base::result in(Pt::MBState& state,
449  const char* from,
450  const char* from_end,
451  const char*& from_next,
452  char* to, char* to_end,
453  char*& to_next) const
454  { return this->do_in(state, from, from_end, from_next, to, to_end, to_next); }
455 
456  int encoding() const
457  { return this->do_encoding(); }
458 
459  bool always_noconv() const
460  { return this->do_always_noconv(); }
461 
462  int length(Pt::MBState& state, const char* from,
463  const char* end, std::size_t max) const
464  { return this->do_length(state, from, end, max); }
465 
466  int max_length() const
467  { return this->do_max_length(); }
468 
469  protected:
470  virtual codecvt_base::result do_out(Pt::MBState& state,
471  const char* from,
472  const char* from_end,
473  const char*& from_next,
474  char* to,
475  char* to_end,
476  char*& to_next) const = 0;
477 
478  virtual codecvt_base::result do_unshift(Pt::MBState& state,
479  char* to,
480  char* to_end,
481  char*& to_next) const = 0;
482 
483  virtual codecvt_base::result do_in(Pt::MBState& state,
484  const char* from,
485  const char* from_end,
486  const char*& from_next,
487  char* to,
488  char* to_end,
489  char*& to_next) const = 0;
490 
491  virtual int do_encoding() const throw() = 0;
492 
493  virtual bool do_always_noconv() const throw() = 0;
494 
495  virtual int do_length(Pt::MBState&,
496  const char* from,
497  const char* end,
498  std::size_t max) const = 0;
499 
500  virtual int do_max_length() const throw() = 0;
501 };
502 
503 } // namespace std
504 
505 
506 namespace Pt {
507 
508 static std::ios_base::Init pt_stream_init;
509 
510 static struct PT_API InitLocale
511 {
512  InitLocale()
513  {
514  std::locale::global( std::locale(std::locale(), new std::ctype<Pt::Char>) );
515  std::locale::global( std::locale(std::locale(), new std::numpunct<Pt::Char>) );
516  std::locale::global( std::locale(std::locale(), new std::num_get<Pt::Char>) );
517  std::locale::global( std::locale(std::locale(), new std::num_put<Pt::Char>) );
518 
519  }
520 } pt_init_locale;
521 
522 } // namespace Pt
523 
524 #endif
R narrow(T from)
Checked numeric conversion.
Definition: Convert.h:112
Unicode character type.
Definition: String.h:66