16 #ifndef OPENKALMAN_COLLECTIONS_VIEWS_REPLICATE_HPP 17 #define OPENKALMAN_COLLECTIONS_VIEWS_REPLICATE_HPP 19 #include <type_traits> 20 #ifdef __cpp_lib_ranges 50 #ifdef __cpp_lib_ranges 51 template<collection V, values::index Factor> requires std::same_as<std::decay_t<Factor>, Factor>
52 struct replicate_view : std::ranges::view_interface<replicate_view<V, Factor>>
54 template<typename V, typename Factor>
60 template<
bool Const,
typename T>
61 using maybe_const = std::conditional_t<Const, const T, T>;
73 using Parent = maybe_const<Const, replicate_view>;
77 using iterator_concept = std::random_access_iterator_tag;
78 using iterator_category = std::random_access_iterator_tag;
79 #ifdef __cpp_lib_ranges 80 using value_type = std::ranges::range_value_t<V>;
81 using reference = std::ranges::range_reference_t<V>;
83 using value_type = ranges::range_value_t<V>;
84 using reference = ranges::range_reference_t<V>;
86 using difference_type = std::ptrdiff_t;
91 constexpr
iterator(Parent& parent, difference_type p) : parent_ {std::addressof(parent)}, current_{p} {}
93 constexpr iterator(
iterator<not Const> i) : parent_ {std::move(i.parent_)}, current_ {std::move(i.current_)} {}
96 constexpr decltype(
auto) operator*()
const {
return collections::get(parent_->v_, current_ %
get_size(parent_->v_)); }
97 constexpr decltype(
auto) operator[](difference_type offset) {
return collections::get(parent_->v_, (current_ + offset) %
get_size(parent_->v_)); }
98 constexpr decltype(
auto) operator[](difference_type offset)
const {
return collections::get(parent_->v_, (current_ + offset) %
get_size(parent_->v_)); }
100 constexpr
auto& operator++() noexcept { ++current_;
return *
this; }
101 constexpr
auto operator++(
int) noexcept {
auto temp = *
this; ++*
this;
return temp; }
102 constexpr
auto& operator--() noexcept { --current_;
return *
this; }
103 constexpr
auto operator--(
int) noexcept {
auto temp = *
this; --*
this;
return temp; }
104 constexpr
auto& operator+=(
const difference_type diff) noexcept { current_ += diff;
return *
this; }
105 constexpr
auto& operator-=(
const difference_type diff) noexcept { current_ -= diff;
return *
this; }
106 friend constexpr
auto operator+(
const iterator& it,
const difference_type diff) noexcept
107 {
return iterator {*it.parent_, it.current_ + diff}; }
108 friend constexpr
auto operator+(
const difference_type diff,
const iterator& it) noexcept
109 {
return iterator {*it.parent_, diff + it.current_}; }
110 friend constexpr
auto operator-(
const iterator& it,
const difference_type diff)
111 {
return iterator {*it.parent_, it.current_ - diff}; }
112 friend constexpr difference_type operator-(
const iterator& it,
const iterator& other) noexcept
113 {
return it.current_ - other.current_; }
114 friend constexpr
bool operator==(
const iterator& it,
const iterator& other) noexcept
115 {
return it.current_ == other.current_; }
116 #ifdef __cpp_impl_three_way_comparison 117 constexpr
auto 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_; }
123 constexpr
bool operator>=(
const iterator& other)
const noexcept {
return current_ >= other.current_; }
129 difference_type current_;
137 #ifdef __cpp_concepts 141 template<
bool Enable =
true, std::enable_if_t<Enable and
142 std::is_default_constructible_v<V> and std::is_default_constructible_v<Factor>,
int> = 0>
163 #ifdef __cpp_explicit_this_parameter 164 constexpr decltype(
auto)
165 base(
this auto&&
self) noexcept {
return std::forward<decltype(self)>(
self).v_; }
167 constexpr V&
base() & {
return this->v_; }
168 constexpr
const V&
base()
const & {
return this->v_; }
169 constexpr V&&
base() && noexcept {
return std::move(*this).v_; }
170 constexpr
const V&&
base()
const && noexcept {
return std::move(*this).v_; }
180 #ifdef __cpp_lib_ranges 182 begin()
const requires std::ranges::range<const V>
184 template<
bool Enable = true, std::enable_if_t<Enable and ranges::range<const V>,
int> = 0>
185 constexpr
auto begin()
const 198 #ifdef __cpp_lib_ranges 200 end()
const requires std::ranges::range<const V>
202 template<
bool Enable = true, std::enable_if_t<Enable and ranges::range<const V>,
int> = 0>
214 #ifdef __cpp_concepts 227 #ifdef __cpp_explicit_this_parameter 228 template<std::
size_t i>
229 constexpr decltype(
auto)
230 get(
this auto&&
self) noexcept
232 if constexpr (size_of_v<V> !=
dynamic_size and values::fixed<Factor>)
233 static_assert(i < size_of_v<V> * values::fixed_number_of_v<Factor>,
"Index out of range");
238 template<std::
size_t i>
239 constexpr decltype(
auto)
242 if constexpr (size_of_v<V> !=
dynamic_size and values::fixed<Factor>)
243 static_assert(i < size_of_v<V> * values::fixed_number_of_v<Factor>,
"Index out of range");
248 template<std::
size_t i>
249 constexpr decltype(
auto)
252 if constexpr (size_of_v<V> !=
dynamic_size and values::fixed<Factor>)
253 static_assert(i < size_of_v<V> * values::fixed_number_of_v<Factor>,
"Index out of range");
258 template<std::
size_t i>
259 constexpr decltype(
auto)
262 if constexpr (size_of_v<V> !=
dynamic_size and values::fixed<Factor>)
263 static_assert(i < size_of_v<V> * values::fixed_number_of_v<Factor>,
"Index out of range");
268 template<std::
size_t i>
269 constexpr decltype(
auto)
270 get()
const && noexcept
272 if constexpr (size_of_v<V> !=
dynamic_size and values::fixed<Factor>)
273 static_assert(i < size_of_v<V> * values::fixed_number_of_v<Factor>,
"Index out of range");
289 template<
typename V,
typename F>
296 #ifdef __cpp_lib_ranges 297 namespace std::ranges
302 template<
typename V,
typename F>
303 constexpr
bool enable_borrowed_range<OpenKalman::collections::replicate_view<V, F>> = enable_borrowed_range<V>;
307 #ifndef __cpp_lib_ranges 310 template<
typename V,
typename F,
typename =
void>
313 template<
typename V,
typename F>
315 : std::integral_constant<std::size_t, size_of_v<V> * values::fixed_number_of_v<F>> {};
318 template<std::
size_t i,
typename V,
typename =
void>
321 using type = ranges::range_value_t<V>;
324 template<std::
size_t i,
typename V>
326 : std::tuple_element<i % size_of_v<V>, std::decay_t<V>> {};
334 #ifdef __cpp_lib_ranges 335 template<
typename V, OpenKalman::values::fixed F> requires (OpenKalman::collections::size_of_v<V> !=
OpenKalman::dynamic_size)
337 : integral_constant<std::size_t, std::tuple_size_v<std::decay_t<V>> * OpenKalman::values::fixed_number_of_v<F>> {};
339 template<
typename V,
typename F>
345 #ifdef __cpp_lib_ranges 346 template<
size_t i,
typename V,
typename F> requires (OpenKalman::collections::size_of_v<V> !=
OpenKalman::dynamic_size)
348 : tuple_element<i % OpenKalman::collections::size_of_v<V>, decay_t<V>> {};
350 template<
size_t i,
typename V,
typename F> requires (OpenKalman::collections::size_of_v<V> ==
OpenKalman::dynamic_size)
353 using type = ranges::range_value_t<V>;
356 template<
size_t i,
typename V,
typename F>
368 template<
typename Factor>
370 #if __cpp_lib_ranges >= 202202L
371 : std::ranges::range_adaptor_closure<replicate_closure<Factor>>
378 #ifdef __cpp_concepts 379 template<viewable_collection R>
381 template<
typename R, std::enable_if_t<viewable_collection<R>,
int> = 0>
384 operator() (R&& r)
const 396 #ifdef __cpp_concepts 397 template<values::index Factor>
399 template<
typename Factor, std::enable_if_t<values::index<Factor>,
int> = 0>
402 operator() (Factor factor)
const 408 #ifdef __cpp_concepts 409 template<viewable_collection R, values::index Factor>
411 template<
typename R,
typename Factor, std::enable_if_t<viewable_collection<R> and values::index<Factor>,
int> = 0>
414 operator() (R&& r, Factor factor)
const 416 return replicate_view {all(std::forward<R>(r)), std::move(factor)};
435 #endif //OPENKALMAN_COLLECTIONS_VIEWS_REPLICATE_HPP constexpr auto end() const noexcept
Definition: replicate.hpp:204
Definition for values::index.
Namespace for collections.
Definition: collections.hpp:27
Definition for collections::get.
Definition for collections::collection.
constexpr replicate_view()
Default constructor.
Definition: replicate.hpp:144
constexpr replicate_view(V &v, Factor f)
Construct from a collection.
Definition: replicate.hpp:152
decltype(auto) constexpr get(Arg &&arg, I i)
A generalization of std::get.
Definition: get.hpp:62
An operation involving some number of values.
Definition: operation.hpp:69
Definition: view_interface.hpp:32
Iterator for replicate_view.
Definition: replicate.hpp:69
Definition: tuple_reverse.hpp:103
constexpr V & base() &
The base view.
Definition: replicate.hpp:167
constexpr replicate_view(V &&v, Factor f)
Definition: replicate.hpp:157
Definition: replicate.hpp:311
constexpr auto end()
Definition: replicate.hpp:194
constexpr auto to_number(Arg arg)
Convert any values::value to a values::number.
Definition: to_number.hpp:34
constexpr detail::replicate_adaptor replicate
a std::ranges::range_adaptor_closure associated with replicate_view.
Definition: replicate.hpp:430
Definition for collections::get_size.
The root namespace for OpenKalman.
Definition: basics.hpp:34
Definitions relating to the availability of c++ language features.
A view that replicates a collection some number of times.
Definition: replicate.hpp:55
decltype(auto) constexpr get() &
Get element i.
Definition: replicate.hpp:240
constexpr auto size() const
Definition: replicate.hpp:217
Definition: range_adaptor_closure.hpp:35
Namespace for generalized views.
Definition: collections.hpp:33
Definitions implementing features of the c++ ranges library for compatibility.
constexpr bool index
T is an index value.
Definition: index.hpp:56
Definition: replicate.hpp:319
Definition: replicate.hpp:369
Definition: gettable.hpp:27
constexpr std::size_t dynamic_size
A constant indicating that a size or index is dynamic.
Definition: global-definitions.hpp:33
Definition: replicate.hpp:394
constexpr auto begin()
Definition: replicate.hpp:178
constexpr auto get_size(Arg &&arg)
Get the size of a sized object (e.g, a collection)
Definition: get_size.hpp:191
replicate_view(const V &, const F &) -> replicate_view< V, F >
Deduction guide.