mimic++ v9.2.1
Loading...
Searching...
No Matches
Common.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_COMMON_HPP
7#define MIMICPP_MATCHERS_COMMON_HPP
8
9#pragma once
10
11#include "mimic++/Fwd.hpp"
15
16#ifndef MIMICPP_DETAIL_IS_MODULE
17 #include <concepts>
18 #include <optional>
19 #include <type_traits>
20#endif
21
23{
24 template <typename Matcher>
26}
27
28namespace mimicpp::detail::matches_hook
29{
30 template <typename Matcher, typename T, typename... Others>
31 [[nodiscard]]
32 constexpr bool matches_impl(
33 [[maybe_unused]] util::priority_tag<1> const,
34 Matcher const& matcher,
35 T& target,
36 Others&... others)
37 requires requires {
38 { custom::matcher_traits<Matcher>{}.matches(matcher, target, others...) } -> util::boolean_testable;
39 }
40 {
41 return custom::matcher_traits<Matcher>{}.matches(matcher, target, others...);
42 }
43
44 template <typename Matcher, typename T, typename... Others>
45 [[nodiscard]]
46 constexpr bool matches_impl(
47 [[maybe_unused]] util::priority_tag<0> const,
48 Matcher const& matcher,
49 T& target,
50 Others&... others)
51 requires requires {
52 { matcher.matches(target, others...) } -> util::boolean_testable;
53 }
54 {
55 return matcher.matches(target, others...);
56 }
57
58 inline constexpr util::priority_tag<1> maxTag{};
59
60 struct matches_fn
61 {
62 template <typename Matcher, typename T, typename... Others>
63 [[nodiscard]]
64 constexpr bool operator()(Matcher const& matcher, T& target, Others&... others) const
65 requires requires {
66 { matches_impl(maxTag, matcher, target, others...) } -> util::boolean_testable;
67 }
68 {
69 return matches_impl(maxTag, matcher, target, others...);
70 }
71 };
72
73 inline constexpr matches_fn matches{};
74}
75
76namespace mimicpp::detail::describe_hook
77{
78 // This section uses trailing return-types because this seems to help clangd in some cases.
79 template <typename Matcher>
80 [[nodiscard]]
81 constexpr auto describe_impl([[maybe_unused]] util::priority_tag<1> const, Matcher const& matcher)
82 -> decltype(custom::matcher_traits<Matcher>{}.describe(matcher))
83 requires requires {
84 {
85 custom::matcher_traits<Matcher>{}.describe(matcher)
86 } -> util::explicitly_convertible_to<std::optional<StringT>>;
87 }
88 {
89 return custom::matcher_traits<Matcher>{}.describe(matcher);
90 }
91
92 template <typename Matcher>
93 [[nodiscard]]
94 constexpr auto describe_impl([[maybe_unused]] util::priority_tag<0> const, Matcher const& matcher)
95 -> decltype(matcher.describe())
96 requires requires {
97 { matcher.describe() } -> util::explicitly_convertible_to<std::optional<StringT>>;
98 }
99 {
100 return matcher.describe();
101 }
102
103 inline constexpr util::priority_tag<1> maxTag{};
104
105 struct describe_fn
106 {
107 template <typename Matcher>
108 [[nodiscard]]
109 constexpr auto operator()(Matcher const& matcher) const
110 -> decltype(describe_impl(maxTag, matcher))
111 requires requires {
112 { describe_impl(maxTag, matcher) } -> util::explicitly_convertible_to<std::optional<StringT>>;
113 }
114 {
115 return describe_impl(maxTag, matcher);
116 }
117 };
118
119 inline constexpr describe_fn describe{};
120}
121
122namespace mimicpp
123{
124 namespace detail
125 {
131 template <typename Matcher, typename... Args>
132 struct is_matcher_accepting
133 : public std::true_type
134 {
135 };
136
137 template <template <typename...> typename is_accepting, typename... Args>
138 struct is_matcher_accepting_helper
139 : public is_accepting<Args...>
140 {
141 };
142
148 template <typename Matcher, typename... Args>
149 requires requires { typename is_matcher_accepting_helper<Matcher::template is_accepting, Args...>; }
150 struct is_matcher_accepting<Matcher, Args...>
151 : public is_matcher_accepting_helper<Matcher::template is_accepting, Args...>
152 {
153 };
154 }
155
166 template <typename Matcher, typename... Args>
167 inline constexpr bool is_matcher_accepting_v{detail::is_matcher_accepting<Matcher, Args...>::value};
168}
169
171{
172 template <typename T, typename First, typename... Others>
173 concept matcher_for = std::same_as<T, std::remove_cvref_t<T>>
174 && std::is_move_constructible_v<T>
175 && std::destructible<T>
176 && is_matcher_accepting_v<T, First, Others...>
177 && requires(T const& matcher, First& first, Others&... others) {
178 { detail::matches_hook::matches(matcher, first, others...) } -> util::boolean_testable;
179 { detail::describe_hook::describe(matcher) } -> util::explicitly_convertible_to<std::optional<StringT>>;
180 };
181}
182
183#endif
#define MIMICPP_DETAIL_MODULE_EXPORT
Definition Config.hpp:19
Definition Common.hpp:173
Determines, whether B behaves as a the builtin type bool.
Definition Concepts.hpp:66
Determines, whether From can be explicitly converted to To.
Definition Concepts.hpp:34
Definition Common.hpp:23
Definition Call.hpp:24
constexpr bool is_matcher_accepting_v
Determines, whether the given Matcher accepts the specified Args.
Definition Common.hpp:167
Definition Common.hpp:25
Definition PriorityTag.hpp:24