halcheck 1.0
Loading...
Searching...
No Matches
range.hpp
1#ifndef HALCHECK_GEN_RANGE_HPP
2#define HALCHECK_GEN_RANGE_HPP
3
10#include <halcheck/gen/discard.hpp>
11#include <halcheck/gen/sample.hpp>
12#include <halcheck/gen/shrink.hpp>
13#include <halcheck/lib/atom.hpp>
14#include <halcheck/lib/iterator/type_traits.hpp>
15#include <halcheck/lib/type_traits.hpp>
16
17#include <cstdint>
18#include <iterator>
19#include <limits>
20#include <type_traits>
21
22namespace halcheck { namespace gen {
23
24struct range_t {
25 template<typename T, HALCHECK_REQUIRE(std::is_integral<T>())>
26 T operator()(lib::atom id, T min, T max) const {
27 gen::guard(min < max);
28 return gen::shrink_to(id, min, gen::sample(id, std::uintmax_t(max) - std::uintmax_t(min) - 1) + min);
29 }
30
31 template<typename T, HALCHECK_REQUIRE(std::is_floating_point<T>())>
32 T operator()(lib::atom id, T min, T max) const {
33 gen::guard(min < max);
34 auto factor = T(gen::sample(id, std::numeric_limits<std::uintmax_t>::max() - 1)) /
36 return gen::shrink_to(id, min, min * factor + max * (1 - factor));
37 }
38
39 template<typename T, typename U, HALCHECK_REQUIRE(!std::is_same<T, U>())>
40 lib::common_type_t<T, U> operator()(lib::atom id, T min, U max) const {
42 return (*this)(id, V(min), V(max));
43 }
44
45 template<typename T, HALCHECK_REQUIRE(lib::is_forward_iterator<T>())>
46 T operator()(lib::atom id, T min, T max) const {
47 return std::next(min, (*this)(id, 0, std::distance(min, max)));
48 }
49};
50
51extern template unsigned char range_t::operator()(lib::atom, unsigned char, unsigned char) const;
52extern template signed char range_t::operator()(lib::atom, signed char, signed char) const;
53extern template char range_t::operator()(lib::atom, char, char) const;
54extern template unsigned short range_t::operator()(lib::atom, unsigned short, unsigned short) const;
55extern template signed short range_t::operator()(lib::atom, signed short, signed short) const;
56extern template unsigned int range_t::operator()(lib::atom, unsigned int, unsigned int) const;
57extern template signed int range_t::operator()(lib::atom, signed int, signed int) const;
58extern template unsigned long range_t::operator()(lib::atom, unsigned long, unsigned long) const;
59extern template signed long range_t::operator()(lib::atom, signed long, signed long) const;
60extern template unsigned long long range_t::operator()(lib::atom, unsigned long long, unsigned long long) const;
61extern template signed long long range_t::operator()(lib::atom, signed long long, signed long long) const;
62extern template float range_t::operator()(lib::atom, float, float) const;
63extern template double range_t::operator()(lib::atom, double, double) const;
64extern template long double range_t::operator()(lib::atom, long double, double) const;
65
93static const range_t range;
94
95}} // namespace halcheck::gen
96
97#endif
T distance(T... args)
void guard(bool cond)
Throws a gen::discard_exception if the given condition is false.
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.
lib::variant< lib::symbol, lib::number > atom
An atom is either a symbol or a number.
Definition atom.hpp:194
typename std::common_type< Args... >::type common_type_t
An implementation of std::common_type_t.
Definition type_traits.hpp:133
T max(T... args)
T min(T... args)
T next(T... args)