1#ifndef HALCHECK_GEN_VARIANT_HPP
2#define HALCHECK_GEN_VARIANT_HPP
4#include <halcheck/gen/element.hpp>
5#include <halcheck/gen/label.hpp>
6#include <halcheck/lib/atom.hpp>
7#include <halcheck/lib/functional.hpp>
8#include <halcheck/lib/type_traits.hpp>
9#include <halcheck/lib/utility.hpp>
10#include <halcheck/lib/variant.hpp>
16namespace halcheck {
namespace gen {
19template<
typename... Fs>
20struct variant_visitor {
22 lib::variant<lib::invoke_result_t<Fs, lib::atom>...> operator()(T i) {
23 using namespace lib::literals;
24 static constexpr auto I =
decltype(i)::value;
25 return lib::variant<lib::invoke_result_t<Fs, lib::atom>...>(
26 lib::in_place_index_t<I>(),
29 explicit variant_visitor(Fs... gens) : tuple(
std::move(gens)...) {}
40 using T = lib::variant<std::integral_constant<std::size_t, Ints>...>;
50template<
typename... Fs,
HALCHECK_REQUIRE(lib::conjunction<lib::is_invocable<Fs, lib::atom>...>())>
51lib::variant<lib::invoke_result_t<Fs, lib::atom>...> variant(
lib::atom id, Fs... gens) {
52 using namespace lib::literals;
55 return lib::visit(detail::variant_visitor<Fs...>(std::move(gens)...), i);
59template<
typename T,
typename... Fs>
62 T operator()(I i)
const {
63 using namespace lib::literals;
64 static constexpr auto index =
decltype(i)::value;
65 return lib::invoke(std::get<index>(tuple),
"gen"_s);
67 explicit one_visitor(Fs... gens) : tuple(
std::move(gens)...) {}
79template<
typename T,
typename... Fs,
HALCHECK_REQUIRE(lib::conjunction<lib::is_invocable_r<T, Fs, lib::atom>...>())>
81 using namespace lib::literals;
84 return lib::visit(detail::one_visitor<T, Fs...>(std::move(gens)...), i);
HALCHECK_INLINE_CONSTEXPR struct halcheck::gen::@7 element
Generates a random value from a fixed list of elements.
static struct halcheck::gen::@9 label
Extends the unique identifiers passed to other random generation functions.
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.
decltype(lib::invoke(std::declval< F >(), std::declval< Args >()...)) invoke_result_t
An implementation of std::invoke_result_t.
Definition invoke.hpp:42
typename std::common_type< Args... >::type common_type_t
An implementation of std::common_type_t.
Definition type_traits.hpp:133
#define HALCHECK_REQUIRE(...)
Expands to a template argument that is only valid if the given argument evaluates to true.
Definition type_traits.hpp:24
lib::variant< std::integral_constant< std::size_t, Ints >... > index(lib::atom id, lib::index_sequence< Ints... >={})
Generates a random std::integral_constant from the given set of indices.
Definition variant.hpp:39
T one(lib::atom id, lib::in_place_type_t< T >, Fs... gens)
Generates a value according to a randomly selected generator.
Definition variant.hpp:80
An implementation of std::conjunction.
Definition type_traits.hpp:59
An implementation of std::integer_sequence.
Definition utility.hpp:53
An implementation of std::is_invocable.
Definition invoke.hpp:66
An implementation of std::make_integer_sequence.
Definition utility.hpp:82