From fed0e1f21d74f83f36cb1fbc8e14717d9d4c3713 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sun, 22 Feb 2026 08:41:25 +0200 Subject: [PATCH 1/6] Stop accepting `string` --- stl/inc/__msvc_string_view.hpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 303653318e3..d34b989301d 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -474,8 +474,28 @@ struct _WChar_traits : private _Char_traits<_Elem, unsigned short> { } }; +#ifndef _ALLOW_ANY_TYPE_STD_CHAR_TRAIS +#define _ALLOW_ANY_TYPE_STD_CHAR_TRAIS 0 +#endif // _ALLOW_ANY_TYPE_CHAR_TRAIS + +#ifndef _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS +#define _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS 1 +#endif // _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS + +#ifndef _ALLOW_UNSIGNED_INTEGER_STD_CHAR_TRAIS +#define _ALLOW_UNSIGNED_INTEGER_STD_CHAR_TRAIS 1 +#endif // _ALLOW_UNSIGNED_INTEGER_STD_CHAR_TRAIS + _EXPORT_STD template -struct char_traits : _Char_traits<_Elem, long> {}; // properties of a string or stream unknown element +struct char_traits : _Char_traits<_Elem, long> { // properties of a string or stream unknown element +#if !_ALLOW_ANY_TYPE_STD_CHAR_TRAIS + static_assert( + is_integral_v<_Elem> + && (is_signed_v<_Elem> ? _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS : _ALLOW_UNSIGNED_INTEGER_STD_CHAR_TRAIS), + "Standard char_traits is only provided for char, wchar_t, char8_t, char16_t, and char32_t. " + "See N5032 [char.traits]. Visual C++ accepts other unsigned integral types as an extension."); +#endif // !_ALLOW_ANY_TYPE_STD_CHAR_TRAIS +}; template <> struct char_traits : _WChar_traits {}; @@ -914,7 +934,7 @@ template class _String_bitmap<_Elem, false> { // _String_bitmap for wchar_t/unsigned short/char16_t/char32_t/etc. types public: 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]. " + "and char32_t. See N5032 [char.traits]. " "Visual C++ accepts other unsigned integral types as an extension."); constexpr bool _Mark(const _Elem* _First, const _Elem* const _Last) noexcept { From 85ca085003aad6c80843bbd83168045ad37f07f5 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sun, 22 Feb 2026 09:54:48 +0200 Subject: [PATCH 2/6] Yeah, lets construct bitsets from unicorns! --- tests/std/tests/Dev10_860410_bitset_ctors/env.lst | 2 ++ tests/std/tests/P0980R1_constexpr_strings/env.lst | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/std/tests/Dev10_860410_bitset_ctors/env.lst b/tests/std/tests/Dev10_860410_bitset_ctors/env.lst index 19f025bd0e6..bcf68f4e5c5 100644 --- a/tests/std/tests/Dev10_860410_bitset_ctors/env.lst +++ b/tests/std/tests/Dev10_860410_bitset_ctors/env.lst @@ -2,3 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception RUNALL_INCLUDE ..\usual_matrix.lst +RUNALL_CROSSLIST +* PM_CL="/D_ALLOW_ANY_TYPE_STD_CHAR_TRAIS" diff --git a/tests/std/tests/P0980R1_constexpr_strings/env.lst b/tests/std/tests/P0980R1_constexpr_strings/env.lst index 351a8293d9d..b1d8b3f2277 100644 --- a/tests/std/tests/P0980R1_constexpr_strings/env.lst +++ b/tests/std/tests/P0980R1_constexpr_strings/env.lst @@ -2,3 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception RUNALL_INCLUDE ..\usual_20_matrix.lst +RUNALL_CROSSLIST +* PM_CL="/D_ALLOW_ANY_TYPE_STD_CHAR_TRAIS" From 26f34486825f71bd6bc81d98ecfcae0b2c2d0d2b Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sun, 22 Feb 2026 10:16:50 +0200 Subject: [PATCH 3/6] Fix preprocessor comment --- stl/inc/__msvc_string_view.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index d34b989301d..acee3ad53c2 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -476,7 +476,7 @@ struct _WChar_traits : private _Char_traits<_Elem, unsigned short> { #ifndef _ALLOW_ANY_TYPE_STD_CHAR_TRAIS #define _ALLOW_ANY_TYPE_STD_CHAR_TRAIS 0 -#endif // _ALLOW_ANY_TYPE_CHAR_TRAIS +#endif // _ALLOW_ANY_TYPE_STD_CHAR_TRAIS #ifndef _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS #define _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS 1 From 2567db345bb775f86005107eca35f26279fb321d Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sun, 22 Feb 2026 10:37:21 +0200 Subject: [PATCH 4/6] Rough internally --- stl/inc/__msvc_string_view.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index acee3ad53c2..565664f0db3 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -479,11 +479,19 @@ struct _WChar_traits : private _Char_traits<_Elem, unsigned short> { #endif // _ALLOW_ANY_TYPE_STD_CHAR_TRAIS #ifndef _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS +#if defined(_ENABLE_STL_INTERNAL_CHECK) +#define _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS 0 +#else // ^^^ defined(_ENABLE_STL_INTERNAL_CHECK) / !defined(_ENABLE_STL_INTERNAL_CHECK) vvv #define _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS 1 +#endif // ^^^ !defined(_ENABLE_STL_INTERNAL_CHECK) ^^^ #endif // _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS #ifndef _ALLOW_UNSIGNED_INTEGER_STD_CHAR_TRAIS +#if defined(_ENABLE_STL_INTERNAL_CHECK) +#define _ALLOW_UNSIGNED_INTEGER_STD_CHAR_TRAIS 0 +#else // ^^^ defined(_ENABLE_STL_INTERNAL_CHECK) / !defined(_ENABLE_STL_INTERNAL_CHECK) vvv #define _ALLOW_UNSIGNED_INTEGER_STD_CHAR_TRAIS 1 +#endif // ^^^ !defined(_ENABLE_STL_INTERNAL_CHECK) ^^^ #endif // _ALLOW_UNSIGNED_INTEGER_STD_CHAR_TRAIS _EXPORT_STD template From dcc2aa31508a71b8baba947f2aa63c9b9eeeb6eb Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sun, 22 Feb 2026 11:49:08 +0200 Subject: [PATCH 5/6] It's getting compilcated, let's go even more conservatively --- stl/inc/__msvc_string_view.hpp | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 565664f0db3..46c376c314d 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -478,28 +478,10 @@ struct _WChar_traits : private _Char_traits<_Elem, unsigned short> { #define _ALLOW_ANY_TYPE_STD_CHAR_TRAIS 0 #endif // _ALLOW_ANY_TYPE_STD_CHAR_TRAIS -#ifndef _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS -#if defined(_ENABLE_STL_INTERNAL_CHECK) -#define _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS 0 -#else // ^^^ defined(_ENABLE_STL_INTERNAL_CHECK) / !defined(_ENABLE_STL_INTERNAL_CHECK) vvv -#define _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS 1 -#endif // ^^^ !defined(_ENABLE_STL_INTERNAL_CHECK) ^^^ -#endif // _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS - -#ifndef _ALLOW_UNSIGNED_INTEGER_STD_CHAR_TRAIS -#if defined(_ENABLE_STL_INTERNAL_CHECK) -#define _ALLOW_UNSIGNED_INTEGER_STD_CHAR_TRAIS 0 -#else // ^^^ defined(_ENABLE_STL_INTERNAL_CHECK) / !defined(_ENABLE_STL_INTERNAL_CHECK) vvv -#define _ALLOW_UNSIGNED_INTEGER_STD_CHAR_TRAIS 1 -#endif // ^^^ !defined(_ENABLE_STL_INTERNAL_CHECK) ^^^ -#endif // _ALLOW_UNSIGNED_INTEGER_STD_CHAR_TRAIS - _EXPORT_STD template struct char_traits : _Char_traits<_Elem, long> { // properties of a string or stream unknown element #if !_ALLOW_ANY_TYPE_STD_CHAR_TRAIS - static_assert( - is_integral_v<_Elem> - && (is_signed_v<_Elem> ? _ALLOW_SIGNED_INTEGER_STD_CHAR_TRAIS : _ALLOW_UNSIGNED_INTEGER_STD_CHAR_TRAIS), + static_assert(is_integral_v<_Elem>, "Standard char_traits is only provided for char, wchar_t, char8_t, char16_t, and char32_t. " "See N5032 [char.traits]. Visual C++ accepts other unsigned integral types as an extension."); #endif // !_ALLOW_ANY_TYPE_STD_CHAR_TRAIS From 63614951093ecad831c0c6d792717b1657256107 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sun, 22 Feb 2026 11:51:29 +0200 Subject: [PATCH 6/6] Simplistic macro --- stl/inc/__msvc_string_view.hpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 46c376c314d..da52a7dd839 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -474,17 +474,13 @@ struct _WChar_traits : private _Char_traits<_Elem, unsigned short> { } }; -#ifndef _ALLOW_ANY_TYPE_STD_CHAR_TRAIS -#define _ALLOW_ANY_TYPE_STD_CHAR_TRAIS 0 -#endif // _ALLOW_ANY_TYPE_STD_CHAR_TRAIS - _EXPORT_STD template struct char_traits : _Char_traits<_Elem, long> { // properties of a string or stream unknown element -#if !_ALLOW_ANY_TYPE_STD_CHAR_TRAIS +#ifndef _ALLOW_ANY_TYPE_STD_CHAR_TRAIS static_assert(is_integral_v<_Elem>, "Standard char_traits is only provided for char, wchar_t, char8_t, char16_t, and char32_t. " "See N5032 [char.traits]. Visual C++ accepts other unsigned integral types as an extension."); -#endif // !_ALLOW_ANY_TYPE_STD_CHAR_TRAIS +#endif // _ALLOW_ANY_TYPE_STD_CHAR_TRAIS }; template <>