On Mon, 26 Oct 2026 at 11:58, Tomasz Kamiński <[email protected]> wrote:
>
> 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);

This fails the static_assert in __time_zone_representation_struct,
because zone_offset is not convertible to string_view.



> +  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