File indexing completed on 2025-01-18 09:39:16
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_LOCALE_FORMATTING_HPP_INCLUDED
0009 #define BOOST_LOCALE_FORMATTING_HPP_INCLUDED
0010
0011 #include <boost/locale/time_zone.hpp>
0012 #include <boost/assert.hpp>
0013 #include <boost/utility/string_view.hpp>
0014 #include <cstdint>
0015 #include <cstring>
0016 #include <istream>
0017 #include <ostream>
0018 #include <string>
0019 #include <typeinfo>
0020
0021 #ifdef BOOST_MSVC
0022 # pragma warning(push)
0023 # pragma warning(disable : 4275 4251 4231 4660)
0024 #endif
0025
0026 namespace boost { namespace locale {
0027
0028
0029
0030 namespace flags {
0031
0032
0033
0034 enum display_flags_type {
0035 posix = 0,
0036 number = 1,
0037 currency = 2,
0038 percent = 3,
0039 date = 4,
0040 time = 5,
0041 datetime = 6,
0042 strftime = 7,
0043 spellout = 8,
0044 ordinal = 9,
0045
0046 display_flags_mask = 31,
0047
0048 currency_default = 0 << 5,
0049 currency_iso = 1 << 5,
0050 currency_national = 2 << 5,
0051
0052 currency_flags_mask = 3 << 5,
0053
0054 time_default = 0 << 7,
0055 time_short = 1 << 7,
0056 time_medium = 2 << 7,
0057 time_long = 3 << 7,
0058 time_full = 4 << 7,
0059 time_flags_mask = 7 << 7,
0060
0061 date_default = 0 << 10,
0062 date_short = 1 << 10,
0063 date_medium = 2 << 10,
0064 date_long = 3 << 10,
0065 date_full = 4 << 10,
0066 date_flags_mask = 7 << 10,
0067 };
0068
0069
0070 enum pattern_type {
0071 datetime_pattern,
0072 time_zone_id
0073 };
0074
0075
0076 enum value_type {
0077 domain_id
0078 };
0079
0080 }
0081
0082
0083
0084
0085
0086
0087 class BOOST_LOCALE_DECL ios_info {
0088 public:
0089
0090 ios_info();
0091 ios_info(const ios_info&);
0092 ios_info& operator=(const ios_info&);
0093 ~ios_info();
0094
0095
0096
0097 static ios_info& get(std::ios_base& ios);
0098
0099
0100 void display_flags(uint64_t flags);
0101
0102 uint64_t display_flags() const;
0103
0104
0105 void currency_flags(uint64_t flags);
0106
0107 uint64_t currency_flags() const;
0108
0109
0110 void date_flags(uint64_t flags);
0111
0112 uint64_t date_flags() const;
0113
0114
0115 void time_flags(uint64_t flags);
0116
0117 uint64_t time_flags() const;
0118
0119
0120 void domain_id(int);
0121
0122 int domain_id() const;
0123
0124
0125 void time_zone(const std::string&);
0126
0127 std::string time_zone() const;
0128
0129
0130 template<typename CharType>
0131 void date_time_pattern(const std::basic_string<CharType>& str)
0132 {
0133 date_time_pattern_set().set<CharType>(str);
0134 }
0135
0136 template<typename CharType>
0137 std::basic_string<CharType> date_time_pattern() const
0138 {
0139 return date_time_pattern_set().get<CharType>();
0140 }
0141
0142
0143 void on_imbue();
0144
0145
0146 private:
0147 class string_set;
0148
0149 const string_set& date_time_pattern_set() const;
0150 string_set& date_time_pattern_set();
0151
0152 class BOOST_LOCALE_DECL string_set {
0153 public:
0154 string_set();
0155 ~string_set();
0156 string_set(const string_set& other);
0157 string_set& operator=(string_set other);
0158 void swap(string_set& other);
0159
0160 template<typename Char>
0161 void set(const boost::basic_string_view<Char> s)
0162 {
0163 BOOST_ASSERT(!s.empty());
0164 delete[] ptr;
0165 ptr = nullptr;
0166 type = &typeid(Char);
0167 size = sizeof(Char) * s.size();
0168 ptr = size ? new char[size] : nullptr;
0169 memcpy(ptr, s.data(), size);
0170 }
0171
0172 template<typename Char>
0173 std::basic_string<Char> get() const
0174 {
0175 if(type == nullptr || *type != typeid(Char))
0176 throw std::bad_cast();
0177 std::basic_string<Char> result(size / sizeof(Char), Char(0));
0178 memcpy(&result.front(), ptr, size);
0179 return result;
0180 }
0181
0182 private:
0183 const std::type_info* type;
0184 size_t size;
0185 char* ptr;
0186 };
0187
0188 uint64_t flags_;
0189 int domain_id_;
0190 std::string time_zone_;
0191 string_set datetime_;
0192 };
0193
0194
0195 namespace as {
0196
0197
0198
0199
0200
0201
0202 inline std::ios_base& posix(std::ios_base& ios)
0203 {
0204 ios_info::get(ios).display_flags(flags::posix);
0205 return ios;
0206 }
0207
0208
0209
0210 inline std::ios_base& number(std::ios_base& ios)
0211 {
0212 ios_info::get(ios).display_flags(flags::number);
0213 return ios;
0214 }
0215
0216
0217 inline std::ios_base& currency(std::ios_base& ios)
0218 {
0219 ios_info::get(ios).display_flags(flags::currency);
0220 return ios;
0221 }
0222
0223
0224 inline std::ios_base& percent(std::ios_base& ios)
0225 {
0226 ios_info::get(ios).display_flags(flags::percent);
0227 return ios;
0228 }
0229
0230
0231 inline std::ios_base& date(std::ios_base& ios)
0232 {
0233 ios_info::get(ios).display_flags(flags::date);
0234 return ios;
0235 }
0236
0237
0238 inline std::ios_base& time(std::ios_base& ios)
0239 {
0240 ios_info::get(ios).display_flags(flags::time);
0241 return ios;
0242 }
0243
0244
0245 inline std::ios_base& datetime(std::ios_base& ios)
0246 {
0247 ios_info::get(ios).display_flags(flags::datetime);
0248 return ios;
0249 }
0250
0251
0252
0253 inline std::ios_base& strftime(std::ios_base& ios)
0254 {
0255 ios_info::get(ios).display_flags(flags::strftime);
0256 return ios;
0257 }
0258
0259
0260 inline std::ios_base& spellout(std::ios_base& ios)
0261 {
0262 ios_info::get(ios).display_flags(flags::spellout);
0263 return ios;
0264 }
0265
0266
0267 inline std::ios_base& ordinal(std::ios_base& ios)
0268 {
0269 ios_info::get(ios).display_flags(flags::ordinal);
0270 return ios;
0271 }
0272
0273
0274 inline std::ios_base& currency_default(std::ios_base& ios)
0275 {
0276 ios_info::get(ios).currency_flags(flags::currency_default);
0277 return ios;
0278 }
0279
0280
0281 inline std::ios_base& currency_iso(std::ios_base& ios)
0282 {
0283 ios_info::get(ios).currency_flags(flags::currency_iso);
0284 return ios;
0285 }
0286
0287
0288 inline std::ios_base& currency_national(std::ios_base& ios)
0289 {
0290 ios_info::get(ios).currency_flags(flags::currency_national);
0291 return ios;
0292 }
0293
0294
0295 inline std::ios_base& time_default(std::ios_base& ios)
0296 {
0297 ios_info::get(ios).time_flags(flags::time_default);
0298 return ios;
0299 }
0300
0301
0302 inline std::ios_base& time_short(std::ios_base& ios)
0303 {
0304 ios_info::get(ios).time_flags(flags::time_short);
0305 return ios;
0306 }
0307
0308
0309 inline std::ios_base& time_medium(std::ios_base& ios)
0310 {
0311 ios_info::get(ios).time_flags(flags::time_medium);
0312 return ios;
0313 }
0314
0315
0316 inline std::ios_base& time_long(std::ios_base& ios)
0317 {
0318 ios_info::get(ios).time_flags(flags::time_long);
0319 return ios;
0320 }
0321
0322
0323 inline std::ios_base& time_full(std::ios_base& ios)
0324 {
0325 ios_info::get(ios).time_flags(flags::time_full);
0326 return ios;
0327 }
0328
0329
0330 inline std::ios_base& date_default(std::ios_base& ios)
0331 {
0332 ios_info::get(ios).date_flags(flags::date_default);
0333 return ios;
0334 }
0335
0336
0337 inline std::ios_base& date_short(std::ios_base& ios)
0338 {
0339 ios_info::get(ios).date_flags(flags::date_short);
0340 return ios;
0341 }
0342
0343
0344 inline std::ios_base& date_medium(std::ios_base& ios)
0345 {
0346 ios_info::get(ios).date_flags(flags::date_medium);
0347 return ios;
0348 }
0349
0350
0351 inline std::ios_base& date_long(std::ios_base& ios)
0352 {
0353 ios_info::get(ios).date_flags(flags::date_long);
0354 return ios;
0355 }
0356
0357
0358 inline std::ios_base& date_full(std::ios_base& ios)
0359 {
0360 ios_info::get(ios).date_flags(flags::date_full);
0361 return ios;
0362 }
0363
0364
0365 namespace detail {
0366 inline bool is_datetime_display_flags(const uint64_t display_flags)
0367 {
0368 return (display_flags == flags::date || display_flags == flags::time || display_flags == flags::datetime
0369 || display_flags == flags::strftime);
0370 }
0371
0372 template<typename CharType>
0373 struct add_ftime {
0374 std::basic_string<CharType> ftime;
0375
0376 void apply(std::basic_ios<CharType>& ios) const
0377 {
0378 ios_info::get(ios).date_time_pattern(ftime);
0379 as::strftime(ios);
0380 }
0381 };
0382
0383 template<typename CharType>
0384 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const add_ftime<CharType>& fmt)
0385 {
0386 fmt.apply(out);
0387 return out;
0388 }
0389
0390 template<typename CharType>
0391 std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, const add_ftime<CharType>& fmt)
0392 {
0393 fmt.apply(in);
0394 return in;
0395 }
0396
0397 }
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434 template<typename CharType>
0435 #ifdef BOOST_LOCALE_DOXYGEN
0436 unspecified_type
0437 #else
0438 detail::add_ftime<CharType>
0439 #endif
0440 ftime(const std::basic_string<CharType>& format)
0441 {
0442 detail::add_ftime<CharType> fmt;
0443 fmt.ftime = format;
0444 return fmt;
0445 }
0446
0447
0448 template<typename CharType>
0449 #ifdef BOOST_LOCALE_DOXYGEN
0450 unspecified_type
0451 #else
0452 detail::add_ftime<CharType>
0453 #endif
0454 ftime(const CharType* format)
0455 {
0456 detail::add_ftime<CharType> fmt;
0457 fmt.ftime = format;
0458 return fmt;
0459 }
0460
0461
0462 namespace detail {
0463 struct set_timezone {
0464 std::string id;
0465 };
0466 template<typename CharType>
0467 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const set_timezone& fmt)
0468 {
0469 ios_info::get(out).time_zone(fmt.id);
0470 return out;
0471 }
0472
0473 template<typename CharType>
0474 std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, const set_timezone& fmt)
0475 {
0476 ios_info::get(in).time_zone(fmt.id);
0477 return in;
0478 }
0479 }
0480
0481
0482
0483 inline std::ios_base& gmt(std::ios_base& ios)
0484 {
0485 ios_info::get(ios).time_zone("GMT");
0486 return ios;
0487 }
0488
0489
0490 inline std::ios_base& local_time(std::ios_base& ios)
0491 {
0492 ios_info::get(ios).time_zone(time_zone::global());
0493 return ios;
0494 }
0495
0496
0497 inline
0498 #ifdef BOOST_LOCALE_DOXYGEN
0499 unspecified_type
0500 #else
0501 detail::set_timezone
0502 #endif
0503 time_zone(const char* id)
0504 {
0505 detail::set_timezone tz;
0506 tz.id = id;
0507 return tz;
0508 }
0509
0510
0511 inline
0512 #ifdef BOOST_LOCALE_DOXYGEN
0513 unspecified_type
0514 #else
0515 detail::set_timezone
0516 #endif
0517 time_zone(const std::string& id)
0518 {
0519 detail::set_timezone tz;
0520 tz.id = id;
0521 return tz;
0522 }
0523
0524
0525
0526 }
0527
0528 }}
0529
0530 #ifdef BOOST_MSVC
0531 # pragma warning(pop)
0532 #endif
0533
0534 #endif