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