16 #ifndef OPENKALMAN_PATTERNS_VIEWS_TRANSPOSE_HPP 17 #define OPENKALMAN_PATTERNS_VIEWS_TRANSPOSE_HPP 33 #ifdef __cpp_lib_ranges 34 template<pattern_collection P, std::
size_t indexa = 0, std::
size_t indexb = 1> requires (indexa < indexb)
36 template<
typename P, std::
size_t indexa = 0, std::
size_t indexb = 1>
42 template<
bool Const,
typename T>
43 using maybe_const = std::conditional_t<Const, const T, T>;
53 using iterator_concept = std::random_access_iterator_tag;
54 using iterator_category = std::random_access_iterator_tag;
55 using value_type = stdex::ranges::range_value_t<P>;
56 using reference = stdex::ranges::range_reference_t<P>;
57 using difference_type = std::ptrdiff_t;
62 using Parent = maybe_const<Const, transpose_view>;
68 constexpr
iterator(Parent& parent, difference_type p) : parent_ {std::addressof(parent)}, current_{p} {}
70 constexpr iterator(
iterator<not Const> i) : parent_ {std::move(i.parent_)}, current_ {std::move(i.current_)} {}
72 constexpr decltype(
auto) operator*()
74 return get_pattern(parent_->p_.get(), current_ == indexa ? indexb : current_ == indexb ? indexa : current_);
77 constexpr decltype(
auto) operator*()
const 79 return get_pattern(parent_->p_.get(), current_ == indexa ? indexb : current_ == indexb ? indexa : current_);
82 constexpr decltype(
auto) operator[](difference_type offset)
84 return get_pattern(parent_->p_.get(), (current_ == indexa ? indexb : current_ == indexb ? indexa : current_) + offset);
87 constexpr decltype(
auto) operator[](difference_type offset)
const 89 return get_pattern(parent_->p_.get(), (current_ == indexa ? indexb : current_ == indexb ? indexa : current_) + offset);
92 constexpr
auto& operator++() noexcept { ++current_;
return *
this; }
93 constexpr
auto operator++(
int) noexcept {
auto temp = *
this; ++*
this;
return temp; }
94 constexpr
auto& operator--() noexcept { --current_;
return *
this; }
95 constexpr
auto operator--(
int) noexcept {
auto temp = *
this; --*
this;
return temp; }
96 constexpr
auto& operator+=(
const difference_type diff) noexcept { current_ += diff;
return *
this; }
97 constexpr
auto& operator-=(
const difference_type diff) noexcept { current_ -= diff;
return *
this; }
98 friend constexpr
auto operator+(
const iterator& it,
const difference_type diff) noexcept
99 {
return iterator {*it.parent_, it.current_ + diff}; }
100 friend constexpr
auto operator+(
const difference_type diff,
const iterator& it) noexcept
101 {
return iterator {*it.parent_, diff + it.current_}; }
102 friend constexpr
auto operator-(
const iterator& it,
const difference_type diff)
103 {
return iterator {*it.parent_, it.current_ - diff}; }
104 friend constexpr difference_type operator-(
const iterator& it,
const iterator& other) noexcept
105 {
return it.current_ - other.current_; }
106 friend constexpr
bool operator==(
const iterator& it,
const iterator& other) noexcept
107 {
return it.current_ == other.current_; }
108 #ifdef __cpp_impl_three_way_comparison 109 constexpr
auto operator<=>(
const iterator& other)
const noexcept {
return current_ <=> other.current_; }
111 constexpr
bool operator!=(
const iterator& other)
const noexcept {
return current_ != other.current_; }
112 constexpr
bool operator<(
const iterator& other)
const noexcept {
return current_ < other.current_; }
113 constexpr
bool operator>(
const iterator& other)
const noexcept {
return current_ > other.current_; }
114 constexpr
bool operator<=(
const iterator& other)
const noexcept {
return current_ <= other.current_; }
115 constexpr
bool operator>=(
const iterator& other)
const noexcept {
return current_ >= other.current_; }
121 difference_type current_;
129 #ifdef __cpp_concepts 132 template<
bool Enable = true, std::enable_if_t<Enable and stdex::default_initializable<P>,
int> = 0>
147 #ifdef __cpp_explicit_this_parameter 148 constexpr decltype(
auto)
149 base(
this auto&&
self) noexcept {
return std::forward<decltype(self)>(
self).p_.get(); }
151 constexpr P&
base() & {
return this->p_.get(); }
152 constexpr
const P&
base()
const & {
return this->p_.get(); }
153 constexpr P&&
base() && noexcept {
return std::move(*this).p_.get(); }
154 constexpr
const P&&
base()
const && noexcept {
return std::move(*this).p_.get(); }
161 #ifdef __cpp_concepts 163 begin() requires stdex::ranges::random_access_range<P>
165 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::random_access_range<P>,
int> = 0>
171 #ifdef __cpp_concepts 173 begin()
const requires stdex::ranges::random_access_range<P>
175 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::random_access_range<P>,
int> = 0>
176 constexpr
auto begin()
const 184 #ifdef __cpp_concepts 186 end() requires stdex::ranges::random_access_range<P>
188 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::random_access_range<P>,
int> = 0>
198 #ifdef __cpp_concepts 200 end()
const requires stdex::ranges::random_access_range<P>
202 template<
bool Enable = true, std::enable_if_t<Enable and stdex::ranges::random_access_range<P>,
int> = 0>
214 #ifdef __cpp_concepts 216 size()
const noexcept requires collections::sized<P>
218 template<
bool Enable = true, std::enable_if_t<collections::sized<P>,
int> = 0>
223 struct Max { constexpr
auto operator()(std::size_t a)
const {
return std::max(a, indexb + 1_uz); } };
231 #ifdef __cpp_explicit_this_parameter 232 template<std::
size_t i>
233 constexpr decltype(
auto)
234 get(
this auto&&
self) noexcept
236 constexpr std::size_t ti = i == indexa ? indexb : i == indexb ? indexa : i;
237 return get_pattern<ti>(std::forward<decltype(self)>(
self).p_.get());
240 template<std::
size_t i>
241 constexpr decltype(
auto)
244 constexpr std::size_t ti = i == indexa ? indexb : i == indexb ? indexa : i;
245 return get_pattern<ti>(p_.get());
248 template<std::
size_t i>
249 constexpr decltype(
auto)
252 constexpr std::size_t ti = i == indexa ? indexb : i == indexb ? indexa : i;
253 return get_pattern<ti>(p_.get());
256 template<std::
size_t i>
257 constexpr decltype(
auto)
260 constexpr std::size_t ti = i == indexa ? indexb : i == indexb ? indexa : i;
261 return get_pattern<ti>(std::move(*this).p_.get());
264 template<std::
size_t i>
265 constexpr decltype(
auto)
266 get()
const && noexcept
268 constexpr std::size_t ti = i == indexa ? indexb : i == indexb ? indexa : i;
269 return get_pattern<ti>(std::move(*this).p_.get());
289 #ifdef __cpp_lib_ranges 290 namespace std::ranges
292 namespace OpenKalman::stdex::ranges
295 template<
typename P, std::
size_t indexa, std::
size_t indexb>
296 constexpr
bool enable_borrowed_range<OpenKalman::patterns::transpose_view<P, indexa, indexb>> = enable_borrowed_range<P>;
300 #ifndef __cpp_lib_ranges 303 template<
typename S, std::
size_t indexb,
typename =
void>
306 template<
typename S, std::
size_t indexb>
308 values::fixed_value_compares_with<S, OpenKalman::stdex::dynamic_extent, &stdex::is_neq>>>
309 : std::integral_constant<std::size_t, std::max(values::fixed_value_of_v<S>, indexb + 1_uz)> {};
316 #ifdef __cpp_concepts 317 template<
typename P, std::
size_t indexa, std::
size_t indexb> requires
318 OpenKalman::values::fixed_value_compares_with<OpenKalman::collections::size_of<P>, OpenKalman::stdex::dynamic_extent, &is_neq>
320 : std::integral_constant<std::size_t, max(OpenKalman::collections::size_of_v<P>, indexb + 1)> {};
322 template<
typename P, std::
size_t indexa, std::
size_t indexb>
328 template<
size_t i,
typename P, std::
size_t indexa, std::
size_t indexb>
342 #ifdef __cpp_concepts 343 template<std::
size_t indexa = 0, std::
size_t indexb = 1> requires (indexa < indexb)
345 template<std::
size_t indexa = 0, std::
size_t indexb = 1>
351 #ifdef __cpp_concepts 352 template<pattern_collection R>
354 template<
typename R, std::enable_if_t<pattern_collection<R> and (indexa < indexb),
int> = 0>
357 operator() (R&& r) const
359 if constexpr (values::fixed_value_compares_with<collections::size_of<R>, 0> or
360 compares_with<pattern_collection_element_t<indexa, R>, pattern_collection_element_t<indexb, R>>)
362 if constexpr (collections::viewable_collection<R>) return collections::views::all(std::forward<R>(r));
363 else return std::forward<R>(r);
365 else if constexpr (collections::viewable_collection<R>)
367 using AR = collections::views::all_t<R&&>;
368 return transpose_view<AR, indexa, indexb> {collections::views::all(std::forward<R>(r))};
372 return transpose_view<R, indexa, indexb> {std::forward<R>(r)};
378 #ifdef __cpp_concepts
379 template<std::
size_t indexa = 0, std::
size_t indexb = 1> requires (indexa < indexb)
381 template<std::
size_t indexa = 0, std::
size_t indexb = 1>
392 #ifdef __cpp_concepts 393 template<pattern_collection R>
395 template<
typename R, std::enable_if_t<pattern_collection<R>,
int> = 0>
397 constexpr decltype(
auto)
398 operator() (R&& r)
const 414 #ifdef __cpp_concepts 415 template<std::
size_t indexa = 0, std::
size_t indexb = 1> requires (indexa < indexb)
417 template<std::
size_t indexa = 0, std::
size_t indexb = 1, std::enable_if_t<indexa < indexb,
int> = 0>
419 inline constexpr detail::transpose_adapter<indexa, indexb> transpose;
constexpr transpose_view()
Default constructor.
Definition: transpose.hpp:133
Definition for pattern_collection.
constexpr transpose_view(P &&p)
Construct from a collection.
Definition: transpose.hpp:141
constexpr auto get_size(Arg &&arg)
Get the size of a sized object (e.g, a collection)
Definition: get_size.hpp:224
decltype(auto) constexpr get_pattern(P &&p, I i)
Get a pattern within a pattern_collection.
Definition: get_pattern.hpp:39
The namespace for views for patterns::pattern object.
Definition: patterns.hpp:51
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
Definition for patterns::get_pattern.
Definition: view_interface.hpp:32
The namespace for features relating to patterns::pattern object.
Definition: collection_compares_with.hpp:24
decltype(auto) constexpr get() &
Get element i.
Definition: transpose.hpp:242
constexpr auto begin()
Definition: transpose.hpp:166
Definition: transpose.hpp:347
A view representing a transpose of a pattern_collection.
Definition: transpose.hpp:38
Inclusion file for collections.
Definition: transpose.hpp:304
constexpr auto end()
Definition: transpose.hpp:190
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
Definition: range_adaptor_closure.hpp:34
Iterator for transpose_view.
Definition: transpose.hpp:51
Definition: collection_compares_with.hpp:26
constexpr auto end() const
Definition: transpose.hpp:204
transpose_view(P &&) -> transpose_view< P >
Deduction guides.
constexpr auto size() const noexcept
Definition: transpose.hpp:220
The type of the element at a given index, if it can be determined at compile time.
Definition: pattern_collection_element.hpp:34
Definition: transpose.hpp:383
constexpr P & base() &
The base view.
Definition: transpose.hpp:151
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98