halcheck 1.0
Loading...
Searching...
No Matches
generate.hpp
1#ifndef HALCHECK_LIB_ITERATOR_GENERATE_HPP
2#define HALCHECK_LIB_ITERATOR_GENERATE_HPP
3
4// IWYU pragma: private, include <halcheck/lib/iterator.hpp>
5
6#include <halcheck/lib/functional.hpp>
7#include <halcheck/lib/iterator/interface.hpp>
8#include <halcheck/lib/optional.hpp>
9#include <halcheck/lib/type_traits.hpp>
10
11#include <cstddef>
12#include <iterator>
13
14namespace halcheck { namespace lib {
15
16template<
17 typename F,
18 HALCHECK_REQUIRE(lib::is_copyable<F>()),
19 typename = decltype(bool(std::declval<lib::invoke_result_t<F &>>())),
20 typename = decltype(*std::declval<lib::invoke_result_t<F &>>())>
21class generate_iterator : public lib::iterator_interface<generate_iterator<F>> {
22public:
23 using lib::iterator_interface<generate_iterator>::operator++;
24
25 using value_type = lib::decay_t<decltype(*std::declval<lib::invoke_result_t<F>>())>;
26 using reference = const value_type &;
27 using pointer = void;
28 using difference_type = std::ptrdiff_t;
29 using iterator_category = std::input_iterator_tag;
30
31 constexpr generate_iterator() = default;
32
33 explicit generate_iterator(F func) : _func(std::move(func)) { ++(*this); }
34
35 constexpr reference &operator*() const noexcept { return *_value; }
36
37 generate_iterator &operator++() {
38 if (auto value = lib::invoke(*_func))
39 _value.emplace(std::move(*value));
40 else
41 _value.reset();
42 return *this;
43 }
44
45private:
46 friend bool operator==(const generate_iterator &lhs, const generate_iterator &rhs) {
47 return !lhs._value && !rhs._value;
48 }
49
50 lib::optional<F> _func;
51 lib::optional<value_type> _value;
52};
53
54template<typename F>
55lib::generate_iterator<F> make_generate_iterator(F func) {
56 return lib::generate_iterator<F>(std::move(func));
57}
58
59}} // namespace halcheck::lib
60#endif
T declval(T... args)
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::decay< T >::type decay_t
An implementation of std::decay_t.
Definition type_traits.hpp:101
#define HALCHECK_REQUIRE(...)
Expands to a template argument that is only valid if the given argument evaluates to true.
Definition type_traits.hpp:24
STL namespace.