16 #ifndef OPENKALMAN_COLLECTIONS_VIEWS_UPDATE_HPP 17 #define OPENKALMAN_COLLECTIONS_VIEWS_UPDATE_HPP 19 #include <type_traits> 20 #ifdef __cpp_lib_ranges 43 #ifdef __cpp_lib_ranges 44 template<collection_view V,
typename F> requires
45 std::is_invocable_r_v<std::ranges::range_value_t<const V>, F&, std::remove_cvref_t<V>&, std::integral_constant<std::size_t, 0>>
46 struct update_view : std::ranges::view_interface<update_view<V, F>>
48 template<typename V, typename F>
54 template<
bool Const,
typename T>
55 using maybe_const = std::conditional_t<Const, const T, T>;
59 using value_type = std::invoke_result_t<F, V&, std::size_t>;
66 template<
bool Const,
typename Index>
69 using Parent = maybe_const<Const, update_view>;
71 template<
typename Fun,
typename...Args>
72 static constexpr decltype(
auto)
73 invoke_fun(Fun&& f, Args&&... args) noexcept(std::is_nothrow_invocable_v<Fun, Args...>)
75 #if __cplusplus >= 202002L 80 return ns::invoke(std::forward<Fun>(f), std::forward<Args>(args)...);
85 constexpr
proxy(Parent * parent, Index current = {}) : parent_ {parent}, current_ {std::move(current)} {}
87 constexpr
operator std::ranges::range_value_t<V> ()
const 89 return invoke_fun(parent_->f_.get(), parent_->v_, current_);
92 #ifdef __cpp_lib_ranges 93 constexpr
proxy& operator=(std::ranges::range_value_t<V> x) requires
94 std::invocable<S&, std::remove_cvref_t<V>&, std::integral_constant<std::size_t, 0>, std::ranges::range_value_t<V>> and
95 std::ranges::output_range<V, std::ranges::range_value_t<views::all_t<V>>>
97 template<
bool Enable =
true, std::enable_if_t<Enable and
98 std::is_invocable_v<S&, remove_cvref_t<V>&, std::integral_constant<std::size_t, 0>, ranges::range_value_t<V>> and
99 ranges::output_range<V, ranges::range_value_t<views::all_t<V>>>,
int> = 0>
100 constexpr
proxy& operator=(std::ranges::range_value_t<V> x) requires
103 invoke_fun(parent_->s_.get(), parent_->v_, current_, std::move(x));
121 using Parent = maybe_const<Const, update_view>;
122 using Base = maybe_const<Const, V>;
126 using iterator_concept = std::random_access_iterator_tag;
127 using iterator_category = std::random_access_iterator_tag;
128 using difference_type = std::ptrdiff_t;
129 using pointer = void;
135 constexpr
iterator(maybe_const<Const, Parent>* parent, std::size_t pos)
136 : current_ {
static_cast<difference_type
>(pos)}, parent_ {parent} {}
138 explicit constexpr iterator(
iterator<not Const> i) : current_ {std::move(i.current_)}, parent_ {std::move(i.parent_)} {}
140 constexpr
auto operator*()
const {
return value_type {parent_,
static_cast<std::size_t
>(current_)}; }
142 constexpr
auto operator[](difference_type n)
const {
return value_type {parent_,
static_cast<std::size_t
>(current_ + n)}; }
144 constexpr iterator& operator++() { ++current_;
return *
this; }
146 constexpr iterator operator++(
int) {
auto tmp = *
this; ++*
this;
return tmp; }
148 constexpr iterator& operator--() { --current_;
return *
this; }
150 constexpr iterator operator--(
int) {
auto tmp = *
this; --*
this;
return tmp; }
152 constexpr iterator& operator+=(
const difference_type& n) { current_ += n;
return *
this; }
154 constexpr iterator& operator-=(
const difference_type& n) { current_ -= n;
return *
this; }
156 friend constexpr
bool operator==(
const iterator& x,
const iterator& y) {
return x.current_ == y.current_; }
158 friend constexpr
bool operator!=(
const iterator& x,
const iterator& y) {
return not (x.current_ == y.current_); }
160 friend constexpr
bool operator<(
const iterator& x,
const iterator& y) {
return x.current_ < y.current_; }
162 friend constexpr
bool operator>(
const iterator& x,
const iterator& y) {
return y < x; }
164 friend constexpr
bool operator<=(
const iterator& x,
const iterator& y) {
return not (y < x); }
166 friend constexpr
bool operator>=(
const iterator& x,
const iterator& y) {
return not (x < y); }
168 friend constexpr iterator operator+(
const iterator& i,
const difference_type& n) {
return iterator {*i.parent_, i.current_ + n}; }
170 friend constexpr iterator operator+(
const difference_type& n,
const iterator& i) {
return iterator {*i.parent_, i.current_ + n}; }
172 friend constexpr iterator operator-(
const iterator& i,
const difference_type& n) {
return iterator {*i.parent_, i.current_ - n}; }
174 friend constexpr difference_type operator-(
const iterator& x,
const iterator& y) {
return x.current_ - y.current_; }
178 difference_type current_;
186 #ifdef __cpp_concepts 188 update_view() requires std::default_initializable<V> =
default;
190 template<
bool Enable = true, std::enable_if_t<Enable and std::is_default_constructible_v<V> and
191 std::is_default_constructible_v<F_box> and std::is_default_constructible_v<S_box>,
int> = 0>
200 template<
typename G_,
typename S_>
202 update_view(V& v, G_&& g, S_&& s) : v_ {v}, f_ {std::forward<G_>(g)}, s_ {std::forward<S_>(s)} {}
205 template<
typename G_,
typename S_>
207 update_view(V&& v, G_&& g, S_&& s) : v_ {std::move(v)}, f_ {std::forward<G_>(g)}, s_ {std::forward<S_>(s)} {}
226 else return unreachable_sentinel;
230 constexpr
auto end()
const 234 else return unreachable_sentinel;
241 #ifdef __cpp_concepts 243 size()
const requires sized<V>
245 template<
bool Enable = true, std::enable_if_t<Enable and sized<V>,
int> = 0>
256 template<std::
size_t i>
257 constexpr decltype(
auto)
260 if constexpr (sized<V>)
if constexpr (size_of_v<V> !=
dynamic_size) static_assert(i < size_of_v<V>,
"Index out of range");
265 template<std::
size_t i>
266 constexpr decltype(
auto)
269 if constexpr (sized<V>)
if constexpr (size_of_v<V> !=
dynamic_size) static_assert(i < size_of_v<V>,
"Index out of range");
281 template<
typename V,
typename F>
285 #ifndef __cpp_concepts 288 template<std::
size_t i,
typename C,
typename Fun,
typename =
void>
291 template<std::
size_t i,
typename C,
typename Fun>
294 using type = std::invoke_result_t<Fun, std::tuple_element_t<i, C>>;
301 #ifndef __cpp_concepts 302 namespace detail_update
304 template<
typename V,
typename =
void>
317 #ifdef __cpp_concepts 318 template<OpenKalman::collections::sized V,
typename F> requires
322 template<
typename V,
typename F>
327 template<std::
size_t i,
typename V,
typename F>
328 struct tuple_element<i, OpenKalman::collections::update_view<V, F>>
330 #ifdef __cpp_lib_ranges 331 using type = std::invoke_result_t<F, V&, std::integral_constant<std::size_t, i>>;
333 using type = std::invoke_result_t<F, V&, std::integral_constant<std::size_t, i>>;
346 #if __cpp_lib_ranges >= 202202L
347 : std::ranges::range_adaptor_closure<update_closure<F>>
355 #ifdef __cpp_concepts 356 template<viewable_collection R> requires
357 std::is_invocable_r_v<std::ranges::range_value_t<R>, F,
all_t<R&&>, std::integral_constant<std::size_t, 0>>
362 operator() (R&& r)
const {
return update_view {all(std::forward<R>(r)), f_}; }
374 operator() (F&& f)
const 380 #ifdef __cpp_concepts 381 template<viewable_collection R,
typename F> requires
382 std::is_invocable_r_v<std::ranges::range_value_t<R>, F,
all_t<R&&>, std::integral_constant<std::size_t, 0>>
384 template<
typename R,
typename F>
387 operator() (R&& r, F&& g)
const 389 return update_view {std::forward<R>(r) | all, std::forward<F>(g)};
407 #endif //OPENKALMAN_COLLECTIONS_VIEWS_UPDATE_HPP Definition for values::index.
Namespace for collections.
Definition: collections.hpp:27
constexpr auto end() const
Definition: update.hpp:230
Definition: update.hpp:370
A collection_view that updates an underlying collection_view on an element-by-element basis...
Definition: update.hpp:49
Definition: view_interface.hpp:32
Definition for collections::sized_random_access_range.
Definition: tuple_reverse.hpp:103
The size of a sized object (including a collection).
Definition: size_of.hpp:36
Definition: update.hpp:305
Definition for collections::get_size.
The root namespace for OpenKalman.
Definition: basics.hpp:34
Definition for collections::collection_view.
Definition: update.hpp:345
Definition: update.hpp:289
Iterator for update_view.
Definition: update.hpp:119
constexpr auto end()
Definition: update.hpp:222
Definition: range_adaptor_closure.hpp:35
constexpr auto begin()
Definition: update.hpp:213
Namespace for generalized views.
Definition: collections.hpp:33
constexpr update_view(V &v, G_ &&g, S_ &&s)
Construct from a collection, a getter function, and a setter function.
Definition: update.hpp:202
decltype(auto) constexpr get()
Get element i.
Definition: update.hpp:258
constexpr auto begin() const
Definition: update.hpp:216
Definitions implementing features of the c++ ranges library for compatibility.
constexpr bool index
T is an index value.
Definition: index.hpp:56
Definition for collections::viewable_collection.
constexpr std::size_t dynamic_size
A constant indicating that a size or index is dynamic.
Definition: global-definitions.hpp:33
decltype(all(std::declval< R >())) all_t
Calculates the suitable collection_view type of a viewable_collection type.
Definition: all.hpp:97
constexpr auto get_size(Arg &&arg)
Get the size of a sized object (e.g, a collection)
Definition: get_size.hpp:191
constexpr update_view(V &&v, G_ &&g, S_ &&s)
Definition: update.hpp:207
constexpr auto size() const
The size of the resulting object.
Definition: update.hpp:246
constexpr update_view()
Default constructor.
Definition: update.hpp:193
A proxy object for accessing the base view.
Definition: update.hpp:67
constexpr detail::update_adaptor update
a std::ranges::range_adaptor_closure associated with update_view.
Definition: update.hpp:403