Thread-safe replacement for std::gmtime
| 352 | |
| 353 | // Thread-safe replacement for std::gmtime |
| 354 | inline std::tm gmtime(std::time_t time) { |
| 355 | struct dispatcher { |
| 356 | std::time_t time_; |
| 357 | std::tm tm_; |
| 358 | |
| 359 | dispatcher(std::time_t t) : time_(t) {} |
| 360 | |
| 361 | bool run() { |
| 362 | using namespace fmt::internal; |
| 363 | return handle(gmtime_r(&time_, &tm_)); |
| 364 | } |
| 365 | |
| 366 | bool handle(std::tm* tm) { return tm != nullptr; } |
| 367 | |
| 368 | bool handle(internal::null<>) { |
| 369 | using namespace fmt::internal; |
| 370 | return fallback(gmtime_s(&tm_, &time_)); |
| 371 | } |
| 372 | |
| 373 | bool fallback(int res) { return res == 0; } |
| 374 | |
| 375 | #if !FMT_MSC_VER |
| 376 | bool fallback(internal::null<>) { |
| 377 | std::tm* tm = std::gmtime(&time_); |
| 378 | if (tm) tm_ = *tm; |
| 379 | return tm != nullptr; |
| 380 | } |
| 381 | #endif |
| 382 | }; |
| 383 | dispatcher gt(time); |
| 384 | // Too big time values may be unsupported. |
| 385 | if (!gt.run()) FMT_THROW(format_error("time_t value out of range")); |
| 386 | return gt.tm_; |
| 387 | } |
| 388 | |
| 389 | namespace internal { |
| 390 | inline std::size_t strftime(char* str, std::size_t count, const char* format, |
no test coverage detected