16 #ifndef OPENKALMAN_COLLECTIONS_VIEWS_FROM_TUPLE_HPP 17 #define OPENKALMAN_COLLECTIONS_VIEWS_FROM_TUPLE_HPP 19 #include <type_traits> 20 #ifdef __cpp_lib_ranges 37 template<
typename D,
typename = std::make_index_sequence<std::tuple_size_v<D>>>
44 using element_type = int;
47 call_table_get(
const D&) noexcept {
return 0; }
49 static constexpr std::array<decltype(call_table_get), 0>
value {};
53 template<
typename D, std::size_t...is>
58 template<std::
size_t i>
59 static constexpr element_type
60 call_table_get(
const D& tup) noexcept {
return OpenKalman::internal::generalized_std_get<i>(tup); }
62 static constexpr std::array
value {call_table_get<is>...};
70 #ifdef __cpp_lib_ranges 71 template<uniform_tuple_like Tup>
72 struct from_tuple : std::ranges::view_interface<from_tuple<Tup>>
74 template<typename Tup>
82 template<
bool Const,
typename T>
83 using maybe_const = std::conditional_t<Const, const T, T>;
96 using Parent = maybe_const<Const, from_tuple>;
101 using iterator_concept = std::random_access_iterator_tag;
102 using iterator_category = std::random_access_iterator_tag;
103 using value_type = maybe_const<Const, typename call_table::element_type>;
104 using difference_type = std::ptrdiff_t;
105 using reference =
typename call_table::element_type&;
106 using pointer = void;
108 constexpr
iterator(Parent& p, std::size_t pos) : parent_ {std::addressof(p)}, current_{
static_cast<difference_type
>(pos)} {}
109 constexpr iterator(
iterator<not Const> it) : parent_ {std::move(it.parent_)}, current_ {std::move(it.current_)} {}
110 constexpr decltype(
auto) operator*() {
return call_table::value[current_](parent_->tup_); }
111 constexpr decltype(
auto) operator*()
const {
return call_table::value[current_](parent_->tup_); }
112 constexpr decltype(
auto) operator[](difference_type offset) {
return call_table::value[current_ + offset](parent_->tup_); }
113 constexpr decltype(
auto) operator[](difference_type offset)
const {
return call_table::value[current_ + offset](parent_->tup_); }
114 constexpr
auto& operator++() { ++current_;
return *
this; }
115 constexpr
auto operator++(
int) {
auto temp = *
this; ++*
this;
return temp; }
116 constexpr
auto& operator--() { --current_;
return *
this; }
117 constexpr
auto operator--(
int) {
auto temp = *
this; --*
this;
return temp; }
118 constexpr
auto& operator+=(
const difference_type diff) { current_ += diff;
return *
this; }
119 constexpr
auto& operator-=(
const difference_type diff) { current_ -= diff;
return *
this; }
120 friend constexpr
auto operator+(
const iterator& it,
const difference_type diff)
121 {
return iterator {*it.parent_,
static_cast<std::size_t
>(it.current_ + diff)}; }
122 friend constexpr
auto operator+(
const difference_type diff,
const iterator& it)
123 {
return iterator {*it.parent_,
static_cast<std::size_t
>(diff + it.current_)}; }
124 friend constexpr
auto operator-(
const iterator& it,
const difference_type diff)
125 {
if (it.current_ < diff)
throw std::out_of_range{
"Iterator out of range"};
return iterator {*it.parent_,
static_cast<std::size_t
>(it.current_ - diff)}; }
126 friend constexpr difference_type operator-(
const iterator& it,
const iterator& other)
127 {
return it.current_ - other.current_; }
128 friend constexpr
bool operator==(
const iterator& it,
const iterator& other)
129 {
return it.current_ == other.current_; }
130 #ifdef __cpp_impl_three_way_comparison 131 constexpr
auto operator<=>(
const iterator& other)
const {
return current_ <=> other.current_; }
133 constexpr
bool operator!=(
const iterator& other)
const {
return current_ != other.current_; }
134 constexpr
bool operator<(
const iterator& other)
const {
return current_ < other.current_; }
135 constexpr
bool operator>(
const iterator& other)
const {
return current_ > other.current_; }
136 constexpr
bool operator<=(
const iterator& other)
const {
return current_ <= other.current_; }
137 constexpr
bool operator>=(
const iterator& other)
const {
return current_ >= other.current_; }
143 difference_type current_;
151 #ifdef __cpp_concepts 155 template<
bool Enable = true, std::enable_if_t<Enable and std::is_default_constructible_v<TupBox>,
int> = 0>
164 #if defined(__cpp_concepts) and defined(__cpp_lib_remove_cvref) 165 template<
typename Arg> requires std::constructible_from<TupBox, Arg&&> and (not std::same_as<std::remove_cvref_t<Arg>,
from_tuple>)
167 template<
typename Arg, std::enable_if_t<
168 std::is_constructible_v<TupBox, Arg&&> and (not std::is_same_v<remove_cvref_t<Arg>,
from_tuple>),
int> = 0>
171 from_tuple(Arg&& arg) noexcept : tup_ {std::forward<Arg>(arg)} {}
177 #ifdef __cpp_explicit_this_parameter 178 constexpr decltype(
auto)
179 base(
this auto&&
self) noexcept {
return std::forward<decltype(self)>(
self).tup_.get(); }
181 constexpr decltype(
auto) base() & {
return this->tup_.get(); }
182 constexpr decltype(
auto) base()
const & {
return this->tup_.get(); }
183 constexpr decltype(
auto) base() && noexcept {
return std::move(*this).tup_.get(); }
184 constexpr decltype(
auto) base()
const && noexcept {
return std::move(*this).tup_.get(); }
195 #ifdef __cpp_lib_ranges 196 namespace ranges = std::ranges;
198 if constexpr (ranges::range<Tup>)
return ranges::begin(base());
205 #ifdef __cpp_lib_ranges 206 namespace ranges = std::ranges;
208 if constexpr (ranges::range<Tup>)
return ranges::begin(base());
220 #ifdef __cpp_lib_ranges 221 namespace ranges = std::ranges;
223 if constexpr (ranges::range<Tup>)
return ranges::end(base());
224 else return iterator<false> {*
this, std::tuple_size_v<std::decay_t<Tup>>};
228 constexpr
auto end()
const 230 #ifdef __cpp_lib_ranges 231 namespace ranges = std::ranges;
233 if constexpr (ranges::range<Tup>)
return ranges::end(base());
234 else return iterator<true> {*
this, std::tuple_size_v<std::decay_t<Tup>>};
241 static constexpr
auto 242 size() {
return std::tuple_size<std::decay_t<Tup>>{}; }
248 static constexpr
auto 251 if constexpr (std::tuple_size_v<std::decay_t<Tup>> == 0)
return std::true_type{};
252 else return std::false_type{};
259 constexpr decltype(
auto)
260 front() {
return OpenKalman::internal::generalized_std_get<0>(base()); }
263 constexpr decltype(
auto)
264 front()
const {
return OpenKalman::internal::generalized_std_get<0>(base()); }
270 constexpr decltype(
auto)
271 back() {
return OpenKalman::internal::generalized_std_get<
size() - 1_uz>(base()); }
274 constexpr decltype(
auto)
275 back()
const {
return OpenKalman::internal::generalized_std_get<
size() - 1_uz>(base()); }
281 #ifdef __cpp_explicit_this_parameter 282 template<
typename Self, values::index I>
283 constexpr decltype(
auto)
284 operator[](
this Self&&
self, I i) noexcept
290 template<
typename I, std::enable_if_t<values::index<I>,
int> = 0>
291 constexpr decltype(
auto)
298 template<
typename I, std::enable_if_t<values::index<I>,
int> = 0>
299 constexpr decltype(
auto)
300 operator[](I i)
const &
306 template<
typename I, std::enable_if_t<values::index<I>,
int> = 0>
307 constexpr decltype(
auto)
308 operator[](I i) && noexcept
314 template<
typename I, std::enable_if_t<values::index<I>,
int> = 0>
315 constexpr decltype(
auto)
316 operator[](I i)
const && noexcept
327 #ifdef __cpp_explicit_this_parameter 328 template<std::
size_t i>
329 constexpr decltype(
auto)
330 get(
this auto&&
self) noexcept
332 static_assert(i <
size(),
"Index out of range");
333 return OpenKalman::internal::generalized_std_get<i>(std::forward<decltype(self)>(
self).base());
336 template<std::
size_t i>
337 constexpr decltype(
auto)
340 static_assert(i <
size(),
"Index out of range");
341 return OpenKalman::internal::generalized_std_get<i>(base());
344 template<std::
size_t i>
345 constexpr decltype(
auto)
348 static_assert(i <
size(),
"Index out of range");
349 return OpenKalman::internal::generalized_std_get<i>(base());
352 template<std::
size_t i>
353 constexpr decltype(
auto)
356 static_assert(i <
size(),
"Index out of range");
357 return OpenKalman::internal::generalized_std_get<i>(std::move(*this).base());
360 template<std::
size_t i>
361 constexpr decltype(
auto)
362 get()
const && noexcept
364 static_assert(i <
size(),
"Index out of range");
365 return OpenKalman::internal::generalized_std_get<i>(std::move(*this).base());
376 template<
typename Tup>
382 #ifdef __cpp_lib_ranges 383 namespace std::ranges
388 template<
typename Tup>
389 constexpr
bool enable_borrowed_range<OpenKalman::collections::from_tuple<Tup>> =
390 std::is_lvalue_reference_v<Tup> or enable_borrowed_range<remove_cvref_t<Tup>>;
396 template<
typename Tup>
397 struct tuple_size<
OpenKalman::collections::from_tuple<Tup>> : tuple_size<decay_t<Tup>> {};
400 template<std::
size_t i,
typename Tup>
401 struct tuple_element<i, OpenKalman::collections::from_tuple<Tup>> : tuple_element<i, decay_t<Tup>> {};
405 #endif //OPENKALMAN_COLLECTIONS_VIEWS_FROM_TUPLE_HPP Definition for values::index.
Namespace for collections.
Definition: collections.hpp:27
typename common_tuple_type< T >::type common_tuple_type_t
Helper template for common_collection_type.
Definition: common_tuple_type.hpp:59
Definition for collections::get.
decltype(auto) constexpr get(Arg &&arg, I i)
A generalization of std::get.
Definition: get.hpp:62
Definition: view_interface.hpp:32
constexpr auto begin()
An iterator to the beginning of the tuple (treated as a std::ranges::range).
Definition: from_tuple.hpp:193
constexpr auto end() const
Definition: from_tuple.hpp:228
Definition: tuple_reverse.hpp:103
constexpr auto end()
An iterator to the end of the tuple (treated as a std::ranges::range).
Definition: from_tuple.hpp:218
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
The root namespace for OpenKalman.
Definition: basics.hpp:34
Iterator for from_tuple.
Definition: from_tuple.hpp:92
Definitions relating to the availability of c++ language features.
Definition: from_tuple.hpp:38
The fixed number associated with a values::fixed.
Definition: fixed_number_of.hpp:45
constexpr bool size
T is either an index representing a size, or void which represents that there is no size...
Definition: size.hpp:32
constexpr from_tuple()
Default constructor.
Definition: from_tuple.hpp:157
A collection_view created from a uniform_tuple_like object.
Definition: from_tuple.hpp:75
constexpr auto begin() const
Definition: from_tuple.hpp:203
Definitions implementing features of the c++ ranges library for compatibility.
constexpr from_tuple(Arg &&arg) noexcept
Construct from a uniform_tuple_like object.
Definition: from_tuple.hpp:171
static constexpr auto size()
The size of the resulting object.
Definition: from_tuple.hpp:242
static constexpr auto empty()
Definition: from_tuple.hpp:249