6#ifndef MIMICPP_MATCHERS_STRING_MATCHERS_HPP
7#define MIMICPP_MATCHERS_STRING_MATCHERS_HPP
15#ifndef MIMICPP_DETAIL_IS_MODULE
34namespace mimicpp::matches::detail
36 template <
string Target,
string Pattern>
37 constexpr void check_string_compatibility() noexcept
43 "Pattern and target string must have the same character-type.");
50 constexpr auto operator()(T
const& str)
const
56 template <
string String>
58 constexpr auto make_view(String
const& str)
60 return std::invoke(make_view_fn{}, str);
63 template <case_foldable_
string String, std::ranges::borrowed_range View>
65 constexpr auto make_case_folded_string(View&& str)
69 std::forward<View>(str));
76 constexpr auto operator()(T
const& str)
const
85 using string_arg_storage = mimicpp::detail::arg_storage<
90 template <
string String>
92 constexpr auto forward_store(std::remove_reference_t<String>& str)
94 return string_arg_storage<std::decay_t<String>>{
95 std::forward<String>(str)};
155 template <
string Pattern>
157 constexpr auto eq(Pattern&& pattern)
160 []<
string T>(T&& target,
auto const& patternView) {
161 detail::check_string_compatibility<T, Pattern>();
163 return std::ranges::equal(
164 detail::make_view(target),
168 "is not equal to {}",
169 std::make_tuple(detail::forward_store<Pattern>(pattern))};
177 template <case_foldable_
string Pattern>
183 detail::check_string_compatibility<T, Pattern>();
185 return std::ranges::equal(
186 detail::make_case_folded_string<T>(detail::make_view(target)),
187 detail::make_case_folded_string<Pattern>(patternView));
189 "is case-insensitively equal to {}",
190 "is case-insensitively not equal to {}",
191 std::make_tuple(detail::forward_store<Pattern>(pattern))};
199 template <
string Pattern>
204 []<
string T>(T&& target,
auto const& patternView) {
205 detail::check_string_compatibility<T, Pattern>();
207 auto const [ignore, patternIter] = std::ranges::mismatch(
208 detail::make_view(target),
211 return patternIter == std::ranges::end(patternView);
214 "starts not with {}",
215 std::make_tuple(detail::forward_store<Pattern>(pattern))};
223 template <
string Pattern>
229 detail::check_string_compatibility<T, Pattern>();
231 auto const caseFoldedPattern = detail::make_case_folded_string<Pattern>(patternView);
232 auto const [ignore, patternIter] = std::ranges::mismatch(
233 detail::make_case_folded_string<T>(detail::make_view(target)),
236 return patternIter == std::ranges::end(caseFoldedPattern);
238 "case-insensitively starts with {}",
239 "case-insensitively starts not with {}",
240 std::make_tuple(detail::forward_store<Pattern>(pattern))};
248 template <
string Pattern>
253 []<
string T>(T&& target,
auto const& patternView) {
254 detail::check_string_compatibility<T, Pattern>();
256 auto reversedPattern = patternView | std::views::reverse;
257 const auto [ignore, patternIter] = std::ranges::mismatch(
258 detail::make_view(target) | std::views::reverse,
261 return patternIter == std::ranges::end(reversedPattern);
265 std::make_tuple(detail::forward_store<Pattern>(pattern))};
273 template <
string Pattern>
279 detail::check_string_compatibility<T, Pattern>();
281 auto caseFoldedPattern = detail::make_case_folded_string<Pattern>(patternView);
282 auto reversedCaseFoldedPattern = caseFoldedPattern | std::views::reverse;
283 auto caseFoldedTargetPattern = detail::make_case_folded_string<T>(detail::make_view(target));
284 const auto [ignore, patternIter] = std::ranges::mismatch(
285 caseFoldedTargetPattern | std::views::reverse,
286 reversedCaseFoldedPattern);
288 return patternIter == std::ranges::end(reversedCaseFoldedPattern);
290 "case-insensitively ends with {}",
291 "case-insensitively ends not with {}",
292 std::make_tuple(detail::forward_store<Pattern>(pattern))};
300 template <
string Pattern>
305 []<
string T>(T&& target,
auto const& patternView) {
306 detail::check_string_compatibility<T, Pattern>();
308 return std::ranges::empty(patternView)
309 || !std::ranges::empty(
311 detail::make_view(target),
316 std::make_tuple(detail::forward_store<Pattern>(pattern))};
324 template <
string Pattern>
330 detail::check_string_compatibility<T, Pattern>();
332 auto caseFoldedPattern = detail::make_case_folded_string<Pattern>(patternView);
333 auto targetView = detail::make_case_folded_string<T>(detail::make_view(target));
334 return std::ranges::empty(caseFoldedPattern)
335 || !std::ranges::empty(std::ranges::search(targetView, caseFoldedPattern));
337 "case-insensitively contains {}",
338 "case-insensitively contains not {}",
339 std::make_tuple(detail::forward_store<Pattern>(pattern))};
#define MIMICPP_DETAIL_MODULE_EXPORT
Definition Config.hpp:19
Generic matcher and the basic building block of most of the built-in matchers.
Definition GeneralMatchers.hpp:75
Determines, whether the given type supports string normalization.
Definition String.hpp:379
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:157
constexpr auto ends_with(Pattern &&pattern)
Tests, whether the target string ends with the pattern string.
Definition StringMatchers.hpp:250
constexpr auto contains(Pattern &&pattern)
Tests, whether the pattern string is part of the target string.
Definition StringMatchers.hpp:302
constexpr auto starts_with(Pattern &&pattern)
Tests, whether the target string starts with the pattern string.
Definition StringMatchers.hpp:201
constexpr printing::PrintFn print
Functional object, converting the given object to its textual representation.
Definition Print.hpp:183
typename string_traits< std::remove_cvref_t< T > >::char_t string_char_t
Computes the character type for the given string.
Definition String.hpp:263
Definition StringMatchers.hpp:100
Tag type, used in string matchers.
Definition StringMatchers.hpp:30
static constexpr view_t view(const std::remove_pointer_t< T > *str) noexcept
Definition String.hpp:278