16 #ifndef OPENKALMAN_COLLECTIONS_VIEWS_SLICE_HPP 17 #define OPENKALMAN_COLLECTIONS_VIEWS_SLICE_HPP 36 #ifdef __cpp_lib_ranges 37 template<collection V, values::index Offset, values::size Extent = values::unbounded_
size_t> requires
38 std::same_as<std::decay_t<Offset>, Offset> and std::same_as<std::decay_t<Extent>, Extent> and
44 template<
typename V,
typename Offset,
typename Extent = values::unbounded_
size_t>
54 template<
bool Enable = true, std::enable_if_t<Enable and stdex::default_initializable<V> and
55 stdex::default_initializable<Offset> and stdex::default_initializable<Extent>,
int> = 0>
64 slice_view(V&& v, Offset offset = {}, Extent extent = {})
65 : v_ {std::forward<V>(v)}, offset_ {std::move(offset)}, extent_ {std::move(extent)} {}
71 #ifdef __cpp_explicit_this_parameter 72 constexpr decltype(
auto)
73 base(
this auto&&
self) noexcept {
return std::forward<decltype(self)>(
self).v_.
get(); }
75 constexpr V&
base() & {
return this->v_.
get(); }
76 constexpr
const V&
base()
const & {
return this->v_.
get(); }
77 constexpr V&&
base() && noexcept {
return std::move(*this).v_.get(); }
78 constexpr
const V&&
base()
const && noexcept {
return std::move(*this).v_.get(); }
81 #ifndef __cpp_explicit_this_parameter 84 template<
typename Self>
86 begin_impl(Self&&
self) noexcept
88 return stdex::ranges::begin(std::forward<Self>(
self).v_.
get());
91 template<
typename Self>
93 end_impl(Self&&
self) noexcept
95 return stdex::ranges::end(std::forward<Self>(
self).v_.
get());
104 #ifdef __cpp_explicit_this_parameter 106 begin(
this auto&&
self) noexcept requires stdex::ranges::range<const V>
108 return stdex::ranges::begin(std::forward<decltype(
self)>(
self).v_.
get()) + std::forward<decltype(
self)>(
self).offset_;
111 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
112 constexpr
auto begin() & {
return begin_impl(*
this) + offset_; }
114 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
115 constexpr
auto begin()
const & {
return begin_impl(*
this) + offset_; }
117 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
118 constexpr
auto begin() && noexcept {
return begin_impl(std::move(*
this)) + std::move(*this).offset_; }
120 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
121 constexpr
auto begin()
const && noexcept {
return begin_impl(std::move(*
this)) + std::move(*this).offset_; }
128 #ifdef __cpp_explicit_this_parameter 130 end(
this auto&&
self) noexcept requires stdex::ranges::range<const V>
132 if constexpr (values::index<Extent>)
133 return std::forward<decltype(self)>(
self).
begin() + std::forward<decltype(self)>(
self).extent_;
135 return stdex::ranges::end(std::forward<decltype(
self)>(
self).v_.
get());
138 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
141 if constexpr (values::index<Extent>)
return this->
begin() + extent_;
142 else return end_impl(*
this);
145 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
146 constexpr
auto end()
const &
148 if constexpr (values::index<Extent>)
return this->
begin() + extent_;
149 else return end_impl(*
this);
152 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
153 constexpr
auto end() && noexcept
155 if constexpr (values::index<Extent>)
return std::move(*this).begin() + std::move(*this).extent_;
156 else return end_impl(std::move(*
this));
159 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
160 constexpr
auto end()
const && noexcept
162 if constexpr (values::index<Extent>)
return std::move(*this).begin() + std::move(*this).extent_;
163 else return end_impl(std::move(*
this));
171 #ifdef __cpp_explicit_this_parameter 173 size(
this auto&&
self) noexcept requires values::index<Extent> or sized<V>
175 if constexpr (values::index<Extent>)
176 return std::forward<decltype(self)>(
self).extent_;
180 get_size(std::forward<decltype(
self)>(
self).v_.
get()),
181 std::forward<decltype(
self)>(
self).offset_);
184 template<
bool Enable = true, std::enable_if_t<values::index<Extent> or sized<V>,
int> = 0>
188 if constexpr (values::index<Extent>)
199 #ifdef __cpp_explicit_this_parameter 200 template<std::
size_t i>
201 constexpr decltype(
auto)
202 get(
this auto&&
self) noexcept
204 if constexpr (values::fixed<Extent>) static_assert(i < values::fixed_value_of_v<Extent>,
"Index exceeds range");
206 values::operation(std::plus{}, std::forward<decltype(self)>(
self).offset_, std::integral_constant<std::size_t, i>{}));
209 template<std::
size_t i>
210 constexpr decltype(
auto)
213 if constexpr (values::fixed<Extent>) static_assert(i < values::fixed_value_of_v<Extent>,
"Index exceeds range");
215 values::operation(std::plus{}, offset_, std::integral_constant<std::size_t, i>{}));
218 template<std::
size_t i>
219 constexpr decltype(
auto)
222 if constexpr (values::fixed<Extent>) static_assert(i < values::fixed_value_of_v<Extent>,
"Index exceeds range");
224 values::operation(std::plus{}, offset_, std::integral_constant<std::size_t, i>{}));
227 template<std::
size_t i>
228 constexpr decltype(
auto)
231 if constexpr (values::fixed<Extent>) static_assert(i < values::fixed_value_of_v<Extent>,
"Index exceeds range");
233 values::operation(std::plus{}, offset_, std::integral_constant<std::size_t, i>{}));
236 template<std::
size_t i>
237 constexpr decltype(
auto)
238 get()
const && noexcept
240 if constexpr (values::fixed<Extent>) static_assert(i < values::fixed_value_of_v<Extent>,
"Index exceeds range");
258 template<
typename V,
typename O,
typename E>
261 template<
typename V,
typename O>
268 #ifdef __cpp_lib_ranges 269 namespace std::ranges
271 namespace OpenKalman::stdex::ranges
274 template<
typename V,
typename O,
typename E>
275 constexpr
bool enable_borrowed_range<OpenKalman::collections::slice_view<V, O, E>> = enable_borrowed_range<V>;
279 #ifndef __cpp_lib_ranges 282 template<std::
size_t i,
typename V,
typename O,
typename =
void>
285 template<std::
size_t i,
typename V,
typename O>
294 template<
typename V,
typename O,
typename E>
297 template<
typename V,
typename O>
299 : std::conditional_t<
300 OpenKalman::values::fixed<OpenKalman::collections::size_of<V>> and OpenKalman::values::fixed<O>,
301 OpenKalman::values::operation_t<std::minus<>, OpenKalman::collections::size_of<V>, O>,
305 #ifdef __cpp_concepts 306 template<
size_t i,
typename V,
typename O,
typename E>
309 template<
size_t i,
typename V, OpenKalman::values::fixed O,
typename E>
313 template<
size_t i,
typename V,
typename O,
typename E>
324 template<
typename R,
typename O,
typename E>
326 slice_impl(R&& r, O&& o, E&& e)
328 if constexpr (viewable_collection<R>)
331 return all(std::forward<R>(r));
333 return slice_view {all(std::forward<R>(r)), std::forward<O>(o), std::forward<E>(e)};
335 else return slice_view {std::forward<R>(r), std::forward<O>(o), std::forward<E>(e)};
343 template<
typename O,
typename E>
346 constexpr
slice_closure(O o, E e) : offset_ {std::move(o)}, extent_ {std::move(e)} {};
348 #ifdef __cpp_concepts 349 template<
typename R> requires
350 (viewable_collection<R> or
351 (uniformly_gettable<R> and values::fixed<O> and (values::fixed<E> or not values::index<E>))) and
354 (not sized<R> or size_of_v<R> == std::dynamic_extent or
355 values::dynamic<O> or values::dynamic<E> or
356 values::fixed_value_of_v<O> + values::fixed_value_of_v<E> <= size_of_v<R>)
358 template<
typename R, std::enable_if_t<
359 ((viewable_collection<R> or (uniformly_gettable<R> and values::fixed<O> and (values::fixed<E> or not values::index<E>))) and
360 values::index<O> and values::size<E>) and
365 operator() (R&& r)
const 367 return slice_impl(std::forward<R>(r), offset_, extent_);
378 #ifdef __cpp_concepts 379 template<values::index O, values::size E = values::unbounded_
size_t>
382 values::index<O> and values::size<E>,
int> = 0>
391 #ifdef __cpp_concepts 392 template<
typename R, values::index O, values::size E = values::unbounded_
size_t> requires
393 (viewable_collection<R> or
394 (uniformly_gettable<R> and values::fixed<O> and (values::fixed<E> or not values::index<E>))) and
397 (not sized<R> or not values::index<E> or
401 ((viewable_collection<R> or (uniformly_gettable<R> and values::fixed<O> and (values::fixed<E> or not values::index<E>))) and
402 values::index<O> and values::size<E>) and
406 constexpr decltype(
auto)
409 return slice_impl(std::forward<R>(r), std::move(o), std::move(e));
Namespace for collections.
Definition: collections.hpp:27
Definition for collections::collection.
constexpr slice_view(V &&v, Offset offset={}, Extent extent={})
Construct from a collection.
Definition: slice.hpp:64
constexpr auto get_size(Arg &&arg)
Get the size of a sized object (e.g, a collection)
Definition: get_size.hpp:224
Header file for code relating to values (e.g., scalars and indices)
constexpr auto begin() &
Definition: slice.hpp:112
The size of a sized object (including a collection).
Definition: size_of.hpp:33
The fixed value associated with a fixed.
Definition: fixed_value_of.hpp:44
constexpr auto size() const noexcept
Definition: slice.hpp:186
Definition: view_interface.hpp:32
Definition for collections::get_size.
constexpr slice_view()
Default constructor.
Definition: slice.hpp:56
Definition for collections::get_element.
std::conditional_t< sized< T >, size_of< T >, values::unbounded_size_t > size_of_t
The type of the argument's size, which will satisfy values::size.
Definition: size_of.hpp:69
constexpr bool sized
An object (std::ranges::sized_range, std::tuple, std::span, etc.) that has a discernible size...
Definition: sized.hpp:32
A type reflecting an unbound size.
Definition: size.hpp:27
Definition: slice.hpp:283
Definition: slice.hpp:376
constexpr V & base() &
The base view.
Definition: slice.hpp:75
constexpr T & get() &noexcept
Retrieve the stored value.
Definition: movable_wrapper.hpp:72
constexpr bool size
T is either an index representing a size, or unbounded_size_t, which indicates that the size is unbou...
Definition: size.hpp:71
constexpr bool size_compares_with
T and U are sizes that compare in a particular way based on parameter comp.
Definition: size_compares_with.hpp:98
Namespace for generalized views.
Definition: collections.hpp:33
constexpr detail::slice_adapter slice
a RangeAdapterObject associated with slice_view.
Definition: slice.hpp:423
Definition: range_adaptor_closure.hpp:34
decltype(operation(std::declval< Operation && >(), std::declval< Args && >()...)) operation_t
The resulting type from an values::operation.
Definition: operation.hpp:115
A view representing a slice of a collection.
Definition: slice.hpp:46
The type of the element at a given index, if it can be determined at compile time.
Definition: collection_element.hpp:48
Definition: slice.hpp:344
decltype(auto) constexpr get_element(Arg &&arg, I i)
A generalization of std::get and the range subscript operator.
Definition: get_element.hpp:124
constexpr unbounded_size_t unbounded_size
An instance of unbounded_size_t;.
Definition: size.hpp:60
Definition: gettable.hpp:24
Definition for collections::viewable_collection.
slice_view(V &&, const O &, const E &) -> slice_view< V, O, E >
Deduction guides.
constexpr auto end() &
Definition: slice.hpp:139
decltype(auto) constexpr get() &
Get element i.
Definition: slice.hpp:211
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98
constexpr bool index
An object describing a collection of /ref values::index objects.
Definition: index.hpp:77