16 #ifndef OPENKALMAN_COLLECTIONS_VIEWS_SLICE_HPP 17 #define OPENKALMAN_COLLECTIONS_VIEWS_SLICE_HPP 41 #ifdef __cpp_lib_ranges 42 template<collection V, values::index Offset, values::index Extent> requires
43 std::same_as<std::decay_t<Offset>, Offset> and std::same_as<std::decay_t<Extent>, Extent> and
44 (not sized<V> or size_of_v<V> == stdex::dynamic_extent or
45 ((values::dynamic<Offset> or values::fixed_value_of_v<Offset> <= size_of_v<V>) and
46 (values::dynamic<Extent> or values::fixed_value_of_v<Extent> <= size_of_v<V>) and
47 (values::dynamic<Offset> or values::dynamic<Extent> or values::fixed_value_of_v<Offset> + values::fixed_value_of_v<Extent> <= size_of_v<V>)))
49 template<
typename V,
typename Offset,
typename Extent>
59 template<
bool Enable = true, std::enable_if_t<Enable and stdex::default_initializable<V> and
60 stdex::default_initializable<Offset> and stdex::default_initializable<Extent>,
int> = 0>
70 : v_ {v}, offset_ {std::move(offset)}, extent_ {std::move(extent)} {}
75 : v_ {std::move(v)}, offset_ {std::move(offset)}, extent_ {std::move(extent)} {}
81 #ifdef __cpp_explicit_this_parameter 82 constexpr decltype(
auto)
83 base(
this auto&&
self) noexcept {
return std::forward<decltype(self)>(
self).v_; }
85 constexpr V&
base() & {
return this->v_; }
86 constexpr
const V&
base()
const & {
return this->v_; }
87 constexpr V&&
base() && noexcept {
return std::move(*this).v_; }
88 constexpr
const V&&
base()
const && noexcept {
return std::move(*this).v_; }
91 #ifndef __cpp_explicit_this_parameter 94 template<
typename Self>
96 begin_impl(Self&&
self) noexcept
98 return stdex::ranges::begin(std::forward<Self>(
self).v_);
107 #ifdef __cpp_explicit_this_parameter 109 begin(
this auto&&
self) noexcept requires stdex::ranges::range<const V>
111 return stdex::ranges::begin(std::forward<decltype(
self)>(
self).v_) + std::forward<decltype(self)>(
self).offset_;
114 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
115 constexpr
auto begin() & {
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()
const & {
return begin_impl(*
this) + offset_; }
120 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
121 constexpr
auto begin() && noexcept {
return begin_impl(std::move(*
this)) + std::move(*this).offset_; }
123 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
124 constexpr
auto begin()
const && noexcept {
return begin_impl(std::move(*
this)) + std::move(*this).offset_; }
131 #ifdef __cpp_explicit_this_parameter 133 end(
this auto&&
self) noexcept requires stdex::ranges::range<const V>
135 return std::forward<decltype(self)>(
self).
begin() + std::forward<decltype(self)>(
self).extent_;
138 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
139 constexpr
auto end() & {
return this->
begin() + extent_; }
141 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
142 constexpr
auto end()
const & {
return this->
begin() + extent_; }
144 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
145 constexpr
auto end() && noexcept {
return std::move(*this).begin() + std::move(*this).extent_; }
147 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
148 constexpr
auto end()
const && noexcept {
return std::move(*this).begin() + std::move(*this).extent_; }
155 #ifdef __cpp_explicit_this_parameter 157 size(
this auto&&
self) noexcept {
return std::forward<decltype(self)>(
self).extent_; }
160 size() const noexcept {
return extent_; }
167 #ifdef __cpp_explicit_this_parameter 168 template<std::
size_t i>
169 constexpr decltype(
auto)
170 get(
this auto&&
self) noexcept
172 if constexpr (values::fixed<Extent>) static_assert(i < values::fixed_value_of_v<Extent>,
"Index exceeds range");
174 values::operation(std::plus{}, std::forward<decltype(self)>(
self).offset_, std::integral_constant<std::size_t, i>{}));
177 template<std::
size_t i>
178 constexpr decltype(
auto)
181 if constexpr (values::fixed<Extent>) static_assert(i < values::fixed_value_of_v<Extent>,
"Index exceeds range");
183 values::operation(std::plus{}, offset_, std::integral_constant<std::size_t, i>{}));
186 template<std::
size_t i>
187 constexpr decltype(
auto)
190 if constexpr (values::fixed<Extent>) static_assert(i < values::fixed_value_of_v<Extent>,
"Index exceeds range");
192 values::operation(std::plus{}, offset_, std::integral_constant<std::size_t, i>{}));
195 template<std::
size_t i>
196 constexpr decltype(
auto)
199 if constexpr (values::fixed<Extent>) static_assert(i < values::fixed_value_of_v<Extent>,
"Index exceeds range");
201 values::operation(std::plus{}, offset_, std::integral_constant<std::size_t, i>{}));
204 template<std::
size_t i>
205 constexpr decltype(
auto)
206 get()
const && noexcept
208 if constexpr (values::fixed<Extent>) static_assert(i < values::fixed_value_of_v<Extent>,
"Index exceeds range");
226 template<
typename V,
typename O,
typename E>
232 #ifdef __cpp_lib_ranges 233 namespace std::ranges
235 namespace OpenKalman::stdex::ranges
238 template<
typename V,
typename O,
typename E>
239 constexpr
bool enable_borrowed_range<OpenKalman::collections::slice_view<V, O, E>> = enable_borrowed_range<V>;
243 #ifndef __cpp_lib_ranges 246 template<std::
size_t i,
typename V,
typename O,
typename =
void>
249 template<std::
size_t i,
typename V,
typename O>
258 template<
typename V,
typename O,
typename E>
262 #ifdef __cpp_concepts 263 template<
size_t i,
typename V,
typename O,
typename E>
266 template<
size_t i,
typename V, OpenKalman::values::fixed O,
typename E>
270 template<
size_t i,
typename V,
typename O,
typename E>
281 #ifdef __cpp_concepts 282 template<
typename O,
typename E,
typename N>
284 template<
typename O,
typename E,
typename N,
typename =
void>
288 #ifdef __cpp_concepts 289 template<values::fixed O, values::fixed E, values::fixed N>
292 template<typename O, typename E, typename N>
293 struct
slice_is_whole<O, E, N,
std::enable_if_t<values::fixed<O> and values::fixed<E> and values::fixed<N>>>
295 : std::bool_constant<(values::fixed_value_of_v<O> == 0_uz and values::fixed_value_of_v<E> == values::fixed_value_of_v<N>)> {};
299 template<
typename O,
typename E>
302 constexpr
slice_closure(O o, E e) : offset_ {std::move(o)}, extent_ {std::move(e)} {};
304 #ifdef __cpp_concepts 305 template<viewable_collection R>
307 template<
typename R, std::enable_if_t<viewable_collection<R>,
int> = 0>
310 operator() (R&& r)
const 313 return all(std::forward<R>(r));
315 return slice_view {all(std::forward<R>(r)), offset_, extent_};
326 #ifdef __cpp_concepts 327 template<values::index O, values::index E>
329 template<
typename O,
typename E, std::enable_if_t<values::index<O> and values::index<E>,
int> = 0>
332 operator() (O o, E e)
const 338 #ifdef __cpp_concepts 339 template<viewable_collection R, values::index O, values::index E>
341 template<
typename R,
typename O,
typename E, std::enable_if_t<
342 viewable_collection<R> and values::index<O> and values::index<E>,
int> = 0>
344 constexpr decltype(
auto)
345 operator() (R&& r, O o, E e)
const 348 return all(std::forward<R>(r));
350 return slice_view {all(std::forward<R>(r)), std::move(o), std::move(e)};
Definition for values::index.
Namespace for collections.
Definition: collections.hpp:27
Definition for collections::get.
Definition for collections::collection.
constexpr auto size() const noexcept
Definition: slice.hpp:160
Definition of lexicographical_compare_three_way for collections.
constexpr slice_view(const V &v, Offset offset, Extent extent)
Construct from a collection.
Definition: slice.hpp:69
constexpr auto begin() &
Definition: slice.hpp:115
Definition: slice.hpp:286
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 bool value
T is a fixed or dynamic value that is reducible to a number.
Definition: value.hpp:45
Definition: view_interface.hpp:32
constexpr slice_view()
Default constructor.
Definition: slice.hpp:61
slice_view(const V &, const O &, const E &) -> slice_view< V, O, E >
Deduction guide.
Definition: slice.hpp:247
Definition: slice.hpp:324
constexpr V & base() &
The base view.
Definition: slice.hpp:85
Namespace for generalized views.
Definition: collections.hpp:33
constexpr detail::slice_adapter slice
a RangeAdapterObject associated with slice_view.
Definition: slice.hpp:364
Definition: range_adaptor_closure.hpp:34
A view representing a slice of a collection.
Definition: slice.hpp:51
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:300
constexpr bool index
T is an index value.
Definition: index.hpp:62
decltype(auto) constexpr get_element(Arg &&arg, I i)
A generalization of std::get and the range subscript operator.
Definition: get_element.hpp:122
Definition: gettable.hpp:24
Definition for collections::viewable_collection.
constexpr auto end() &
Definition: slice.hpp:139
decltype(auto) constexpr get() &
Get element i.
Definition: slice.hpp:179
constexpr auto get_size(Arg &&arg)
Get the size of a sized object (e.g, a collection)
Definition: get_size.hpp:188
constexpr slice_view(V &&v, Offset offset, Extent extent)
Definition: slice.hpp:74
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98