OpenKalman
tuple_reverse.hpp
Go to the documentation of this file.
1 /* This file is part of OpenKalman, a header-only C++ library for
2  * Kalman filters and other recursive filters.
3  *
4  * Copyright (c) 2025 Christopher Lee Ogden <ogden@gatech.edu>
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
9  */
10 
17 #ifndef OPENKALMAN_TUPLE_REVERSE_HPP
18 #define OPENKALMAN_TUPLE_REVERSE_HPP
19 
20 #include <type_traits>
21 #include <tuple>
23 
25 {
30 #ifdef __cpp_concepts
31  template<tuple_like T>
32 #else
33  template<typename T>
34 #endif
36  {
37  private:
38 
39  static constexpr auto base_size = std::tuple_size_v<std::decay_t<T>>;
40 
41  public:
42 
43 #ifdef __cpp_concepts
44  constexpr tuple_reverse_view() requires std::default_initializable<T> = default;
45 #else
46  template<typename aT = T, std::enable_if_t<std::is_default_constructible_v<aT>, int> = 0>
47  constexpr tuple_reverse_view() {};
48 #endif
49 
50 
51 #ifdef __cpp_concepts
52  template<typename Arg> requires std::constructible_from<T, Arg&&>
53 #else
54  template<typename Arg, std::enable_if_t<std::is_constructible_v<T, Arg&&>, int> = 0>
55 #endif
56  explicit constexpr tuple_reverse_view(Arg&& arg) : t {std::forward<Arg>(arg)} {}
57 
58 
62 #ifdef __cpp_concepts
63  template<std::size_t i> requires (i < std::tuple_size_v<std::decay_t<T>>)
64 #else
65  template<std::size_t i, std::enable_if_t<i < std::tuple_size_v<std::decay_t<T>>, int> = 0>
66 #endif
67  friend constexpr decltype(auto)
68  get(const tuple_reverse_view& v)
69  {
70  return collections::get(v.t, std::integral_constant<std::size_t, base_size - i - 1_uz>{});
71  }
72 
73 
77 #ifdef __cpp_concepts
78  template<std::size_t i> requires (i < std::tuple_size_v<std::decay_t<T>>)
79 #else
80  template<std::size_t i, std::enable_if_t<i < std::tuple_size_v<std::decay_t<T>>, int> = 0>
81 #endif
82  friend constexpr decltype(auto)
83  get(tuple_reverse_view&& v)
84  {
85  return collections::get(std::move(v).t, std::integral_constant<std::size_t, base_size - i - 1_uz>{});
86  }
87 
88  private:
89 
90  T t;
91  };
92 
93 
97  template<typename Arg>
98  tuple_reverse_view(Arg&&) -> tuple_reverse_view<Arg>;
99 
100 } // namespace OpenKalman::internal
101 
102 
103 namespace std
104 {
105  template<typename T>
106  struct tuple_size<OpenKalman::collections::tuple_reverse_view<T>> : std::tuple_size<std::decay_t<T>> {};
107 
108 
109  template<std::size_t i, typename T>
110  struct tuple_element<i, OpenKalman::collections::tuple_reverse_view<T>>
111  {
112  static_assert(i < std::tuple_size_v<std::decay_t<T>>);
113  using type = std::tuple_element_t<std::tuple_size_v<std::decay_t<T>> - i - 1_uz, std::decay_t<T>>;
114  };
115 } // namespace std
116 
117 
118 namespace OpenKalman::collections
119 {
123 #ifdef __cpp_concepts
124  template<tuple_like Arg>
125  constexpr tuple_like auto
126 #else
127  template<typename Arg, std::enable_if_t<tuple_like<Arg>, int> = 0>
128  constexpr auto
129 #endif
130  tuple_reverse(Arg&& arg)
131  {
132  return tuple_reverse_view {std::forward<Arg>(arg)};
133  }
134 
135 
139 #ifdef __cpp_concepts
140  template<tuple_like T> requires std::default_initializable<T>
141 #else
142  template<typename T, std::enable_if_t<tuple_like<T> and std::is_default_constructible_v<T>, int> = 0>
143 #endif
144  constexpr auto
146  {
147  return tuple_reverse_view<T> {};
148  }
149 
150 } // namespace OpenKalman::collections
151 
152 #endif //OPENKALMAN_TUPLE_REVERSE_HPP
Definition for collections::tuple_like.
Namespace for collections.
Definition: collections.hpp:27
tuple_reverse_view(Arg &&) -> tuple_reverse_view< Arg >
Deduction guide.
Definition: tuple_reverse.hpp:103
A view of a tuple that reverses the order of a base tuple.
Definition: tuple_reverse.hpp:35
The root namespace for OpenKalman.
Definition: basics.hpp:34
constexpr auto tuple_reverse(Arg &&arg)
Reverses the order of a tuple_like object.
Definition: tuple_reverse.hpp:130
constexpr bool tuple_like
T is a non-empty tuple, pair, array, or other type that acts like a tuple.
Definition: tuple_like.hpp:51