From 5558bd6ccc9a76ac0418121cc65db4d678e876b5 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Fri, 8 Sep 2023 17:54:20 +0200 Subject: [PATCH] string: add strchr, strstr and stristr Signed-off-by: Simon Rozman --- include/stdex/string.hpp | 78 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/include/stdex/string.hpp b/include/stdex/string.hpp index ec2d9790b..bf32ca72e 100644 --- a/include/stdex/string.hpp +++ b/include/stdex/string.hpp @@ -214,6 +214,23 @@ namespace stdex constexpr auto npos{ static_cast(-1) }; + /// + /// Find a code unit in a string. + /// + /// \param[in] str String + /// \param[in] chr Code unit to search for + /// + /// \return Offset to the first occurence of chr code unit or stdex::npos if not found. + /// + template + inline size_t strchr(_In_z_ const T* str, _In_ T chr) + { + assert(str); + for (size_t i = 0; str[i]; ++i) + if (str[i] == chr) return i; + return npos; + } + /// /// Find a code unit in a string. /// @@ -386,7 +403,34 @@ namespace stdex } /// - /// Binary search for a substring + /// Search for a substring + /// + /// \param[in] str String to search in + /// \param[in] sample Substring to search for + /// + /// \return Offset inside str where sample string is found; stdex::npos if not found + /// + template + inline size_t strstr( + _In_z_ const T1* str, + _In_z_ const T2* sample) + { + assert(str); + assert(sample); + for (size_t offset = 0;; ++offset) { + for (size_t i = offset, j = 0;; ++i, ++j) { + if (!sample[j]) + return offset; + if (!str[i]) + return npos; + if (str[i] != sample[j]) + break; + } + } + } + + /// + /// Search for a substring /// /// \param[in] str String to search in /// \param[in] count String code unit count limit @@ -415,7 +459,37 @@ namespace stdex } /// - /// Binary search for a substring case-insensitive + /// Search for a substring case-insensitive + /// + /// \param[in] str String to search in + /// \param[in] sample Substring to search for + /// + /// \return Offset inside str where sample string is found; stdex::npos if not found + /// + template + inline size_t stristr( + _In_z_ const T1* str, + _In_z_ const T2* sample, + _In_ const std::locale& locale) + { + assert(str); + assert(sample); + const auto& ctype1 = std::use_facet>(locale); + const auto& ctype2 = std::use_facet>(locale); + for (size_t offset = 0;; ++offset) { + for (size_t i = offset, j = 0;; ++i, ++j) { + if (!sample[j]) + return offset; + if (!str[i]) + return npos; + if (ctype1.tolower(str[i]) != ctype2.tolower(sample[j])) + break; + } + } + } + + /// + /// Search for a substring case-insensitive /// /// \param[in] str String to search in /// \param[in] count String code unit count limit