Skip to content

Commit 873d6d1

Browse files
committed
#182-Implement method CppStringT::contains()
Completed. Validated.
1 parent 7588cb6 commit 873d6d1

File tree

2 files changed

+86
-1
lines changed

2 files changed

+86
-1
lines changed

cpp-strings-tests/cpp-strings-tests.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,65 @@ namespace cppstringstests
714714
Assert::AreEqual(pcs::CppWString(L"zyxwvutsrqp").c_str(), ws.center(10, L'#').c_str(), L"--16--");
715715
}
716716

717+
TEST_METHOD(contains)
718+
{
719+
pcs::CppString text("Abcd. Efgh ij!");
720+
for (std::size_t index = 0; index < text.size(); ++index) {
721+
Assert::IsTrue(text.contains(text.substr(index)));
722+
for (std::size_t count = 0; count < text.size() - index; ++count)
723+
Assert::IsTrue(text.contains(text.substr(index, count)));
724+
}
725+
Assert::IsFalse(text.contains("zzz"cs));
726+
Assert::IsFalse(text.contains("abc"cs));
727+
Assert::IsFalse(text.contains("Abcd. Efgh ij!!"cs));
728+
Assert::IsTrue(text.contains(""cs));
729+
730+
pcs::CppWString wtext(L"Abcd. Efgh ij!");
731+
for (std::size_t index = 0; index < wtext.size(); ++index) {
732+
Assert::IsTrue(wtext.contains(wtext.substr(index)));
733+
for (std::size_t count = 0; count < text.size() - index; ++count)
734+
Assert::IsTrue(wtext.contains(wtext.substr(index, count)));
735+
}
736+
Assert::IsFalse(wtext.contains(L"zzz"cs));
737+
Assert::IsFalse(wtext.contains(L"abc"cs));
738+
Assert::IsFalse(wtext.contains(L"Abcd. Efgh ij!!"cs));
739+
Assert::IsTrue(wtext.contains(L""cs));
740+
741+
742+
for (std::size_t index = 0; index < text.size(); ++index) {
743+
Assert::IsTrue(text.contains(text.substr(index).c_str()));
744+
for (std::size_t count = 0; count < text.size() - index; ++count)
745+
Assert::IsTrue(text.contains(text.substr(index, count).c_str()));
746+
}
747+
Assert::IsFalse(text.contains("z"));
748+
Assert::IsFalse(text.contains("a"));
749+
Assert::IsFalse(text.contains("Abcd. Efgh ij!!"));
750+
Assert::IsTrue(text.contains(""));
751+
Assert::IsTrue(text.contains(nullptr));
752+
753+
for (std::size_t index = 0; index < wtext.size(); ++index) {
754+
Assert::IsTrue(wtext.contains(wtext.substr(index).c_str()));
755+
for (std::size_t count = 0; count < text.size() - index; ++count)
756+
Assert::IsTrue(wtext.contains(wtext.substr(index, count).c_str()));
757+
}
758+
Assert::IsFalse(wtext.contains(L"zzz"));
759+
Assert::IsFalse(wtext.contains(L"abc"));
760+
Assert::IsFalse(wtext.contains(L"Abcd. Efgh ij!!"));
761+
Assert::IsTrue(wtext.contains(L""));
762+
Assert::IsTrue(wtext.contains(nullptr));
763+
764+
765+
for (auto const ch : text)
766+
Assert::IsTrue(text.contains(ch));
767+
Assert::IsFalse(text.contains('z'));
768+
Assert::IsFalse(text.contains('a'));
769+
770+
for (auto const wch : wtext)
771+
Assert::IsTrue(wtext.contains(wch));
772+
Assert::IsFalse(wtext.contains(L'z'));
773+
Assert::IsFalse(wtext.contains(L'a'));
774+
}
775+
717776
TEST_METHOD(count)
718777
{
719778
pcs::CppString s("abcabcabcdefabca bca bcabca");

cpp-strings/cppstrings.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ namespace pcs // i.e. "pythonic c++ strings"
457457

458458

459459
//--- contains() --------------------------------------
460-
/** \brief Returns true if this string contains the passed string or char.
460+
/** \brief Returns true if this string contains the passed string, or false otherwise.
461461
*
462462
* This is the c++ implementation of Python keyword 'in' applied to strings.
463463
*/
@@ -487,6 +487,32 @@ namespace pcs // i.e. "pythonic c++ strings"
487487
#endif
488488
}
489489

490+
/** \brief Returns true if this string contains the passed C-string, or false otherwise. */
491+
inline const bool contains(const CharT* substr) const noexcept
492+
{
493+
if (substr == nullptr)
494+
// just to avoid system error on invalid access
495+
return true;
496+
497+
#if (defined(_HAS_CXX23) && _HAS_CXX23) || (!defined(_HAS_CXX23) && __cplusplus >= 202302L)
498+
// c++23 and above already defines this method
499+
return MyBaseClass::contains(substr);
500+
#else
501+
return contains(CppStringT(substr));
502+
#endif
503+
}
504+
/** \brief Returns true if this string contains the passed char, or false otherwise. */
505+
const bool contains(const CharT& ch) const noexcept
506+
{
507+
#if (defined(_HAS_CXX23) && _HAS_CXX23) || (!defined(_HAS_CXX23) && __cplusplus >= 202302L)
508+
// c++23 and above already defines this method
509+
return MyBaseClass::contains(ch);
510+
#else
511+
// up to c++20, we have to implement this method
512+
return std::ranges::any_of(*this, [ch](const value_type c) -> bool { return c == ch; });
513+
#endif
514+
}
515+
490516

491517
//--- count() -----------------------------------------
492518
/** \brief Returns the number of non-overlapping occurrences of substring sub in the range [start, end]. */

0 commit comments

Comments
 (0)