15 #ifndef BELUGA_VIEWS_RANDOM_INTERSPERSE_HPP
16 #define BELUGA_VIEWS_RANDOM_INTERSPERSE_HPP
21 #include <type_traits>
23 #include <range/v3/functional/bind_back.hpp>
24 #include <range/v3/utility/random.hpp>
25 #include <range/v3/view/adaptor.hpp>
44 template <
class Range,
class Fn,
class URNG =
typename ranges::detail::default_random_engine>
46 :
public ranges::view_adaptor<
47 random_intersperse_view<Range, Fn, URNG>,
68 URNG& engine = ranges::detail::get_random_engine())
72 engine_{std::addressof(engine)} {}
76 friend ranges::range_access;
78 using result_type = ranges::common_type_t<decltype(std::declval<Fn>()()), ranges::range_value_t<Range>>;
81 struct adaptor :
public ranges::adaptor_base {
90 [[nodiscard]] constexpr
auto read(ranges::iterator_t<Range> it)
const {
return fn_return_.value_or(*it); }
93 constexpr
void next(ranges::iterator_t<Range>& it) {
102 void prev(ranges::iterator_t<Range>& it) =
delete;
117 ranges::semiregular_box_t<Fn>
fn_;
139 template <
class Range,
class Fn,
class URNG =
typename ranges::detail::default_random_engine>
144 URNG& engine = ranges::detail::get_random_engine())
const {
146 auto gen = [&fn, &engine]() {
147 if constexpr (std::is_invocable_v<Fn>) {
149 return std::move(fn);
151 static_assert(std::is_invocable_v<Fn, decltype(engine)>);
152 return [fn = std::move(fn), &engine]() {
return fn(engine); };
156 return random_intersperse_view{ranges::views::all(std::forward<Range>(range)), std::move(gen), probability, engine};
160 template <
class Range,
class Fn,
class URNG>
161 constexpr
auto operator()(Range&& range, Fn fn,
double probability, std::reference_wrapper<URNG> engine)
const {
162 return (*
this)(ranges::views::all(std::forward<Range>(range)), std::move(fn), probability, engine.get());
175 template <
class Fn,
class URNG =
typename ranges::detail::default_random_engine>
179 URNG& engine = ranges::detail::get_random_engine())
const {
180 return ranges::make_view_closure(