[gcc r17-3771] libstdc++: Skip locale in chrono operator<< for integer seconds precision
Tomasz Kaminski
tkaminsk@gcc.gnu.org
Sun Aug 30 13:41:36 GMT 2026
https://gcc.gnu.org/g:9c40d80365f334e01f6e864e62ca9965841774cb
commit r17-3771-g9c40d80365f334e01f6e864e62ca9965841774cb
Author: Anlai Lu <agicy@qq.com>
Date: Sun Aug 30 14:35:54 2026 +0200
libstdc++: Skip locale in chrono operator<< for integer seconds precision
When _Duration uses integer seconds precision (period::den == 1, not
floating-point), time_point formatting has no sub-second digits and
therefore no locale-dependent components. Add __detail::__chrono_write_time
that conditionally skips the locale argument for integer-second time_points,
eliminating the format_to_n locale overload and the basic_format_context
locale member initialization.
Also add [[__gnu__::__always_inline__]] to __formatter_chrono::_M_subsecs
to mitigate a small mixed-TU inlining regression.
libstdc++-v3/ChangeLog:
* include/bits/chrono_io.h (__detail::__chrono_write_time):
New function that conditionally skips locale for integer-second
time_points.
(__formatter_chrono::_M_subsecs): Add __always_inline__.
(operator<<(basic_ostream<...>, const hh_mm_ss<_Duration>&)):
Use if constexpr to skip locale for integer-second durations.
(operator<<(basic_ostream<...>, const zoned_time<_Duration>&))
(operator<<(basic_ostream<...>, const sys_time<_Duration>&))
(operator<<(basic_ostream<...>, const utc_time<_Duration>&))
(operator<<(basic_ostream<...>, const tai_time<_Duration>&))
(operator<<(basic_ostream<...>, const file_time<_Duration>&))
(operator<<(basic_ostream<...>, const local_time<_Duration>&)):
Use __chrono_write_time.
(operator<<(basic_ostream<...>, const sys_days<_Duration>&)):
Remove trailing semicolon.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Anlai Lu <agicy@qq.com>
Diff:
---
libstdc++-v3/include/bits/chrono_io.h | 44 +++++++++++++++++++++++++++--------
1 file changed, 34 insertions(+), 10 deletions(-)
diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h
index 0044b5a2ecc8..eec12357fdf7 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -1656,6 +1656,7 @@ namespace __format
}
template<typename _OutIter, typename _FormatContext>
+ [[__gnu__::__always_inline__]]
_OutIter
_M_subsecs(const _ChronoData<_CharT>& __t, _OutIter __out,
_FormatContext& __ctx) const
@@ -3635,6 +3636,23 @@ namespace __detail
return std::__ostream_insert(__os, __s.data(), __s.size());
}
+ // Wrapper around __chrono_write that skips locale for
+ // integer-second time_points.
+ template<size_t _BufSize, typename _TimePoint, typename _CharT,
+ typename _Traits>
+ [[__gnu__::__always_inline__]]
+ inline basic_ostream<_CharT, _Traits>&
+ __chrono_write_time(basic_ostream<_CharT, _Traits>& __os,
+ const _TimePoint& __tp)
+ {
+ using _Duration = typename _TimePoint::duration;
+ if constexpr (!treat_as_floating_point_v<typename _Duration::rep>
+ && _Duration::period::den == 1)
+ return __chrono_write<_BufSize>(__os, __tp);
+ else
+ return __chrono_write<_BufSize>(__os, __tp, __os.getloc());
+ }
+
} // namespace __detail
/// @endcond
@@ -3740,7 +3758,7 @@ namespace __detail
operator<<(basic_ostream<_CharT, _Traits>& __os,
const weekday_last& __wdl)
{ return __detail::__chrono_write<128>(__os, __wdl, __os.getloc()); }
-
+
template<typename _CharT, typename _Traits>
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md)
@@ -3846,7 +3864,13 @@ namespace __detail
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
const hh_mm_ss<_Duration>& __hms)
- { return __detail::__chrono_write<64>(__os, __hms, __os.getloc()); }
+ {
+ if constexpr (!treat_as_floating_point_v<typename _Duration::rep>
+ && _Duration::period::den == 1)
+ return __detail::__chrono_write<64>(__os, __hms);
+ else
+ return __detail::__chrono_write<64>(__os, __hms, __os.getloc());
+ }
#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
/// Writes a sys_info object to an ostream in an unspecified format.
@@ -3866,7 +3890,7 @@ namespace __detail
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
const zoned_time<_Duration, _TimeZonePtr>& __t)
- { return __detail::__chrono_write<128>(__os, __t, __os.getloc()); }
+ { return __detail::__chrono_write_time<128>(__os, __t); }
#endif
template<typename _CharT, typename _Traits, typename _Duration>
@@ -3875,12 +3899,12 @@ namespace __detail
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
const sys_time<_Duration>& __tp)
- { return __detail::__chrono_write<64>(__os, __tp, __os.getloc()); }
+ { return __detail::__chrono_write_time<64>(__os, __tp); }
template<typename _CharT, typename _Traits>
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_days& __dp)
- { return __detail::__chrono_write<32>(__os, __dp); };
+ { return __detail::__chrono_write<32>(__os, __dp); }
template<typename _CharT, typename _Traits, typename _Duration,
typename _Alloc = allocator<_CharT>>
@@ -3914,7 +3938,7 @@ namespace __detail
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
const utc_time<_Duration>& __t)
- { return __detail::__chrono_write<64>(__os, __t, __os.getloc()); }
+ { return __detail::__chrono_write_time<64>(__os, __t); }
template<typename _CharT, typename _Traits, typename _Duration,
typename _Alloc = allocator<_CharT>>
@@ -3946,7 +3970,7 @@ namespace __detail
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
const tai_time<_Duration>& __t)
- { return __detail::__chrono_write<64>(__os, __t, __os.getloc()); }
+ { return __detail::__chrono_write_time<64>(__os, __t); }
template<typename _CharT, typename _Traits, typename _Duration,
typename _Alloc = allocator<_CharT>>
@@ -3982,7 +4006,7 @@ namespace __detail
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
const gps_time<_Duration>& __t)
- { return __detail::__chrono_write<64>(__os, __t, __os.getloc()); }
+ { return __detail::__chrono_write_time<64>(__os, __t); }
template<typename _CharT, typename _Traits, typename _Duration,
typename _Alloc = allocator<_CharT>>
@@ -4017,7 +4041,7 @@ namespace __detail
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
const file_time<_Duration>& __t)
- { return __detail::__chrono_write<64>(__os, __t, __os.getloc()); }
+ { return __detail::__chrono_write_time<64>(__os, __t); }
template<typename _CharT, typename _Traits, typename _Duration,
typename _Alloc = allocator<_CharT>>
@@ -4040,7 +4064,7 @@ namespace __detail
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 4257. Stream insertion for chrono::local_time should be constrained
requires requires(const sys_time<_Duration>& __st) { __os << __st; }
- { return __detail::__chrono_write<64>(__os, __lt, __os.getloc()); }
+ { return __detail::__chrono_write_time<64>(__os, __lt); }
template<typename _CharT, typename _Traits, typename _Duration,
typename _Alloc = allocator<_CharT>>
More information about the Libstdc++-cvs
mailing list