This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4400. enable_nonlocking_formatter_optimization for durations with custom rep

Section: 30.12 [time.format] Status: New Submitter: Tomasz KamiƄski Opened: 2025-10-02 Last modified: 2025-10-04

Priority: Not Prioritized

View other active issues in [time.format].

View all other issues in [time.format].

View all issues with New status.

Discussion:

Currently the enable_nonlocking_formatter_optimization is enabled for duration<Rep, Ratio> if it is enabled for Rep.

template<class Rep, class Period> 
  constexpr bool enable_nonlocking_formatter_optimization<chrono::duration<Rep, Period>>
    =  enable_nonlocking_formatter_optimization<Rep>;

However, this does not take into the consideration that for custom Rep types, the arithmetic operations on Rep may also lock the stream leading to deadlock (for example log on overflow). Since they are required to handle the specifiers such as %S we should specialize enable_nonlocking_formatter_optimization only for built-in types:

template<class Rep, class Period> 
  constexpr bool enable_nonlocking_formatter_optimization<chrono::duration<Rep, Period>>
    =  is_arithmetic_v<Rep>;

Furtheremore, for all types that are currently templated on Duration (hh_mm_ss, sys_time, local_time, etc.), we enable_nonlocking_formatter_optimization by default. This again does not take into consideration the arithmetic operations performed as duration. We should specialize enable_nonlocking_formatter_optimization for all of them to be enabled if enable_nonlocking_formatter_optimization is enabled for duration:

template<class Duration> 
  constexpr bool enable_nonlocking_formatter_optimization<chrono::hh_mm_ss<Duration>>
    =  enable_nonlocking_formatter_optimization<Duration>;

Note, that forwarding to enable_nonlocking_formatter_optimization on Duration instead of checking Duration::rep allows users to specialize enable_nonlocking_formatter_optimization for Durations with there custom representation types.

The proposed wording has recently been implemented in gcc's libstdc++.

Proposed resolution:

This wording is relative to N5014.

  1. Modify 30.12 [time.format] as indicated:

    -8- For chrono::duration, chrono::hh_mm_ss, chrono::sys_time, chrono::utc_time, chrono::tai_time, chrono::gps_time, chrono::file_time, chrono::local_time, chrono::local-time-format-t, and chrono::zoned_time the library only provides the following specializations of enable_nonlocking_formatter_optimization:

    template<class Rep, class Period>
      constexpr bool enable_nonlocking_formatter_optimization<
        chrono::duration<Rep, Period>> =
          enable_nonlocking_formatter_optimizationis_arithmetic_v<Rep>;
          
    template<class Duration> 
      constexpr bool enable_nonlocking_formatter_optimization<chrono::hh_mm_ss<Duration>> 
         = enable_nonlocking_formatter_optimization<Duration>;
    
    template<class Duration> 
      constexpr bool enable_nonlocking_formatter_optimization<chrono::sys_time<Duration>> 
         = enable_nonlocking_formatter_optimization<Duration>;
    
    template<class Duration> 
      constexpr bool enable_nonlocking_formatter_optimization<chrono::utc_time<Duration>> 
         = enable_nonlocking_formatter_optimization<Duration>;
    
    template<class Duration> 
      constexpr bool enable_nonlocking_formatter_optimization<chrono::tai_time<Duration>> 
         = enable_nonlocking_formatter_optimization<Duration>;
    
    template<class Duration> 
      constexpr bool enable_nonlocking_formatter_optimization<chrono::gps_time<Duration>> 
         = enable_nonlocking_formatter_optimization<Duration>;
    
    template<class Duration> 
      constexpr bool enable_nonlocking_formatter_optimization<chrono::file_time<Duration>> 
         = enable_nonlocking_formatter_optimization<Duration>;
    
    template<class Duration> 
      constexpr bool enable_nonlocking_formatter_optimization<chrono::local_time<Duration>> 
         = enable_nonlocking_formatter_optimization<Duration>;
    
    template<class Duration> 
      constexpr bool enable_nonlocking_formatter_optimization<chrono::local-time-format-t<Duration>> 
         = enable_nonlocking_formatter_optimization<Duration>;
    

    -9- For chrono::zoned_time the library only provides the following specialization of enable_nonlocking_formatter_optimization:

    template<class Duration>
      constexpr bool enable_nonlocking_formatter_optimization<
        chrono::zoned_time<Duration, const std::chrono::time_zone*>> 
          = trueenable_nonlocking_formatter_optimization<Duration>;