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 
70  enum pattern_type {
73  };
74 
76  enum value_type {
78  };
79 
80  } // namespace flags
81 
87  class BOOST_LOCALE_DECL ios_info {
88  public:
90  ios_info();
91  ios_info(const ios_info&);
92  ios_info& operator=(const ios_info&);
93  ~ios_info();
95 
97  static ios_info& get(std::ios_base& ios);
98 
100  void display_flags(uint64_t flags);
102  uint64_t display_flags() const;
103 
105  void currency_flags(uint64_t flags);
107  uint64_t currency_flags() const;
108 
110  void date_flags(uint64_t flags);
112  uint64_t date_flags() const;
113 
115  void time_flags(uint64_t flags);
117  uint64_t time_flags() const;
118 
120  void domain_id(int);
122  int domain_id() const;
123 
125  void time_zone(const std::string&);
127  std::string time_zone() const;
128 
130  template<typename CharType>
131  void date_time_pattern(const std::basic_string<CharType>& str)
132  {
133  string_set& s = date_time_pattern_set();
134  s.set(str.c_str());
135  }
137  template<typename CharType>
138  std::basic_string<CharType> date_time_pattern() const
139  {
140  const string_set& s = date_time_pattern_set();
141  return s.get<CharType>();
142  }
143 
145  void on_imbue();
147 
148  private:
149  class string_set;
150 
151  const string_set& date_time_pattern_set() const;
152  string_set& date_time_pattern_set();
153 
154  class BOOST_LOCALE_DECL string_set {
155  public:
156  string_set();
157  ~string_set();
158  string_set(const string_set& other);
159  string_set& operator=(string_set other);
160  void swap(string_set& other);
161 
162  template<typename Char>
163  void set(const Char* s)
164  {
165  BOOST_ASSERT(s);
166  delete[] ptr;
167  ptr = nullptr;
168  type = &typeid(Char);
169  size = sizeof(Char) * (util::str_end(s) - s + 1);
170  ptr = new char[size];
171  memcpy(ptr, s, size);
172  }
173 
174  template<typename Char>
175  std::basic_string<Char> get() const
176  {
177  if(type == 0 || *type != typeid(Char))
178  throw std::bad_cast();
179  std::basic_string<Char> result = reinterpret_cast<const Char*>(ptr);
180  return result;
181  }
182 
183  private:
184  const std::type_info* type;
185  size_t size;
186  char* ptr;
187  };
188 
189  uint64_t flags_;
190  int domain_id_;
191  std::string time_zone_;
192  string_set datetime_;
193  };
194 
196  namespace as {
200 
203  inline std::ios_base& posix(std::ios_base& ios)
204  {
205  ios_info::get(ios).display_flags(flags::posix);
206  return ios;
207  }
208 
211  inline std::ios_base& number(std::ios_base& ios)
212  {
213  ios_info::get(ios).display_flags(flags::number);
214  return ios;
215  }
216 
218  inline std::ios_base& currency(std::ios_base& ios)
219  {
220  ios_info::get(ios).display_flags(flags::currency);
221  return ios;
222  }
223 
225  inline std::ios_base& percent(std::ios_base& ios)
226  {
227  ios_info::get(ios).display_flags(flags::percent);
228  return ios;
229  }
230 
232  inline std::ios_base& date(std::ios_base& ios)
233  {
234  ios_info::get(ios).display_flags(flags::date);
235  return ios;
236  }
237 
239  inline std::ios_base& time(std::ios_base& ios)
240  {
241  ios_info::get(ios).display_flags(flags::time);
242  return ios;
243  }
244 
246  inline std::ios_base& datetime(std::ios_base& ios)
247  {
248  ios_info::get(ios).display_flags(flags::datetime);
249  return ios;
250  }
251 
254  inline std::ios_base& strftime(std::ios_base& ios)
255  {
256  ios_info::get(ios).display_flags(flags::strftime);
257  return ios;
258  }
259 
261  inline std::ios_base& spellout(std::ios_base& ios)
262  {
263  ios_info::get(ios).display_flags(flags::spellout);
264  return ios;
265  }
266 
268  inline std::ios_base& ordinal(std::ios_base& ios)
269  {
270  ios_info::get(ios).display_flags(flags::ordinal);
271  return ios;
272  }
273 
275  inline std::ios_base& currency_default(std::ios_base& ios)
276  {
277  ios_info::get(ios).currency_flags(flags::currency_default);
278  return ios;
279  }
280 
282  inline std::ios_base& currency_iso(std::ios_base& ios)
283  {
284  ios_info::get(ios).currency_flags(flags::currency_iso);
285  return ios;
286  }
287 
289  inline std::ios_base& currency_national(std::ios_base& ios)
290  {
291  ios_info::get(ios).currency_flags(flags::currency_national);
292  return ios;
293  }
294 
296  inline std::ios_base& time_default(std::ios_base& ios)
297  {
298  ios_info::get(ios).time_flags(flags::time_default);
299  return ios;
300  }
301 
303  inline std::ios_base& time_short(std::ios_base& ios)
304  {
305  ios_info::get(ios).time_flags(flags::time_short);
306  return ios;
307  }
308 
310  inline std::ios_base& time_medium(std::ios_base& ios)
311  {
312  ios_info::get(ios).time_flags(flags::time_medium);
313  return ios;
314  }
315 
317  inline std::ios_base& time_long(std::ios_base& ios)
318  {
319  ios_info::get(ios).time_flags(flags::time_long);
320  return ios;
321  }
322 
324  inline std::ios_base& time_full(std::ios_base& ios)
325  {
326  ios_info::get(ios).time_flags(flags::time_full);
327  return ios;
328  }
329 
331  inline std::ios_base& date_default(std::ios_base& ios)
332  {
333  ios_info::get(ios).date_flags(flags::date_default);
334  return ios;
335  }
336 
338  inline std::ios_base& date_short(std::ios_base& ios)
339  {
340  ios_info::get(ios).date_flags(flags::date_short);
341  return ios;
342  }
343 
345  inline std::ios_base& date_medium(std::ios_base& ios)
346  {
347  ios_info::get(ios).date_flags(flags::date_medium);
348  return ios;
349  }
350 
352  inline std::ios_base& date_long(std::ios_base& ios)
353  {
354  ios_info::get(ios).date_flags(flags::date_long);
355  return ios;
356  }
357 
359  inline std::ios_base& date_full(std::ios_base& ios)
360  {
361  ios_info::get(ios).date_flags(flags::date_full);
362  return ios;
363  }
364 
366  namespace detail {
367  template<typename CharType>
368  struct add_ftime {
369  std::basic_string<CharType> ftime;
370 
371  void apply(std::basic_ios<CharType>& ios) const
372  {
374  as::strftime(ios);
375  }
376  };
377 
378  template<typename CharType>
379  std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const add_ftime<CharType>& fmt)
380  {
381  fmt.apply(out);
382  return out;
383  }
384 
385  template<typename CharType>
386  std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, const add_ftime<CharType>& fmt)
387  {
388  fmt.apply(in);
389  return in;
390  }
391 
392  } // namespace detail
394 
428 
429  template<typename CharType>
430 #ifdef BOOST_LOCALE_DOXYGEN
431  unspecified_type
432 #else
433  detail::add_ftime<CharType>
434 #endif
435  ftime(const std::basic_string<CharType>& format)
436  {
437  detail::add_ftime<CharType> fmt;
438  fmt.ftime = format;
439  return fmt;
440  }
441 
443  template<typename CharType>
444 #ifdef BOOST_LOCALE_DOXYGEN
445  unspecified_type
446 #else
447  detail::add_ftime<CharType>
448 #endif
449  ftime(const CharType* format)
450  {
451  detail::add_ftime<CharType> fmt;
452  fmt.ftime = format;
453  return fmt;
454  }
455 
457  namespace detail {
458  struct set_timezone {
459  std::string id;
460  };
461  template<typename CharType>
462  std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const set_timezone& fmt)
463  {
464  ios_info::get(out).time_zone(fmt.id);
465  return out;
466  }
467 
468  template<typename CharType>
469  std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, const set_timezone& fmt)
470  {
471  ios_info::get(in).time_zone(fmt.id);
472  return in;
473  }
474  } // namespace detail
476 
478  inline std::ios_base& gmt(std::ios_base& ios)
479  {
480  ios_info::get(ios).time_zone("GMT");
481  return ios;
482  }
483 
485  inline std::ios_base& local_time(std::ios_base& ios)
486  {
488  return ios;
489  }
490 
492  inline
493 #ifdef BOOST_LOCALE_DOXYGEN
494  unspecified_type
495 #else
496  detail::set_timezone
497 #endif
498  time_zone(const char* id)
499  {
500  detail::set_timezone tz;
501  tz.id = id;
502  return tz;
503  }
504 
506  inline
507 #ifdef BOOST_LOCALE_DOXYGEN
508  unspecified_type
509 #else
510  detail::set_timezone
511 #endif
512  time_zone(const std::string& id)
513  {
514  detail::set_timezone tz;
515  tz.id = id;
516  return tz;
517  }
518 
520 
521  } // namespace as
522 
523 }} // namespace boost::locale
524 
525 #ifdef BOOST_MSVC
526 # pragma warning(pop)
527 #endif
528 
529 #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:498
std::ios_base & date_long(std::ios_base &ios)
set long date formatting style
Definition: formatting.hpp:352
std::ios_base & time_default(std::ios_base &ios)
set default (medium) time formatting style
Definition: formatting.hpp:296
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:254
std::ios_base & date_medium(std::ios_base &ios)
set medium date formatting style
Definition: formatting.hpp:345
std::ios_base & currency(std::ios_base &ios)
Format currency, number is treated like amount of money.
Definition: formatting.hpp:218
std::ios_base & time_full(std::ios_base &ios)
set full time formatting style
Definition: formatting.hpp:324
std::ios_base & ordinal(std::ios_base &ios)
Write an order of the number like 4th.
Definition: formatting.hpp:268
std::ios_base & date_full(std::ios_base &ios)
set full date formatting style
Definition: formatting.hpp:359
std::ios_base & posix(std::ios_base &ios)
Definition: formatting.hpp:203
std::ios_base & currency_default(std::ios_base &ios)
Set default currency formatting style – national, like "$".
Definition: formatting.hpp:275
std::ios_base & time_medium(std::ios_base &ios)
set medium time formatting style
Definition: formatting.hpp:310
void date_flags(uint64_t flags)
Set flags that define how to format date.
std::ios_base & time_long(std::ios_base &ios)
set long time formatting style
Definition: formatting.hpp:317
std::ios_base & gmt(std::ios_base &ios)
Set GMT time zone to stream.
Definition: formatting.hpp:478
display_flags_type
Definition: formatting.hpp:34
std::ios_base & number(std::ios_base &ios)
Definition: formatting.hpp:211
std::ios_base & percent(std::ios_base &ios)
Format percent, value 0.3 is treated as 30%.
Definition: formatting.hpp:225
std::ios_base & spellout(std::ios_base &ios)
Spell the number, like "one hundred and ten".
Definition: formatting.hpp:261
std::ios_base & currency_national(std::ios_base &ios)
Set national currency formatting style, like "$".
Definition: formatting.hpp:289
time zone name
Definition: formatting.hpp:72
std::ios_base & date(std::ios_base &ios)
Format a date, number is treated as POSIX time.
Definition: formatting.hpp:232
void display_flags(uint64_t flags)
Set flags that define how to format data, e.g. 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 external data beyond existing fmtflags that std::ios_base holds.
Definition: formatting.hpp:87
strftime like formatting
Definition: formatting.hpp:71
unspecified_type time_zone(const std::string &id)
Set time zone using id.
Definition: formatting.hpp:512
void time_flags(uint64_t flags)
Set 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:331
std::ios_base & datetime(std::ios_base &ios)
Format a date and time, number is treated as POSIX time.
Definition: formatting.hpp:246
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:435
void date_time_pattern(const std::basic_string< CharType > &str)
Set date/time pattern (strftime like)
Definition: formatting.hpp:131
std::ios_base & time_short(std::ios_base &ios)
set short time formatting style
Definition: formatting.hpp:303
std::ios_base & date_short(std::ios_base &ios)
set short date formatting style
Definition: formatting.hpp:338
std::ios_base & local_time(std::ios_base &ios)
Set local time zone to stream.
Definition: formatting.hpp:485
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:138
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:239
void time_zone(const std::string &)
Set time zone for formatting dates and time.
void currency_flags(uint64_t flags)
Set flags that define how to format currency.
Domain code - for message formatting.
Definition: formatting.hpp:77
pattern_type
Special string patterns that can be used for text formatting.
Definition: formatting.hpp:70
value_type
Special integer values that can be used for formatting.
Definition: formatting.hpp:76
std::ios_base & currency_iso(std::ios_base &ios)
Set ISO currency formatting style, like "USD", (requires ICU >= 4.2)
Definition: formatting.hpp:282