Date: Thu, 29 Oct 2026 09:43:30 +0000
Oh, yeah I see how _BitInt types would break the guarantee. Darn, I do care about being able to support those in my code. I guess I'll just check the max value anyways.
Thanks
On Wednesday, October 28th, 2026 at 12:37 PM, Jan Schultke <janschultke_at_[hidden]> wrote:
> On Wed, 28 Oct 2026 at 10:25, Keenan Horrigan via Std-Discussion <std-discussion_at_[hidden]> wrote:
>
>> Hi,
>>
>> I was writing a version of 'std::saturating_cast' that would work with integer-class types as well, because I want to saturate-cast to an iterator's difference type, so I was reading where the standard lays out the rules for integer-class types: https://eel.is/c++draft/iterator.concept.winc
>>
>> In there, it's mentioned that "The width of an integer-class type is greater than that of every integral type of the same signedness", and I was wondering if the "of the same signedness" part really matters? Every (non-bool, non-character) integral type has a corresponding integer type of the opposite signedness which has the same width, and bool and the character types are defined in terms of signed or unsigned integer types, which again should come with a corresponding signed/unsigned version of the same width. So I'm not sure how the signedness of the integer-class type would affect how its width compares to integral types, which makes me worry that I'm missing something.
>
> I don't think that the "of the same signedness" part is meaningful because every signed integer type has a corresponding unsigned type, and these have the same width. Integral types other than the signed integer types (e.g. char32_t) have an unsigned integer type as their underlying type, so they also don't cause any asymmetry.
>
> Maybe someone was overly cautious when writing this wording; I don't see how the signedness matters.
>
>> It's somewhat meaningful to me, since I'm wanting to saturate-cast a 'std::size_t' into the iterator's difference type, and since 'std::size_t' is some unsigned integer type, if all integer-class types have a greater width than all integral types, then theoretically I wouldn't need to even check that the 'std::size_t' value fits into the range of the integer-class type, including in the case where the integer-class type is signed. Because if we say that 'std::size_t' has a width of 'N', then its maximum value is '2^N - 1', and if the integer-class type has a width of 'N + 1', then, in the case that it's signed, its max value would be '2^(N + 1 - 1) - 1', aka '2^N - 1'.
>
> That is correct. If std::size_t is, say, 64-bit unsigned, the narrowest possible integer-class type is 65-bit signed, and that can represent all the values. There cannot be a 64-bit signed integer-class type. So I think you're safe to assume that an integer-class type can represent all standard and extended integer types.
>
> However, this entire principle falls apart once P3666 and thus bit-precise integers are introduced into the language. We have std::_Signed128 for example, which is clearly not able to represent, say, all _BitInt(1000000) values, and std::is_integral_v is true for bit-precise integers. Also, integer-class types are not going away because it would break ABI. iota_view needs to stay the same.
Thanks
On Wednesday, October 28th, 2026 at 12:37 PM, Jan Schultke <janschultke_at_[hidden]> wrote:
> On Wed, 28 Oct 2026 at 10:25, Keenan Horrigan via Std-Discussion <std-discussion_at_[hidden]> wrote:
>
>> Hi,
>>
>> I was writing a version of 'std::saturating_cast' that would work with integer-class types as well, because I want to saturate-cast to an iterator's difference type, so I was reading where the standard lays out the rules for integer-class types: https://eel.is/c++draft/iterator.concept.winc
>>
>> In there, it's mentioned that "The width of an integer-class type is greater than that of every integral type of the same signedness", and I was wondering if the "of the same signedness" part really matters? Every (non-bool, non-character) integral type has a corresponding integer type of the opposite signedness which has the same width, and bool and the character types are defined in terms of signed or unsigned integer types, which again should come with a corresponding signed/unsigned version of the same width. So I'm not sure how the signedness of the integer-class type would affect how its width compares to integral types, which makes me worry that I'm missing something.
>
> I don't think that the "of the same signedness" part is meaningful because every signed integer type has a corresponding unsigned type, and these have the same width. Integral types other than the signed integer types (e.g. char32_t) have an unsigned integer type as their underlying type, so they also don't cause any asymmetry.
>
> Maybe someone was overly cautious when writing this wording; I don't see how the signedness matters.
>
>> It's somewhat meaningful to me, since I'm wanting to saturate-cast a 'std::size_t' into the iterator's difference type, and since 'std::size_t' is some unsigned integer type, if all integer-class types have a greater width than all integral types, then theoretically I wouldn't need to even check that the 'std::size_t' value fits into the range of the integer-class type, including in the case where the integer-class type is signed. Because if we say that 'std::size_t' has a width of 'N', then its maximum value is '2^N - 1', and if the integer-class type has a width of 'N + 1', then, in the case that it's signed, its max value would be '2^(N + 1 - 1) - 1', aka '2^N - 1'.
>
> That is correct. If std::size_t is, say, 64-bit unsigned, the narrowest possible integer-class type is 65-bit signed, and that can represent all the values. There cannot be a 64-bit signed integer-class type. So I think you're safe to assume that an integer-class type can represent all standard and extended integer types.
>
> However, this entire principle falls apart once P3666 and thus bit-precise integers are introduced into the language. We have std::_Signed128 for example, which is clearly not able to represent, say, all _BitInt(1000000) values, and std::is_integral_v is true for bit-precise integers. Also, integer-class types are not going away because it would break ABI. iota_view needs to stay the same.
Received on 2026-10-29 09:43:36
