16 #ifndef OPENKALMAN_COLLECTIONS_VIEWS_TO_TUPLE_HPP 17 #define OPENKALMAN_COLLECTIONS_VIEWS_TO_TUPLE_HPP 19 #include <type_traits> 20 #ifdef __cpp_lib_ranges 36 namespace detail_to_tuple
39 #ifdef __cpp_lib_ranges 40 namespace ranges = std::ranges;
45 template<std::
size_t i,
typename T>
47 template<std::
size_t i,
typename T,
typename =
void>
51 using type = ranges::range_value_t<T>;
53 template<
typename R> constexpr decltype(
auto) operator() (R&& r)
const 54 {
return collections::get(std::forward<R>(r), std::integral_constant<std::size_t, i>{}); }
59 template<std::
size_t i,
typename T> requires gettable<i, T>
62 template<std::size_t i, typename T>
65 : std::tuple_element<i, T>
67 using type = std::tuple_element_t<i, T>;
69 template<
typename R> constexpr decltype(
auto) operator() (R&& r)
const 70 {
return OpenKalman::internal::generalized_std_get<i>(std::forward<R>(r)); }
75 template<std::
size_t i,
typename T>
77 template<std::
size_t i,
typename T,
typename =
void>
82 template<std::
size_t i,
typename R>
83 inline constexpr decltype(
auto)
91 template<
typename U> constexpr decltype(
auto) operator() (U&& u)
const {
return *std::forward<U>(u).data(); }
95 template<std::
size_t i,
typename R>
98 template<
typename T> constexpr decltype(
auto) operator() (T&& t)
const {
return get_from_base<i>(std::forward<T>(t).base()); }
102 template<std::
size_t i,
typename R>
105 template<
typename T> constexpr decltype(
auto) operator() (T&& t)
const {
return get_from_base<i>(std::forward<T>(t).base()); }
109 #ifdef __cpp_concepts 110 template<std::
size_t i,
typename V> requires (size_of_v<V> !=
dynamic_size)
111 struct get_elem<i, ranges::reverse_view<V>>
113 template<std::size_t i, typename V>
114 struct
get_elem<i, ranges::reverse_view<V>, std::enable_if_t<size_of_v<V> != dynamic_size>>
116 :
get_elem<size_of_v<V> - i - 1_uz, remove_cvref_t<V>>
118 template<
typename T> constexpr decltype(
auto) operator() (T&& t)
const 120 if constexpr (not std::is_lvalue_reference_v<T> or std::is_copy_constructible_v<V>)
121 return get_from_base<size_of_v<V> - i - 1_uz>(std::forward<T>(t).base());
123 return collections::get(std::forward<T>(t), std::integral_constant<std::size_t, i>{});
134 #ifdef __cpp_lib_ranges 135 template<std::ranges::random_access_range V> requires std::ranges::view<std::remove_cvref_t<V>> or std::ranges::viewable_range<V>
136 struct to_tuple : std::ranges::view_interface<to_tuple<V>>
151 #ifdef __cpp_concepts 155 template<
bool Enable = true, std::enable_if_t<Enable and std::is_default_constructible_v<RangeBox>,
int> = 0>
164 #if defined(__cpp_concepts) and defined(__cpp_lib_remove_cvref) 165 template<
typename Arg> requires std::constructible_from<RangeBox, Arg&&> and (not std::same_as<std::remove_cvref_t<Arg>,
to_tuple>)
167 template<
typename Arg, std::enable_if_t<
168 std::is_constructible_v<RangeBox, Arg&&> and (not std::is_same_v<remove_cvref_t<Arg>,
to_tuple>),
int> = 0>
171 to_tuple(Arg&& arg) noexcept : r_ {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).r_.get(); }
181 constexpr V&
base() & {
return this->r_.get(); }
182 constexpr
const V& base()
const & {
return this->r_.get(); }
183 constexpr V&& base() && noexcept {
return std::move(*this).r_.get(); }
184 constexpr
const V&& base()
const && noexcept {
return std::move(*this).r_.get(); }
193 #ifdef __cpp_lib_ranges 194 namespace ranges = std::ranges;
196 return ranges::begin(base());
202 #ifdef __cpp_lib_ranges 203 namespace ranges = std::ranges;
205 return ranges::begin(base());
214 #ifdef __cpp_lib_ranges 215 namespace ranges = std::ranges;
217 return ranges::end(base());
221 constexpr
auto end()
const 223 #ifdef __cpp_lib_ranges 224 namespace ranges = std::ranges;
226 return ranges::end(base());
233 #ifdef __cpp_concepts 235 size()
const requires sized<V>
237 template<
bool Enable = true, std::enable_if_t<Enable and sized<V>,
int> = 0>
249 #ifdef __cpp_concepts 251 empty()
const requires sized<V> or std::ranges::forward_range<V>
253 template<
bool Enable = true, std::enable_if_t<Enable and (sized<V> or ranges::forward_range<V>),
int> = 0>
258 if constexpr (sized<V>)
261 else if constexpr (size_of_v<V> == 0)
return std::true_type{};
262 else return std::false_type{};
266 #ifdef __cpp_lib_ranges 267 namespace ranges = std::ranges;
269 return ranges::begin(base()) == ranges::end(base());
277 constexpr decltype(
auto)
281 constexpr decltype(
auto)
282 front()
const {
return collections::get(base(), std::integral_constant<std::size_t, 0>{}); }
286 #ifdef __cpp_lib_ranges 289 template<
typename T,
typename =
void>
291 struct back_gettable : std::false_type {};
293 #ifdef __cpp_lib_ranges 295 struct back_gettable<T>
298 struct back_gettable<T, std::enable_if_t<sized<T>>>
300 : std::bool_constant<size_of_v<T> != dynamic_size and gettable<size_of_v<T> - 1_uz, T>> {};
307 #ifdef __cpp_lib_ranges 308 constexpr decltype(
auto)
309 back() requires (std::ranges::bidirectional_range<V> and std::ranges::common_range<V>) or
back_gettable<V>::value 311 template<
bool Enable =
true, std::enable_if_t<Enable and
313 constexpr decltype(
auto)
317 if constexpr (back_gettable<V>::value)
318 {
return OpenKalman::internal::generalized_std_get<size_of_v<V> - 1_uz>(base()); }
321 #ifdef __cpp_lib_ranges 322 namespace ranges = std::ranges;
329 #ifdef __cpp_lib_ranges 330 constexpr decltype(
auto)
331 back()
const requires (std::ranges::bidirectional_range<V> and std::ranges::common_range<V>) or back_gettable<V>::value
333 template<
bool Enable =
true, std::enable_if_t<Enable and
334 (ranges::bidirectional_range<V> and ranges::common_range<V>) or back_gettable<V>::value,
int> = 0>
335 constexpr decltype(
auto)
339 if constexpr (back_gettable<V>::value)
340 {
return OpenKalman::internal::generalized_std_get<size_of_v<V> - 1_uz>(base()); }
343 #ifdef __cpp_lib_ranges 344 namespace ranges = std::ranges;
354 #ifdef __cpp_explicit_this_parameter 355 template<
typename Self, values::index I>
356 constexpr decltype(
auto)
357 operator[](
this Self&&
self, I i) noexcept
359 if constexpr (values::fixed<I> and sized<V>)
360 static_assert(size_of_v<V> ==
dynamic_size or values::fixed_number_of_v<I> < size_of_v<V>,
"Index out of range");
364 template<
typename I, std::enable_if_t<values::index<I>,
int> = 0>
365 constexpr decltype(
auto)
368 if constexpr (values::fixed<I> and sized<V>)
369 static_assert(size_of_v<V> ==
dynamic_size or values::fixed_number_of_v<I> < size_of_v<V>,
"Index out of range");
373 template<
typename I, std::enable_if_t<values::index<I>,
int> = 0>
374 constexpr decltype(
auto)
375 operator[](I i)
const &
377 if constexpr (values::fixed<I> and sized<V>)
378 static_assert(size_of_v<V> ==
dynamic_size or values::fixed_number_of_v<I> < size_of_v<V>,
"Index out of range");
382 template<
typename I, std::enable_if_t<values::index<I>,
int> = 0>
383 constexpr decltype(
auto)
384 operator[](I i) && noexcept
386 if constexpr (values::fixed<I> and sized<V>)
387 static_assert(size_of_v<V> ==
dynamic_size or values::fixed_number_of_v<I> < size_of_v<V>,
"Index out of range");
391 template<
typename I, std::enable_if_t<values::index<I>,
int> = 0>
392 constexpr decltype(
auto)
393 operator[](I i)
const && noexcept
395 if constexpr (values::fixed<I> and sized<V>)
396 static_assert(size_of_v<V> ==
dynamic_size or values::fixed_number_of_v<I> < size_of_v<V>,
"Index out of range");
405 #ifdef __cpp_explicit_this_parameter 406 template<std::
size_t i>
407 constexpr decltype(
auto)
408 get(
this auto&&
self) noexcept
410 if constexpr(sized<V>)
if constexpr (size_of_v<V> !=
dynamic_size) static_assert(i < size_of_v<V>,
"Index out of range");
411 return detail_to_tuple::get_from_base<i>(std::forward<decltype(self)>(
self).base());
414 template<std::
size_t i>
415 constexpr decltype(
auto)
418 if constexpr(sized<V>)
if constexpr (size_of_v<V> !=
dynamic_size) static_assert(i < size_of_v<V>,
"Index out of range");
419 return detail_to_tuple::get_from_base<i>(base());
422 template<std::
size_t i>
423 constexpr decltype(
auto)
426 if constexpr(sized<V>)
if constexpr (size_of_v<V> !=
dynamic_size) static_assert(i < size_of_v<V>,
"Index out of range");
427 return detail_to_tuple::get_from_base<i>(base());
430 template<std::
size_t i>
431 constexpr decltype(
auto)
434 if constexpr(sized<V>)
if constexpr (size_of_v<V> !=
dynamic_size) static_assert(i < size_of_v<V>,
"Index out of range");
435 return detail_to_tuple::get_from_base<i>(std::move(*this).base());
438 template<std::
size_t i>
439 constexpr decltype(
auto)
440 get()
const && noexcept
442 if constexpr(sized<V>)
if constexpr (size_of_v<V> !=
dynamic_size) static_assert(i < size_of_v<V>,
"Index out of range");
443 return detail_to_tuple::get_from_base<i>(std::move(*this).base());
458 #ifndef __cpp_concepts 459 namespace detail_to_tuple
461 template<
typename V,
typename =
void>
472 #ifdef __cpp_lib_ranges 473 namespace std::ranges
479 constexpr
bool enable_borrowed_range<OpenKalman::collections::to_tuple<V>> =
480 std::is_lvalue_reference_v<V> or enable_borrowed_range<remove_cvref_t<V>>;
486 #ifdef __cpp_concepts 487 template<OpenKalman::collections::sized V> requires (OpenKalman::collections::size_of_v<V> !=
OpenKalman::dynamic_size)
495 template<std::
size_t i,
typename V>
496 struct tuple_element<i, OpenKalman::collections::to_tuple<V>>
497 #ifdef __cpp_lib_remove_cvref 505 #endif //OPENKALMAN_COLLECTIONS_VIEWS_TO_TUPLE_HPP Definition for values::index.
Namespace for collections.
Definition: collections.hpp:27
Definition for collections::get.
decltype(auto) constexpr get(Arg &&arg, I i)
A generalization of std::get.
Definition: get.hpp:62
Definition: to_tuple.hpp:49
Definition: view_interface.hpp:32
A collection_view created from a std::ranges::random_access_range that is a std::ranges::viewable_ran...
Definition: to_tuple.hpp:139
Definition: tuple_reverse.hpp:103
The size of a sized object (including a collection).
Definition: size_of.hpp:36
constexpr auto empty() const
Definition: to_tuple.hpp:255
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
constexpr auto end()
An iterator to the end of the range.
Definition: to_tuple.hpp:212
Definition for collections::get_size.
The root namespace for OpenKalman.
Definition: basics.hpp:34
Definitions relating to the availability of c++ language features.
constexpr to_tuple(Arg &&arg) noexcept
Construct from a std::ranges::random_access_range.
Definition: to_tuple.hpp:171
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 auto begin() const
Definition: to_tuple.hpp:200
Definition: to_tuple.hpp:462
constexpr to_tuple()
Default constructor.
Definition: to_tuple.hpp:157
constexpr V & base() &
The base tuple.
Definition: to_tuple.hpp:181
Definitions implementing features of the c++ ranges library for compatibility.
constexpr std::size_t dynamic_size
A constant indicating that a size or index is dynamic.
Definition: global-definitions.hpp:33
Definition: to_tuple.hpp:79
constexpr auto size() const
The size of the resulting object.
Definition: to_tuple.hpp:239
constexpr auto get_size(Arg &&arg)
Get the size of a sized object (e.g, a collection)
Definition: get_size.hpp:191
constexpr auto begin()
An iterator to the beginning of the range.
Definition: to_tuple.hpp:191
constexpr auto end() const
Definition: to_tuple.hpp:221