diff --git a/stl/inc/xstring b/stl/inc/xstring index 357798a7ac..91cdb517d1 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -773,47 +773,37 @@ constexpr size_t _Traits_find_first_of(_In_reads_(_Hay_size) const _Traits_ptr_t return static_cast(-1); // no match } -template +template > constexpr size_t _Traits_find_last_of(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits> _Haystack, const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, - const size_t _Needle_size, false_type) noexcept { + const size_t _Needle_size) noexcept { // in [_Haystack, _Haystack + _Hay_size), look for last of [_Needle, _Needle + _Needle_size), before _Start_at - // general algorithm if (_Needle_size != 0 && _Hay_size != 0) { // worth searching, do it - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { - if (_Traits::find(_Needle, _Needle_size, *_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match - } - - if (_Match_try == _Haystack) { - break; // at beginning, no more chance for match + if constexpr (_Special) { + _String_bitmap _Matches; + if (!_Matches._Mark(_Needle, _Needle + _Needle_size)) { // couldn't put one of the characters into the + // bitmap, fall back to the serial algorithm + return _Traits_find_last_of<_Traits, false>(_Haystack, _Hay_size, _Start_at, _Needle, _Needle_size); } - } - } - - return static_cast(-1); // no match -} -template -constexpr size_t _Traits_find_last_of(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits> _Haystack, - const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, - const size_t _Needle_size, true_type) noexcept { - // in [_Haystack, _Haystack + _Hay_size), look for last of [_Needle, _Needle + _Needle_size), before _Start_at - // special case for std::char_traits - if (_Needle_size != 0 && _Hay_size != 0) { // worth searching, do it - _String_bitmap _Matches; - if (!_Matches._Mark(_Needle, _Needle + _Needle_size)) { // couldn't put one of the characters into the bitmap, - // fall back to the serial algorithm - return _Traits_find_last_of<_Traits>(_Haystack, _Hay_size, _Start_at, _Needle, _Needle_size, false_type{}); - } + for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + if (_Matches._Match(*_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match + } - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { - if (_Matches._Match(*_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match + if (_Match_try == _Haystack) { + break; // at beginning, no more chance for match + } } + } else { + for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + if (_Traits::find(_Needle, _Needle_size, *_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match + } - if (_Match_try == _Haystack) { - break; // at beginning, no more chance for match + if (_Match_try == _Haystack) { + break; // at beginning, no more chance for match + } } } } @@ -821,42 +811,32 @@ constexpr size_t _Traits_find_last_of(_In_reads_(_Hay_size) const _Traits_ptr_t< return static_cast(-1); // no match } -template +template > constexpr size_t _Traits_find_first_not_of(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits> _Haystack, const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, - const size_t _Needle_size, false_type) noexcept { + const size_t _Needle_size) noexcept { // in [_Haystack, _Haystack + _Hay_size), look for none of [_Needle, _Needle + _Needle_size), at/after _Start_at - // general algorithm if (_Start_at < _Hay_size) { // room for match, look for it - const auto _End = _Haystack + _Hay_size; - for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) { - if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match + if constexpr (_Special) { + _String_bitmap _Matches; + if (!_Matches._Mark(_Needle, _Needle + _Needle_size)) { // couldn't put one of the characters into the + // bitmap, fall back to the serial algorithm + return _Traits_find_first_not_of<_Traits, false>( + _Haystack, _Hay_size, _Start_at, _Needle, _Needle_size); } - } - } - - return static_cast(-1); // no match -} -template -constexpr size_t _Traits_find_first_not_of(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits> _Haystack, - const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, - const size_t _Needle_size, true_type) noexcept { - // in [_Haystack, _Haystack + _Hay_size), look for none of [_Needle, _Needle + _Needle_size), at/after _Start_at - // special case for std::char_traits - if (_Start_at < _Hay_size) { // room for match, look for it - _String_bitmap _Matches; - if (!_Matches._Mark(_Needle, _Needle + _Needle_size)) { // couldn't put one of the characters into the bitmap, - // fall back to the serial algorithm - return _Traits_find_first_not_of<_Traits>( - _Haystack, _Hay_size, _Start_at, _Needle, _Needle_size, false_type{}); - } - - const auto _End = _Haystack + _Hay_size; - for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) { - if (!_Matches._Match(*_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match + const auto _End = _Haystack + _Hay_size; + for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) { + if (!_Matches._Match(*_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match + } + } + } else { + const auto _End = _Haystack + _Hay_size; + for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) { + if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match + } } } } @@ -880,48 +860,37 @@ constexpr size_t _Traits_find_not_ch(_In_reads_(_Hay_size) const _Traits_ptr_t<_ return static_cast(-1); // no match } -template +template > constexpr size_t _Traits_find_last_not_of(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits> _Haystack, const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, - const size_t _Needle_size, false_type) noexcept { + const size_t _Needle_size) noexcept { // in [_Haystack, _Haystack + _Hay_size), look for none of [_Needle, _Needle + _Needle_size), before _Start_at - // general algorithm if (_Hay_size != 0) { // worth searching, do it - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { - if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match - } - - if (_Match_try == _Haystack) { - break; // at beginning, no more chance for match + if constexpr (_Special) { + _String_bitmap _Matches; + if (!_Matches._Mark(_Needle, _Needle + _Needle_size)) { // couldn't put one of the characters into the + // bitmap, fall back to the serial algorithm + return _Traits_find_last_not_of<_Traits, false>(_Haystack, _Hay_size, _Start_at, _Needle, _Needle_size); } - } - } - return static_cast(-1); // no match -} - -template -constexpr size_t _Traits_find_last_not_of(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits> _Haystack, - const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, - const size_t _Needle_size, true_type) noexcept { - // in [_Haystack, _Haystack + _Hay_size), look for none of [_Needle, _Needle + _Needle_size), before _Start_at - // special case for std::char_traits - if (_Hay_size != 0) { // worth searching, do it - _String_bitmap _Matches; - if (!_Matches._Mark(_Needle, _Needle + _Needle_size)) { // couldn't put one of the characters into the bitmap, - // fall back to the serial algorithm - return _Traits_find_last_not_of<_Traits>( - _Haystack, _Hay_size, _Start_at, _Needle, _Needle_size, false_type{}); - } + for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + if (!_Matches._Match(*_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match + } - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { - if (!_Matches._Match(*_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match + if (_Match_try == _Haystack) { + break; // at beginning, no more chance for match + } } + } else { + for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match + } - if (_Match_try == _Haystack) { - break; // at beginning, no more chance for match + if (_Match_try == _Haystack) { + break; // at beginning, no more chance for match + } } } } @@ -1588,8 +1557,7 @@ public: _NODISCARD constexpr size_type find_last_of(const basic_string_view _Right, const size_type _Off = npos) const noexcept { // look for one of _Right before _Off - return _Traits_find_last_of<_Traits>( - _Mydata, _Mysize, _Off, _Right._Mydata, _Right._Mysize, _Is_specialization<_Traits, char_traits>{}); + return _Traits_find_last_of<_Traits>(_Mydata, _Mysize, _Off, _Right._Mydata, _Right._Mysize); } _NODISCARD constexpr size_type find_last_of(const _Elem _Ch, const size_type _Off = npos) const noexcept { @@ -1600,21 +1568,18 @@ public: _NODISCARD constexpr size_type find_last_of(_In_reads_(_Count) const _Elem* const _Ptr, const size_type _Off, const size_type _Count) const noexcept /* strengthened */ { // look for one of [_Ptr, _Ptr + _Count) before _Off - return _Traits_find_last_of<_Traits>( - _Mydata, _Mysize, _Off, _Ptr, _Count, _Is_specialization<_Traits, char_traits>{}); + return _Traits_find_last_of<_Traits>(_Mydata, _Mysize, _Off, _Ptr, _Count); } _NODISCARD constexpr size_type find_last_of( _In_z_ const _Elem* const _Ptr, const size_type _Off = npos) const noexcept /* strengthened */ { // look for one of [_Ptr, ) before _Off - return _Traits_find_last_of<_Traits>( - _Mydata, _Mysize, _Off, _Ptr, _Traits::length(_Ptr), _Is_specialization<_Traits, char_traits>{}); + return _Traits_find_last_of<_Traits>(_Mydata, _Mysize, _Off, _Ptr, _Traits::length(_Ptr)); } _NODISCARD constexpr size_type find_first_not_of(const basic_string_view _Right, const size_type _Off = 0) const noexcept { // look for none of _Right at or after _Off - return _Traits_find_first_not_of<_Traits>( - _Mydata, _Mysize, _Off, _Right._Mydata, _Right._Mysize, _Is_specialization<_Traits, char_traits>{}); + return _Traits_find_first_not_of<_Traits>(_Mydata, _Mysize, _Off, _Right._Mydata, _Right._Mysize); } _NODISCARD constexpr size_type find_first_not_of(const _Elem _Ch, const size_type _Off = 0) const noexcept { @@ -1625,21 +1590,18 @@ public: _NODISCARD constexpr size_type find_first_not_of(_In_reads_(_Count) const _Elem* const _Ptr, const size_type _Off, const size_type _Count) const noexcept /* strengthened */ { // look for none of [_Ptr, _Ptr + _Count) at or after _Off - return _Traits_find_first_not_of<_Traits>( - _Mydata, _Mysize, _Off, _Ptr, _Count, _Is_specialization<_Traits, char_traits>{}); + return _Traits_find_first_not_of<_Traits>(_Mydata, _Mysize, _Off, _Ptr, _Count); } _NODISCARD constexpr size_type find_first_not_of( _In_z_ const _Elem* const _Ptr, const size_type _Off = 0) const noexcept /* strengthened */ { // look for none of [_Ptr, ) at or after _Off - return _Traits_find_first_not_of<_Traits>( - _Mydata, _Mysize, _Off, _Ptr, _Traits::length(_Ptr), _Is_specialization<_Traits, char_traits>{}); + return _Traits_find_first_not_of<_Traits>(_Mydata, _Mysize, _Off, _Ptr, _Traits::length(_Ptr)); } _NODISCARD constexpr size_type find_last_not_of(const basic_string_view _Right, const size_type _Off = npos) const noexcept { // look for none of _Right before _Off - return _Traits_find_last_not_of<_Traits>( - _Mydata, _Mysize, _Off, _Right._Mydata, _Right._Mysize, _Is_specialization<_Traits, char_traits>{}); + return _Traits_find_last_not_of<_Traits>(_Mydata, _Mysize, _Off, _Right._Mydata, _Right._Mysize); } _NODISCARD constexpr size_type find_last_not_of(const _Elem _Ch, const size_type _Off = npos) const noexcept { @@ -1650,15 +1612,13 @@ public: _NODISCARD constexpr size_type find_last_not_of(_In_reads_(_Count) const _Elem* const _Ptr, const size_type _Off, const size_type _Count) const noexcept /* strengthened */ { // look for none of [_Ptr, _Ptr + _Count) before _Off - return _Traits_find_last_not_of<_Traits>( - _Mydata, _Mysize, _Off, _Ptr, _Count, _Is_specialization<_Traits, char_traits>{}); + return _Traits_find_last_not_of<_Traits>(_Mydata, _Mysize, _Off, _Ptr, _Count); } _NODISCARD constexpr size_type find_last_not_of( _In_z_ const _Elem* const _Ptr, const size_type _Off = npos) const noexcept /* strengthened */ { // look for none of [_Ptr, ) before _Off - return _Traits_find_last_not_of<_Traits>( - _Mydata, _Mysize, _Off, _Ptr, _Traits::length(_Ptr), _Is_specialization<_Traits, char_traits>{}); + return _Traits_find_last_not_of<_Traits>(_Mydata, _Mysize, _Off, _Ptr, _Traits::length(_Ptr)); } _NODISCARD constexpr bool _Starts_with(const basic_string_view _View) const noexcept { @@ -4230,30 +4190,29 @@ public: noexcept(_Is_nothrow_convertible_v>) { // look for one of _Right before _Off basic_string_view<_Elem, _Traits> _As_view = _Right; - return static_cast(_Traits_find_last_of<_Traits>(_Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, - _Off, _As_view.data(), _As_view.size(), _Is_specialization<_Traits, char_traits>{})); + return static_cast(_Traits_find_last_of<_Traits>( + _Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, _Off, _As_view.data(), _As_view.size())); } #endif // _HAS_CXX17 _NODISCARD _CONSTEXPR20 size_type find_last_of(const basic_string& _Right, size_type _Off = npos) const noexcept { // look for one of _Right before _Off return static_cast(_Traits_find_last_of<_Traits>(_Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, - _Off, _Right._Mypair._Myval2._Myptr(), _Right._Mypair._Myval2._Mysize, - _Is_specialization<_Traits, char_traits>{})); + _Off, _Right._Mypair._Myval2._Myptr(), _Right._Mypair._Myval2._Mysize)); } _NODISCARD _CONSTEXPR20 size_type find_last_of(_In_reads_(_Count) const _Elem* const _Ptr, const size_type _Off, const size_type _Count) const noexcept /* strengthened */ { // look for one of [_Ptr, _Ptr + _Count) before _Off - return static_cast(_Traits_find_last_of<_Traits>(_Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, - _Off, _Ptr, _Count, _Is_specialization<_Traits, char_traits>{})); + return static_cast( + _Traits_find_last_of<_Traits>(_Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, _Off, _Ptr, _Count)); } _NODISCARD _CONSTEXPR20 size_type find_last_of( _In_z_ const _Elem* const _Ptr, const size_type _Off = npos) const noexcept /* strengthened */ { // look for one of [_Ptr, ) before _Off - return static_cast(_Traits_find_last_of<_Traits>(_Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, - _Off, _Ptr, _Traits::length(_Ptr), _Is_specialization<_Traits, char_traits>{})); + return static_cast(_Traits_find_last_of<_Traits>( + _Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, _Off, _Ptr, _Traits::length(_Ptr))); } _NODISCARD _CONSTEXPR20 size_type find_last_of(const _Elem _Ch, const size_type _Off = npos) const noexcept { @@ -4268,9 +4227,8 @@ public: noexcept(_Is_nothrow_convertible_v>) { // look for none of _Right at or after _Off basic_string_view<_Elem, _Traits> _As_view = _Right; - return static_cast( - _Traits_find_first_not_of<_Traits>(_Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, _Off, _As_view.data(), - _As_view.size(), _Is_specialization<_Traits, char_traits>{})); + return static_cast(_Traits_find_first_not_of<_Traits>( + _Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, _Off, _As_view.data(), _As_view.size())); } #endif // _HAS_CXX17 @@ -4278,22 +4236,21 @@ public: const basic_string& _Right, const size_type _Off = 0) const noexcept { // look for none of _Right at or after _Off return static_cast(_Traits_find_first_not_of<_Traits>(_Mypair._Myval2._Myptr(), - _Mypair._Myval2._Mysize, _Off, _Right._Mypair._Myval2._Myptr(), _Right._Mypair._Myval2._Mysize, - _Is_specialization<_Traits, char_traits>{})); + _Mypair._Myval2._Mysize, _Off, _Right._Mypair._Myval2._Myptr(), _Right._Mypair._Myval2._Mysize)); } _NODISCARD _CONSTEXPR20 size_type find_first_not_of(_In_reads_(_Count) const _Elem* const _Ptr, const size_type _Off, const size_type _Count) const noexcept /* strengthened */ { // look for none of [_Ptr, _Ptr + _Count) at or after _Off - return static_cast(_Traits_find_first_not_of<_Traits>(_Mypair._Myval2._Myptr(), - _Mypair._Myval2._Mysize, _Off, _Ptr, _Count, _Is_specialization<_Traits, char_traits>{})); + return static_cast( + _Traits_find_first_not_of<_Traits>(_Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, _Off, _Ptr, _Count)); } _NODISCARD _CONSTEXPR20 size_type find_first_not_of( _In_z_ const _Elem* const _Ptr, size_type _Off = 0) const noexcept /* strengthened */ { // look for one of [_Ptr, ) at or after _Off - return static_cast(_Traits_find_first_not_of<_Traits>(_Mypair._Myval2._Myptr(), - _Mypair._Myval2._Mysize, _Off, _Ptr, _Traits::length(_Ptr), _Is_specialization<_Traits, char_traits>{})); + return static_cast(_Traits_find_first_not_of<_Traits>( + _Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, _Off, _Ptr, _Traits::length(_Ptr))); } _NODISCARD _CONSTEXPR20 size_type find_first_not_of(const _Elem _Ch, const size_type _Off = 0) const noexcept { @@ -4308,9 +4265,8 @@ public: noexcept(_Is_nothrow_convertible_v>) { // look for none of _Right before _Off basic_string_view<_Elem, _Traits> _As_view = _Right; - return static_cast( - _Traits_find_last_not_of<_Traits>(_Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, _Off, _As_view.data(), - _As_view.size(), _Is_specialization<_Traits, char_traits>{})); + return static_cast(_Traits_find_last_not_of<_Traits>( + _Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, _Off, _As_view.data(), _As_view.size())); } #endif // _HAS_CXX17 @@ -4318,22 +4274,21 @@ public: const basic_string& _Right, const size_type _Off = npos) const noexcept { // look for none of _Right before _Off return static_cast(_Traits_find_last_not_of<_Traits>(_Mypair._Myval2._Myptr(), - _Mypair._Myval2._Mysize, _Off, _Right._Mypair._Myval2._Myptr(), _Right._Mypair._Myval2._Mysize, - _Is_specialization<_Traits, char_traits>{})); + _Mypair._Myval2._Mysize, _Off, _Right._Mypair._Myval2._Myptr(), _Right._Mypair._Myval2._Mysize)); } _NODISCARD _CONSTEXPR20 size_type find_last_not_of(_In_reads_(_Count) const _Elem* const _Ptr, const size_type _Off, const size_type _Count) const noexcept /* strengthened */ { // look for none of [_Ptr, _Ptr + _Count) before _Off - return static_cast(_Traits_find_last_not_of<_Traits>(_Mypair._Myval2._Myptr(), - _Mypair._Myval2._Mysize, _Off, _Ptr, _Count, _Is_specialization<_Traits, char_traits>{})); + return static_cast( + _Traits_find_last_not_of<_Traits>(_Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, _Off, _Ptr, _Count)); } _NODISCARD _CONSTEXPR20 size_type find_last_not_of( _In_z_ const _Elem* const _Ptr, const size_type _Off = npos) const noexcept /* strengthened */ { // look for none of [_Ptr, ) before _Off - return static_cast(_Traits_find_last_not_of<_Traits>(_Mypair._Myval2._Myptr(), - _Mypair._Myval2._Mysize, _Off, _Ptr, _Traits::length(_Ptr), _Is_specialization<_Traits, char_traits>{})); + return static_cast(_Traits_find_last_not_of<_Traits>( + _Mypair._Myval2._Myptr(), _Mypair._Myval2._Mysize, _Off, _Ptr, _Traits::length(_Ptr))); } _NODISCARD _CONSTEXPR20 size_type find_last_not_of(const _Elem _Ch, const size_type _Off = npos) const noexcept {