From 206dc6f2cca575d5ac58d69bcf2919f86fda3926 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 28 May 2023 09:26:22 +0800 Subject: [PATCH 1/7] Strengthen exception specification for `sv.compare(psz)` --- stl/inc/xstring | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stl/inc/xstring b/stl/inc/xstring index b7fcb187ec..1abcb1dfc1 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -1399,7 +1399,8 @@ public: return substr(_Off, _Nx).compare(_Right.substr(_Roff, _Count)); } - _NODISCARD constexpr int compare(_In_z_ const _Elem* const _Ptr) const { // compare [0, _Mysize) with [_Ptr, ) + _NODISCARD constexpr int compare(_In_z_ const _Elem* const _Ptr) const noexcept /* strengthened */ { + // compare [0, _Mysize) with [_Ptr, ) return compare(basic_string_view(_Ptr)); } From 5e735927717cd6f367f9e0b1defeed43dbaa572c Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 28 May 2023 09:28:37 +0800 Subject: [PATCH 2/7] Correspondingly modify the test file --- tests/std/tests/P0220R1_string_view/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0220R1_string_view/test.cpp b/tests/std/tests/P0220R1_string_view/test.cpp index 0484c73dcf..2ef556e407 100644 --- a/tests/std/tests/P0220R1_string_view/test.cpp +++ b/tests/std/tests/P0220R1_string_view/test.cpp @@ -127,7 +127,7 @@ static_assert(noexcept(g_example.swap(g_example_swap_target)), "swap() not noexc static_assert(noexcept(g_example.compare(string_view{})), "compare(basic_string_view) not noexcept"); // compare(pos1, n1, basic_string_view) throws out_of_range // compare(pos1, n1, basic_string_view, pos2, n2) throws out_of_range -static_assert(!noexcept(g_example.compare("literal")), "compare(const charT*) not noexcept (this is bad, char_traits)"); +static_assert(noexcept(g_example.compare("literal")), "compare(const charT*) not noexcept"); // compare(pos1, n1, const charT*) throws out_of_range and calls through char_traits // compare(pos1, n1, const charT*, n2) throws out_of_range and calls through char_traits static_assert(noexcept(g_example.find(string_view{})), "find(basic_string_view, offset) not noexcept"); From f8c484bd0ea3b48cbf1939f80cdcfbdf857b913f Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 28 May 2023 10:16:34 +0800 Subject: [PATCH 3/7] Missed ` // strengthened` comment --- tests/std/tests/P0220R1_string_view/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0220R1_string_view/test.cpp b/tests/std/tests/P0220R1_string_view/test.cpp index 2ef556e407..51ddb88b12 100644 --- a/tests/std/tests/P0220R1_string_view/test.cpp +++ b/tests/std/tests/P0220R1_string_view/test.cpp @@ -127,7 +127,7 @@ static_assert(noexcept(g_example.swap(g_example_swap_target)), "swap() not noexc static_assert(noexcept(g_example.compare(string_view{})), "compare(basic_string_view) not noexcept"); // compare(pos1, n1, basic_string_view) throws out_of_range // compare(pos1, n1, basic_string_view, pos2, n2) throws out_of_range -static_assert(noexcept(g_example.compare("literal")), "compare(const charT*) not noexcept"); +static_assert(noexcept(g_example.compare("literal")), "compare(const charT*) not noexcept"); // strengthened // compare(pos1, n1, const charT*) throws out_of_range and calls through char_traits // compare(pos1, n1, const charT*, n2) throws out_of_range and calls through char_traits static_assert(noexcept(g_example.find(string_view{})), "find(basic_string_view, offset) not noexcept"); From a18c3f4bc85aa693e16fae8c83feb29eeb4077b1 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 28 May 2023 14:18:31 +0800 Subject: [PATCH 4/7] Also `_Eos`, `_Swap_proxy_and_iterators`, and `_Swap_data` Since they are already called by `noexcept` functions. --- stl/inc/xstring | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/xstring b/stl/inc/xstring index 1abcb1dfc1..253698fa40 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -4259,7 +4259,7 @@ public: _Construct_in_place(_Starts_small._Bx._Ptr, _Ptr); } - _CONSTEXPR20 void _Swap_data(basic_string& _Right) { + _CONSTEXPR20 void _Swap_data(basic_string& _Right) noexcept { using _STD swap; auto& _My_data = _Mypair._Myval2; @@ -4811,7 +4811,7 @@ private: _My_data._Myres = _BUF_SIZE - 1; } - _CONSTEXPR20 void _Eos(const size_type _New_size) { // set new length and null terminator + _CONSTEXPR20 void _Eos(const size_type _New_size) noexcept { // set new length and null terminator _ASAN_STRING_MODIFY(*this, _Mypair._Myval2._Mysize, _New_size); _Traits::assign(_Mypair._Myval2._Myptr()[_Mypair._Myval2._Mysize = _New_size], _Elem()); } @@ -4851,7 +4851,7 @@ public: } private: - _CONSTEXPR20 void _Swap_proxy_and_iterators(basic_string& _Right) { + _CONSTEXPR20 void _Swap_proxy_and_iterators(basic_string& _Right) noexcept { _Mypair._Myval2._Swap_proxy_and_iterators(_Right._Mypair._Myval2); } From 5a05f1a0ee951ed51b4e383109533b4f5badcec9 Mon Sep 17 00:00:00 2001 From: nicole mazzuca <83086508+strega-nil-ms@users.noreply.github.com> Date: Wed, 14 Jun 2023 12:51:01 -0800 Subject: [PATCH 5/7] Update tests/std/tests/P0220R1_string_view/test.cpp --- tests/std/tests/P0220R1_string_view/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0220R1_string_view/test.cpp b/tests/std/tests/P0220R1_string_view/test.cpp index 51ddb88b12..5e1102f2bd 100644 --- a/tests/std/tests/P0220R1_string_view/test.cpp +++ b/tests/std/tests/P0220R1_string_view/test.cpp @@ -127,7 +127,7 @@ static_assert(noexcept(g_example.swap(g_example_swap_target)), "swap() not noexc static_assert(noexcept(g_example.compare(string_view{})), "compare(basic_string_view) not noexcept"); // compare(pos1, n1, basic_string_view) throws out_of_range // compare(pos1, n1, basic_string_view, pos2, n2) throws out_of_range -static_assert(noexcept(g_example.compare("literal")), "compare(const charT*) not noexcept"); // strengthened +static_assert(noexcept(g_example.compare("literal")), "compare(const charT*) noexcept (strengthened)"); // compare(pos1, n1, const charT*) throws out_of_range and calls through char_traits // compare(pos1, n1, const charT*, n2) throws out_of_range and calls through char_traits static_assert(noexcept(g_example.find(string_view{})), "find(basic_string_view, offset) not noexcept"); From 5ec275cc12398c39f46a3984ab8f28f0c6267612 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 14 Jun 2023 14:41:47 -0700 Subject: [PATCH 6/7] Revert "Update tests/std/tests/P0220R1_string_view/test.cpp" This reverts commit 5a05f1a0ee951ed51b4e383109533b4f5badcec9. --- tests/std/tests/P0220R1_string_view/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0220R1_string_view/test.cpp b/tests/std/tests/P0220R1_string_view/test.cpp index 5e1102f2bd..51ddb88b12 100644 --- a/tests/std/tests/P0220R1_string_view/test.cpp +++ b/tests/std/tests/P0220R1_string_view/test.cpp @@ -127,7 +127,7 @@ static_assert(noexcept(g_example.swap(g_example_swap_target)), "swap() not noexc static_assert(noexcept(g_example.compare(string_view{})), "compare(basic_string_view) not noexcept"); // compare(pos1, n1, basic_string_view) throws out_of_range // compare(pos1, n1, basic_string_view, pos2, n2) throws out_of_range -static_assert(noexcept(g_example.compare("literal")), "compare(const charT*) noexcept (strengthened)"); +static_assert(noexcept(g_example.compare("literal")), "compare(const charT*) not noexcept"); // strengthened // compare(pos1, n1, const charT*) throws out_of_range and calls through char_traits // compare(pos1, n1, const charT*, n2) throws out_of_range and calls through char_traits static_assert(noexcept(g_example.find(string_view{})), "find(basic_string_view, offset) not noexcept"); From a58bd4c656c926f3b406de7e4cf485856d3f1368 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 14 Jun 2023 14:50:05 -0700 Subject: [PATCH 7/7] Mechanically replace P0220R1_string_view to use terse static_assert. --- tests/std/tests/P0220R1_string_view/test.cpp | 298 ++++++++----------- 1 file changed, 131 insertions(+), 167 deletions(-) diff --git a/tests/std/tests/P0220R1_string_view/test.cpp b/tests/std/tests/P0220R1_string_view/test.cpp index 51ddb88b12..bda8ed7943 100644 --- a/tests/std/tests/P0220R1_string_view/test.cpp +++ b/tests/std/tests/P0220R1_string_view/test.cpp @@ -93,174 +93,139 @@ static_assert(is_trivially_destructible_v); // noexcept assertions: // (functions that explicitly throw have their throws tested and therefore have no static_asserts) -static_assert(noexcept(string_view{}), "default constructor not noexcept"); -static_assert(noexcept(string_view{string_view{}}), "copy constructor not noexcept"); +static_assert(noexcept(string_view{})); +static_assert(noexcept(string_view{string_view{}})); string_view g_example{"text", 2}; // the assignment operator is arguably noexcept in the WP (it is defaulted) -static_assert(noexcept(declval() = declval()), "assignment operator not noexcept"); -static_assert(noexcept(string_view{"text"}), "NTCTS constructor not noexcept"); // strengthened -static_assert(noexcept(string_view{"text", 2}), "buffer constructor not noexcept"); // strengthened -static_assert(noexcept(g_example.begin()), "begin not noexcept"); -static_assert(noexcept(g_example.end()), "end not noexcept"); -static_assert(noexcept(g_example.cbegin()), "cbegin not noexcept"); -static_assert(noexcept(g_example.cend()), "cend not noexcept"); -static_assert(noexcept(g_example.rbegin()), "rbegin not noexcept"); -static_assert(noexcept(g_example.rend()), "rend not noexcept"); -static_assert(noexcept(g_example.crbegin()), "crbegin not noexcept"); -static_assert(noexcept(g_example.crend()), "crend not noexcept"); -static_assert(noexcept(g_example.size()), "size not noexcept"); -static_assert(noexcept(g_example.length()), "length not noexcept"); -static_assert(noexcept(g_example.max_size()), "max_size not noexcept"); -static_assert(noexcept(g_example.empty()), "empty not noexcept"); -static_assert(noexcept(g_example[0]), "operator[] not noexcept"); // strengthened +static_assert(noexcept(declval() = declval())); +static_assert(noexcept(string_view{"text"})); // strengthened +static_assert(noexcept(string_view{"text", 2})); // strengthened +static_assert(noexcept(g_example.begin())); +static_assert(noexcept(g_example.end())); +static_assert(noexcept(g_example.cbegin())); +static_assert(noexcept(g_example.cend())); +static_assert(noexcept(g_example.rbegin())); +static_assert(noexcept(g_example.rend())); +static_assert(noexcept(g_example.crbegin())); +static_assert(noexcept(g_example.crend())); +static_assert(noexcept(g_example.size())); +static_assert(noexcept(g_example.length())); +static_assert(noexcept(g_example.max_size())); +static_assert(noexcept(g_example.empty())); +static_assert(noexcept(g_example[0])); // strengthened // at throws out_of_range -static_assert(noexcept(g_example.front()), "front() not noexcept"); // strengthened -static_assert(noexcept(g_example.back()), "back() not noexcept"); // strengthened -static_assert(noexcept(g_example.data()), "data() not noexcept"); -static_assert(noexcept(g_example.remove_prefix(1)), "remove_prefix() not noexcept"); // strengthened -static_assert(noexcept(g_example.remove_suffix(1)), "remove_suffix() not noexcept"); // strengthened +static_assert(noexcept(g_example.front())); // strengthened +static_assert(noexcept(g_example.back())); // strengthened +static_assert(noexcept(g_example.data())); +static_assert(noexcept(g_example.remove_prefix(1))); // strengthened +static_assert(noexcept(g_example.remove_suffix(1))); // strengthened string_view g_example_swap_target{"text", 3}; -static_assert(noexcept(g_example.swap(g_example_swap_target)), "swap() not noexcept"); +static_assert(noexcept(g_example.swap(g_example_swap_target))); // copy throws out_of_range // substr throws out_of_range -static_assert(noexcept(g_example.compare(string_view{})), "compare(basic_string_view) not noexcept"); +static_assert(noexcept(g_example.compare(string_view{}))); // compare(pos1, n1, basic_string_view) throws out_of_range // compare(pos1, n1, basic_string_view, pos2, n2) throws out_of_range -static_assert(noexcept(g_example.compare("literal")), "compare(const charT*) not noexcept"); // strengthened +static_assert(noexcept(g_example.compare("literal"))); // strengthened // compare(pos1, n1, const charT*) throws out_of_range and calls through char_traits // compare(pos1, n1, const charT*, n2) throws out_of_range and calls through char_traits -static_assert(noexcept(g_example.find(string_view{})), "find(basic_string_view, offset) not noexcept"); -static_assert(noexcept(g_example.find('c')), "find(charT, count) not noexcept"); -static_assert(noexcept(g_example.find("text", 0, 0)), "find(const charT *, pos, n) not noexcept"); // strengthened -static_assert(noexcept(g_example.find("text")), "find(const charT *, pos) not noexcept"); // strengthened -static_assert(noexcept(g_example.rfind(string_view{})), "rfind(basic_string_view, offset) not noexcept"); -static_assert(noexcept(g_example.rfind('c')), "rfind(charT, count) not noexcept"); -static_assert(noexcept(g_example.rfind("text", 0, 0)), "rfind(const charT *, pos, n) not noexcept"); // strengthened -static_assert(noexcept(g_example.rfind("text")), "rfind(const charT *, pos) not noexcept"); // strengthened -static_assert( - noexcept(g_example.find_first_of(string_view{})), "find_first_of(basic_string_view, offset) not noexcept"); -static_assert(noexcept(g_example.find_first_of('c')), "find_first_of(charT, count) not noexcept"); -static_assert(noexcept(g_example.find_first_of("text", 0, 0)), - "find_first_of(const charT *, pos, n) not noexcept"); // strengthened -static_assert(noexcept(g_example.find_first_of("text")), - "find_first_of(const charT *, pos) not noexcept"); // strengthened -static_assert(noexcept(g_example.find_last_of(string_view{})), "find_last_of(basic_string_view, offset) not noexcept"); -static_assert(noexcept(g_example.find_last_of('c')), "find_last_of(charT, count) not noexcept"); -static_assert(noexcept(g_example.find_last_of("text", 0, 0)), - "find_last_of(const charT *, pos, n) not noexcept"); // strengthened -static_assert(noexcept(g_example.find_last_of("text")), - "find_last_of(const charT *, pos) noexcept"); // strengthened -static_assert( - noexcept(g_example.find_first_not_of(string_view{})), "find_first_not_of(basic_string_view, offset) not noexcept"); -static_assert(noexcept(g_example.find_first_not_of('c')), "find_first_not_of(charT, count) not noexcept"); -static_assert(noexcept(g_example.find_first_not_of("text", 0, 0)), - "find_first_not_of(const charT *, pos, n) not noexcept"); // strengthened -static_assert(noexcept(g_example.find_first_not_of("text")), - "find_first_not_of(const charT *, pos) not noexcept"); // strengthened -static_assert( - noexcept(g_example.find_last_not_of(string_view{})), "find_last_not_of(basic_string_view, offset) not noexcept"); -static_assert(noexcept(g_example.find_last_not_of('c')), "find_last_not_of(charT, count) not noexcept"); -static_assert(noexcept(g_example.find_last_not_of("text", 0, 0)), - "find_last_not_of(const charT *, pos, n) not noexcept"); // strengthened -static_assert(noexcept(g_example.find_last_not_of("text")), - "find_last_not_of(const charT *, pos) noexcept"); // strengthened - -static_assert(noexcept(string_view{} == string_view{}), "operator== not noexcept"); -static_assert(!noexcept(conversion_to_string_view{} == string_view{}), "operator== left noexcept forward"); -static_assert( - noexcept(evil_conversion_to_string_view_rvalue_only{} == string_view{}), "operator== left noexcept forward"); -static_assert(!noexcept(convert_rvalue_only == string_view{}), "operator== left noexcept forward"); -static_assert( - !noexcept(evil_conversion_to_string_view_lvalue_only{} == string_view{}), "operator== left noexcept forward"); -static_assert(noexcept(convert_lvalue_only == string_view{}), "operator== left noexcept forward"); -static_assert(!noexcept(string_view{} == conversion_to_string_view{}), "operator== right noexcept forward"); -static_assert( - noexcept(string_view{} == evil_conversion_to_string_view_rvalue_only{}), "operator== right noexcept forward"); -static_assert(!noexcept(string_view{} == convert_rvalue_only), "operator== right noexcept forward"); -static_assert( - !noexcept(string_view{} == evil_conversion_to_string_view_lvalue_only{}), "operator== right noexcept forward"); -static_assert(noexcept(string_view{} == convert_lvalue_only), "operator== right noexcept forward"); - -static_assert(noexcept(string_view{} != string_view{}), "operator!= not noexcept"); -static_assert(!noexcept(conversion_to_string_view{} != string_view{}), "operator!= left noexcept forward"); -static_assert( - noexcept(evil_conversion_to_string_view_rvalue_only{} != string_view{}), "operator!= left noexcept forward"); -static_assert(!noexcept(convert_rvalue_only != string_view{}), "operator!= left noexcept forward"); -static_assert( - !noexcept(evil_conversion_to_string_view_lvalue_only{} != string_view{}), "operator!= left noexcept forward"); -static_assert(noexcept(convert_lvalue_only != string_view{}), "operator!= left noexcept forward"); -static_assert(!noexcept(string_view{} != conversion_to_string_view{}), "operator!= right noexcept forward"); -static_assert( - noexcept(string_view{} != evil_conversion_to_string_view_rvalue_only{}), "operator!= right noexcept forward"); -static_assert(!noexcept(string_view{} != convert_rvalue_only), "operator!= right noexcept forward"); -static_assert( - !noexcept(string_view{} != evil_conversion_to_string_view_lvalue_only{}), "operator!= right noexcept forward"); -static_assert(noexcept(string_view{} != convert_lvalue_only), "operator!= right noexcept forward"); - -static_assert(noexcept(string_view{} < string_view{}), "operator< not noexcept"); -static_assert(!noexcept(conversion_to_string_view{} < string_view{}), "operator< left noexcept forward"); -static_assert( - noexcept(evil_conversion_to_string_view_rvalue_only{} < string_view{}), "operator< left noexcept forward"); -static_assert(!noexcept(convert_rvalue_only < string_view{}), "operator< left noexcept forward"); -static_assert( - !noexcept(evil_conversion_to_string_view_lvalue_only{} < string_view{}), "operator< left noexcept forward"); -static_assert(noexcept(convert_lvalue_only < string_view{}), "operator< left noexcept forward"); -static_assert(!noexcept(string_view{} < conversion_to_string_view{}), "operator< right noexcept forward"); -static_assert( - noexcept(string_view{} < evil_conversion_to_string_view_rvalue_only{}), "operator< right noexcept forward"); -static_assert(!noexcept(string_view{} < convert_rvalue_only), "operator< right noexcept forward"); -static_assert( - !noexcept(string_view{} < evil_conversion_to_string_view_lvalue_only{}), "operator< right noexcept forward"); -static_assert(noexcept(string_view{} < convert_lvalue_only), "operator< right noexcept forward"); - -static_assert(noexcept(string_view{} > string_view{}), "operator> not noexcept"); -static_assert(!noexcept(conversion_to_string_view{} > string_view{}), "operator> left noexcept forward"); -static_assert( - noexcept(evil_conversion_to_string_view_rvalue_only{} > string_view{}), "operator> left noexcept forward"); -static_assert(!noexcept(convert_rvalue_only > string_view{}), "operator> left noexcept forward"); -static_assert( - !noexcept(evil_conversion_to_string_view_lvalue_only{} > string_view{}), "operator> left noexcept forward"); -static_assert(noexcept(convert_lvalue_only > string_view{}), "operator> left noexcept forward"); -static_assert(!noexcept(string_view{} > conversion_to_string_view{}), "operator> right noexcept forward"); -static_assert( - noexcept(string_view{} > evil_conversion_to_string_view_rvalue_only{}), "operator> right noexcept forward"); -static_assert(!noexcept(string_view{} > convert_rvalue_only), "operator> right noexcept forward"); -static_assert( - !noexcept(string_view{} > evil_conversion_to_string_view_lvalue_only{}), "operator> right noexcept forward"); -static_assert(noexcept(string_view{} > convert_lvalue_only), "operator> right noexcept forward"); - -static_assert(noexcept(string_view{} <= string_view{}), "operator<= not noexcept"); -static_assert(!noexcept(conversion_to_string_view{} <= string_view{}), "operator<= left noexcept forward"); -static_assert( - noexcept(evil_conversion_to_string_view_rvalue_only{} <= string_view{}), "operator<= left noexcept forward"); -static_assert(!noexcept(convert_rvalue_only <= string_view{}), "operator<= left noexcept forward"); -static_assert( - !noexcept(evil_conversion_to_string_view_lvalue_only{} <= string_view{}), "operator<= left noexcept forward"); -static_assert(noexcept(convert_lvalue_only <= string_view{}), "operator<= left noexcept forward"); -static_assert(!noexcept(string_view{} <= conversion_to_string_view{}), "operator<= right noexcept forward"); -static_assert( - noexcept(string_view{} <= evil_conversion_to_string_view_rvalue_only{}), "operator<= right noexcept forward"); -static_assert(!noexcept(string_view{} <= convert_rvalue_only), "operator<= right noexcept forward"); -static_assert( - !noexcept(string_view{} <= evil_conversion_to_string_view_lvalue_only{}), "operator<= right noexcept forward"); -static_assert(noexcept(string_view{} <= convert_lvalue_only), "operator<= right noexcept forward"); - -static_assert(noexcept(string_view{} >= string_view{}), "operator>= not noexcept"); -static_assert(!noexcept(conversion_to_string_view{} >= string_view{}), "operator>= left noexcept forward"); -static_assert( - noexcept(evil_conversion_to_string_view_rvalue_only{} >= string_view{}), "operator>= left noexcept forward"); -static_assert(!noexcept(convert_rvalue_only >= string_view{}), "operator>= left noexcept forward"); -static_assert( - !noexcept(evil_conversion_to_string_view_lvalue_only{} >= string_view{}), "operator>= left noexcept forward"); -static_assert(noexcept(convert_lvalue_only >= string_view{}), "operator>= left noexcept forward"); -static_assert(!noexcept(string_view{} >= conversion_to_string_view{}), "operator>= right noexcept forward"); -static_assert( - noexcept(string_view{} >= evil_conversion_to_string_view_rvalue_only{}), "operator>= right noexcept forward"); -static_assert(!noexcept(string_view{} >= convert_rvalue_only), "operator>= right noexcept forward"); -static_assert( - !noexcept(string_view{} >= evil_conversion_to_string_view_lvalue_only{}), "operator>= right noexcept forward"); -static_assert(noexcept(string_view{} >= convert_lvalue_only), "operator>= right noexcept forward"); +static_assert(noexcept(g_example.find(string_view{}))); +static_assert(noexcept(g_example.find('c'))); +static_assert(noexcept(g_example.find("text", 0, 0))); // strengthened +static_assert(noexcept(g_example.find("text"))); // strengthened +static_assert(noexcept(g_example.rfind(string_view{}))); +static_assert(noexcept(g_example.rfind('c'))); +static_assert(noexcept(g_example.rfind("text", 0, 0))); // strengthened +static_assert(noexcept(g_example.rfind("text"))); // strengthened +static_assert(noexcept(g_example.find_first_of(string_view{}))); +static_assert(noexcept(g_example.find_first_of('c'))); +static_assert(noexcept(g_example.find_first_of("text", 0, 0))); // strengthened +static_assert(noexcept(g_example.find_first_of("text"))); // strengthened +static_assert(noexcept(g_example.find_last_of(string_view{}))); +static_assert(noexcept(g_example.find_last_of('c'))); +static_assert(noexcept(g_example.find_last_of("text", 0, 0))); // strengthened +static_assert(noexcept(g_example.find_last_of("text"))); // strengthened +static_assert(noexcept(g_example.find_first_not_of(string_view{}))); +static_assert(noexcept(g_example.find_first_not_of('c'))); +static_assert(noexcept(g_example.find_first_not_of("text", 0, 0))); // strengthened +static_assert(noexcept(g_example.find_first_not_of("text"))); // strengthened +static_assert(noexcept(g_example.find_last_not_of(string_view{}))); +static_assert(noexcept(g_example.find_last_not_of('c'))); +static_assert(noexcept(g_example.find_last_not_of("text", 0, 0))); // strengthened +static_assert(noexcept(g_example.find_last_not_of("text"))); // strengthened + +static_assert(noexcept(string_view{} == string_view{})); +static_assert(!noexcept(conversion_to_string_view{} == string_view{})); +static_assert(noexcept(evil_conversion_to_string_view_rvalue_only{} == string_view{})); +static_assert(!noexcept(convert_rvalue_only == string_view{})); +static_assert(!noexcept(evil_conversion_to_string_view_lvalue_only{} == string_view{})); +static_assert(noexcept(convert_lvalue_only == string_view{})); +static_assert(!noexcept(string_view{} == conversion_to_string_view{})); +static_assert(noexcept(string_view{} == evil_conversion_to_string_view_rvalue_only{})); +static_assert(!noexcept(string_view{} == convert_rvalue_only)); +static_assert(!noexcept(string_view{} == evil_conversion_to_string_view_lvalue_only{})); +static_assert(noexcept(string_view{} == convert_lvalue_only)); + +static_assert(noexcept(string_view{} != string_view{})); +static_assert(!noexcept(conversion_to_string_view{} != string_view{})); +static_assert(noexcept(evil_conversion_to_string_view_rvalue_only{} != string_view{})); +static_assert(!noexcept(convert_rvalue_only != string_view{})); +static_assert(!noexcept(evil_conversion_to_string_view_lvalue_only{} != string_view{})); +static_assert(noexcept(convert_lvalue_only != string_view{})); +static_assert(!noexcept(string_view{} != conversion_to_string_view{})); +static_assert(noexcept(string_view{} != evil_conversion_to_string_view_rvalue_only{})); +static_assert(!noexcept(string_view{} != convert_rvalue_only)); +static_assert(!noexcept(string_view{} != evil_conversion_to_string_view_lvalue_only{})); +static_assert(noexcept(string_view{} != convert_lvalue_only)); + +static_assert(noexcept(string_view{} < string_view{})); +static_assert(!noexcept(conversion_to_string_view{} < string_view{})); +static_assert(noexcept(evil_conversion_to_string_view_rvalue_only{} < string_view{})); +static_assert(!noexcept(convert_rvalue_only < string_view{})); +static_assert(!noexcept(evil_conversion_to_string_view_lvalue_only{} < string_view{})); +static_assert(noexcept(convert_lvalue_only < string_view{})); +static_assert(!noexcept(string_view{} < conversion_to_string_view{})); +static_assert(noexcept(string_view{} < evil_conversion_to_string_view_rvalue_only{})); +static_assert(!noexcept(string_view{} < convert_rvalue_only)); +static_assert(!noexcept(string_view{} < evil_conversion_to_string_view_lvalue_only{})); +static_assert(noexcept(string_view{} < convert_lvalue_only)); + +static_assert(noexcept(string_view{} > string_view{})); +static_assert(!noexcept(conversion_to_string_view{} > string_view{})); +static_assert(noexcept(evil_conversion_to_string_view_rvalue_only{} > string_view{})); +static_assert(!noexcept(convert_rvalue_only > string_view{})); +static_assert(!noexcept(evil_conversion_to_string_view_lvalue_only{} > string_view{})); +static_assert(noexcept(convert_lvalue_only > string_view{})); +static_assert(!noexcept(string_view{} > conversion_to_string_view{})); +static_assert(noexcept(string_view{} > evil_conversion_to_string_view_rvalue_only{})); +static_assert(!noexcept(string_view{} > convert_rvalue_only)); +static_assert(!noexcept(string_view{} > evil_conversion_to_string_view_lvalue_only{})); +static_assert(noexcept(string_view{} > convert_lvalue_only)); + +static_assert(noexcept(string_view{} <= string_view{})); +static_assert(!noexcept(conversion_to_string_view{} <= string_view{})); +static_assert(noexcept(evil_conversion_to_string_view_rvalue_only{} <= string_view{})); +static_assert(!noexcept(convert_rvalue_only <= string_view{})); +static_assert(!noexcept(evil_conversion_to_string_view_lvalue_only{} <= string_view{})); +static_assert(noexcept(convert_lvalue_only <= string_view{})); +static_assert(!noexcept(string_view{} <= conversion_to_string_view{})); +static_assert(noexcept(string_view{} <= evil_conversion_to_string_view_rvalue_only{})); +static_assert(!noexcept(string_view{} <= convert_rvalue_only)); +static_assert(!noexcept(string_view{} <= evil_conversion_to_string_view_lvalue_only{})); +static_assert(noexcept(string_view{} <= convert_lvalue_only)); + +static_assert(noexcept(string_view{} >= string_view{})); +static_assert(!noexcept(conversion_to_string_view{} >= string_view{})); +static_assert(noexcept(evil_conversion_to_string_view_rvalue_only{} >= string_view{})); +static_assert(!noexcept(convert_rvalue_only >= string_view{})); +static_assert(!noexcept(evil_conversion_to_string_view_lvalue_only{} >= string_view{})); +static_assert(noexcept(convert_lvalue_only >= string_view{})); +static_assert(!noexcept(string_view{} >= conversion_to_string_view{})); +static_assert(noexcept(string_view{} >= evil_conversion_to_string_view_rvalue_only{})); +static_assert(!noexcept(string_view{} >= convert_rvalue_only)); +static_assert(!noexcept(string_view{} >= evil_conversion_to_string_view_lvalue_only{})); +static_assert(noexcept(string_view{} >= convert_lvalue_only)); template struct choose_literal; // not defined @@ -1235,14 +1200,13 @@ static_assert(test_case_contains()); static_assert(test_case_operators()); static_assert(test_case_find()); -static_assert(string_view{}.max_size() == ptrdiff_max, "bad max_size for string_view"); +static_assert(string_view{}.max_size() == ptrdiff_max); #ifdef __cpp_lib_char8_t -static_assert(u8string_view{}.max_size() == ptrdiff_max, "bad max_size for u8string_view"); +static_assert(u8string_view{}.max_size() == ptrdiff_max); #endif // __cpp_lib_char8_t -static_assert(u16string_view{}.max_size() == ptrdiff_max, "bad max_size for u16string_view"); -static_assert( - u32string_view{}.max_size() == static_cast(-1) / sizeof(char32_t), "bad max_size for u32string_view"); -static_assert(wstring_view{}.max_size() == ptrdiff_max, "bad max_size for wstring_view"); +static_assert(u16string_view{}.max_size() == ptrdiff_max); +static_assert(u32string_view{}.max_size() == static_cast(-1) / sizeof(char32_t)); +static_assert(wstring_view{}.max_size() == ptrdiff_max); // P0403R1 UDLs For ("meow"sv, etc.) static_assert("abc"sv[1] == 'b'); @@ -1260,9 +1224,9 @@ static_assert(noexcept(u8"abc"sv)); // P2166R1 Prohibiting basic_string And basic_string_view Construction From nullptr #if _HAS_CXX23 -static_assert(!is_constructible_v, "constructing string_view from nullptr_t is prohibited"); -static_assert(!is_constructible_v, "constructing string from nullptr_t is prohibited"); -static_assert(!is_assignable_v, "assigning nullptr_t to string is prohibited"); +static_assert(!is_constructible_v); +static_assert(!is_constructible_v); +static_assert(!is_assignable_v); #endif // _HAS_CXX23 // Also test that no C6510 warning @@ -1279,7 +1243,7 @@ struct std::char_traits { } static size_t length(const char_wrapper* a) { - static_assert(sizeof(char_wrapper) == 1, "strlen requires this"); + static_assert(sizeof(char_wrapper) == 1); return strlen(reinterpret_cast(a)); }