Re: [PATCH, libstdc++, C++20] Implement P0457R2 String Prefix and Suffix Checking.
On 11/30/18 5:33 AM, Jonathan Wakely wrote: On 29/11/18 21:35 -0500, Ed Smith-Rowland wrote: Greetings, This patch implements starts_with and ends_with for basic_string and basic_string_view for C++20. This was on my TODO list, thanks for taking care of it. +#if __cplusplus > 201703L + bool + starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + starts_with(_CharT __x) const noexcept + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + starts_with(const _CharT* __x) const This can be noexcept. It isn't in the standard, because it has a narrow contract (there's a precondition that __x is null-terminated). But since we can't reliably detect whether __x is null-terminated, and even if we could we wouldn't want to throw an exception, we can just make it noexcept. Same for the ends_with(const _CharT*) one, and the equivalent members in the COW basic_string and basic_string_view. Index: include/std/string_view === --- include/std/string_view (revision 266645) +++ include/std/string_view (working copy) @@ -227,7 +227,6 @@ __sv = __tmp; } - // [string.view.ops], string operations: size_type @@ -387,6 +386,36 @@ traits_type::length(__str)); } +#if __cplusplus > 201703L + constexpr bool + starts_with(basic_string_view __x) const noexcept + { return this->size() >= __x.size() + && this->compare(0, __x.size(), __x) == 0; } Please put the opening and closing braces on their own lines, as for ends_with below: + constexpr bool + ends_with(basic_string_view __x) const noexcept + { + return this->size() >= __x.size() + && this->compare(this->size() - __x.size(), npos, __x) == 0; + } OK with those changes, thanks Committed 266674. New patch attached. Ed 2018-11-30 Edward Smith-Rowland <3dw...@verizon.net> Implement P0457R2 String Prefix and Suffix Checking. * include/bits/basic_string.h: Add starts_with, ends_with members. * include/std/string_view: Ditto. * testsuite/21_strings/basic_string/operations/starts_with/ char/1.cc: New test. * testsuite/21_strings/basic_string/operations/starts_with/ wchar_t/1.cc: New test. * testsuite/21_strings/basic_string/operations/ends_with/ char/1.cc: New test. * testsuite/21_strings/basic_string/operations/ends_with/ wchar_t/1.cc: New test. * testsuite/21_strings/basic_string_view/operations/starts_with/ char/1.cc: New test. * testsuite/21_strings/basic_string_view/operations/starts_with/ wchar_t/1.cc: New test. * testsuite/21_strings/basic_string_view/operations/ends_with/ char/1.cc: New test. * testsuite/21_strings/basic_string_view/operations/ends_with/ wchar_t/1.cc: New test. Index: include/bits/basic_string.h === --- include/bits/basic_string.h (revision 266671) +++ include/bits/basic_string.h (working copy) @@ -3038,6 +3038,32 @@ compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const; +#if __cplusplus > 201703L + bool + starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + starts_with(_CharT __x) const noexcept + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + starts_with(const _CharT* __x) const noexcept + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + ends_with(basic_string_view<_CharT, _Traits> __x) const noexcept + { return __sv_type(this->data(), this->size()).ends_with(__x); } + + bool + ends_with(_CharT __x) const noexcept + { return __sv_type(this->data(), this->size()).ends_with(__x); } + + bool + ends_with(const _CharT* __x) const noexcept + { return __sv_type(this->data(), this->size()).ends_with(__x); } +#endif // C++20 + // Allow basic_stringbuf::__xfer_bufptrs to call _M_length: template friend class basic_stringbuf; }; @@ -5884,6 +5910,32 @@ compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const; +#if __cplusplus > 201703L + bool + starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + starts_with(_CharT __x) const noexcept + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + starts_with(const _CharT* __x) const noexcept + { return __sv_type(this->data(),
Re: [PATCH, libstdc++, C++20] Implement P0457R2 String Prefix and Suffix Checking.
On 29/11/18 21:35 -0500, Ed Smith-Rowland wrote: Greetings, This patch implements starts_with and ends_with for basic_string and basic_string_view for C++20. This was on my TODO list, thanks for taking care of it. +#if __cplusplus > 201703L + bool + starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + starts_with(_CharT __x) const noexcept + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + starts_with(const _CharT* __x) const This can be noexcept. It isn't in the standard, because it has a narrow contract (there's a precondition that __x is null-terminated). But since we can't reliably detect whether __x is null-terminated, and even if we could we wouldn't want to throw an exception, we can just make it noexcept. Same for the ends_with(const _CharT*) one, and the equivalent members in the COW basic_string and basic_string_view. Index: include/std/string_view === --- include/std/string_view (revision 266645) +++ include/std/string_view (working copy) @@ -227,7 +227,6 @@ __sv = __tmp; } - // [string.view.ops], string operations: size_type @@ -387,6 +386,36 @@ traits_type::length(__str)); } +#if __cplusplus > 201703L + constexpr bool + starts_with(basic_string_view __x) const noexcept + { return this->size() >= __x.size() + && this->compare(0, __x.size(), __x) == 0; } Please put the opening and closing braces on their own lines, as for ends_with below: + constexpr bool + ends_with(basic_string_view __x) const noexcept + { + return this->size() >= __x.size() + && this->compare(this->size() - __x.size(), npos, __x) == 0; + } OK with those changes, thanks.
[PATCH, libstdc++, C++20] Implement P0457R2 String Prefix and Suffix Checking.
Greetings, This patch implements starts_with and ends_with for basic_string and basic_string_view for C++20. This builds and tests cleanly on x86_64-linux. Ed 2018-11-30 Edward Smith-Rowland <3dw...@verizon.net> Implement P0457R2 String Prefix and Suffix Checking. * include/bits/basic_string.h: Add starts_with, ends_with members. * include/std/string_view: Ditto. * testsuite/21_strings/basic_string/operations/starts_with/ char/1.cc: New test. * testsuite/21_strings/basic_string/operations/starts_with/ wchar_t/1.cc: New test. * testsuite/21_strings/basic_string/operations/ends_with/ char/1.cc: New test. * testsuite/21_strings/basic_string/operations/ends_with/ wchar_t/1.cc: New test. * testsuite/21_strings/basic_string_view/operations/starts_with/ char/1.cc: New test. * testsuite/21_strings/basic_string_view/operations/starts_with/ wchar_t/1.cc: New test. * testsuite/21_strings/basic_string_view/operations/ends_with/ char/1.cc: New test. * testsuite/21_strings/basic_string_view/operations/ends_with/ wchar_t/1.cc: New test. Index: include/bits/basic_string.h === --- include/bits/basic_string.h (revision 266645) +++ include/bits/basic_string.h (working copy) @@ -3038,6 +3038,32 @@ compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const; +#if __cplusplus > 201703L + bool + starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + starts_with(_CharT __x) const noexcept + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + starts_with(const _CharT* __x) const + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + ends_with(basic_string_view<_CharT, _Traits> __x) const noexcept + { return __sv_type(this->data(), this->size()).ends_with(__x); } + + bool + ends_with(_CharT __x) const noexcept + { return __sv_type(this->data(), this->size()).ends_with(__x); } + + bool + ends_with(const _CharT* __x) const + { return __sv_type(this->data(), this->size()).ends_with(__x); } +#endif // C++20 + // Allow basic_stringbuf::__xfer_bufptrs to call _M_length: template friend class basic_stringbuf; }; @@ -5884,6 +5910,32 @@ compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const; +#if __cplusplus > 201703L + bool + starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + starts_with(_CharT __x) const noexcept + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + starts_with(const _CharT* __x) const + { return __sv_type(this->data(), this->size()).starts_with(__x); } + + bool + ends_with(basic_string_view<_CharT, _Traits> __x) const noexcept + { return __sv_type(this->data(), this->size()).ends_with(__x); } + + bool + ends_with(_CharT __x) const noexcept + { return __sv_type(this->data(), this->size()).ends_with(__x); } + + bool + ends_with(const _CharT* __x) const + { return __sv_type(this->data(), this->size()).ends_with(__x); } +#endif // C++20 + # ifdef _GLIBCXX_TM_TS_INTERNAL friend void ::_txnal_cow_string_C1_for_exceptions(void* that, const char* s, Index: include/std/string_view === --- include/std/string_view (revision 266645) +++ include/std/string_view (working copy) @@ -227,7 +227,6 @@ __sv = __tmp; } - // [string.view.ops], string operations: size_type @@ -387,6 +386,36 @@ traits_type::length(__str)); } +#if __cplusplus > 201703L + constexpr bool + starts_with(basic_string_view __x) const noexcept + { return this->size() >= __x.size() + && this->compare(0, __x.size(), __x) == 0; } + + constexpr bool + starts_with(_CharT __x) const noexcept + { return this->starts_with(basic_string_view(&__x, 1)); } + + constexpr bool + starts_with(const _CharT* __x) const + { return this->starts_with(basic_string_view(__x)); } + + constexpr bool + ends_with(basic_string_view __x) const noexcept + { + return this->size() >= __x.size() + && this->compare(this->size() - __x.size(), npos, __x) == 0; + } + + constexpr bool + ends_with(_CharT __x) const noexcept + { return this->ends_with(basic_string_view(&__x, 1)); } + + constexpr bool + ends_with(const _CharT* __x) const + { return