Am Mi., 4. Juni 2025 um 11:27 Uhr schrieb Tomasz Kamiński <
tkami...@redhat.com>:

> This patches fixes an obvious error, where the output iterator argument was
> missing for call to format_to, when duration with custom representation
> types
> are used.
>
> It's also adding the test for behavior of ostream operator and the
> formatting
> with empty chron-spec for the chrono types. Current coverage is:
>  * duration and hh_mm_ss in this commit,
>  * calendar types in r16-1016-g28a17985dd34b7.
>
> libstdc++-v3/ChangeLog:
>
>         * include/bits/chrono_io.h (__formatter_chrono:_M_s): Add missing
>         __out argument to format_to call.
>         * testsuite/std/time/format/empty_spec.cc: New test.
> ---
> Tested on x86_64-linux. OK for trunk?
>
>  libstdc++-v3/include/bits/chrono_io.h         |   3 +-
>  .../testsuite/std/time/format/empty_spec.cc   | 271 ++++++++++++++++++
>  2 files changed, 273 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/include/bits/chrono_io.h
> b/libstdc++-v3/include/bits/chrono_io.h
> index 346eb8b3c33..239f9c78009 100644
> --- a/libstdc++-v3/include/bits/chrono_io.h
> +++ b/libstdc++-v3/include/bits/chrono_io.h
> @@ -1296,7 +1296,8 @@ namespace __format
>                   else
>                     {
>                       auto __str = std::format(_S_empty_spec,
> __ss.count());
> -                     __out = std::format_to(_GLIBCXX_WIDEN("{:0>{}s}"),
> +                     __out = std::format_to(std::move(__out),
> +                                            _GLIBCXX_WIDEN("{:0>{}s}"),
>                                              __str,
>                                              __hms.fractional_width);
>                     }
> diff --git a/libstdc++-v3/testsuite/std/time/format/empty_spec.cc
> b/libstdc++-v3/testsuite/std/time/format/empty_spec.cc
> index 322faa1939d..46942dc30fc 100644
> --- a/libstdc++-v3/testsuite/std/time/format/empty_spec.cc
> +++ b/libstdc++-v3/testsuite/std/time/format/empty_spec.cc
> @@ -1,7 +1,9 @@
>  // { dg-do run { target c++20 } }
> +// { dg-require-effective-target hosted }
>  // { dg-timeout-factor 2 }
>
>  #include <chrono>
> +#include <ranges>
>  #include <sstream>
>  #include <testsuite_hooks.h>
>
> @@ -49,6 +51,274 @@ void verify(const T& t, const _CharT* str)
>    VERIFY( res == str );
>  }
>
> +template<typename Ret = void>
> +struct Rep
> +{
> +  using Return
> +    = std::conditional_t<std::is_void_v<Ret>, Rep, Ret>;
> +
> +  Rep(long v = 0) : val(v) {}
> +
> +  operator long() const
> +  { return val; }
> +
> +  Return
> +  operator+() const
> +  { return val; }
> +
> +  Rep
> +  operator-() const
> +  { return -val; }
> +
> +  friend Rep
> +  operator+(Rep lhs, Rep rhs)
> +  { return lhs.val + rhs.val; }
> +
> +  friend Rep
> +  operator-(Rep lhs, Rep rhs)
> +  { return lhs.val - rhs.val; }
> +
> +  friend Rep
> +  operator*(Rep lhs, Rep rhs)
> +  { return lhs.val * rhs.val; }
> +
> +  friend Rep
> +  operator/(Rep lhs, Rep rhs)
> +  { return lhs.val / rhs.val; }
> +
> +  friend auto operator<=>(Rep, Rep) = default;
> +
> +  template<typename _CharT>
> +  friend std::basic_ostream<_CharT>&
> +  operator<<(std::basic_ostream<_CharT>& os, const Rep& t)
> +  { return os << t.val << WIDEN("[via <<]"); }
> +
> +  long val;
> +};
> +
> +template<typename Ret, typename Other>
> +  requires std::is_integral_v<Other>
> +struct std::common_type<Rep<Ret>, Other>
> +{
> +  using type = Rep<Ret>;
> +};
> +
> +template<typename Ret, typename Other>
> +  requires std::is_integral_v<Other>
> +struct std::common_type<Other, Rep<Ret>>
> +  : std::common_type<Rep<Ret>, Other>
> +{ };
>

Why is this second specialization needed? It seems to me
that [meta.trans.other] p5 says that it is already provided by the library
implementation of  std::common_type.

- Daniel

Reply via email to