// { dg-do run { target c++20 } } // { dg-require-effective-target tzdb } #include #include #include #include struct local_tz { local_tz() : name(std::chrono::current_zone()->name()) { } explicit local_tz(std::string_view name) : name(name) { } template std::chrono::sys_time to_sys(const std::chrono::local_time& d) { return std::chrono::locate_zone(name)->to_sys(d); } template std::chrono::sys_time to_local(const std::chrono::sys_time& d) { return std::chrono::locate_zone(name)->to_sys(d); } template std::chrono::sys_info get_info(const std::chrono::sys_time& d) { return std::chrono::locate_zone(name)->get_info(d); } struct indirect_cmp { bool operator()(const local_tz* lhs, const local_tz* rhs) const { return lhs->name < rhs->name; } }; bool eq(const std::chrono::time_zone* tz) const noexcept { return name == tz->name(); } private: std::string_view name; }; template<> struct std::chrono::zoned_traits { static const local_tz* default_zone() { return locate_zone(std::chrono::current_zone()->name()); } static const local_tz* locate_zone(std::string_view name) { static std::set zones; local_tz tz(name); if (auto z = zones.find(&tz); z != zones.end()) return *z; if (std::chrono::locate_zone(name)) return *zones.insert(new local_tz(tz)).first; throw std::runtime_error("zone not found"); } }; void test_custom_tzptr() { using namespace std::chrono; zoned_time z; VERIFY( z.get_time_zone()->eq(std::chrono::current_zone()) ); zoned_time z2(std::string_view("Europe/London")); VERIFY( z2.get_time_zone()->eq(std::chrono::locate_zone("Europe/London")) ); } int main() { test_custom_tzptr(); }