74 template <
typename... Matchers_>
requires std::conjunction_v<std::is_same<std::remove_cvref_t<Matchers_>, Matchers>...>
76 : matchers{std::forward<Matchers_>(matchers_)...} {}
78 template <
typename IterableType>
79 bool MatchAndExplain([[maybe_unused]]
const IterableType& arg, [[maybe_unused]]::testing::MatchResultListener*
const listener)
const
81 if constexpr(
sizeof...(Matchers) == 0) {
84 return MatchAndExplainImpl<0>(arg.cbegin(), arg.cend(), listener);
90 *out <<
"contains in order elements that match ";
91 DescribeInnerMatchersImpl(out);
96 *out <<
"does not contain in order elements that match ";
97 DescribeInnerMatchersImpl(out);
101 template <
size_t Idx,
typename IteratorType>
102 bool MatchAndExplainImpl(
const IteratorType it_first,
const IteratorType it_last, ::testing::MatchResultListener*
const listener)
const
104 if (it_first == it_last) {;
105 *listener <<
"does not contain in order an element that "
106 << ::testing::DescribeMatcher<T>(std::get<Idx>(matchers),
false);
110 if (::testing::Matches(std::get<Idx>(matchers))(*it_first)) {
111 if constexpr (Idx ==
sizeof...(Matchers) - 1) {
114 return MatchAndExplainImpl<Idx + 1>(std::next(it_first), it_last, listener);
117 return MatchAndExplainImpl<Idx>(std::next(it_first), it_last, listener);
121 void DescribeInnerMatchersImpl(std::ostream* out)
const
124 if constexpr (
sizeof...(Matchers) >= 2)
126 [&] <
size_t... Idxs>(std::index_sequence<Idxs...>) {
127 ((*out << ::testing::DescribeMatcher<T>(std::get<Idxs>(matchers),
false) <<
", "), ...);
128 }(std::make_index_sequence<
sizeof...(Matchers) - 1>{});
130 if constexpr (
sizeof...(Matchers) >= 1)
131 *out << ::testing::DescribeMatcher<T>(std::get<
sizeof...(Matchers) - 1>(matchers),
false);
136 std::tuple<Matchers...> matchers;