16 #ifndef OPENKALMAN_COLLECTIONS_VIEWS_GENERATE_HPP 17 #define OPENKALMAN_COLLECTIONS_VIEWS_GENERATE_HPP 34 template<
typename F, values::size Size = values::unbounded_
size_t> requires
35 std::same_as<Size, std::remove_reference_t<Size>> and std::is_object_v<F> and std::invocable<F&, std::size_t>
37 template<
typename F,
typename Size = values::unbounded_
size_t>
43 static_assert(not values::fixed_value_compares_with<Size, stdex::dynamic_extent>,
44 "Size parameter for generate_view cannot be std::dynamic_extent");
48 template<
bool Const,
typename T>
49 using maybe_const = std::conditional_t<Const, const T, T>;
59 using iterator_concept = std::random_access_iterator_tag;
60 using iterator_category = std::random_access_iterator_tag;
61 using value_type = std::invoke_result_t<F_box&, std::size_t>;
62 using difference_type = std::ptrdiff_t;
63 using reference = value_type;
68 constexpr
iterator(maybe_const<Const, F_box>& f, std::size_t pos)
69 : f_ {std::addressof(f)}, current_ {
static_cast<difference_type
>(pos)} {};
71 constexpr iterator(
iterator<not Const> i) : f_ {std::move(i.f_)}, current_ {std::move(i.current_)} {}
73 constexpr value_type operator*()
const 75 return stdex::invoke(*f_, static_cast<std::size_t>(current_));
78 constexpr value_type operator[](difference_type offset)
const 80 return stdex::invoke(*f_, static_cast<std::size_t>(current_ + offset));
83 constexpr
auto& operator++() noexcept { ++current_;
return *
this; }
84 constexpr
auto operator++(
int) noexcept {
auto temp = *
this; ++*
this;
return temp; }
85 constexpr
auto& operator--() noexcept { --current_;
return *
this; }
86 constexpr
auto operator--(
int) noexcept {
auto temp = *
this; --*
this;
return temp; }
87 constexpr
auto& operator+=(
const difference_type diff) noexcept { current_ += diff;
return *
this; }
88 constexpr
auto& operator-=(
const difference_type diff) noexcept { current_ -= diff;
return *
this; }
90 friend constexpr
auto operator+(
const iterator& it,
const difference_type diff)
91 {
return iterator {*it.f_,
static_cast<std::size_t
>(it.current_ + diff)}; }
92 friend constexpr
auto operator+(
const difference_type diff,
const iterator& it)
93 {
return iterator {*it.f_,
static_cast<std::size_t
>(diff + it.current_)}; }
94 friend constexpr
auto operator-(
const iterator& it,
const difference_type diff)
95 {
if (it.current_ < diff)
throw std::out_of_range{
"Iterator out of range"};
return iterator {*it.f_,
static_cast<std::size_t
>(it.current_ - diff)}; }
96 friend constexpr difference_type operator-(
const iterator& it,
const iterator& other)
97 {
return it.current_ - other.current_; }
98 friend constexpr
bool operator==(
const iterator& it,
const iterator& other)
99 {
return it.current_ == other.current_; }
100 #ifdef __cpp_impl_three_way_comparison 101 constexpr
auto operator<=>(
const iterator& other)
const noexcept {
return current_ <=> other.current_; }
103 constexpr
bool operator!=(
const iterator& other)
const noexcept {
return current_ != other.current_; }
104 constexpr
bool operator<(
const iterator& other)
const noexcept {
return current_ < other.current_; }
105 constexpr
bool operator>(
const iterator& other)
const noexcept {
return current_ > other.current_; }
106 constexpr
bool operator<=(
const iterator& other)
const noexcept {
return current_ <= other.current_; }
107 constexpr
bool operator>=(
const iterator& other)
const noexcept {
return current_ >= other.current_; }
112 maybe_const<Const, F_box> * f_;
113 difference_type current_;
123 : f_box {std::move(f)}, size_ {std::move(
size)} {}
129 #ifdef __cpp_concepts 131 generate_view(F f) noexcept requires (not values::index<Size>)
133 template<
bool Enable = true, std::enable_if_t<Enable and (not values::index<Size>),
int> = 0>
137 : f_box {std::move(f)} {}
150 constexpr
auto begin() {
return iterator<false> {f_box, 0}; }
153 constexpr
auto begin()
const {
return iterator<true> {f_box, 0}; }
161 if constexpr (values::index<Size>)
162 return iterator<false> {f_box,
static_cast<std::size_t
>(size_)};
164 return stdex::unreachable_sentinel;
168 constexpr
auto end()
const 170 if constexpr (values::index<Size>)
171 return iterator<true> {f_box,
static_cast<std::size_t
>(size_)};
173 return stdex::unreachable_sentinel;
180 #ifdef __cpp_concepts 182 size()
const noexcept requires values::index<Size>
184 template<
bool Enable = true, std::enable_if_t<Enable and (values::index<Size>),
int> = 0>
185 constexpr
auto size() const noexcept
195 #ifdef __cpp_explicit_this_parameter 196 template<std::
size_t i>
197 constexpr decltype(
auto)
198 get(
this auto&&
self) noexcept
200 static_assert (not values::fixed_value_compares_with<Size, i, &std::is_lteq>,
"Index out of range");
201 return std::forward<decltype(self)>(
self).f_box(std::integral_constant<std::size_t, i>{});
204 template<std::
size_t i>
205 constexpr decltype(
auto)
208 static_assert (not values::fixed_value_compares_with<Size, i, &stdex::is_lteq>,
"Index out of range");
209 return f_box(std::integral_constant<std::size_t, i>{});
212 template<std::
size_t i>
213 constexpr decltype(
auto)
216 static_assert (not values::fixed_value_compares_with<Size, i, &stdex::is_lteq>,
"Index out of range");
217 return f_box(std::integral_constant<std::size_t, i>{});
220 template<std::
size_t i>
221 constexpr decltype(
auto)
224 static_assert (not values::fixed_value_compares_with<Size, i, &stdex::is_lteq>,
"Index out of range");
225 return std::move(*this).f_box(std::integral_constant<std::size_t, i>{});
228 template<std::
size_t i>
229 constexpr decltype(
auto)
230 get()
const && noexcept
232 static_assert (not values::fixed_value_compares_with<Size, i, &stdex::is_lteq>,
"Index out of range");
233 return std::move(*this).f_box(std::integral_constant<std::size_t, i>{});
248 template<
typename F,
typename S>
259 #ifdef __cpp_lib_ranges 260 namespace std::ranges
265 template<
typename F,
typename S>
266 constexpr
bool enable_borrowed_range<OpenKalman::collections::generate_view<F, S>> = std::is_lvalue_reference_v<F> or
267 OpenKalman::stdex::semiregular<OpenKalman::collections::internal::movable_wrapper<F>>;
273 template<
typename F,
typename S>
277 template<std::
size_t i,
typename F,
typename S>
280 using type = std::invoke_result_t<F, std::integral_constant<std::size_t, i>>;
295 #ifdef __cpp_concepts 296 template<
typename F, values::index Size> requires
297 std::invocable<F, std::size_t> and std::invocable<F, std::integral_constant<std::size_t, 0>>
299 template<
typename F,
typename Size, std::enable_if_t<values::index<Size> and
300 std::is_invocable_v<F, std::
size_t> and std::is_invocable_v<F, std::
integral_constant<std::
size_t, 0>>,
int> = 0>
303 operator() (F&& f, Size s)
const 312 #ifdef __cpp_concepts 313 template<
typename F> requires
314 std::invocable<F, std::size_t> and std::invocable<F, std::integral_constant<std::size_t, 0>>
316 template<
typename F, std::enable_if_t<std::is_invocable_v<F, std::
size_t> and
317 std::is_invocable_v<F, std::
integral_constant<std::
size_t, 0>>,
int> = 0>
320 operator() (F&& f)
const Namespace for collections.
Definition: collections.hpp:27
constexpr auto size() const noexcept
The size of the resulting object.
Definition: generate.hpp:185
Definition of lexicographical_compare_three_way for collections.
Iterator for generate_view.
Definition: generate.hpp:57
Header file for code relating to values (e.g., scalars and indices)
Definition: generate.hpp:290
generate_view(F, S) -> generate_view< F, S >
Deduction guide.
The fixed value associated with a fixed.
Definition: fixed_value_of.hpp:44
constexpr auto begin() const
Definition: generate.hpp:153
constexpr auto begin()
Definition: generate.hpp:150
Definition: view_interface.hpp:32
constexpr generate_view(F f, Size size)
Construct from a callable object and a size.
Definition: generate.hpp:122
A collection_view created by lazily generating elements based on an index.
Definition: generate.hpp:39
The root namespace for OpenKalman.
Definition: basics.hpp:34
decltype(auto) constexpr get() &
Get element i.
Definition: generate.hpp:206
Namespace for generalized views.
Definition: collections.hpp:33
constexpr detail::generate_adaptor generate
a collection_view generator associated with generate_view.
Definition: generate.hpp:335
constexpr generate_view()=default
Default constructor.
constexpr generate_view(F f) noexcept
Construct from a callable object, if the view is unsized.
Definition: generate.hpp:135
constexpr auto end()
Definition: generate.hpp:159
constexpr auto end() const
Definition: generate.hpp:168