From ac241b7132d8bbbbe77c1c230fecdc0f803f210b Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 21 Oct 2018 15:53:58 -0700 Subject: [PATCH] Simplify and add tests for ifind --- src/common.h | 30 +++++++++--------------------- src/fish_tests.cpp | 12 ++++++++++++ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/common.h b/src/common.h index 5ff81fe04..633570d42 100644 --- a/src/common.h +++ b/src/common.h @@ -353,35 +353,23 @@ bool string_suffixes_string_case_insensitive(const wcstring &proposed_suffix, bool string_prefixes_string_case_insensitive(const wcstring &proposed_prefix, const wcstring &value); -/// Helper struct for ifind, templated to allow using it with both std::string and std::wstring -/// Supports locale-specific search for characters that transform into a different character -/// when upper/lower-cased, such as those in Turkish and German. -template -struct string_iequal_t { -private: - const std::locale &_locale; -public: - string_iequal_t(const std::locale &locale) - : _locale(locale) {} - bool operator() (T char1, T char2) { - return std::toupper(char1, _locale) == std::toupper(char2, _locale); - } -}; /// Case-insensitive string search, templated for use with both std::string and std::wstring. /// Modeled after std::string::find(). /// \return the offset of the first case-insensitive matching instance of `needle` within /// `haystack`, or `string::npos()` if no results were found. -template -size_t ifind(const T &haystack, const T &needle, - const std::locale &locale = std::locale()) { - auto result = std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end(), - string_iequal_t(locale)); - +template +size_t ifind(const T &haystack, const T &needle) { + using char_t = typename T::value_type; + auto icase_eq = [](char_t c1, char_t c2) { + auto locale = std::locale(); + return std::toupper(c1, locale) == std::toupper(c2, locale); + }; + auto result = + std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end(), icase_eq); if (result != haystack.end()) { return result - haystack.begin(); } - return T::npos; } diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index a46bd37e9..02b5c34a5 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -1731,6 +1731,17 @@ static void test_fuzzy_match() { err(L"test_fuzzy_match failed on line %ld", __LINE__); } +static void test_ifind() { + say(L"Testing ifind"); + do_test(ifind(std::string{"alpha"}, std::string{"alpha"}) == 0); + do_test(ifind(wcstring{L"alphab"}, wcstring{L"alpha"}) == 0); + do_test(ifind(std::string{"alpha"}, std::string{"balpha"}) == std::string::npos); + do_test(ifind(std::string{"balpha"}, std::string{"alpha"}) == 1); + do_test(ifind(std::string{"alphab"}, std::string{"balpha"}) == std::string::npos); + do_test(ifind(std::string{"balpha"}, std::string{"lPh"}) == 2); + do_test(ifind(std::string{"balpha"}, std::string{"Plh"}) == std::string::npos); +} + static void test_abbreviations() { say(L"Testing abbreviations"); env_push(true); @@ -4786,6 +4797,7 @@ int main(int argc, char **argv) { if (should_test_function("lru")) test_lru(); if (should_test_function("expand")) test_expand(); if (should_test_function("fuzzy_match")) test_fuzzy_match(); + if (should_test_function("ifind")) test_ifind(); if (should_test_function("abbreviations")) test_abbreviations(); if (should_test_function("test")) test_test(); if (should_test_function("path")) test_path();