1#ifndef HALCHECK_GEN_CONTAINER_HPP
2#define HALCHECK_GEN_CONTAINER_HPP
4#include <halcheck/gen/label.hpp>
5#include <halcheck/gen/range.hpp>
6#include <halcheck/gen/sample.hpp>
7#include <halcheck/gen/shrink.hpp>
8#include <halcheck/gen/size.hpp>
9#include <halcheck/lib/atom.hpp>
10#include <halcheck/lib/effect.hpp>
11#include <halcheck/lib/functional.hpp>
12#include <halcheck/lib/iterator.hpp>
13#include <halcheck/lib/optional.hpp>
14#include <halcheck/lib/pp.hpp>
15#include <halcheck/lib/scope.hpp>
16#include <halcheck/lib/type_traits.hpp>
25namespace halcheck {
namespace gen {
31 lib::invoke_result_t<const F &, lib::atom> operator()(
std::uintmax_t i)
const {
return context.
handle(func, i); }
32 lib::effect::state context;
42 using view = lib::transform_view<lib::filter_view<lib::iota_view<std::uintmax_t>, if_noshrink>, to_label<F>>;
45 template<typename F, HALCHECK_REQUIRE(lib::is_invocable<const F &, lib::atom>())>
46 view<F>
operator()(
lib::atom id, F gen)
const {
47 using namespace lib::literals;
58 skip.
push_back(gen::shrink(i).has_value());
62 lib::filter(lib::iota(
size), if_noshrink{std::move(skip)}),
63 to_label<F>{std::move(context), std::move(gen)});
71 auto label1 = gen::label(
id);
72 auto label2 = gen::label(i);
73 return std::move(label1) + std::move(label2);
84 using view = lib::transform_view<lib::filter_view<lib::iota_view<std::uintmax_t>, if_noshrink>, to_label>;
88 using namespace lib::literals;
98 skip.
push_back(gen::shrink(i).has_value());
101 return lib::transform(lib::filter(lib::iota(
size), if_noshrink{std::move(skip)}), to_label{
id});
108 template<typename F, HALCHECK_REQUIRE(lib::is_invocable<F, lib::atom>())>
109 void operator()(
lib::atom id, F func)
const {
110 using namespace lib::literals;
111 for (
auto _ : (*
this)(
id))
128 using namespace lib::literals;
130 auto it = lib::end(output);
131 for (
auto _ : gen::repeat(
id))
152 auto it = lib::end(output);
158template<typename I, HALCHECK_REQUIRE(lib::is_forward_iterator<I>())>
159void shuffle(
lib::atom id, I begin, I end) {
161 for (
auto it = begin; it != end; ++it)
165template<
typename Range, HALCHECK_REQUIRE(lib::is_forward_range<lib::decay_t<Range>>())>
167 gen::shuffle(
id, lib::begin(
range), lib::end(
range));
lib::finally_t handle() &
Overrides the current set of effect handlers.
static state save()
Copies the current set of effect handlers.
Definition effect.hpp:337
static struct halcheck::gen::@9 label
Extends the unique identifiers passed to other random generation functions.
static const range_t range
Generates a random value in an closed-open interval.
Definition range.hpp:93
HALCHECK_INLINE_CONSTEXPR struct halcheck::gen::@11 sample
Obtains a random value.
std::uintmax_t size()
Gets the maximum size of value that should be generated.
Definition size.hpp:35
lib::variant< lib::symbol, lib::number > atom
An atom is either a symbol or a number.
Definition atom.hpp:194
HALCHECK_INLINE_CONSTEXPR struct halcheck::lib::@20 invoke
An implementation of std::invoke.
lib::iter_value_t< lib::iterator_t< R > > range_value_t
The type of element contained in a range.
Definition range.hpp:332
HALCHECK_INLINE_CONSTEXPR struct halcheck::lib::@31 transform
Constructs a transform_view.
#define HALCHECK_INLINE_CONSTEXPR
A backwards-compatible substitute for inline constexpr.
Definition pp.hpp:70
#define HALCHECK_REQUIRE(...)
Expands to a template argument that is only valid if the given argument evaluates to true.
Definition type_traits.hpp:24
T container(lib::atom id, F gen)
Generates a random container value.
Definition container.hpp:127
Determines whether a range is insertable.
Definition range.hpp:401
An implementation of std::is_invocable_r.
Definition invoke.hpp:54