constexpr
and noexcept
for operators for bitmask typesSection: 16.3.3.3.3 [bitmask.types] Status: New Submitter: Jiang An Opened: 2023-08-19 Last modified: 2024-02-22
Priority: 3
View other active issues in [bitmask.types].
View all other issues in [bitmask.types].
View all issues with New status.
Discussion:
Currently, no operator in 16.3.3.3.3 [bitmask.types]/2 is specified as noexcept
, and the compound assignment
operators are not specified as constexpr
.
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
.
[2024-02-22; Reflector poll]
Set priority to 3 after reflector poll in September 2023.
[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."
[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."
Proposed resolution:
This wording is relative to N4958.
Modify 16.3.3.3.3 [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; }