11#pragma once
22
3+ #include < type_traits>
34#include < cassert>
45
56#include " rapidcheck/detail/Any.h"
@@ -17,6 +18,18 @@ Gen<Decay<typename std::result_of<Mapper(T)>::type>> map(Gen<T> gen,
1718
1819} // namespace gen
1920
21+ // Concept check for types that have method
22+ // `Shrinkable<T> G::operator()(const Random &, int) const`
23+ template <typename T, typename G, typename = void >
24+ struct MakesShrinkable : std::false_type {};
25+
26+ template <typename T, typename G>
27+ struct MakesShrinkable <T, G, typename std::enable_if<
28+ std::is_convertible<
29+ decltype (std::declval<const G>()(std::declval<Random>(), 0)),
30+ Shrinkable<T> >::value>::type>
31+ : std::true_type {};
32+
2033template <typename T>
2134class Gen <T>::IGenImpl {
2235public:
@@ -55,7 +68,12 @@ class Gen<T>::GenImpl : public IGenImpl {
5568template <typename T>
5669template <typename Impl, typename >
5770Gen<T>::Gen(Impl &&impl)
58- : m_impl(new GenImpl<Decay<Impl>>(std::forward<Impl>(impl))) {}
71+ : m_impl(new GenImpl<Decay<Impl>>(std::forward<Impl>(impl))) {
72+ static_assert (MakesShrinkable<T, Impl>::value,
73+ " Generator implementation must have a method Shrinkable<T> operator()(const Random &, int) const" );
74+ static_assert (std::is_copy_constructible<Impl>::value,
75+ " Generator implementation must have a copy constructor" );
76+ }
5977
6078template <typename T>
6179std::string Gen<T>::name() const {
0 commit comments