[Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'

2024-01-18 Thread Hirthammer--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500

Bug ID: 113500
   Summary: Using std::format with float or double based
std::chrono::time_point causes error: no match for
'operator<<'
   Product: gcc
   Version: 13.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: hirtham...@allterra-dno.de
  Target Milestone: ---

Consider the following code snippet:

---
using Representation = double;
using Duration   = std::chrono::duration;
using Clock  = std::chrono::system_clock;
using TimePoint  = std::chrono::time_point;

TimePoint tp = {};

std::string time_string = std::format("{:%d.%m.%Y %H:%M:%S}", tp);
---


This results in the compile error:


---
error: no match for 'operator<<' (operand types are
'std::__cxx11::basic_ostringstream' and 'const
std::chrono::time_point >')
  726 |   __os << __t;
  |   ~^~
---

If you change the type def `Representation` to an integer or unsigned integer
type, the code compiles.

System Info:

~~~
OS: Ubuntu 22.04 LTS
GCC-Version: 13.1.0
arguments: -std=c++20
~~~

Here is a link with the code that produces the error in Compiler Explorer:

https://godbolt.org/z/hhPrG1z37

Side note: 
Don't know if it helps, but the latest clang compiler version produces the same
error. The related bug report can be found here:

https://github.com/llvm/llvm-project/issues/78555

[Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'

2024-01-19 Thread Hirthammer--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500

--- Comment #3 from hirtham...@allterra-dno.de ---
Sorry, for the missing includes.

> Since this is a bug in libstdc++ headers it's not at all surprising that you 
> get 
> the same error with any compiler using those headers. This should not have 
> been 
> reported to llvm.

Thanks for clarifying this.

[Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'

2024-01-19 Thread Hirthammer--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500

--- Comment #5 from hirtham...@allterra-dno.de ---
(In reply to Jonathan Wakely from comment #4)
> MSVC rejects this the same way, although libc++ from LLVM 17 compiles it.
> 
> AFAICT std::format("{}", tp) would be invalid because that formats tp by
> writing to a stream, and there is no operator<< for
> sys_time>.
> 
> Arguably, std::format("{:%S}", tp) could work, because it doesn't need to
> use operator<< but the problem is that we can't detect at compile-time
> whether or not we need to use operator<< for a given format string. So it
> always fails to compile.
> 
> The reason it works with libc++ is because they have a bug in their
> operator<< for sys_time.
> 
> I think libstdc++ is correct here, but I've asked the C++ committee whether
> we might want to change the standard to support this case.

This whole thing with std::format and std::chrono::time_point is currently a
total minefield. In MSVC it is even more complicated and I already reported the
bug in October 2023. See:

https://developercommunity.visualstudio.com/t/Using-std::format-with-unsigned-integer-/10501153

If you change the clock to utc_clock or gps_clock the code compiles with MSVC
(but not with GCC) on Compiler Explorer.

I don't know much about the exact definitions of the standard. But I find it
very confusing if std::format generally supports a std::chrono::time_point as
an input, but depending on the chosen template arguments of the time_point it
does or does not compile.

[Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'

2024-01-22 Thread Hirthammer--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500

--- Comment #11 from hirtham...@allterra-dno.de ---
(In reply to Jonathan Wakely from comment #7)
> (In reply to Jonathan Wakely from comment #6)
> > (In reply to Hirthammer from comment #5)
> > > This whole thing with std::format and std::chrono::time_point is 
> > > currently a
> > > total minefield.
> > 
> > That seems like an exaggeration.
> > 
> > > In MSVC it is even more complicated and I already reported
> > > the bug in October 2023. See:
> > > 
> > > https://developercommunity.visualstudio.com/t/Using-std::format-with-
> > > unsigned-integer-/10501153
> > > 
> > > If you change the clock to utc_clock or gps_clock the code compiles with
> > > MSVC (but not with GCC) on Compiler Explorer.
> > 
> > It compiles fine with GCC for me.
> 
> Ah, maybe you mean your original example. The one at in the MSVC bug report
> compiles fine with GCC using utc_clock and gps_clock.
> 
> Your original example doesn't, because formatting a utc_time or gps_time is
> specified in terms of a sys_time, and that's how libstdc++ implements it. So
> if the utc_time or gps_time uses a float rep, we're back to square one.
> 
> I'll ask the committee to clarify that too.

Yes, I was referring to my original example because it helped me to understand
which combinations worked and which did not. 

I wrote a wrapper class around std::chrono::time_point, because I am dealing a
lot with different time formats. I am also doing multi-platform development,
and during the testing phase, it turned out that no compiler was able to
compile all templated test cases (Clang uses libstdc++ if you do not explicitly
tell it not to do, as you pointed out on the llvm bug report). Since the error
case parameter combinations differed from MSVC and GCC, I had to use many
different compiler-specific sections to get consistent and valid behavior in
the tests. That's why I called it a minefield. Maybe it was exaggerated ;).

Anyways, thank you a lot for your effort and clarifications and especially for
the fast fix.