Title
§[format.formatter.spec]/3 unconditionally enables nonlocking for container adaptors
Status
new
Section
[format.formatter.spec][container.adaptors.format]
Submitter
Casey Carter

Created on 2024-08-31.00:00:00 last changed 1 month ago

Messages

Date: 2024-09-01.07:51:02

Proposed resolution:

This wording is relative to N4988.

  1. Modify [container.adaptors.format] as indicated:

    -1- For each of queue, priority_queue, and stack, the library provides the following formatter specializations where adaptor-type is the name of the template:

    namespace std {
      template<class charT, class T, formattable<charT> Container, class... U>
      struct formatter<adaptor-type<T, Container, U...>, charT> {
        […]
      };
    
      template<class T, class Container, class... U>
      constexpr bool enable_nonlocking_formatter_optimization<adaptor-type<T, Container, U...>> =
        enable_nonlocking_formatter_optimization<T>;
    }
    
Date: 2024-08-31.00:00:00

[format.formatter.spec]/3 says that the library provides a specialization of `enable_nonlocking_formatter_optimization` with value `true` corresponding to each library-provided specialization of `formatter`, unless otherwise specified. Although it actually states "for each type `T`", the intent is that partial specializations are also provided corresponding to library-provided partial specializations of formatter.

[container.adaptors.format]/1 says the library provides a partial specialization of `formatter` for each of the container adaptor templates `priority_queue`, `queue`, and `stack`. Together with [format.formatter.spec]/3, that means that e.g. enable_nonlocking_formatter_optimization<stack<T>> == true. Formatting a stack of that type will enable the nonlocking optimization even if enable_nonlocking_formatter_optimization<T> == false. To avoid this, the author of `T` must partially specialize `enable_nonlocking_formatter_optimization` to `false` for all container adaptors when they adapt a container of `T`.

It is clearly not the design intent that programmers must explicitly opt out of the nonlocking optimization, so this is a defect that LWG should correct. Since P3235R3 was applied as a Defect Report to C++23, the resolution of this issue should be so applied as well.

Suggested Resolution:

LEWG was reticent to apply the optimization to general ranges — ostensibly due to the possibility of deadlock in program-defined iterator operations — but apparently unconcerned about the iterators of program-defined containers nor the fancy pointers of program-defined allocators. It seems consistent with that design to ignore the "container" part of "container adaptors" and only pay attention to the elements that are going to be formatted. (I have prototyped this resolution on MSVCSTL, albeit slightly modified since neither MSVC nor Clang like this partial specialization form.)

History
Date User Action Args
2024-09-01 07:51:02adminsetmessages: + msg14351
2024-08-31 00:00:00admincreate