halcheck 1.0
Loading...
Searching...
No Matches
strategy.hpp
1#ifndef HALCHECK_TEST_STRATEGY_HPP
2#define HALCHECK_TEST_STRATEGY_HPP
3
10#include <halcheck/lib/functional.hpp>
11#include <halcheck/lib/type_traits.hpp>
12#include <halcheck/lib/utility.hpp>
13#include <halcheck/lib/variant.hpp>
14
15#include <memory>
16
17namespace halcheck { namespace test {
18
23class strategy {
24public:
29 strategy() = default;
30
38 template<
39 typename F,
40 typename... Args,
42 HALCHECK_REQUIRE(lib::is_invocable<const F &, lib::function_view<void()>>())>
43 explicit strategy(lib::in_place_type_t<F>, Args &&...args) : _impl(new derived<F>(std::forward<Args>(args)...)) {}
44
51 template<typename F, HALCHECK_REQUIRE(lib::is_invocable<const lib::decay_t<F> &, lib::function_view<void()>>())>
52 strategy(F &&func) // NOLINT: implicit conversion from functor
53 : strategy(lib::in_place_type_t<lib::decay_t<F>>(), std::forward<F>(func)) {}
54
59 void operator()(lib::function_view<void()> func) const {
60 if (_impl)
61 _impl->invoke(func);
62 else
63 lib::invoke(func);
64 }
65
66private:
67 struct base {
68 virtual ~base() = default;
69 virtual void invoke(lib::function_view<void()>) const = 0;
70 };
71
72 template<typename T>
73 struct derived final : base {
74 template<typename... Args>
75 explicit derived(Args &&...args) : value(std::forward<Args>(args)...) {}
76
77 void invoke(lib::function_view<void()> func) const override { lib::invoke(value, func); }
78
79 T value;
80 };
81
83};
84
92template<
93 typename F,
94 typename... Args,
96 HALCHECK_REQUIRE(lib::is_invocable<const F &, lib::function_view<void()>>())>
98 return test::strategy(lib::in_place_type_t<F>(), std::forward<Args>(args)...);
99}
100
108
116
117}} // namespace halcheck::test
118
119#endif
strategy()=default
Constructs an empty strategy.
void operator()(lib::function_view< void()> func) const
Executes the function stored in this strategy.
Definition strategy.hpp:59
strategy(F &&func)
Constructs a strategy.
Definition strategy.hpp:52
strategy(lib::in_place_type_t< F >, Args &&...args)
Constructs a strategy.
Definition strategy.hpp:43
A strategy executes a nullary function while handling effects or performing other operations such as ...
Definition strategy.hpp:23
T forward(T... args)
HALCHECK_INLINE_CONSTEXPR struct halcheck::lib::@20 invoke
An implementation of std::invoke.
#define HALCHECK_REQUIRE(...)
Expands to a template argument that is only valid if the given argument evaluates to true.
Definition type_traits.hpp:24
test::strategy make_strategy(Args &&...args)
Constructs a strategy of the given type.
Definition strategy.hpp:97
test::strategy operator|(test::strategy lhs, test::strategy rhs)
Composes one strategy inside another.
test::strategy operator&(test::strategy lhs, test::strategy rhs)
Composes two strategies sequentially.
STL namespace.
An implementation of std::is_invocable.
Definition invoke.hpp:66