6#ifndef MIMICPP_MATCHERS_STRING_MATCHERS_HPP
7#define MIMICPP_MATCHERS_STRING_MATCHERS_HPP
30namespace mimicpp::matches::detail
32 template <
string String>
34 constexpr auto make_view(String&& str)
36 using traits_t = string_traits<std::remove_cvref_t<String>>;
37 return traits_t::view(std::forward<String>(str));
40 template <case_foldable_
string String>
42 constexpr auto make_case_folded_string(String&& str)
46 detail::make_view(std::forward<String>(str)));
49 template <
string Target,
string Pattern>
50 constexpr void check_string_compatibility() noexcept
56 "Pattern and target string must have the same character-type.");
116 template <
string Pattern>
118 constexpr auto eq(Pattern&& pattern)
121 []<
string T,
typename Stored>(T&& target, Stored&& stored) {
122 detail::check_string_compatibility<T, Pattern>();
124 return std::ranges::equal(
125 detail::make_view(std::forward<T>(target)),
126 detail::make_view(std::forward<Stored>(stored)));
129 "is not equal to {}",
130 std::make_tuple(std::forward<Pattern>(pattern))};
138 template <case_foldable_
string Pattern>
144 detail::check_string_compatibility<T, Pattern>();
146 return std::ranges::equal(
147 detail::make_case_folded_string(std::forward<T>(target)),
148 detail::make_case_folded_string(std::forward<Stored>(stored)));
150 "is case-insensitively equal to {}",
151 "is case-insensitively not equal to {}",
152 std::make_tuple(std::forward<Pattern>(pattern))};
160 template <
string Pattern>
165 []<
string T,
typename Stored>(T&& target, Stored&& stored) {
166 detail::check_string_compatibility<T, Pattern>();
168 auto patternView = detail::make_view(std::forward<Stored>(stored));
169 const auto [ignore, patternIter] = std::ranges::mismatch(
170 detail::make_view(std::forward<T>(target)),
173 return patternIter == std::ranges::end(patternView);
176 "starts not with {}",
177 std::make_tuple(std::forward<Pattern>(pattern))};
185 template <
string Pattern>
190 []<
string T,
typename Stored>(T&& target, Stored&& stored) {
191 detail::check_string_compatibility<T, Pattern>();
193 auto caseFoldedPattern = detail::make_case_folded_string(std::forward<Stored>(stored));
194 const auto [ignore, patternIter] = std::ranges::mismatch(
195 detail::make_case_folded_string(std::forward<T>(target)),
198 return patternIter == std::ranges::end(caseFoldedPattern);
200 "case-insensitively starts with {}",
201 "case-insensitively starts not with {}",
202 std::make_tuple(std::forward<Pattern>(pattern))};
210 template <
string Pattern>
215 []<
string T,
typename Stored>(T&& target, Stored&& stored) {
216 detail::check_string_compatibility<T, Pattern>();
218 auto patternView = detail::make_view(std::forward<Stored>(stored))
219 | std::views::reverse;
220 const auto [ignore, patternIter] = std::ranges::mismatch(
221 detail::make_view(std::forward<T>(target)) | std::views::reverse,
224 return patternIter == std::ranges::end(patternView);
228 std::make_tuple(std::forward<Pattern>(pattern))};
236 template <
string Pattern>
241 []<
string T,
typename Stored>(T&& target, Stored&& stored) {
242 detail::check_string_compatibility<T, Pattern>();
244 auto caseFoldedPattern = detail::make_case_folded_string(std::forward<Stored>(stored))
245 | std::views::reverse;
246 const auto [ignore, patternIter] = std::ranges::mismatch(
247 detail::make_case_folded_string(std::forward<T>(target)) | std::views::reverse,
250 return patternIter == std::ranges::end(caseFoldedPattern);
252 "case-insensitively ends with {}",
253 "case-insensitively ends not with {}",
254 std::make_tuple(std::forward<Pattern>(pattern))};
262 template <
string Pattern>
267 []<
string T,
typename Stored>(T&& target, Stored&& stored) {
268 detail::check_string_compatibility<T, Pattern>();
270 auto patternView = detail::make_view(std::forward<Stored>(stored));
271 return std::ranges::empty(patternView)
272 || !std::ranges::empty(
274 detail::make_view(std::forward<T>(target)),
275 std::move(patternView)));
279 std::make_tuple(std::forward<Pattern>(pattern))};
287 template <
string Pattern>
292 []<
string T,
typename Stored>(T&& target, Stored&& stored) {
293 detail::check_string_compatibility<T, Pattern>();
295 auto patternView = detail::make_case_folded_string(std::forward<Stored>(stored));
296 auto targetView = detail::make_case_folded_string(std::forward<T>(target));
297 return std::ranges::empty(patternView)
298 || !std::ranges::empty(std::ranges::search(targetView, patternView));
300 "case-insensitively contains {}",
301 "case-insensitively contains not {}",
302 std::make_tuple(std::forward<Pattern>(pattern))};
Generic matcher and the basic building block of most of the built-in matchers.
Definition GeneralMatchers.hpp:68
Determines, whether the given type supports string normalization.
Definition String.hpp:376
struct mimicpp::case_insensitive_t case_insensitive
constexpr auto eq(Pattern &&pattern)
Tests, whether the target string compares equal to the expected string.
Definition StringMatchers.hpp:118
constexpr auto ends_with(Pattern &&pattern)
Tests, whether the target string ends with the pattern string.
Definition StringMatchers.hpp:212
constexpr auto contains(Pattern &&pattern)
Tests, whether the pattern string is part of the target string.
Definition StringMatchers.hpp:264
constexpr auto starts_with(Pattern &&pattern)
Tests, whether the target string starts with the pattern string.
Definition StringMatchers.hpp:162
typename string_traits< std::remove_cvref_t< T > >::char_t string_char_t
Computes the character type for the given string.
Definition String.hpp:260
Definition StringMatchers.hpp:61
Definition BoostTest.hpp:20
Tag type, used in string matchers.
Definition StringMatchers.hpp:26