On Mon, 26 Oct 2026 at 12:14, Tomasz Kaminski <[email protected]> wrote:
>
>
>
> On Mon, Oct 26, 2026 at 1:12 PM Jonathan Wakely <[email protected]> wrote:
>>
>> 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.
>
> The patch has corrected version, the condtion should be negated.
> > +  template<typename _TimeZonePtr>
> > +    struct __time_zone_representation_impl
> > +    {
> > +      static_assert(!std::is_convertible_v<_TimeZonePtr, string_view>,
> We should accept anything that is not zone name, not reverse.

Yes. I copy&pasted the static_assert from your first email, rather
than applying the incremental patch, because I'd already applied the
changes to <chrono> when you sent the patch.


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