Title
Partial specialization of `std::format_kind` for `std::optional` is not marked hosted
Status
new
Section
[freestanding.item] [optional.syn] [format.syn]
Submitter
Jiang An

Created on 2026-05-29.00:00:00 last changed 1 week ago

Messages

Date: 2026-05-29.16:09:51

Proposed resolution:

This wording is relative to N5046.

[Drafting Note: Three options are prepared, depicted below by Option A, Option B, and Option C, respectively, where option C is mutually exclusive with option A and B.

Note that libstdc++ effectively implemented option A recently (in commit 23b9ac257cf508bc4fa479c82fcfc768c4abcd79).]

Option A: Just marking the partial specialization hosted

  1. Modify [optional.syn], header <optional> synopsis, as indicated:

    […]
    template<class T>
      constexpr bool ranges::enable_view<optional<T>> = true;
    template<class T>
      constexpr auto format_kind<optional<T>> = range_format::disabled; // hosted
    template<class T>
      constexpr bool ranges::enable_borrowed_range<optional<T&>> = true;
    […]
    

Option B: Adding a general rule that infers hosted-ness of specializations

  1. Modify [freestanding.item] as indicated:

    -4- A declaration in a synopsis is a freestanding item if […]

    -5- An entity or deduction guide is a freestanding item if its introducing declaration is not followed by a comment that includes hosted, and is: […]

    -6- A macro is a freestanding item if it is defined in a header synopsis and […]

    -?- A partial or full template specialization is not a freestanding item if its primary template is not a freestanding item.

Option C: Making `range_format` and `format_kind` freestanding

  1. Modify Table 27 [tab:headers.cpp.fs] as indicated:

    Table 27: C++ headers for freestanding implementations [tab:headers.cpp.fs]
    Subclause Header
    […]
    [charconv] Primitive numeric conversions <charconv>
    [format] Formatting <format>
    [rand] Random number generation <random>
    […]
  2. Modify [format.syn], header <format> synopsis, as indicated:

    […]
    // [format.range], formatting of ranges
    // [format.range.fmtkind], variable template format_kind
    enum class range_format {
      disabled,
      map,
      set,
      sequence,
      string,
      debug_string
    };
    
    template<class R>
      constexpr unspecified format_kind = unspecified;         // freestanding
    
    template<ranges::input_range R>
      requires same_as<R, remove_cvref_t<R>>
      constexpr range_format format_kind<R> = see below;       // freestanding
    […]
    
Date: 2026-05-29.00:00:00

Currently, <optional> is a mostly freestanding header and provides a partial specialization of `std::format_kind` which isn't mark `// hosted` in the synopsis ([optional.syn]). The current rules in [freestanding.item] p4 seemingly requires the partial specialization to be a freestanding item, while nothing seems to requires the primary template (provided by <format>) to be freestanding.

The status quo looks quite weird. Perhaps we should make the freestanding status same for the primary template and the partial specialization.

History
Date User Action Args
2026-05-29 16:09:51adminsetmessages: + msg16349
2026-05-29 00:00:00admincreate