29 template <
typename T>
struct IGenerator {
31 virtual ~IGenerator() =
default;
36 virtual T do_draw(
const TestCase& tc)
const = 0;
76 T do_draw(
const TestCase& tc)
const {
return inner_->do_draw(tc); }
102 template <
typename F>
104 using ResultType = std::invoke_result_t<F, T>;
130 template <
typename F> std::invoke_result_t<F, T>
flat_map(F&& f)
const {
133 using ResultType =
typename std::invoke_result_t<F, T>::value_type;
135 return compose([inner, f = std::forward<F>(f)](
137 internal::start_span(tc, internal::SpanLabel::FlatMap);
138 ResultType result = f(inner->do_draw(tc)).do_draw(tc);
139 internal::stop_span(tc);
172 for (
int i = 0; i < 3; ++i) {
173 internal::start_span(tc, internal::SpanLabel::Filter);
174 T value = inner->do_draw(tc);
176 internal::stop_span(tc);
181 internal::stop_span(tc,
true);
185 throw internal::HegelReject();
190 std::shared_ptr<IGenerator<T>> inner_;
197 template <
typename T>
class CompositeGenerator :
public IGenerator<T> {
199 explicit CompositeGenerator(std::function<T(
const TestCase&)> fn)
200 : gen_fn_(std::move(fn)) {}
202 T do_draw(
const TestCase& tc)
const override {
return gen_fn_(tc); }
205 std::function<T(
const TestCase&)> gen_fn_;
212 template <
typename T,
typename U>
215 MappedGenerator(std::shared_ptr<IGenerator<T>> source,
216 std::function<U(T)> f)
217 : source_(std::move(source)), f_(std::move(f)) {}
219 U do_draw(
const TestCase& tc)
const override {
220 internal::start_span(tc, internal::SpanLabel::Mapped);
221 U result = f_(source_->do_draw(tc));
222 internal::stop_span(tc);
227 std::shared_ptr<IGenerator<T>> source_;
228 std::function<U(T)> f_;
254 using T = std::invoke_result_t<F, const TestCase&>;
256 std::function<T(
const TestCase&)>(std::forward<F>(fn))));
263 template <
typename T>
265 return draw(std::string_view(), gen);
268 template <
typename T>
270 bool repeatable)
const {
271 internal::DrawLogScope scope(*
this, name, repeatable);
272 T value = gen.do_draw(*
this);
273 if (scope.should_log()) {
274 scope.log(internal::repr(value));
Handle to the currently-executing test case.
Definition test_case.h:40
void assume(bool condition) const
Reject the current test case if condition is false.
T draw(const generators::Generator< T > &gen) const
Draw a random value from a generator.
Definition core.h:264
The base class of all generators.
Definition core.h:67
Generator< std::invoke_result_t< F, T > > map(F &&f) const
*/
Definition core.h:103
Generator< T > filter(std::function< bool(const T &)> pred) const
Filter generated values by a predicate.
Definition core.h:169
std::invoke_result_t< F, T > flat_map(F &&f) const
Chain generators for dependent generation.
Definition core.h:130
T value_type
The type of value this generator produces.
Definition core.h:70
Hegel generators.
Definition core.h:17
auto compose(F &&fn)
*/
Definition core.h:253
Main namespace.
Definition config.h:29
Base interface for generators.
Definition core.h:29