Title
constexpr and noexcept for operators for bitmask types
Status
new
Section
[bitmask.types]
Submitter
Jiang An

Created on 2023-08-19.00:00:00 last changed 2 months ago

Messages

Date: 2024-02-22.16:40:40

Proposed resolution:

This wording is relative to N4958.

  1. Modify [bitmask.types] as indicated:

    -2- The bitmask type bitmask can be written:

    // For exposition only.
    // int_type is an integral type capable of representing all values of the bitmask type.
    enum bitmask : int_type {
      V0 = 1 << 0, V1 = 1 << 1, V2 = 1 << 2, V3 = 1 << 3, …
    };
    
    inline constexpr bitmask C0(V0);
    inline constexpr bitmask C1(V1);
    inline constexpr bitmask C2(V2);
    inline constexpr bitmask C3(V3);
    
    […]
    
    constexpr bitmask operator&(bitmask X, bitmask Y) noexcept {
      return static_cast<bitmask>(
        static_cast<int_type>(X) & static_cast<int_type>(Y));
    }
    constexpr bitmask operator|(bitmask X, bitmask Y) noexcept {
      return static_cast<bitmask>(
        static_cast<int_type>(X) | static_cast<int_type>(Y));
    }
    constexpr bitmask operator^(bitmask X, bitmask Y) noexcept {
      return static_cast<bitmask>(
        static_cast<int_type>(X) ^ static_cast<int_type>(Y));
    }
    constexpr bitmask operator~(bitmask X) noexcept {
      return static_cast<bitmask>(~static_cast<int_type>(X));
    }
    constexpr bitmask& operator&=(bitmask& X, bitmask Y) noexcept {
      X = X & Y; return X;
    }
    constexpr bitmask& operator|=(bitmask& X, bitmask Y) noexcept {
      X = X | Y; return X;
    }
    constexpr bitmask& operator^=(bitmask& X, bitmask Y) noexcept {
      X = X ^ Y; return X;
    }
    
Date: 2024-02-22.16:40:40

[ Casey agreed ]

"We should strike paragraph two completely and write up the actual requirements that a bitmask type is required to meet, but that's a lot of work for someone."

Date: 2024-02-22.16:40:40

[ Jonathan commented ]

"The proposed change only affects an example showing a possible way to implement a made-up example type. It doesn't change any requirements on bitmask types, or change anything for any of the bitmask types defined in the standard library. It doesn't say that implementing them without noexcept and constexpr would be invalid. This change has no normative effect and certainly doesn't achieve the stated aim of requiring these assignments to be constexpr and non-throwing."

Date: 2024-02-15.00:00:00

[ 2024-02-22; Reflector poll ]

Set priority to 3 after reflector poll in September 2023.

Date: 2023-08-19.00:00:00

Currently, no operator in [bitmask.types]/2 is specified as noexcept, and the compound assignment operators are not specified as constexpr.

Implementations are divergent on this. E.g., MSVC STL consistently marks them constexpr and noexcept (given MSVC STL doesn't support pre-C++14 modes), while libstdc++'s compound assignment operators for match_flag_type are constexpr since C++14 but lack noexcept, and the operators for launch are noexcept but not constexpr.

I think it's better to ensure more consistency be integer types and non-integer bitmask types, i.e., require the compound assignment operators to be constexpr (only available in C++14 and later) and all operators to be noexcept.

History
Date User Action Args
2024-02-22 16:40:40adminsetmessages: + msg13962
2024-02-22 16:40:40adminsetmessages: + msg13961
2024-02-22 16:40:40adminsetmessages: + msg13960
2023-09-23 12:41:28adminsetmessages: + msg13723
2023-08-19 00:00:00admincreate