CppCMS
|
00001 // 00002 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) 00003 // 00004 // Distributed under the Boost Software License, Version 1.0. (See 00005 // accompanying file LICENSE_1_0.txt or copy at 00006 // http://www.boost.org/LICENSE_1_0.txt) 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 } // flags 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 // if ptr = 0 it does not matter what is value of size 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 } // as manipulators 00663 00664 } // locale 00665 } // boost 00666 00667 #ifdef BOOSTER_MSVC 00668 #pragma warning(pop) 00669 #endif 00670 00671 00672 #endif 00673 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4