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.

4362. Inconsistent usage of constexpr for inplace_stop_token and inplace_stop_source

Section: 32.3.8 [stoptoken.inplace] Status: New Submitter: Lewis Baker Opened: 2025-08-28 Last modified: 2025-09-15

Priority: Not Prioritized

View all issues with New status.

Discussion:

The inplace_stop_source::get_token() member function is declared constexpr, but there are no constexpr member-functions declared on inplace_stop_token, making the utility of being able to call this member function during constant evaluation limited.

Should the member functions of inplace_stop_token also be declared constexpr? i.e. operator==, swap(), stop_possible() and stop_requested().

The operator== and stop_possible() and swap() member functions should be able to be made constexpr trivially as they are just required to compare/modify pointers to the associated stop source.

The stop_requested() member function is specified to be equivalent to calling stop_requested() on the associated inplace_stop_source (if any), which is not currently declared constexpr primarily because its implementation requires synchronisation/atomic operations.

Now that std::atomic operations are now constexpr, it may be possible/appropriate for stop_requested() on both inplace_stop_source and inplace_stop_token to also be declared constexpr.

Proposed resolution:

This wording is relative to N5014.

[Drafting note:: This is the minimum proposed wording change. Additionally, consider adding constexpr to the declaration of inplace_stop_token::stop_requested() (in 32.3.8.1 [stoptoken.inplace.general] and 32.3.8.2 [stoptoken.inplace.mem]) and to inplace_stop_source::stop_requested() (in 32.3.9.1 [stopsource.inplace.general] and 32.3.9.3 [stopsource.inplace.mem])]

  1. Modify 32.3.8.1 [stoptoken.inplace.general], class inplace_stop_token synopsis, as indicated:

    namespace std {
      class inplace_stop_token {
      public:
        template<class CallbackFn>
          using callback_type = inplace_stop_callback<CallbackFn>;
        
        constexpr inplace_stop_token() = default;
        constexpr bool operator==(const inplace_stop_token&) const = default;
        
        // 32.3.8.2 [stoptoken.inplace.mem], member functions
        bool stop_requested() const noexcept;
        constexpr bool stop_possible() const noexcept;
        constexpr void swap(inplace_stop_token&) noexcept;
        
      private:
        const inplace_stop_source* stop-source = nullptr; // exposition only
      };
    }
    
  2. Modify 32.3.8.2 [stoptoken.inplace.mem] as indicated:

    [Drafting note:: As a drive-by fix this adds the missing return type bool to the stop_possible() prototype]

    constexpr void swap(inplace_stop_token& rhs) noexcept;
    

    -1- Effects: Exchanges the values of stop-source and rhs.stop-source.

    […]
    constexpr bool stop_possible() const noexcept;
    

    -4- Returns: stop-source != nullptr.