19namespace sequoia::testing
21 enum class check_ordering :
bool {no, yes};
23 template<
class T, invocable_r<T, const T&> TransitionFn>
26 std::string description;
30 template<
class T, invocable_r<T, const T&> TransitionFn, check_ordering=check_ordering{std::totally_ordered<T>}>
34 template<std::totally_ordered T, invocable_r<T, const T&> TransitionFn>
37 std::weak_ordering ordering;
44 template<std::invocable Fn>
45 requires std::convertible_to<std::invoke_result_t<Fn>, T>
50 requires std::movable<T>
51 : m_Fn{[t{std::move(t)}]() ->
const T& {
return t; }}
54 template<
class... Args>
56 ((
sizeof...(Args) != 1) || (!std::is_same_v<T, std::remove_cvref_t<Args>> && ...)))
61 template<
class InitCheckFn,
class... Args>
62 requires (
initializable_from<T, Args...> && std::invocable<InitCheckFn, std::string, T, Args...>)
63 object_generator(std::string_view message, InitCheckFn initCheckFn,
const Args&... args)
66 initCheckFn(message, m_Fn(), args...);
70 decltype(
auto)
operator()()
const {
return m_Fn(); }
72 std::function<T()> m_Fn;
75 template<
class T, check_ordering CheckOrdering=check_ordering{std::totally_ordered<T>}>
82 using size_type =
typename transition_graph::size_type;
85 using edge_iterator =
typename transition_graph::const_edge_iterator;
87 template<
class CheckFn,
class... Args>
88 static void invoke_check_fn(
const transition_graph& g, edge_iterator i, CheckFn fn,
const std::string& message,
object_generator<T> parentGenerator, size_type target, Args... args)
90 const auto& w{i->weight()};
92 w.fn(parentGenerator()),
93 g.cbegin_node_weights()[target](),
97 template<
class CheckFn,
class... Args>
98 static void invoke_check_fn(std::string_view description,
const transition_graph& g, edge_iterator i, CheckFn fn, Args... args)
100 const auto [message, parentGenerator, target] {make(description, g, i)};
101 const auto& w{i->weight()};
103 [&w,pg{parentGenerator}]() {
return w.fn(pg()); },
104 g.cbegin_node_weights()[target],
109 using edge =
typename transition_graph::edge_type;
111 template<std::invocable<std::
string, T, T> CheckFn>
112 static void check(std::string_view description,
const transition_graph& g, CheckFn checkFn)
115 [description,&g,checkFn](edge_iterator i) {
116 const auto [message, parentGenerator, target] {make(description, g, i)};
117 invoke_check_fn(g, i, checkFn, message, parentGenerator, target);
124 template<std::invocable<std::
string, T, T, T> CheckFn>
125 static void check(std::string_view description,
const transition_graph& g, CheckFn checkFn)
128 [description,&g,checkFn](edge_iterator i) {
129 const auto [message, parentGenerator, target] {make(description, g, i)};
130 invoke_check_fn(g, i, checkFn, message, parentGenerator, target, parentGenerator());
137 template<std::invocable<std::
string, T, T, T,
size_type,
size_type> CheckFn>
138 static void check(std::string_view description,
const transition_graph& g, CheckFn checkFn)
141 [description,&g,checkFn](edge_iterator i) {
142 const auto [message, parentGenerator, target] {make(description, g, i)};
143 invoke_check_fn(g, i, checkFn, message, parentGenerator, target, parentGenerator(), i.partition_index(), target);
150 template<std::invocable<std::
string, T, T, T, std::weak_ordering> CheckFn>
152 static void check(std::string_view description,
const transition_graph& g, CheckFn checkFn)
155 [description,&g,checkFn](edge_iterator i) {
156 const auto [message, parentGenerator, target] {make(description, g, i)};
157 invoke_check_fn(g, i, checkFn, message, parentGenerator, target, parentGenerator(), i->weight().ordering);
164 template<std::invocable<std::
string, std::function<T()>, std::function<T()>, std::function<T()>> CheckFn>
165 static void check(std::string_view description,
const transition_graph& g, CheckFn checkFn)
168 [description,&g,checkFn](edge_iterator i) { invoke_check_fn(description, g, i, checkFn); }
174 template<std::invocable<std::
string, std::function<T()>, std::function<T()>, std::function<T()>, std::weak_ordering> CheckFn>
175 requires std::totally_ordered<T>
176 static void check(std::string_view description,
const transition_graph& g, CheckFn checkFn)
179 [description,&g,checkFn](edge_iterator i) { invoke_check_fn(description, g, i, checkFn, i->weight().ordering); }
187 template<std::invocable<edge_iterator> EdgeFn>
190 using namespace maths;
202 static edge_fn_info make(std::string_view description,
const transition_graph& g, edge_iterator i)
204 const auto& w{i->weight()};
205 const auto parent{i.partition_index()}, target{i->target_node()};
206 return {append_lines(description,
207 std::string{
"Transition from node "}.append(std::to_string(parent)).append(
" to ").append(std::to_string(target)),
209 g.cbegin_node_weights()[parent],
Concepts which are sufficiently general to appear in the sequoia namespace.
Edge & Node storage traits, base class and final classes for dynamic graphs.
Breadth first, depth first and priority searches.
A collection of functions for formatting test output.
Definition: DynamicGraph.hpp:303
Definition: GraphTraversalDetails.hpp:72
Definition: StateTransitionUtilities.hpp:42
A concept similar to std::constructible_from, but which considers braced-init.
Definition: Concepts.hpp:75
Similar to std::regular but relaxes the requirement of default initializability.
Definition: Concepts.hpp:39
Definition: GraphTraversalDetails.hpp:24
Definition: StateTransitionUtilities.hpp:77
Definition: StateTransitionUtilities.hpp:25
Definition: StateTransitionUtilities.hpp:32