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/time_zone.hpp>
11 #include <boost/locale/util/string.hpp>
12 #include <boost/assert.hpp>
13 #include <boost/cstdint.hpp>
14 #include <cstring>
15 #include <istream>
16 #include <ostream>
17 #include <string>
18 #include <typeinfo>
19 
20 #ifdef BOOST_MSVC
21 # pragma warning(push)
22 # pragma warning(disable : 4275 4251 4231 4660)
23 #endif
24 
25 namespace boost { namespace locale {
26 
29  namespace flags {
30 
34  posix = 0,
35  number = 1,
36  currency = 2,
37  percent = 3,
38  date = 4,
39  time = 5,
40  datetime = 6,
41  strftime = 7,
42  spellout = 8,
43  ordinal = 9,
44 
45  display_flags_mask = 31,
46 
47  currency_default = 0 << 5,
48  currency_iso = 1 << 5,
49  currency_national = 2 << 5,
50 
51  currency_flags_mask = 3 << 5,
52 
53  time_default = 0 << 7,
54  time_short = 1 << 7,
55  time_medium = 2 << 7,
56  time_long = 3 << 7,
57  time_full = 4 << 7,
58  time_flags_mask = 7 << 7,
59 
60  date_default = 0 << 10,
61  date_short = 1 << 10,
62  date_medium = 2 << 10,
63  date_long = 3 << 10,
64  date_full = 4 << 10,
65  date_flags_mask = 7 << 10,
66  };
67 
69  enum pattern_type {
72  };
73 
75  enum value_type {
77  };
78 
79  } // namespace flags
80 
86  class BOOST_LOCALE_DECL ios_info {
87  public:
89  ios_info();
90  ios_info(const ios_info&);
91  ios_info& operator=(const ios_info&);
92  ~ios_info();
94 
96  static ios_info& get(std::ios_base& ios);
97 
99  void display_flags(uint64_t flags);
101  uint64_t display_flags() const;
102 
104  void currency_flags(uint64_t flags);
106  uint64_t currency_flags() const;
107 
109  void date_flags(uint64_t flags);
111  uint64_t date_flags() const;
112 
114  void time_flags(uint64_t flags);
116  uint64_t time_flags() const;
117 
119  void domain_id(int);
121  int domain_id() const;
122 
124  void time_zone(const std::string&);
126  std::string time_zone() const;
127 
129  template<typename CharType>
130  void date_time_pattern(const std::basic_string<CharType>& str)
131  {
132  string_set& s = date_time_pattern_set();
133  s.set(str.c_str());
134  }
136  template<typename CharType>
137  std::basic_string<CharType> date_time_pattern() const
138  {
139  const string_set& s = date_time_pattern_set();
140  return s.get<CharType>();
141  }
142 
144  void on_imbue();
146 
147  private:
148  class string_set;
149 
150  const string_set& date_time_pattern_set() const;
151  string_set& date_time_pattern_set();
152 
153  class BOOST_LOCALE_DECL string_set {
154  public:
155  string_set();
156  ~string_set();
157  string_set(const string_set& other);
158  string_set& operator=(string_set other);
159  void swap(string_set& other);
160 
161  template<typename Char>
162  void set(const Char* s)
163  {
164  BOOST_ASSERT(s);
165  delete[] ptr;
166  ptr = nullptr;
167  type = &typeid(Char);
168  size = sizeof(Char) * (util::str_end(s) - s + 1);
169  ptr = new char[size];
170  memcpy(ptr, s, size);
171  }
172 
173  template<typename Char>
174  std::basic_string<Char> get() const
175  {
176  if(type == 0 || *type != typeid(Char))
177  throw std::bad_cast();
178  std::basic_string<Char> result = reinterpret_cast<const Char*>(ptr);
179  return result;
180  }
181 
182  private:
183  const std::type_info* type;
184  size_t size;
185  char* ptr;
186  };
187 
188  uint64_t flags_;
189  int domain_id_;
190  std::string time_zone_;
191  string_set datetime_;
192  };
193 
195  namespace as {
199 
202  inline std::ios_base& posix(std::ios_base& ios)
203  {
204  ios_info::get(ios).display_flags(flags::posix);
205  return ios;
206  }
207 
210  inline std::ios_base& number(std::ios_base& ios)
211  {
212  ios_info::get(ios).display_flags(flags::number);
213  return ios;
214  }
215 
217  inline std::ios_base& currency(std::ios_base& ios)
218  {
219  ios_info::get(ios).display_flags(flags::currency);
220  return ios;
221  }
222 
224  inline std::ios_base& percent(std::ios_base& ios)
225  {
226  ios_info::get(ios).display_flags(flags::percent);
227  return ios;
228  }
229 
231  inline std::ios_base& date(std::ios_base& ios)
232  {
233  ios_info::get(ios).display_flags(flags::date);
234  return ios;
235  }
236 
238  inline std::ios_base& time(std::ios_base& ios)
239  {
240  ios_info::get(ios).display_flags(flags::time);
241  return ios;
242  }
243 
245  inline std::ios_base& datetime(std::ios_base& ios)
246  {
247  ios_info::get(ios).display_flags(flags::datetime);
248  return ios;
249  }
250 
253  inline std::ios_base& strftime(std::ios_base& ios)
254  {
255  ios_info::get(ios).display_flags(flags::strftime);
256  return ios;
257  }
258 
260  inline std::ios_base& spellout(std::ios_base& ios)
261  {
262  ios_info::get(ios).display_flags(flags::spellout);
263  return ios;
264  }
265 
267  inline std::ios_base& ordinal(std::ios_base& ios)
268  {
269  ios_info::get(ios).display_flags(flags::ordinal);
270  return ios;
271  }
272 
274  inline std::ios_base& currency_default(std::ios_base& ios)
275  {
276  ios_info::get(ios).currency_flags(flags::currency_default);
277  return ios;
278  }
279 
281  inline std::ios_base& currency_iso(std::ios_base& ios)
282  {
283  ios_info::get(ios).currency_flags(flags::currency_iso);
284  return ios;
285  }
286 
288  inline std::ios_base& currency_national(std::ios_base& ios)
289  {
290  ios_info::get(ios).currency_flags(flags::currency_national);
291  return ios;
292  }
293 
295  inline std::ios_base& time_default(std::ios_base& ios)
296  {
297  ios_info::get(ios).time_flags(flags::time_default);
298  return ios;
299  }
300 
302  inline std::ios_base& time_short(std::ios_base& ios)
303  {
304  ios_info::get(ios).time_flags(flags::time_short);
305  return ios;
306  }
307 
309  inline std::ios_base& time_medium(std::ios_base& ios)
310  {
311  ios_info::get(ios).time_flags(flags::time_medium);
312  return ios;
313  }
314 
316  inline std::ios_base& time_long(std::ios_base& ios)
317  {
318  ios_info::get(ios).time_flags(flags::time_long);
319  return ios;
320  }
321 
323  inline std::ios_base& time_full(std::ios_base& ios)
324  {
325  ios_info::get(ios).time_flags(flags::time_full);
326  return ios;
327  }
328 
330  inline std::ios_base& date_default(std::ios_base& ios)
331  {
332  ios_info::get(ios).date_flags(flags::date_default);
333  return ios;
334  }
335 
337  inline std::ios_base& date_short(std::ios_base& ios)
338  {
339  ios_info::get(ios).date_flags(flags::date_short);
340  return ios;
341  }
342 
344  inline std::ios_base& date_medium(std::ios_base& ios)
345  {
346  ios_info::get(ios).date_flags(flags::date_medium);
347  return ios;
348  }
349 
351  inline std::ios_base& date_long(std::ios_base& ios)
352  {
353  ios_info::get(ios).date_flags(flags::date_long);
354  return ios;
355  }
356 
358  inline std::ios_base& date_full(std::ios_base& ios)
359  {
360  ios_info::get(ios).date_flags(flags::date_full);
361  return ios;
362  }
363 
365  namespace detail {
366  template<typename CharType>
367  struct add_ftime {
368  std::basic_string<CharType> ftime;
369 
370  void apply(std::basic_ios<CharType>& ios) const
371  {
373  as::strftime(ios);
374  }
375  };
376 
377  template<typename CharType>
378  std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const add_ftime<CharType>& fmt)
379  {
380  fmt.apply(out);
381  return out;
382  }
383 
384  template<typename CharType>
385  std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, const add_ftime<CharType>& fmt)
386  {
387  fmt.apply(in);
388  return in;
389  }
390 
391  } // namespace detail
393 
427 
428  template<typename CharType>
429 #ifdef BOOST_LOCALE_DOXYGEN
430  unspecified_type
431 #else
432  detail::add_ftime<CharType>
433 #endif
434  ftime(const std::basic_string<CharType>& format)
435  {
436  detail::add_ftime<CharType> fmt;
437  fmt.ftime = format;
438  return fmt;
439  }
440 
442  template<typename CharType>
443 #ifdef BOOST_LOCALE_DOXYGEN
444  unspecified_type
445 #else
446  detail::add_ftime<CharType>
447 #endif
448  ftime(const CharType* format)
449  {
450  detail::add_ftime<CharType> fmt;
451  fmt.ftime = format;
452  return fmt;
453  }
454 
456  namespace detail {
457  struct set_timezone {
458  std::string id;
459  };
460  template<typename CharType>
461  std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const set_timezone& fmt)
462  {
463  ios_info::get(out).time_zone(fmt.id);
464  return out;
465  }
466 
467  template<typename CharType>
468  std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, const set_timezone& fmt)
469  {
470  ios_info::get(in).time_zone(fmt.id);
471  return in;
472  }
473  } // namespace detail
475 
477  inline std::ios_base& gmt(std::ios_base& ios)
478  {
479  ios_info::get(ios).time_zone("GMT");
480  return ios;
481  }
482 
484  inline std::ios_base& local_time(std::ios_base& ios)
485  {
487  return ios;
488  }
489 
491  inline
492 #ifdef BOOST_LOCALE_DOXYGEN
493  unspecified_type
494 #else
495  detail::set_timezone
496 #endif
497  time_zone(const char* id)
498  {
499  detail::set_timezone tz;
500  tz.id = id;
501  return tz;
502  }
503 
505  inline
506 #ifdef BOOST_LOCALE_DOXYGEN
507  unspecified_type
508 #else
509  detail::set_timezone
510 #endif
511  time_zone(const std::string& id)
512  {
513  detail::set_timezone tz;
514  tz.id = id;
515  return tz;
516  }
517 
519 
520  } // namespace as
521 
522 }} // namespace boost::locale
523 
524 #ifdef BOOST_MSVC
525 # pragma warning(pop)
526 #endif
527 
528 #endif
a printf like class that allows type-safe and locale aware message formatting
Definition: format.hpp:179
unspecified_type time_zone(const char *id)
Set time zone using id.
Definition: formatting.hpp:497
std::ios_base & date_long(std::ios_base &ios)
set long date formatting style
Definition: formatting.hpp:351
std::ios_base & time_default(std::ios_base &ios)
set default (medium) time formatting style
Definition: formatting.hpp:295
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:253
std::ios_base & date_medium(std::ios_base &ios)
set medium date formatting style
Definition: formatting.hpp:344
std::ios_base & currency(std::ios_base &ios)
Format currency, number is treated like amount of money.
Definition: formatting.hpp:217
std::ios_base & time_full(std::ios_base &ios)
set full time formatting style
Definition: formatting.hpp:323
std::ios_base & ordinal(std::ios_base &ios)
Write an order of the number like 4th.
Definition: formatting.hpp:267
std::ios_base & date_full(std::ios_base &ios)
set full date formatting style
Definition: formatting.hpp:358
std::ios_base & posix(std::ios_base &ios)
Definition: formatting.hpp:202
std::ios_base & currency_default(std::ios_base &ios)
Set default currency formatting style – national, like "$".
Definition: formatting.hpp:274
std::ios_base & time_medium(std::ios_base &ios)
set medium time formatting style
Definition: formatting.hpp:309
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:316
std::ios_base & gmt(std::ios_base &ios)
Set GMT time zone to stream.
Definition: formatting.hpp:477
display_flags_type
Definition: formatting.hpp:33
std::ios_base & number(std::ios_base &ios)
Definition: formatting.hpp:210
std::ios_base & percent(std::ios_base &ios)
Format percent, value 0.3 is treated as 30%.
Definition: formatting.hpp:224
std::ios_base & spellout(std::ios_base &ios)
Spell the number, like "one hundred and ten".
Definition: formatting.hpp:260
std::ios_base & currency_national(std::ios_base &ios)
Set national currency formatting style, like "$".
Definition: formatting.hpp:288
time zone name
Definition: formatting.hpp:71
std::ios_base & date(std::ios_base &ios)
Format a date, number is treated as POSIX time.
Definition: formatting.hpp:231
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:86
strftime like formatting
Definition: formatting.hpp:70
unspecified_type time_zone(const std::string &id)
Set time zone using id.
Definition: formatting.hpp:511
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:330
std::ios_base & datetime(std::ios_base &ios)
Format a date and time, number is treated as POSIX time.
Definition: formatting.hpp:245
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:434
void date_time_pattern(const std::basic_string< CharType > &str)
Set date/time pattern (strftime like)
Definition: formatting.hpp:130
std::ios_base & time_short(std::ios_base &ios)
set short time formatting style
Definition: formatting.hpp:302
std::ios_base & date_short(std::ios_base &ios)
set short date formatting style
Definition: formatting.hpp:337
std::ios_base & local_time(std::ios_base &ios)
Set local time zone to stream.
Definition: formatting.hpp:484
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:137
basic_format< char > format
Definition of char based format.
Definition: format.hpp:427
std::ios_base & time(std::ios_base &ios)
Format a time, number is treated as POSIX time.
Definition: formatting.hpp:238
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:76
pattern_type
Special string patterns that can be used for text formatting.
Definition: formatting.hpp:69
value_type
Special integer values that can be used for formatting.
Definition: formatting.hpp:75
std::ios_base & currency_iso(std::ios_base &ios)
Set ISO currency formatting style, like "USD", (requires ICU >= 4.2)
Definition: formatting.hpp:281