Attaching below suggestions as incremental diff from yours patch.
---
 libstdc++-v3/include/std/chrono               | 21 ++++++--
 .../time/zoned_time/custom_freestanding.cc    | 48 +++++++++++++++++++
 2 files changed, 65 insertions(+), 4 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/std/time/zoned_time/custom_freestanding.cc

diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index 10e2830b66c..a74a28e73f9 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -3160,6 +3160,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       };
 
 #if __cpp_lib_chrono >= 201803L // C++ >= 20 && HOSTED && USE_CXX11_ABI
+    using zoned_seconds = zoned_time<seconds>;
 
     zoned_time() -> zoned_time<seconds>;
 
@@ -3174,6 +3175,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                        const time_zone*,
                        remove_cvref_t<_TimeZonePtrOrName>>;
   /// @endcond
+#else
+  /// @cond undocumented
+  template<typename _TimeZonePtr>
+    struct __time_zone_representation_impl
+    {
+      static_assert(!std::is_convertible_v<_TimeZonePtr, string_view>,
+                   "std::time_zone is not supported in freedstanding mode,"
+                   " use custom time_zone representation");
+      using type = remove_cvref_t<_TimeZonePtr>;
+    };
+
+  template<typename _TimeZonePtrOrName>
+    using __time_zone_representation
+      = typename __time_zone_representation_impl<_TimeZonePtrOrName>::type;
+  /// @endcond
+#endif // __cpp_lib_chrono >= 201803L
 
   template<typename _TimeZonePtrOrName>
     zoned_time(_TimeZonePtrOrName&&)
@@ -3197,10 +3214,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       -> zoned_time<common_type_t<_Duration, seconds>,
                     __time_zone_representation<_TimeZonePtrOrName>>;
 
-    using zoned_seconds = zoned_time<seconds>;
-
-#endif // __cpp_lib_chrono >= 201803L
-
   template<typename _Dur1, typename _TZPtr1, typename _Dur2, typename _TZPtr2>
     [[nodiscard]]
     inline bool
diff --git a/libstdc++-v3/testsuite/std/time/zoned_time/custom_freestanding.cc 
b/libstdc++-v3/testsuite/std/time/zoned_time/custom_freestanding.cc
new file mode 100644
index 00000000000..ae7d1970206
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/time/zoned_time/custom_freestanding.cc
@@ -0,0 +1,48 @@
+// { dg-do run { target c++20 } }
+
+#include <chrono>
+#include <type_traits>
+#include <testsuite_hooks.h>
+
+struct zone_offset
+{
+  std::chrono::seconds offset;
+
+  template<typename Dur>
+    std::chrono::local_time<std::common_type_t<Dur, std::chrono::seconds>>
+    to_local(const std::chrono::sys_time<Dur>& tp) const noexcept
+    { return std::chrono::local_time<std::common_type_t<Dur, 
std::chrono::seconds>>(tp.time_since_epoch() + offset); }
+
+  template<typename Dur>
+    std::chrono::sys_time<std::common_type_t<Dur, std::chrono::seconds>>
+    to_sys(const std::chrono::local_time<Dur>& tp) const noexcept
+    { return std::chrono::sys_time<std::common_type_t<Dur, 
std::chrono::seconds>>(tp.time_since_epoch() - offset); }
+
+  // Allows zone_offset to be stored directly in zoned_time
+  const zone_offset* operator->() const noexcept
+  { return this; }
+};
+
+void
+test_custom_tzptr()
+{
+  using namespace std::chrono;
+
+  static_assert( !std::is_default_constructible_v<zoned_time<seconds, 
zone_offset>> );
+  static_assert( !std::is_constructible_v<zoned_time<seconds, zone_offset>, 
std::string_view> );
+
+  zoned_time z1(zone_offset{1h}, sys_days(2012y/December/12) + 12h);
+  static_assert( std::is_same_v<decltype(z1), zoned_time<seconds, 
zone_offset>> );
+  VERIFY( z1.get_sys_time() == sys_days(2012y/December/12) + 12h );
+  VERIFY( z1.get_local_time() == local_days(2012y/December/12) + 13h );
+
+  zoned_time z2(zone_offset{1h}, local_days(2012y/December/12) + 12h);
+  static_assert( std::is_same_v<decltype(z2), zoned_time<seconds, 
zone_offset>> );
+  VERIFY( z1.get_sys_time() == sys_days(2012y/December/12) + 11h );
+  VERIFY( z1.get_local_time() == local_days(2012y/December/12) + 12h );
+}
+
+int main()
+{
+  test_custom_tzptr();
+}
-- 
2.56.0

Reply via email to