Boost.Locale
formatting.hpp
1 //
2 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
3 //
4 // Distributed under the Boost Software License, Version 1.0.
5 // https://www.boost.org/LICENSE_1_0.txt
6 
7 #ifndef BOOST_LOCALE_FORMATTING_HPP_INCLUDED
8 #define BOOST_LOCALE_FORMATTING_HPP_INCLUDED
9 
10 #include <boost/locale/config.hpp>
11 #include <boost/locale/time_zone.hpp>
12 #include <boost/locale/util/string.hpp>
13 #include <boost/assert.hpp>
14 #include <boost/cstdint.hpp>
15 #include <cstring>
16 #include <istream>
17 #include <ostream>
18 #include <string>
19 #include <typeinfo>
20 
21 #ifdef BOOST_MSVC
22 # pragma warning(push)
23 # pragma warning(disable : 4275 4251 4231 4660)
24 #endif
25 
26 namespace boost { namespace locale {
27 
30  namespace flags {
31 
35  posix = 0,
36  number = 1,
37  currency = 2,
38  percent = 3,
39  date = 4,
40  time = 5,
41  datetime = 6,
42  strftime = 7,
43  spellout = 8,
44  ordinal = 9,
45 
46  display_flags_mask = 31,
47 
48  currency_default = 0 << 5,
49  currency_iso = 1 << 5,
50  currency_national = 2 << 5,
51 
52  currency_flags_mask = 3 << 5,
53 
54  time_default = 0 << 7,
55  time_short = 1 << 7,
56  time_medium = 2 << 7,
57  time_long = 3 << 7,
58  time_full = 4 << 7,
59  time_flags_mask = 7 << 7,
60 
61  date_default = 0 << 10,
62  date_short = 1 << 10,
63  date_medium = 2 << 10,
64  date_long = 3 << 10,
65  date_full = 4 << 10,
66  date_flags_mask = 7 << 10,
67 
68  datetime_flags_mask = date_flags_mask | time_flags_mask
69  };
70 
72  enum pattern_type {
75  };
76 
78  enum value_type {
80  };
81 
82  } // namespace flags
83 
89  class BOOST_LOCALE_DECL ios_info {
90  public:
92  ios_info();
93  ios_info(const ios_info&);
94  ios_info& operator=(const ios_info&);
95  ~ios_info();
97 
99  static ios_info& get(std::ios_base& ios);
100 
102  void display_flags(uint64_t flags);
103 
105  void currency_flags(uint64_t flags);
106 
108  void date_flags(uint64_t flags);
109 
111  void time_flags(uint64_t flags);
112 
114  void datetime_flags(uint64_t flags);
115 
117  void domain_id(int);
118 
120  void time_zone(const std::string&);
121 
123  template<typename CharType>
124  void date_time_pattern(const std::basic_string<CharType>& str)
125  {
126  string_set& s = date_time_pattern_set();
127  s.set<CharType>(str.c_str());
128  }
129 
131  uint64_t display_flags() const;
132 
134  uint64_t currency_flags() const;
135 
137  uint64_t date_flags() const;
138 
140  uint64_t time_flags() const;
141 
143  uint64_t datetime_flags() const;
144 
146  int domain_id() const;
147 
149  std::string time_zone() const;
150 
152  template<typename CharType>
153  std::basic_string<CharType> date_time_pattern() const
154  {
155  const string_set& s = date_time_pattern_set();
156  return s.get<CharType>();
157  }
158 
160  void on_imbue();
162 
163  private:
164  class string_set;
165 
166  const string_set& date_time_pattern_set() const;
167  string_set& date_time_pattern_set();
168 
169  class BOOST_LOCALE_DECL string_set {
170  public:
171  string_set();
172  ~string_set();
173  string_set(const string_set& other);
174  string_set& operator=(string_set other);
175  void swap(string_set& other);
176 
177  template<typename Char>
178  void set(const Char* s)
179  {
180  BOOST_ASSERT(s);
181  delete[] ptr;
182  ptr = nullptr;
183  type = &typeid(Char);
184  size = sizeof(Char) * (util::str_end(s) - s + 1);
185  ptr = new char[size];
186  memcpy(ptr, s, size);
187  }
188 
189  template<typename Char>
190  std::basic_string<Char> get() const
191  {
192  if(type == 0 || *type != typeid(Char))
193  throw std::bad_cast();
194  std::basic_string<Char> result = reinterpret_cast<const Char*>(ptr);
195  return result;
196  }
197 
198  private:
199  const std::type_info* type;
200  size_t size;
201  char* ptr;
202  };
203 
204  uint64_t flags_;
205  int domain_id_;
206  std::string time_zone_;
207  string_set datetime_;
208  };
209 
211  namespace as {
215 
218  inline std::ios_base& posix(std::ios_base& ios)
219  {
220  ios_info::get(ios).display_flags(flags::posix);
221  return ios;
222  }
223 
226  inline std::ios_base& number(std::ios_base& ios)
227  {
228  ios_info::get(ios).display_flags(flags::number);
229  return ios;
230  }
231 
233  inline std::ios_base& currency(std::ios_base& ios)
234  {
235  ios_info::get(ios).display_flags(flags::currency);
236  return ios;
237  }
238 
240  inline std::ios_base& percent(std::ios_base& ios)
241  {
242  ios_info::get(ios).display_flags(flags::percent);
243  return ios;
244  }
245 
247  inline std::ios_base& date(std::ios_base& ios)
248  {
249  ios_info::get(ios).display_flags(flags::date);
250  return ios;
251  }
252 
254  inline std::ios_base& time(std::ios_base& ios)
255  {
256  ios_info::get(ios).display_flags(flags::time);
257  return ios;
258  }
259 
261  inline std::ios_base& datetime(std::ios_base& ios)
262  {
263  ios_info::get(ios).display_flags(flags::datetime);
264  return ios;
265  }
266 
269  inline std::ios_base& strftime(std::ios_base& ios)
270  {
271  ios_info::get(ios).display_flags(flags::strftime);
272  return ios;
273  }
274 
276  inline std::ios_base& spellout(std::ios_base& ios)
277  {
278  ios_info::get(ios).display_flags(flags::spellout);
279  return ios;
280  }
281 
283  inline std::ios_base& ordinal(std::ios_base& ios)
284  {
285  ios_info::get(ios).display_flags(flags::ordinal);
286  return ios;
287  }
288 
290  inline std::ios_base& currency_default(std::ios_base& ios)
291  {
292  ios_info::get(ios).currency_flags(flags::currency_default);
293  return ios;
294  }
295 
297  inline std::ios_base& currency_iso(std::ios_base& ios)
298  {
299  ios_info::get(ios).currency_flags(flags::currency_iso);
300  return ios;
301  }
302 
304  inline std::ios_base& currency_national(std::ios_base& ios)
305  {
306  ios_info::get(ios).currency_flags(flags::currency_national);
307  return ios;
308  }
309 
311  inline std::ios_base& time_default(std::ios_base& ios)
312  {
313  ios_info::get(ios).time_flags(flags::time_default);
314  return ios;
315  }
316 
318  inline std::ios_base& time_short(std::ios_base& ios)
319  {
320  ios_info::get(ios).time_flags(flags::time_short);
321  return ios;
322  }
323 
325  inline std::ios_base& time_medium(std::ios_base& ios)
326  {
327  ios_info::get(ios).time_flags(flags::time_medium);
328  return ios;
329  }
330 
332  inline std::ios_base& time_long(std::ios_base& ios)
333  {
334  ios_info::get(ios).time_flags(flags::time_long);
335  return ios;
336  }
337 
339  inline std::ios_base& time_full(std::ios_base& ios)
340  {
341  ios_info::get(ios).time_flags(flags::time_full);
342  return ios;
343  }
344 
346  inline std::ios_base& date_default(std::ios_base& ios)
347  {
348  ios_info::get(ios).date_flags(flags::date_default);
349  return ios;
350  }
351 
353  inline std::ios_base& date_short(std::ios_base& ios)
354  {
355  ios_info::get(ios).date_flags(flags::date_short);
356  return ios;
357  }
358 
360  inline std::ios_base& date_medium(std::ios_base& ios)
361  {
362  ios_info::get(ios).date_flags(flags::date_medium);
363  return ios;
364  }
365 
367  inline std::ios_base& date_long(std::ios_base& ios)
368  {
369  ios_info::get(ios).date_flags(flags::date_long);
370  return ios;
371  }
372 
374  inline std::ios_base& date_full(std::ios_base& ios)
375  {
376  ios_info::get(ios).date_flags(flags::date_full);
377  return ios;
378  }
379 
381  namespace detail {
382  template<typename CharType>
383  struct add_ftime {
384  std::basic_string<CharType> ftime;
385 
386  void apply(std::basic_ios<CharType>& ios) const
387  {
389  as::strftime(ios);
390  }
391  };
392 
393  template<typename CharType>
394  std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const add_ftime<CharType>& fmt)
395  {
396  fmt.apply(out);
397  return out;
398  }
399 
400  template<typename CharType>
401  std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, const add_ftime<CharType>& fmt)
402  {
403  fmt.apply(in);
404  return in;
405  }
406 
407  } // namespace detail
409 
443 
444  template<typename CharType>
445 #ifdef BOOST_LOCALE_DOXYGEN
446  unspecified_type
447 #else
448  detail::add_ftime<CharType>
449 #endif
450  ftime(const std::basic_string<CharType>& format)
451  {
452  detail::add_ftime<CharType> fmt;
453  fmt.ftime = format;
454  return fmt;
455  }
456 
458  template<typename CharType>
459 #ifdef BOOST_LOCALE_DOXYGEN
460  unspecified_type
461 #else
462  detail::add_ftime<CharType>
463 #endif
464  ftime(const CharType* format)
465  {
466  detail::add_ftime<CharType> fmt;
467  fmt.ftime = format;
468  return fmt;
469  }
470 
472  namespace detail {
473  struct set_timezone {
474  std::string id;
475  };
476  template<typename CharType>
477  std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const set_timezone& fmt)
478  {
479  ios_info::get(out).time_zone(fmt.id);
480  return out;
481  }
482 
483  template<typename CharType>
484  std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, const set_timezone& fmt)
485  {
486  ios_info::get(in).time_zone(fmt.id);
487  return in;
488  }
489  } // namespace detail
491 
493  inline std::ios_base& gmt(std::ios_base& ios)
494  {
495  ios_info::get(ios).time_zone("GMT");
496  return ios;
497  }
498 
500  inline std::ios_base& local_time(std::ios_base& ios)
501  {
503  return ios;
504  }
505 
507  inline
508 #ifdef BOOST_LOCALE_DOXYGEN
509  unspecified_type
510 #else
511  detail::set_timezone
512 #endif
513  time_zone(const char* id)
514  {
515  detail::set_timezone tz;
516  tz.id = id;
517  return tz;
518  }
519 
521  inline
522 #ifdef BOOST_LOCALE_DOXYGEN
523  unspecified_type
524 #else
525  detail::set_timezone
526 #endif
527  time_zone(const std::string& id)
528  {
529  detail::set_timezone tz;
530  tz.id = id;
531  return tz;
532  }
533 
535 
536  } // namespace as
537 
538 }} // namespace boost::locale
539 
540 #ifdef BOOST_MSVC
541 # pragma warning(pop)
542 #endif
543 
544 #endif
a printf like class that allows type-safe and locale aware message formatting
Definition: format.hpp:180
unspecified_type time_zone(const char *id)
Set time zone using id.
Definition: formatting.hpp:513
std::ios_base & date_long(std::ios_base &ios)
set long date formatting style
Definition: formatting.hpp:367
std::ios_base & time_default(std::ios_base &ios)
set default (medium) time formatting style
Definition: formatting.hpp:311
std::string global()
Get global time zone identifier. If empty, system time zone is used.
std::ios_base & strftime(std::ios_base &ios)
Definition: formatting.hpp:269
std::ios_base & date_medium(std::ios_base &ios)
set medium date formatting style
Definition: formatting.hpp:360
std::ios_base & currency(std::ios_base &ios)
Format currency, number is treated like amount of money.
Definition: formatting.hpp:233
std::ios_base & time_full(std::ios_base &ios)
set full time formatting style
Definition: formatting.hpp:339
std::ios_base & ordinal(std::ios_base &ios)
Write an order of the number like 4th.
Definition: formatting.hpp:283
std::ios_base & date_full(std::ios_base &ios)
set full date formatting style
Definition: formatting.hpp:374
std::ios_base & posix(std::ios_base &ios)
Definition: formatting.hpp:218
std::ios_base & currency_default(std::ios_base &ios)
Set default currency formatting style – national, like "$".
Definition: formatting.hpp:290
std::ios_base & time_medium(std::ios_base &ios)
set medium time formatting style
Definition: formatting.hpp:325
void date_flags(uint64_t flags)
Set a flags that define how to format date.
std::ios_base & time_long(std::ios_base &ios)
set long time formatting style
Definition: formatting.hpp:332
std::ios_base & gmt(std::ios_base &ios)
Set GMT time zone to stream.
Definition: formatting.hpp:493
display_flags_type
Definition: formatting.hpp:34
std::ios_base & number(std::ios_base &ios)
Definition: formatting.hpp:226
std::ios_base & percent(std::ios_base &ios)
Format percent, value 0.3 is treated as 30%.
Definition: formatting.hpp:240
std::ios_base & spellout(std::ios_base &ios)
Spell the number, like "one hundred and ten".
Definition: formatting.hpp:276
std::ios_base & currency_national(std::ios_base &ios)
Set national currency formatting style, like "$".
Definition: formatting.hpp:304
time zone name
Definition: formatting.hpp:74
std::ios_base & date(std::ios_base &ios)
Format a date, number is treated as POSIX time.
Definition: formatting.hpp:247
void display_flags(uint64_t flags)
Set a flags that define a way for format data like number, spell, currency etc.
static ios_info & get(std::ios_base &ios)
Get ios_info instance for specific stream object.
Char * str_end(Char *str)
Return the end of a C-string, i.e. the pointer to the trailing NULL byte.
Definition: string.hpp:15
This class holds an external data - beyond existing fmtflags that std::ios_base holds.
Definition: formatting.hpp:89
strftime like formatting
Definition: formatting.hpp:73
unspecified_type time_zone(const std::string &id)
Set time zone using id.
Definition: formatting.hpp:527
void time_flags(uint64_t flags)
Set a flags that define how to format time.
std::ios_base & date_default(std::ios_base &ios)
set default (medium) date formatting style
Definition: formatting.hpp:346
std::ios_base & datetime(std::ios_base &ios)
Format a date and time, number is treated as POSIX time.
Definition: formatting.hpp:261
std::basic_ostream< CharType > & operator<<(std::basic_ostream< CharType > &out, const date_time &t)
Definition: date_time.hpp:719
unspecified_type ftime(const std::basic_string< CharType > &format)
Definition: formatting.hpp:450
void date_time_pattern(const std::basic_string< CharType > &str)
Set date/time pattern (strftime like)
Definition: formatting.hpp:124
std::ios_base & time_short(std::ios_base &ios)
set short time formatting style
Definition: formatting.hpp:318
std::ios_base & date_short(std::ios_base &ios)
set short date formatting style
Definition: formatting.hpp:353
std::ios_base & local_time(std::ios_base &ios)
Set local time zone to stream.
Definition: formatting.hpp:500
std::basic_istream< CharType > & operator>>(std::basic_istream< CharType > &in, date_time &t)
Definition: date_time.hpp:739
std::basic_string< CharType > date_time_pattern() const
Get date/time pattern (strftime like)
Definition: formatting.hpp:153
basic_format< char > format
Definition of char based format.
Definition: format.hpp:428
std::ios_base & time(std::ios_base &ios)
Format a time, number is treated as POSIX time.
Definition: formatting.hpp:254
void time_zone(const std::string &)
Set time zone for formatting dates and time.
void currency_flags(uint64_t flags)
Set a flags that define how to format currency.
Domain code - for message formatting.
Definition: formatting.hpp:79
pattern_type
Special string patterns that can be used for text formatting.
Definition: formatting.hpp:72
value_type
Special integer values that can be used for formatting.
Definition: formatting.hpp:78
std::ios_base & currency_iso(std::ios_base &ios)
Set ISO currency formatting style, like "USD", (requires ICU >= 4.2)
Definition: formatting.hpp:297