16 #ifndef OPENKALMAN_COLLECTIONS_VIEWS_REPLICATE_HPP 17 #define OPENKALMAN_COLLECTIONS_VIEWS_REPLICATE_HPP 41 #ifdef __cpp_lib_ranges 42 template<collection V, values::index Factor> requires std::same_as<std::decay_t<Factor>, Factor>
44 template<
typename V,
typename Factor>
50 template<
bool Const,
typename T>
51 using maybe_const = std::conditional_t<Const, const T, T>;
61 using iterator_concept = std::random_access_iterator_tag;
62 using iterator_category = std::random_access_iterator_tag;
63 using value_type = stdex::ranges::range_value_t<V>;
64 using reference = stdex::ranges::range_reference_t<V>;
65 using difference_type = std::ptrdiff_t;
70 using Parent = maybe_const<Const, replicate_view>;
72 constexpr decltype(
auto)
73 get_parent_elem(difference_type ix)
76 else return get_element(parent_->v_, static_cast<std::size_t>(std::move(ix)));
79 constexpr decltype(
auto)
80 get_parent_elem(difference_type ix)
const 83 else return get_element(parent_->v_, static_cast<std::size_t>(std::move(ix)));
90 constexpr
iterator(Parent& parent, difference_type p) : parent_ {std::addressof(parent)}, current_{p} {}
92 constexpr iterator(
iterator<not Const> i) : parent_ {std::move(i.parent_)}, current_ {std::move(i.current_)} {}
94 constexpr decltype(
auto) operator*() {
return get_parent_elem(current_ %
get_size(parent_->v_)); }
95 constexpr decltype(
auto) operator*()
const {
return get_parent_elem(current_ %
get_size(parent_->v_)); }
96 constexpr decltype(
auto) operator[](difference_type offset) {
return get_parent_elem((current_ + offset) %
get_size(parent_->v_)); }
97 constexpr decltype(
auto) operator[](difference_type offset)
const {
return get_parent_elem((current_ + offset) %
get_size(parent_->v_)); }
99 constexpr
auto& operator++() noexcept { ++current_;
return *
this; }
100 constexpr
auto operator++(
int) noexcept {
auto temp = *
this; ++*
this;
return temp; }
101 constexpr
auto& operator--() noexcept { --current_;
return *
this; }
102 constexpr
auto operator--(
int) noexcept {
auto temp = *
this; --*
this;
return temp; }
103 constexpr
auto& operator+=(
const difference_type diff) noexcept { current_ += diff;
return *
this; }
104 constexpr
auto& operator-=(
const difference_type diff) noexcept { current_ -= diff;
return *
this; }
105 friend constexpr
auto operator+(
const iterator& it,
const difference_type diff) noexcept
106 {
return iterator {*it.parent_, it.current_ + diff}; }
107 friend constexpr
auto operator+(
const difference_type diff,
const iterator& it) noexcept
108 {
return iterator {*it.parent_, diff + it.current_}; }
109 friend constexpr
auto operator-(
const iterator& it,
const difference_type diff)
110 {
return iterator {*it.parent_, it.current_ - diff}; }
111 friend constexpr difference_type operator-(
const iterator& it,
const iterator& other) noexcept
112 {
return it.current_ - other.current_; }
113 friend constexpr
bool operator==(
const iterator& it,
const iterator& other) noexcept
114 {
return it.current_ == other.current_; }
115 #ifdef __cpp_impl_three_way_comparison 116 constexpr
auto operator<=>(
const iterator& other)
const noexcept {
return current_ <=> other.current_; }
118 constexpr
bool operator!=(
const iterator& other)
const noexcept {
return current_ != other.current_; }
119 constexpr
bool operator<(
const iterator& other)
const noexcept {
return current_ < other.current_; }
120 constexpr
bool operator>(
const iterator& other)
const noexcept {
return current_ > other.current_; }
121 constexpr
bool operator<=(
const iterator& other)
const noexcept {
return current_ <= other.current_; }
122 constexpr
bool operator>=(
const iterator& other)
const noexcept {
return current_ >= other.current_; }
128 difference_type current_;
136 #ifdef __cpp_concepts 140 template<
bool Enable =
true, std::enable_if_t<Enable and
141 stdex::default_initializable<V> and stdex::default_initializable<Factor>,
int> = 0>
162 #ifdef __cpp_explicit_this_parameter 163 constexpr decltype(
auto)
164 base(
this auto&&
self) noexcept {
return std::forward<decltype(self)>(
self).v_; }
166 constexpr V&
base() & {
return this->v_; }
167 constexpr
const V&
base()
const & {
return this->v_; }
168 constexpr V&&
base() && noexcept {
return std::move(*this).v_; }
169 constexpr
const V&&
base()
const && noexcept {
return std::move(*this).v_; }
176 #ifdef __cpp_concepts 178 begin() requires stdex::ranges::range<const V>
180 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
186 #ifdef __cpp_concepts 188 begin()
const requires stdex::ranges::range<const V>
190 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
191 constexpr
auto begin()
const 199 #ifdef __cpp_concepts 201 end() requires stdex::ranges::range<const V>
203 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
213 #ifdef __cpp_concepts 215 end()
const requires stdex::ranges::range<const V>
217 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
229 #ifdef __cpp_concepts 242 #ifdef __cpp_explicit_this_parameter 243 template<std::
size_t i>
244 constexpr decltype(
auto)
245 get(
this auto&&
self) noexcept
247 if constexpr (size_of_v<V> != stdex::dynamic_extent and values::fixed<Factor>)
248 static_assert(i < size_of_v<V> * values::fixed_value_of_v<Factor>,
"Index out of range");
253 template<std::
size_t i>
254 constexpr decltype(
auto)
257 if constexpr (size_of_v<V> != stdex::dynamic_extent and values::fixed<Factor>)
258 static_assert(i < size_of_v<V> * values::fixed_value_of_v<Factor>,
"Index out of range");
263 template<std::
size_t i>
264 constexpr decltype(
auto)
267 if constexpr (size_of_v<V> != stdex::dynamic_extent and values::fixed<Factor>)
268 static_assert(i < size_of_v<V> * values::fixed_value_of_v<Factor>,
"Index out of range");
273 template<std::
size_t i>
274 constexpr decltype(
auto)
277 if constexpr (size_of_v<V> != stdex::dynamic_extent and values::fixed<Factor>)
278 static_assert(i < size_of_v<V> * values::fixed_value_of_v<Factor>,
"Index out of range");
283 template<std::
size_t i>
284 constexpr decltype(
auto)
285 get()
const && noexcept
287 if constexpr (size_of_v<V> != stdex::dynamic_extent and values::fixed<Factor>)
288 static_assert(i < size_of_v<V> * values::fixed_value_of_v<Factor>,
"Index out of range");
304 template<
typename V,
typename F>
311 #ifdef __cpp_lib_ranges 312 namespace std::ranges
314 namespace OpenKalman::stdex::ranges
317 template<
typename V,
typename F>
318 constexpr
bool enable_borrowed_range<OpenKalman::collections::replicate_view<V, F>> = enable_borrowed_range<V>;
322 #ifndef __cpp_lib_ranges 325 template<
typename V,
typename F,
typename =
void>
328 template<
typename V,
typename F>
330 : std::integral_constant<std::size_t, size_of_v<V> * values::fixed_value_of_v<F>> {};
333 template<std::
size_t i,
typename V,
typename =
void>
336 using type = stdex::ranges::range_value_t<V>;
339 template<std::
size_t i,
typename V>
349 #ifdef __cpp_lib_ranges 350 template<
typename V, OpenKalman::values::fixed F> requires (OpenKalman::collections::size_of_v<V> != OpenKalman::stdex::dynamic_extent)
352 : integral_constant<std::size_t, OpenKalman::collections::size_of_v<V> * OpenKalman::values::fixed_value_of_v<F>> {};
354 template<
typename V,
typename F>
360 #ifdef __cpp_lib_ranges 361 template<
size_t i,
typename V,
typename F> requires (OpenKalman::collections::size_of_v<V> != OpenKalman::stdex::dynamic_extent)
363 : tuple_element<i % OpenKalman::collections::size_of_v<V>, decay_t<V>> {};
365 template<
size_t i,
typename V,
typename F> requires (OpenKalman::collections::size_of_v<V> == OpenKalman::stdex::dynamic_extent)
368 using type = OpenKalman::stdex::ranges::range_value_t<V>;
371 template<
size_t i,
typename V,
typename F>
383 template<
typename Factor>
388 #ifdef __cpp_concepts 389 template<viewable_collection R>
391 template<
typename R, std::enable_if_t<viewable_collection<R>,
int> = 0>
394 operator() (R&& r)
const 406 #ifdef __cpp_concepts 407 template<values::index Factor>
409 template<
typename Factor, std::enable_if_t<values::index<Factor>,
int> = 0>
412 operator() (Factor factor)
const 418 #ifdef __cpp_concepts 419 template<viewable_collection R, values::index Factor>
421 template<
typename R,
typename Factor, std::enable_if_t<viewable_collection<R> and values::index<Factor>,
int> = 0>
424 operator() (R&& r, Factor factor)
const 426 return replicate_view {all(std::forward<R>(r)), std::move(factor)};
constexpr auto begin()
Definition: replicate.hpp:181
Namespace for collections.
Definition: collections.hpp:27
Definition for collections::get.
Definition for collections::collection.
constexpr detail::replicate_adaptor replicate
a std::ranges::range_adaptor_closure for a set of replicated pattern objects.
Definition: replicate.hpp:86
constexpr replicate_view()
Default constructor.
Definition: replicate.hpp:143
constexpr auto end()
Definition: replicate.hpp:205
constexpr replicate_view(V &v, Factor f)
Construct from a collection.
Definition: replicate.hpp:151
Definition of lexicographical_compare_three_way for collections.
Header file for code relating to values (e.g., scalars and indices)
Iterator for replicate_view.
Definition: replicate.hpp:59
decltype(auto) constexpr to_value_type(Arg &&arg)
Convert, if necessary, a fixed or dynamic value to its underlying base type.
Definition: to_value_type.hpp:28
The size of a sized object (including a collection).
Definition: size_of.hpp:33
constexpr V & base() &
The base view.
Definition: replicate.hpp:166
constexpr replicate_view(V &&v, Factor f)
Definition: replicate.hpp:156
Definition: replicate.hpp:326
Definition: view_interface.hpp:32
Definition for collections::get_size.
A view that replicates a collection some number of times.
Definition: replicate.hpp:46
decltype(auto) constexpr get() &
Get element i.
Definition: replicate.hpp:255
constexpr auto size() const
Definition: replicate.hpp:232
Namespace for generalized views.
Definition: collections.hpp:33
Definition: range_adaptor_closure.hpp:34
The type of the element at a given index, if it can be determined at compile time.
Definition: collection_element.hpp:48
constexpr auto end() const
Definition: replicate.hpp:219
constexpr bool fixed_value_compares_with
T has a fixed value that compares with N in a particular way based on parameter comp.
Definition: fixed_value_compares_with.hpp:74
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: replicate.hpp:334
Definition: replicate.hpp:384
Definition: gettable.hpp:24
Definition: replicate.hpp:404
constexpr auto get_size(Arg &&arg)
Get the size of a sized object (e.g, a collection)
Definition: get_size.hpp:188
replicate_view(const V &, const F &) -> replicate_view< V, F >
Deduction guide.
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98