00001
00002
00003
00004
00005
00006
00007
00008 #ifndef BOOSTER_LOCALE_FORMATTING_H_INCLUDED
00009 #define BOOSTER_LOCALE_FORMATTING_H_INCLUDED
00010
00011 #include <booster/config.h>
00012 #ifdef BOOSTER_MSVC
00013 # pragma warning(push)
00014 # pragma warning(disable : 4275 4251 4231 4660)
00015 #endif
00016 #include <booster/cstdint.h>
00017 #include <booster/locale/time_zone.h>
00018 #include <ostream>
00019 #include <istream>
00020 #include <string>
00021 #include <string.h>
00022 #include <typeinfo>
00023
00024 namespace booster {
00025 namespace locale {
00030 namespace flags {
00035 typedef enum {
00036 posix = 0,
00037 number = 1,
00038 currency = 2,
00039 percent = 3,
00040 date = 4,
00041 time = 5,
00042 datetime = 6,
00043 strftime = 7,
00044 spellout = 8,
00045 ordinal = 9,
00046
00047 display_flags_mask = 31,
00048
00049 currency_default = 0 << 5,
00050 currency_iso = 1 << 5,
00051 currency_national = 2 << 5,
00052
00053 currency_flags_mask = 3 << 5,
00054
00055 time_default = 0 << 7,
00056 time_short = 1 << 7,
00057 time_medium = 2 << 7,
00058 time_long = 3 << 7,
00059 time_full = 4 << 7,
00060 time_flags_mask = 7 << 7,
00061
00062 date_default = 0 << 10,
00063 date_short = 1 << 10,
00064 date_medium = 2 << 10,
00065 date_long = 3 << 10,
00066 date_full = 4 << 10,
00067 date_flags_mask = 7 << 10,
00068
00069 datetime_flags_mask = date_flags_mask | time_flags_mask
00070
00071 } display_flags_type;
00072
00077 typedef enum {
00078 datetime_pattern,
00079 time_zone_id
00080 } pattern_type;
00081
00085 typedef enum {
00086 domain_id
00087 } value_type;
00088
00089
00090 }
00091
00098 class BOOSTER_API ios_info {
00099 public:
00100
00102
00103 ios_info();
00104 ios_info(ios_info const &);
00105 ios_info const &operator=(ios_info const &);
00106 ~ios_info();
00107
00109
00113 static ios_info &get(std::ios_base &ios);
00114
00118 void display_flags(uint64_t flags);
00119
00123 void currency_flags(uint64_t flags);
00124
00128 void date_flags(uint64_t flags);
00129
00133 void time_flags(uint64_t flags);
00134
00138 void datetime_flags(uint64_t flags);
00139
00143 void domain_id(int);
00144
00148 void time_zone(std::string const &);
00149
00150
00154 template<typename CharType>
00155 void date_time_pattern(std::basic_string<CharType> const &str)
00156 {
00157 string_set &s = date_time_pattern_set();
00158 s.set<CharType>(str.c_str());
00159 }
00160
00161
00165 uint64_t display_flags() const;
00166
00170 uint64_t currency_flags() const;
00171
00172
00176 uint64_t date_flags() const;
00177
00181 uint64_t time_flags() const;
00182
00186 uint64_t datetime_flags() const;
00187
00191 int domain_id() const;
00192
00196 std::string time_zone() const;
00197
00201 template<typename CharType>
00202 std::basic_string<CharType> date_time_pattern() const
00203 {
00204 string_set const &s = date_time_pattern_set();
00205 return s.get<CharType>();
00206 }
00207
00209 void on_imbue();
00211
00212 private:
00213
00214 class string_set;
00215
00216 string_set const &date_time_pattern_set() const;
00217 string_set &date_time_pattern_set();
00218
00219 class BOOSTER_API string_set {
00220 public:
00221 string_set();
00222 ~string_set();
00223 string_set(string_set const &other);
00224 string_set const &operator=(string_set const &other);
00225 void swap(string_set &other);
00226
00227 template<typename Char>
00228 void set(Char const *s)
00229 {
00230 delete [] ptr;
00231 ptr = 0;
00232 type=&typeid(Char);
00233 Char const *end = s;
00234 while(*end!=0) end++;
00235
00236 size = sizeof(Char)*(end - s+1);
00237 ptr = new char[size];
00238 memcpy(ptr,s,size);
00239 }
00240
00241 template<typename Char>
00242 std::basic_string<Char> get() const
00243 {
00244 if(type==0 || *type!=typeid(Char))
00245 throw std::bad_cast();
00246 std::basic_string<Char> result = reinterpret_cast<Char const *>(ptr);
00247 return result;
00248 }
00249
00250 private:
00251 std::type_info const *type;
00252 size_t size;
00253 char *ptr;
00254 };
00255
00256 uint64_t flags_;
00257 int domain_id_;
00258 std::string time_zone_;
00259 string_set datetime_;
00260
00261 struct data;
00262 data *d;
00263
00264 };
00265
00266
00270 namespace as {
00276
00281
00282 inline std::ios_base & posix(std::ios_base & ios)
00283 {
00284 ios_info::get(ios).display_flags(flags::posix);
00285 return ios;
00286 }
00287
00292 inline std::ios_base & number(std::ios_base & ios)
00293 {
00294 ios_info::get(ios).display_flags(flags::number);
00295 return ios;
00296 }
00297
00301 inline std::ios_base & currency(std::ios_base & ios)
00302 {
00303 ios_info::get(ios).display_flags(flags::currency);
00304 return ios;
00305 }
00306
00310 inline std::ios_base & percent(std::ios_base & ios)
00311 {
00312 ios_info::get(ios).display_flags(flags::percent);
00313 return ios;
00314 }
00315
00319 inline std::ios_base & date(std::ios_base & ios)
00320 {
00321 ios_info::get(ios).display_flags(flags::date);
00322 return ios;
00323 }
00324
00328 inline std::ios_base & time(std::ios_base & ios)
00329 {
00330 ios_info::get(ios).display_flags(flags::time);
00331 return ios;
00332 }
00333
00337 inline std::ios_base & datetime(std::ios_base & ios)
00338 {
00339 ios_info::get(ios).display_flags(flags::datetime);
00340 return ios;
00341 }
00342
00347 inline std::ios_base & strftime(std::ios_base & ios)
00348 {
00349 ios_info::get(ios).display_flags(flags::strftime);
00350 return ios;
00351 }
00352
00356 inline std::ios_base & spellout(std::ios_base & ios)
00357 {
00358 ios_info::get(ios).display_flags(flags::spellout);
00359 return ios;
00360 }
00361
00365 inline std::ios_base & ordinal(std::ios_base & ios)
00366 {
00367 ios_info::get(ios).display_flags(flags::ordinal);
00368 return ios;
00369 }
00370
00374 inline std::ios_base & currency_default(std::ios_base & ios)
00375 {
00376 ios_info::get(ios).currency_flags(flags::currency_default);
00377 return ios;
00378 }
00379
00383 inline std::ios_base & currency_iso(std::ios_base & ios)
00384 {
00385 ios_info::get(ios).currency_flags(flags::currency_iso);
00386 return ios;
00387 }
00388
00392 inline std::ios_base & currency_national(std::ios_base & ios)
00393 {
00394 ios_info::get(ios).currency_flags(flags::currency_national);
00395 return ios;
00396 }
00397
00401 inline std::ios_base & time_default(std::ios_base & ios)
00402 {
00403 ios_info::get(ios).time_flags(flags::time_default);
00404 return ios;
00405 }
00406
00410 inline std::ios_base & time_short(std::ios_base & ios)
00411 {
00412 ios_info::get(ios).time_flags(flags::time_short);
00413 return ios;
00414 }
00415
00419 inline std::ios_base & time_medium(std::ios_base & ios)
00420 {
00421 ios_info::get(ios).time_flags(flags::time_medium);
00422 return ios;
00423 }
00424
00428 inline std::ios_base & time_long(std::ios_base & ios)
00429 {
00430 ios_info::get(ios).time_flags(flags::time_long);
00431 return ios;
00432 }
00433
00437 inline std::ios_base & time_full(std::ios_base & ios)
00438 {
00439 ios_info::get(ios).time_flags(flags::time_full);
00440 return ios;
00441 }
00442
00446 inline std::ios_base & date_default(std::ios_base & ios)
00447 {
00448 ios_info::get(ios).date_flags(flags::date_default);
00449 return ios;
00450 }
00451
00455 inline std::ios_base & date_short(std::ios_base & ios)
00456 {
00457 ios_info::get(ios).date_flags(flags::date_short);
00458 return ios;
00459 }
00460
00464 inline std::ios_base & date_medium(std::ios_base & ios)
00465 {
00466 ios_info::get(ios).date_flags(flags::date_medium);
00467 return ios;
00468 }
00469
00473 inline std::ios_base & date_long(std::ios_base & ios)
00474 {
00475 ios_info::get(ios).date_flags(flags::date_long);
00476 return ios;
00477 }
00478
00482 inline std::ios_base & date_full(std::ios_base & ios)
00483 {
00484 ios_info::get(ios).date_flags(flags::date_full);
00485 return ios;
00486 }
00487
00488
00490 namespace details {
00491 template<typename CharType>
00492 struct add_ftime {
00493
00494 std::basic_string<CharType> ftime;
00495
00496 void apply(std::basic_ios<CharType> &ios) const
00497 {
00498 ios_info::get(ios).date_time_pattern(ftime);
00499 as::strftime(ios);
00500 }
00501
00502 };
00503
00504 template<typename CharType>
00505 std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,add_ftime<CharType> const &fmt)
00506 {
00507 fmt.apply(out);
00508 return out;
00509 }
00510
00511 template<typename CharType>
00512 std::basic_istream<CharType> &operator>>(std::basic_istream<CharType> &in,add_ftime<CharType> const &fmt)
00513 {
00514 fmt.apply(in);
00515 return in;
00516 }
00517
00518 }
00520
00555
00556
00557 template<typename CharType>
00558 #ifdef BOOSTER_LOCALE_DOXYGEN
00559 unspecified_type
00560 #else
00561 details::add_ftime<CharType>
00562 #endif
00563 ftime(std::basic_string<CharType> const &format)
00564 {
00565 details::add_ftime<CharType> fmt;
00566 fmt.ftime=format;
00567 return fmt;
00568 }
00569
00573 template<typename CharType>
00574 #ifdef BOOSTER_LOCALE_DOXYGEN
00575 unspecified_type
00576 #else
00577 details::add_ftime<CharType>
00578 #endif
00579 ftime(CharType const *format)
00580 {
00581 details::add_ftime<CharType> fmt;
00582 fmt.ftime=format;
00583 return fmt;
00584 }
00585
00587 namespace details {
00588 struct set_timezone {
00589 std::string id;
00590 };
00591 template<typename CharType>
00592 std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,set_timezone const &fmt)
00593 {
00594 ios_info::get(out).time_zone(fmt.id);
00595 return out;
00596 }
00597
00598 template<typename CharType>
00599 std::basic_istream<CharType> &operator>>(std::basic_istream<CharType> &in,set_timezone const &fmt)
00600 {
00601 ios_info::get(in).time_zone(fmt.id);
00602 return in;
00603 }
00604 }
00606
00610 inline std::ios_base &gmt(std::ios_base &ios)
00611 {
00612 ios_info::get(ios).time_zone("GMT");
00613 return ios;
00614 }
00615
00619 inline std::ios_base &local_time(std::ios_base &ios)
00620 {
00621 ios_info::get(ios).time_zone(time_zone::global());
00622 return ios;
00623 }
00624
00628 inline
00629 #ifdef BOOSTER_LOCALE_DOXYGEN
00630 unspecified_type
00631 #else
00632 details::set_timezone
00633 #endif
00634 time_zone(char const *id)
00635 {
00636 details::set_timezone tz;
00637 tz.id=id;
00638 return tz;
00639 }
00640
00644 inline
00645 #ifdef BOOSTER_LOCALE_DOXYGEN
00646 unspecified_type
00647 #else
00648 details::set_timezone
00649 #endif
00650 time_zone(std::string const &id)
00651 {
00652 details::set_timezone tz;
00653 tz.id=id;
00654 return tz;
00655 }
00656
00657
00661
00662 }
00663
00664 }
00665 }
00666
00667 #ifdef BOOSTER_MSVC
00668 #pragma warning(pop)
00669 #endif
00670
00671
00672 #endif
00673