diff --git a/doc/container.qbk b/doc/container.qbk
index 7d0a249..51ac0c1 100644
--- a/doc/container.qbk
+++ b/doc/container.qbk
@@ -1459,7 +1459,9 @@ use [*Boost.Container]? There are several reasons for that:
* If available, uses C++17's utilities under the `__cpp_aligned_new` feature.
* Uses alternative aligned allocation functions (`posix_memalign`, `aligned_alloc`, `_aligned_malloc`...) otherwise.
* Implemented overaligned allocation support for `adaptive_pool`and `node_allocator`
-* Updated `basic_string` to the latest standard API: Added missing `string_view` members and updated `operator[]` to be able to return the terminating null.
+* Updated `basic_string` to the latest standard API:
+ * Added missing `string_view` members and updated `operator[]` to be able to return the terminating null.
+ * Added C++23 `contains` overloads
* Fixed bugs/issues:
* [@https://github.com/boostorg/container/issues/323 GitHub #323: ['"flat_tree::try_emplace UB"]].
* [@https://github.com/boostorg/container/issues/328 GitHub #328: ['"boost::container::deque stores a redundant copy of the allocator, increasing size"]].
diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp
index 313cc63..a8d0e89 100644
--- a/include/boost/container/string.hpp
+++ b/include/boost/container/string.hpp
@@ -2953,6 +2953,34 @@ class basic_string
int compare(size_type pos1, size_type n1, const CharT* s) const
{ return this->compare(pos1, n1, s, Traits::length(s)); }
+ //! Effects: Equivalent to find(sv) != npos
+ //!
+ //! Throws: Nothing
+ //!
+ //! Returns: true if the string contains the provided substring, false otherwise.
+ template class BasicStringView>
+ BOOST_CONTAINER_NODISCARD inline
+ bool contains(BasicStringView sv) const BOOST_NOEXCEPT
+ { return this->find(sv) != npos; }
+
+ //! Effects: Equivalent to find(c) != npos
+ //!
+ //! Throws: Nothing
+ //!
+ //! Returns: true if the string contains the provided substring, false otherwise.
+ BOOST_CONTAINER_NODISCARD inline
+ bool contains(CharT c) const BOOST_NOEXCEPT
+ { return this->find(c) != npos; }
+
+ //! Effects: Equivalent to find(c) != npos
+ //!
+ //! Throws: Nothing
+ //!
+ //! Returns: true if the string contains the provided substring, false otherwise.
+ BOOST_CONTAINER_NODISCARD inline
+ bool contains(const CharT* s) const BOOST_NOEXCEPT
+ { return this->find(s) != npos; }
+
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
void priv_move_assign(BOOST_RV_REF(basic_string) x, dtl::bool_ /*steal_resources*/)
diff --git a/test/string_test.cpp b/test/string_test.cpp
index 9cd9737..ec30592 100644
--- a/test/string_test.cpp
+++ b/test/string_test.cpp
@@ -1537,16 +1537,15 @@ void test_contains()
{
string s("Hello, World!");
- using test_helpers::contains;
- BOOST_TEST(contains(s, "World"));
- BOOST_TEST(contains(s, "Hello"));
- BOOST_TEST(contains(s, ", "));
- BOOST_TEST(contains(s, ""));
- BOOST_TEST(contains(s, 'W'));
+ BOOST_TEST(s.contains("World"));
+ BOOST_TEST(s.contains("Hello"));
+ BOOST_TEST(s.contains(", "));
+ BOOST_TEST(s.contains(""));
+ BOOST_TEST(s.contains('W'));
- BOOST_TEST(!contains(s, "world")); // case-sensitive
- BOOST_TEST(!contains(s, "xyz"));
- BOOST_TEST(!contains(s, 'X'));
+ BOOST_TEST(!s.contains("world")); // case-sensitive
+ BOOST_TEST(!s.contains("xyz"));
+ BOOST_TEST(!s.contains('X'));
}
//==============================================================================