16 #ifndef OPENKALMAN_COLLECTIONS_VIEWS_REPLICATE_HPP 17 #define OPENKALMAN_COLLECTIONS_VIEWS_REPLICATE_HPP 40 #ifdef __cpp_lib_ranges 41 template<collection V, values::index Factor> requires std::same_as<std::decay_t<Factor>, Factor>
43 template<
typename V,
typename Factor>
49 template<
bool Const,
typename T>
50 using maybe_const = std::conditional_t<Const, const T, T>;
60 using iterator_concept = std::random_access_iterator_tag;
61 using iterator_category = std::random_access_iterator_tag;
62 using value_type = stdex::ranges::range_value_t<V>;
63 using reference = stdex::ranges::range_reference_t<V>;
64 using difference_type = std::ptrdiff_t;
69 using Parent = maybe_const<Const, replicate_view>;
71 constexpr decltype(
auto)
72 get_parent_elem(difference_type ix)
75 else return get_element(parent_->v_, static_cast<std::size_t>(std::move(ix)));
78 constexpr decltype(
auto)
79 get_parent_elem(difference_type ix)
const 82 else return get_element(parent_->v_, static_cast<std::size_t>(std::move(ix)));
89 constexpr
iterator(Parent& parent, difference_type p) : parent_ {std::addressof(parent)}, current_{p} {}
91 constexpr iterator(
iterator<not Const> i) : parent_ {std::move(i.parent_)}, current_ {std::move(i.current_)} {}
93 constexpr decltype(
auto) operator*() {
return get_parent_elem(current_ %
get_size(parent_->v_)); }
94 constexpr decltype(
auto) operator*()
const {
return get_parent_elem(current_ %
get_size(parent_->v_)); }
95 constexpr decltype(
auto) operator[](difference_type offset) {
return get_parent_elem((current_ + offset) %
get_size(parent_->v_)); }
96 constexpr decltype(
auto) operator[](difference_type offset)
const {
return get_parent_elem((current_ + offset) %
get_size(parent_->v_)); }
98 constexpr
auto& operator++() noexcept { ++current_;
return *
this; }
99 constexpr
auto operator++(
int) noexcept {
auto temp = *
this; ++*
this;
return temp; }
100 constexpr
auto& operator--() noexcept { --current_;
return *
this; }
101 constexpr
auto operator--(
int) noexcept {
auto temp = *
this; --*
this;
return temp; }
102 constexpr
auto& operator+=(
const difference_type diff) noexcept { current_ += diff;
return *
this; }
103 constexpr
auto& operator-=(
const difference_type diff) noexcept { current_ -= diff;
return *
this; }
104 friend constexpr
auto operator+(
const iterator& it,
const difference_type diff) noexcept
105 {
return iterator {*it.parent_, it.current_ + diff}; }
106 friend constexpr
auto operator+(
const difference_type diff,
const iterator& it) noexcept
107 {
return iterator {*it.parent_, diff + it.current_}; }
108 friend constexpr
auto operator-(
const iterator& it,
const difference_type diff)
109 {
return iterator {*it.parent_, it.current_ - diff}; }
110 friend constexpr difference_type operator-(
const iterator& it,
const iterator& other) noexcept
111 {
return it.current_ - other.current_; }
112 friend constexpr
bool operator==(
const iterator& it,
const iterator& other) noexcept
113 {
return it.current_ == other.current_; }
114 #ifdef __cpp_impl_three_way_comparison 115 constexpr
auto operator<=>(
const iterator& other)
const noexcept {
return current_ <=> other.current_; }
117 constexpr
bool 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_; }
127 difference_type current_;
135 #ifdef __cpp_concepts 139 template<
bool Enable =
true, std::enable_if_t<Enable and
140 stdex::default_initializable<V> and stdex::default_initializable<Factor>,
int> = 0>
161 #ifdef __cpp_explicit_this_parameter 162 constexpr decltype(
auto)
163 base(
this auto&&
self) noexcept {
return std::forward<decltype(self)>(
self).v_; }
165 constexpr V&
base() & {
return this->v_; }
166 constexpr
const V&
base()
const & {
return this->v_; }
167 constexpr V&&
base() && noexcept {
return std::move(*this).v_; }
168 constexpr
const V&&
base()
const && noexcept {
return std::move(*this).v_; }
175 #ifdef __cpp_concepts 177 begin() requires stdex::ranges::range<const V>
179 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
185 #ifdef __cpp_concepts 187 begin()
const requires stdex::ranges::range<const V>
189 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
190 constexpr
auto begin()
const 198 #ifdef __cpp_concepts 200 end() requires stdex::ranges::range<const V>
202 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
212 #ifdef __cpp_concepts 214 end()
const requires stdex::ranges::range<const V>
216 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::range<const V>,
int> = 0>
228 #ifdef __cpp_concepts 241 #ifdef __cpp_explicit_this_parameter 242 template<std::
size_t i>
243 constexpr decltype(
auto)
244 get(
this auto&&
self) noexcept
246 if constexpr (size_of_v<V> != stdex::dynamic_extent and values::fixed<Factor>)
247 static_assert(i < size_of_v<V> * values::fixed_value_of_v<Factor>,
"Index out of range");
252 template<std::
size_t i>
253 constexpr decltype(
auto)
256 if constexpr (size_of_v<V> != stdex::dynamic_extent and values::fixed<Factor>)
257 static_assert(i < size_of_v<V> * values::fixed_value_of_v<Factor>,
"Index out of range");
262 template<std::
size_t i>
263 constexpr decltype(
auto)
266 if constexpr (size_of_v<V> != stdex::dynamic_extent and values::fixed<Factor>)
267 static_assert(i < size_of_v<V> * values::fixed_value_of_v<Factor>,
"Index out of range");
272 template<std::
size_t i>
273 constexpr decltype(
auto)
276 if constexpr (size_of_v<V> != stdex::dynamic_extent and values::fixed<Factor>)
277 static_assert(i < size_of_v<V> * values::fixed_value_of_v<Factor>,
"Index out of range");
282 template<std::
size_t i>
283 constexpr decltype(
auto)
284 get()
const && noexcept
286 if constexpr (size_of_v<V> != stdex::dynamic_extent and values::fixed<Factor>)
287 static_assert(i < size_of_v<V> * values::fixed_value_of_v<Factor>,
"Index out of range");
303 template<
typename V,
typename F>
310 #ifdef __cpp_lib_ranges 311 namespace std::ranges
313 namespace OpenKalman::stdex::ranges
316 template<
typename V,
typename F>
317 constexpr
bool enable_borrowed_range<OpenKalman::collections::replicate_view<V, F>> = enable_borrowed_range<V>;
321 #ifndef __cpp_lib_ranges 324 template<
typename V,
typename F,
typename =
void>
327 template<
typename V,
typename F>
329 : std::integral_constant<std::size_t, size_of_v<V> * values::fixed_value_of_v<F>> {};
332 template<std::
size_t i,
typename V,
typename =
void>
335 using type = stdex::ranges::range_value_t<V>;
338 template<std::
size_t i,
typename V>
348 #ifdef __cpp_lib_ranges 349 template<
typename V, OpenKalman::values::fixed F> requires (OpenKalman::collections::size_of_v<V> != OpenKalman::stdex::dynamic_extent)
351 : integral_constant<std::size_t, OpenKalman::collections::size_of_v<V> * OpenKalman::values::fixed_value_of_v<F>> {};
353 template<
typename V,
typename F>
359 #ifdef __cpp_lib_ranges 360 template<
size_t i,
typename V,
typename F> requires (OpenKalman::collections::size_of_v<V> != OpenKalman::stdex::dynamic_extent)
362 : tuple_element<i % OpenKalman::collections::size_of_v<V>, decay_t<V>> {};
364 template<
size_t i,
typename V,
typename F> requires (OpenKalman::collections::size_of_v<V> == OpenKalman::stdex::dynamic_extent)
367 using type = OpenKalman::stdex::ranges::range_value_t<V>;
370 template<
size_t i,
typename V,
typename F>
382 template<
typename Factor>
387 #ifdef __cpp_concepts 388 template<collection R>
390 template<
typename R, std::enable_if_t<collection<R>,
int> = 0>
393 operator() (R&& r)
const 395 if constexpr (viewable_collection<R>)
409 #ifdef __cpp_concepts 410 template<values::index Factor>
412 template<
typename Factor, std::enable_if_t<values::index<Factor>,
int> = 0>
415 operator() (Factor factor)
const 421 #ifdef __cpp_concepts 422 template<collection R, values::index Factor>
424 template<
typename R,
typename Factor, std::enable_if_t<collection<R> and values::index<Factor>,
int> = 0>
427 operator() (R&& r, Factor factor)
const 429 if constexpr (viewable_collection<R>)
430 return replicate_view {all(std::forward<R>(r)), std::move(factor)};
constexpr auto begin()
Definition: replicate.hpp:180
Namespace for collections.
Definition: collections.hpp:27
Definition for collections::collection.
constexpr replicate_view()
Default constructor.
Definition: replicate.hpp:142
constexpr auto end()
Definition: replicate.hpp:204
constexpr replicate_view(V &v, Factor f)
Construct from a collection.
Definition: replicate.hpp:150
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)
Iterator for replicate_view.
Definition: replicate.hpp:58
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:165
constexpr replicate_view(V &&v, Factor f)
Definition: replicate.hpp:155
Definition: replicate.hpp:325
Definition: view_interface.hpp:32
Definition for collections::get_size.
Definition for collections::get_element.
constexpr detail::replicate_adaptor replicate
a std::ranges::range_adaptor_closure for a set of replicated pattern objects.
Definition: replicate.hpp:86
A view that replicates a collection some number of times.
Definition: replicate.hpp:45
decltype(auto) constexpr get() &
Get element i.
Definition: replicate.hpp:254
constexpr auto size() const
Definition: replicate.hpp:231
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:218
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:124
Definition: replicate.hpp:333
Definition: replicate.hpp:383
Definition: gettable.hpp:24
Definition: replicate.hpp:407
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