Skip to content

Comments

Stop accepting string<long double>#6099

Open
AlexGuteniev wants to merge 6 commits intomicrosoft:mainfrom
AlexGuteniev:no-strings-attached
Open

Stop accepting string<long double>#6099
AlexGuteniev wants to merge 6 commits intomicrosoft:mainfrom
AlexGuteniev:no-strings-attached

Conversation

@AlexGuteniev
Copy link
Contributor

@AlexGuteniev AlexGuteniev commented Feb 22, 2026

Very conservative step towards #5311.
Prohibit at least non-integer default char traits, with escape hatch.

🎈 Floating motivation

Out of all types that we should not have supported, floats are my primary concern, especially their interaction with vectorization. We do ban them along with other unexpected types in find_meow_of:

static_assert(is_unsigned_v<_Elem>, "Standard char_traits is only provided for char, wchar_t, char8_t, char16_t, "
"and char32_t. See N4988 [char.traits]. "
"Visual C++ accepts other unsigned integral types as an extension.");

But with find/rfind the effect would be strange. I have not tried, but I expect that the unsupported 80-bit long double would fail to compile with a strange error, but normal floats and doubles would compare bitwise, resulting incorrect results for nans and negative zeros.

This use case has never existed, so everything looks like we should ban it outright.

But while we're at it, let's ban all other non-standard things, except integers.

🔢 Integers

Getting rid of non-character integers, both signed and unsigned, turned out to be much more complicated.

Specifically with filesystem test, where it uses signed char and unsigned char, and expects path conversion to work,

Let's not do this for now.

👮‍♂️ Offenders

Dev10_860410_bitset_ctors starts very normal:

// test encoded character types (expected usages)
test_ntcts_constructibility_for_lengths<char, true>();
#ifdef __cpp_char8_t
test_ntcts_constructibility_for_lengths<char8_t, true>();
#endif // __cpp_char8_t
test_ntcts_constructibility_for_lengths<char16_t, true>();
test_ntcts_constructibility_for_lengths<char32_t, true>();
test_ntcts_constructibility_for_lengths<wchar_t, true>();

Then it tests weird types:

// test scalar types
test_ntcts_constructibility_for_lengths<int, true>();
test_ntcts_constructibility_for_lengths<char*, true>();
test_ntcts_constructibility_for_lengths<void (*)(), true>();
test_ntcts_constructibility_for_lengths<unscoped_enum, true>();
test_ntcts_constructibility_for_lengths<scoped_enum, true>();
test_ntcts_constructibility_for_lengths<int missing_trivial_default_ctor::*, true>();
test_ntcts_constructibility_for_lengths<void (missing_standard_layout::*)() const&, true>();

Culminating in this:

// test worse class types
test_ntcts_constructibility_for_lengths<string, false>();
test_ntcts_constructibility_for_lengths<invalid_argument, false>();

Looks like this is not supported. bitset constructor is defined to work as if with string or string_view, so if no explicit traits are passed, these are the default traits, that should not be defined for these odd types.

In addition P0980R1_constexpr_strings tests for weirdness, but a more modest one:

template <class CharType>
struct CharLikeType {
constexpr CharLikeType() = default;
constexpr CharLikeType(CharType cc) : c(cc) {}
CharType c;
};

basic_string<CharLikeType<CharType>> bs{CharType{'x'}};

I've added escape hatches to both tests matrices.

@StephanTLavavej StephanTLavavej added the enhancement Something can be improved label Feb 22, 2026
@StephanTLavavej
Copy link
Member

For built-in types, I'm fine with banning non-integers. There's no reason to support that complexity. But I don't think we can ban user-defined types, because users are allowed to provide a specialization of char_traits<MyCharLikeType>, right?

@AlexGuteniev
Copy link
Contributor Author

But I don't think we can ban user-defined types, because users are allowed to provide a specialization of char_traits<MyCharLikeType>, right?

Yes you are right>

@AlexGuteniev AlexGuteniev marked this pull request as draft February 22, 2026 12:58
@AlexGuteniev AlexGuteniev marked this pull request as ready for review February 22, 2026 13:02
@AlexGuteniev
Copy link
Contributor Author

But I don't think we can ban user-defined types, because users are allowed to provide a specialization of char_traits<MyCharLikeType>, right?

However!

We ban directly in the primary char_traits template. Any specialization will bypass this ban.

We can additionally ban floats outside, disabling users to provide their own char_traits<long double> specialization, but I dont believe in pursuing basic_string<long double> with this level of persistence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Something can be improved

Projects

Status: Initial Review

Development

Successfully merging this pull request may close these issues.

2 participants