Index: libcxx/include/string =================================================================== --- libcxx/include/string +++ libcxx/include/string @@ -324,6 +324,10 @@ bool ends_with(charT c) const noexcept; // C++2a bool ends_with(const charT* s) const; // C++2a + bool contains(basic_string_view sv) const noexcept; // C++23 + bool contains(charT c) const noexcept; // C++23 + bool contains(const charT* s) const; // C++23 + bool __invariants() const; }; @@ -1433,6 +1437,20 @@ { return ends_with(__self_view(__s)); } #endif +#if _LIBCPP_STD_VER > 20 + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool contains(__self_view __sv) const _NOEXCEPT + { return __self_view(data(), size()).contains(__sv); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool contains(value_type __c) const _NOEXCEPT + { return __self_view(data(), size()).contains(__c); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool contains(const value_type* __s) const _NOEXCEPT + { return __self_view(data(), size()).contains(__s); } +#endif + _LIBCPP_INLINE_VISIBILITY bool __invariants() const; _LIBCPP_INLINE_VISIBILITY void __clear_and_shrink() _NOEXCEPT; Index: libcxx/include/string_view =================================================================== --- libcxx/include/string_view +++ libcxx/include/string_view @@ -149,6 +149,10 @@ constexpr bool ends_with(charT c) const noexcept; // C++2a constexpr bool ends_with(const charT* s) const; // C++2a + constexpr bool contains(basic_string_view s) const noexcept; // C++23 + constexpr bool contains(charT c) const noexcept; // C++23 + constexpr bool contains(const charT* s) const; // C++23 + private: const_pointer data_; // exposition only size_type size_; // exposition only @@ -622,6 +626,20 @@ { return ends_with(basic_string_view(__s)); } #endif +#if _LIBCPP_STD_VER > 20 + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool contains(basic_string_view __sv) const _NOEXCEPT + { return find(__sv) != npos; } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool contains(value_type __c) const _NOEXCEPT + { return find(__c) != npos; } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool contains(const value_type* __s) const _NOEXCEPT + { return find(__s) != npos; } +#endif + private: const value_type* __data; size_type __size; Index: libcxx/test/std/strings/basic.string/string.contains/contains.char.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/strings/basic.string/string.contains/contains.char.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// bool contains(charT x) const noexcept; + +#include +#include + +#include "test_macros.h" + +int main(int, char**) +{ + { + typedef std::string S; + S s1 {}; + S s2 { "abcde", 5 }; + + ASSERT_NOEXCEPT(s1.contains('e')); + + assert (!s1.contains('c')); + assert (!s1.contains('e')); + assert (!s1.contains('x')); + assert ( s2.contains('c')); + assert ( s2.contains('e')); + assert (!s2.contains('x')); + } + + return 0; +} Index: libcxx/test/std/strings/basic.string/string.contains/contains.ptr.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/strings/basic.string/string.contains/contains.ptr.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// bool contains(const CharT *x) const; + +#include +#include + +#include "test_macros.h" + +int main(int, char**) +{ + { + typedef std::string S; + const char *s = "abcde"; + + S s0; + S s1 { s + 4, 1 }; +// S s2 { s + 3, 2 }; + S s3 { s + 2, 3 }; +// S s4 { s + 1, 4 }; +// S s5 { s, 5 }; + S sNot { "xyz", 3 }; + + LIBCPP_ASSERT_NOEXCEPT(s0.contains("")); + + assert ( s0.contains("")); + assert (!s0.contains("e")); + + assert ( s1.contains("")); + assert (!s1.contains("d")); + assert ( s1.contains("e")); + assert (!s1.contains("de")); + assert (!s1.contains("cd")); + assert (!s1.contains("cde")); + assert (!s1.contains("bcde")); + assert (!s1.contains("abcde")); + assert (!s1.contains("xyz")); + + assert ( s3.contains("")); + assert ( s3.contains("d")); + assert ( s3.contains("e")); + assert ( s3.contains("de")); + assert ( s3.contains("cd")); + assert ( s3.contains("cde")); + assert (!s3.contains("bcde")); + assert (!s3.contains("abcde")); + assert (!s3.contains("xyz")); + + assert ( sNot.contains("")); + assert (!sNot.contains("d")); + assert (!sNot.contains("e")); + assert (!sNot.contains("de")); + assert (!sNot.contains("cd")); + assert (!sNot.contains("cde")); + assert (!sNot.contains("bcde")); + assert (!sNot.contains("abcde")); + assert ( sNot.contains("xyz")); + } + + return 0; +} Index: libcxx/test/std/strings/basic.string/string.contains/contains.string_view.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/strings/basic.string/string.contains/contains.string_view.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// bool contains(basic_string_view x) const noexcept; + +#include +#include + +#include "test_macros.h" + +int main(int, char**) +{ + { + typedef std::string S; + typedef std::string_view SV; + const char *s = "abcde"; + + S s0; + S s1 { s + 1, 1 }; +// S s2 { s + 3, 2 }; + S s3 { s + 1, 3 }; +// S s4 { s + 1, 4 }; + S s5 { s, 5 }; + S sNot { "xyz", 3 }; + + SV sv0; + SV sv1 { s + 1, 1 }; + SV sv2 { s + 1, 2 }; + SV sv3 { s + 1, 3 }; + SV sv4 { s + 1, 4 }; + SV sv5 { s , 5 }; + SV svNot {"xyz", 3 }; + + ASSERT_NOEXCEPT(s0.contains(sv0)); + + assert ( s0.contains(sv0)); + assert (!s0.contains(sv1)); + + assert ( s1.contains(sv0)); + assert ( s1.contains(sv1)); + assert (!s1.contains(sv2)); + assert (!s1.contains(sv3)); + assert (!s1.contains(sv4)); + assert (!s1.contains(sv5)); + assert (!s1.contains(svNot)); + + assert ( s3.contains(sv0)); + assert ( s3.contains(sv1)); + assert ( s3.contains(sv2)); + assert ( s3.contains(sv3)); + assert (!s3.contains(sv4)); + assert (!s3.contains(sv5)); + assert (!s3.contains(svNot)); + + assert ( s5.contains(sv0)); + assert ( s5.contains(sv1)); + assert ( s5.contains(sv2)); + assert ( s5.contains(sv3)); + assert ( s5.contains(sv4)); + assert ( s5.contains(sv5)); + assert (!s5.contains(svNot)); + + assert ( sNot.contains(sv0)); + assert (!sNot.contains(sv1)); + assert (!sNot.contains(sv2)); + assert (!sNot.contains(sv3)); + assert (!sNot.contains(sv4)); + assert (!sNot.contains(sv5)); + assert ( sNot.contains(svNot)); + } + + return 0; +} Index: libcxx/test/std/strings/string.view/string.view.template/contains.char.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/strings/string.view/string.view.template/contains.char.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// constexpr bool contains(charT x) const noexcept; + +#include +#include + +#include "test_macros.h" +#include "constexpr_char_traits.h" + +int main(int, char**) +{ + { + typedef std::string_view SV; + SV sv1 {}; + SV sv2 { "abcde", 5 }; + + ASSERT_NOEXCEPT(sv1.contains('e')); + + assert (!sv1.contains('c')); + assert (!sv1.contains('e')); + assert (!sv1.contains('x')); + assert ( sv2.contains('c')); + assert ( sv2.contains('e')); + assert (!sv2.contains('x')); + } + +#if TEST_STD_VER > 11 + { + typedef std::basic_string_view> SV; + constexpr SV sv1 {}; + constexpr SV sv2 { "abcde", 5 }; + static_assert (!sv1.contains('c')); + static_assert (!sv1.contains('e')); + static_assert (!sv1.contains('x')); + static_assert ( sv2.contains('c')); + static_assert ( sv2.contains('e')); + static_assert (!sv2.contains('x')); + } +#endif + + return 0; +} Index: libcxx/test/std/strings/string.view/string.view.template/contains.ptr.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/strings/string.view/string.view.template/contains.ptr.pass.cpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// constexpr bool contains(const CharT *x) const; + +#include +#include + +#include "test_macros.h" +#include "constexpr_char_traits.h" + +int main(int, char**) +{ + { + typedef std::string_view SV; + const char *s = "abcde"; + SV sv0 {}; + SV sv1 { s + 4, 1 }; +// SV sv2 { s + 3, 2 }; + SV sv3 { s + 2, 3 }; +// SV sv4 { s + 1, 4 }; +// SV sv5 { s , 5 }; + SV svNot {"xyz", 3 }; + + LIBCPP_ASSERT_NOEXCEPT(sv0.contains("")); + + assert ( sv0.contains("")); + assert (!sv0.contains("e")); + + assert ( sv1.contains("")); + assert (!sv1.contains("d")); + assert ( sv1.contains("e")); + assert (!sv1.contains("de")); + assert (!sv1.contains("cd")); + assert (!sv1.contains("cde")); + assert (!sv1.contains("bcde")); + assert (!sv1.contains("abcde")); + assert (!sv1.contains("xyz")); + + assert ( sv3.contains("")); + assert ( sv3.contains("d")); + assert ( sv3.contains("e")); + assert ( sv3.contains("de")); + assert ( sv3.contains("cd")); + assert (!sv3.contains("cde")); + assert (!sv3.contains("bcde")); + assert (!sv3.contains("abcde")); + assert (!sv3.contains("xyz")); + + assert ( svNot.contains("")); + assert (!svNot.contains("d")); + assert (!svNot.contains("e")); + assert (!svNot.contains("de")); + assert (!svNot.contains("cd")); + assert (!svNot.contains("cde")); + assert (!svNot.contains("bcde")); + assert (!svNot.contains("abcde")); + assert ( svNot.contains("xyz")); + } + +#if TEST_STD_VER > 11 + { + typedef std::basic_string_view> SV; + constexpr const char *s = "abcde"; + constexpr SV sv0 {}; + constexpr SV sv1 { s + 4, 1 }; +// constexpr SV sv2 { s + 3, 2 }; + constexpr SV sv3 { s + 2, 3 }; +// constexpr SV sv4 { s + 1, 4 }; +// constexpr SV sv5 { s, 5 }; + constexpr SV svNot {"xyz", 3 }; + + static_assert ( sv0.contains("")); + static_assert (!sv0.contains("e")); + + static_assert ( sv1.contains("")); + static_assert (!sv1.contains("d")); + static_assert ( sv1.contains("e")); + static_assert (!sv1.contains("de")); + static_assert (!sv1.contains("cde")); + static_assert (!sv1.contains("bcde")); + static_assert (!sv1.contains("abcde")); + static_assert (!sv1.contains("xyz")); + + static_assert ( sv3.contains("")); + static_assert ( sv3.contains("d")); + static_assert ( sv3.contains("e")); + static_assert ( sv3.contains("de")); + static_assert ( sv3.contains("cd")); + static_assert ( sv3.contains("cde")); + static_assert (!sv3.contains("bcde")); + static_assert (!sv3.contains("abcde")); + static_assert (!sv3.contains("xyz")); + + static_assert ( svNot.contains("")); + static_assert (!svNot.contains("d")); + static_assert (!svNot.contains("e")); + static_assert (!svNot.contains("de")); + static_assert (!svNot.contains("cd")); + static_assert (!svNot.contains("cde")); + static_assert (!svNot.contains("bcde")); + static_assert (!svNot.contains("abcde")); + static_assert ( svNot.contains("xyz")); + } +#endif + + return 0; +} Index: libcxx/test/std/strings/string.view/string.view.template/contains.string_view.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/strings/string.view/string.view.template/contains.string_view.pass.cpp @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// constexpr bool contains(string_view x) const noexcept; + +#include +#include + +#include "test_macros.h" +#include "constexpr_char_traits.h" + +int main(int, char**) +{ + { + typedef std::string_view SV; + const char *s = "abcde"; + SV sv0; + SV sv1 { s + 1, 1 }; + SV sv2 { s + 1, 2 }; + SV sv3 { s + 1, 3 }; + SV sv4 { s + 1, 4 }; + SV sv5 { s , 5 }; + SV svNot {"xyz", 3 }; + + ASSERT_NOEXCEPT(sv0.contains(sv0)); + + assert ( sv0.contains(sv0)); + assert (!sv0.contains(sv1)); + + assert ( sv1.contains(sv0)); + assert ( sv1.contains(sv1)); + assert (!sv1.contains(sv2)); + assert (!sv1.contains(sv3)); + assert (!sv1.contains(sv4)); + assert (!sv1.contains(sv5)); + assert (!sv1.contains(svNot)); + + assert ( sv3.contains(sv0)); + assert ( sv3.contains(sv1)); + assert ( sv3.contains(sv2)); + assert ( sv3.contains(sv3)); + assert (!sv3.contains(sv4)); + assert (!sv3.contains(sv5)); + assert (!sv3.contains(svNot)); + + assert ( sv5.contains(sv0)); + assert ( sv5.contains(sv1)); + assert ( sv5.contains(sv2)); + assert ( sv5.contains(sv3)); + assert ( sv5.contains(sv4)); + assert ( sv5.contains(sv5)); + assert (!sv5.contains(svNot)); + + assert ( svNot.contains(sv0)); + assert (!svNot.contains(sv1)); + assert (!svNot.contains(sv2)); + assert (!svNot.contains(sv3)); + assert (!svNot.contains(sv4)); + assert (!svNot.contains(sv5)); + assert ( svNot.contains(svNot)); + } + +#if TEST_STD_VER > 11 + { + typedef std::basic_string_view> SV; + constexpr const char *s = "abcde"; + constexpr SV sv0 {}; + constexpr SV sv1 { s + 1, 1 }; + constexpr SV sv2 { s + 1, 2 }; + constexpr SV sv3 { s + 1, 3 }; + constexpr SV sv4 { s + 1, 4 }; + constexpr SV sv5 { s, 5 }; + constexpr SV svNot {"xyz", 3 }; + + static_assert ( sv0.contains(sv0)); + static_assert (!sv0.contains(sv1)); + + static_assert ( sv1.contains(sv0)); + static_assert ( sv1.contains(sv1)); + static_assert (!sv1.contains(sv2)); + static_assert (!sv1.contains(sv3)); + static_assert (!sv1.contains(sv4)); + static_assert (!sv1.contains(sv5)); + static_assert (!sv1.contains(svNot)); + + static_assert ( sv3.contains(sv0)); + static_assert ( sv3.contains(sv1)); + static_assert ( sv3.contains(sv2)); + static_assert ( sv3.contains(sv3)); + static_assert (!sv3.contains(sv4)); + static_assert (!sv3.contains(sv5)); + static_assert (!sv3.contains(svNot)); + + static_assert ( sv5.contains(sv0)); + static_assert ( sv5.contains(sv1)); + static_assert ( sv5.contains(sv2)); + static_assert ( sv5.contains(sv3)); + static_assert ( sv5.contains(sv4)); + static_assert ( sv5.contains(sv5)); + static_assert (!sv5.contains(svNot)); + + static_assert ( svNot.contains(sv0)); + static_assert (!svNot.contains(sv1)); + static_assert (!svNot.contains(sv2)); + static_assert (!svNot.contains(sv3)); + static_assert (!svNot.contains(sv4)); + static_assert (!svNot.contains(sv5)); + static_assert ( svNot.contains(svNot)); + } +#endif + + return 0; +}