mimic++ v6
Loading...
Searching...
No Matches
RangeMatchers.hpp
Go to the documentation of this file.
1// Copyright Dominic (DNKpp) Koepke 2024 - 2025.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef MIMICPP_MATCHERS_RANGE_MATCHERS_HPP
7#define MIMICPP_MATCHERS_RANGE_MATCHERS_HPP
8
9#include "mimic++/Fwd.hpp"
12
13#include <algorithm>
14#include <concepts>
15#include <functional>
16#include <ranges>
17#include <tuple>
18#include <utility>
19
21{
29
37 template <std::ranges::forward_range Range, typename Comparator = std::equal_to<>>
38 [[nodiscard]]
39 constexpr auto eq(Range&& expected, Comparator comparator = Comparator{})
40 {
41 return PredicateMatcher{
42 [comp = std::move(comparator)]<typename Target>(Target&& target, auto& range) // NOLINT(cppcoreguidelines-missing-std-forward)
43 requires std::predicate<
44 const Comparator&,
45 std::ranges::range_reference_t<Target>,
46 std::ranges::range_reference_t<Range>>
47 {
48 return std::ranges::equal(
49 target,
50 range,
51 std::ref(comp));
52 },
53 "elements are {}",
54 "elements are not {}",
55 std::make_tuple(std::views::all(std::forward<Range>(expected)))};
56 }
57
65 template <std::ranges::forward_range Range, typename Comparator = std::equal_to<>>
66 [[nodiscard]]
67 constexpr auto unordered_eq(Range&& expected, Comparator comparator = Comparator{})
68 {
69 return PredicateMatcher{
70 [comp = std::move(comparator)]<typename Target>(Target&& target, auto& range) // NOLINT(cppcoreguidelines-missing-std-forward)
71 requires std::predicate<
72 const Comparator&,
73 std::ranges::range_reference_t<Target>,
74 std::ranges::range_reference_t<Range>>
75 {
76 return std::ranges::is_permutation(
77 target,
78 range,
79 std::ref(comp));
80 },
81 "is a permutation of {}",
82 "is not a permutation of {}",
83 std::make_tuple(std::views::all(std::forward<Range>(expected)))};
84 }
85
91 template <typename Relation = std::ranges::less>
92 [[nodiscard]]
93 constexpr auto is_sorted(Relation relation = Relation{})
94 {
95 return PredicateMatcher{
96 [rel = std::move(relation)]<typename Target>(Target&& target) // NOLINT(cppcoreguidelines-missing-std-forward)
97 requires std::equivalence_relation<
98 const Relation&,
99 std::ranges::range_reference_t<Target>,
100 std::ranges::range_reference_t<Target>>
101 {
102 return std::ranges::is_sorted(
103 target,
104 std::ref(rel));
105 },
106 "is a sorted range",
107 "is an unsorted range"};
108 }
109
113 [[nodiscard]]
114 constexpr auto is_empty()
115 {
116 return PredicateMatcher{
117 [](std::ranges::range auto&& target) {
118 return std::ranges::empty(target);
119 },
120 "is an empty range",
121 "is not an empty range"};
122 }
123
128 [[nodiscard]]
129 constexpr auto has_size(const std::integral auto expected)
130 {
131 return PredicateMatcher{
132 [](std::ranges::range auto&& target, const std::integral auto size) {
133 return std::cmp_equal(
134 size,
135 std::ranges::size(target));
136 },
137 "has size of {}",
138 "has different size than {}",
139 std::make_tuple(expected)};
140 }
141
146 template <typename Matcher>
147 [[nodiscard]]
148 constexpr auto each_element(Matcher&& matcher)
149 {
150 using MatcherT = std::remove_cvref_t<Matcher>;
151 return PredicateMatcher{
152 [](std::ranges::range auto&& target, const MatcherT& m) {
153 return std::ranges::all_of(
154 target,
155 [&](const auto& element) { return m.matches(element); });
156 },
157 "each el in range: el {}",
158 "not each el in range: el {}",
159 std::make_tuple(
160 mimicpp::detail::arg_storage<
161 MatcherT,
162 std::identity,
163 decltype([](const auto& m) { return mimicpp::detail::describe_hook::describe(m); })>{
164 std::forward<MatcherT>(matcher)})};
165 }
166
171 template <typename Matcher>
172 [[nodiscard]]
173 constexpr auto any_element(Matcher&& matcher)
174 {
175 using MatcherT = std::remove_cvref_t<Matcher>;
176 return PredicateMatcher{
177 [](std::ranges::range auto&& target, const MatcherT& m) {
178 return std::ranges::any_of(
179 target,
180 [&](const auto& element) { return m.matches(element); });
181 },
182 "any el in range: el {}",
183 "none el in range: el {}",
184 std::make_tuple(
185 mimicpp::detail::arg_storage<
186 MatcherT,
187 std::identity,
188 decltype([](const auto& m) { return mimicpp::detail::describe_hook::describe(m); })>{
189 std::forward<MatcherT>(matcher)})};
190 }
191
195}
196
197#endif
Generic matcher and the basic building block of most of the built-in matchers.
Definition GeneralMatchers.hpp:68
constexpr auto eq(Range &&expected, Comparator comparator=Comparator{})
Tests, whether the target range compares equal to the expected range, by comparing them element-wise.
Definition RangeMatchers.hpp:39
constexpr auto each_element(Matcher &&matcher)
Tests, whether each element of the target range matches the specified matcher.
Definition RangeMatchers.hpp:148
constexpr auto unordered_eq(Range &&expected, Comparator comparator=Comparator{})
Tests, whether the target range is a permutation of the expected range, by comparing them element-wis...
Definition RangeMatchers.hpp:67
constexpr auto any_element(Matcher &&matcher)
Tests, whether any element of the target range matches the specified matcher.
Definition RangeMatchers.hpp:173
constexpr auto has_size(const std::integral auto expected)
Tests, whether the target range has the expected size.
Definition RangeMatchers.hpp:129
constexpr auto is_sorted(Relation relation=Relation{})
Tests, whether the target range is sorted, by applying the relation on each adjacent elements.
Definition RangeMatchers.hpp:93
constexpr auto is_empty()
Tests, whether the target range is empty.
Definition RangeMatchers.hpp:114
Definition RangeMatchers.hpp:21