OpenKalman
tuple_wrapper.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_WRAPPER_HPP
18 #define OPENKALMAN_TUPLE_WRAPPER_HPP
19 
20 #include <functional>
21 #include "basics/basics.hpp"
25 
27 {
34 #ifdef __cpp_concepts
35  template<viewable_tuple_like T>
36 #else
37  template<typename T, typename = void>
38 #endif
40  {
41  private:
42 
43 #ifndef __cpp_concepts
44  static_assert(viewable_tuple_like<T>);
45 #endif
46 
47  using Seq = std::make_index_sequence<size_of_v<T>>;
48 
49 
50  template<typename U, std::size_t...i>
51  static constexpr decltype(auto)
52  fill_tuple(U&& u, std::index_sequence<i...>)
53  {
54  return std::tuple { movable_wrapper {collections::get<i>(std::forward<U>(u))}...};
55  }
56 
57 
59 
60  public:
61 
65  using type = T;
66 
67 
71  constexpr
72 #ifdef __cpp_lib_concepts
73  tuple_wrapper() noexcept(std::is_nothrow_default_constructible_v<T_>) requires std::default_initializable<T_> = default;
74 #else
75  tuple_wrapper() noexcept(std::is_nothrow_default_constructible_v<T_>) = default;
76 #endif
77 
78 
82  explicit constexpr
83  tuple_wrapper(T&& t) noexcept : t_ {fill_tuple(std::forward<T>(t), Seq{})} {}
84 
85 
89 #ifdef __cpp_explicit_this_parameter
90  template<std::size_t i>
91  constexpr decltype(auto)
92  get(this auto&& self) noexcept
93  {
94  static_assert(i < size_of_v<T>, "Index out of range");
95  return collections::get<i>(*(std::forward<decltype(self)>(self).t_).get());
96  }
97 #else
98  template<std::size_t i>
99  constexpr decltype(auto) get() & noexcept
100  {
101  static_assert(i < size_of_v<T>, "Index out of range");
102  return collections::get<i>(*t_).get();
103  }
104 
106  template<std::size_t i>
107  constexpr decltype(auto) get() const & noexcept
108  {
109  static_assert(i < size_of_v<T>, "Index out of range");
110  return collections::get<i>(*t_).get();
111  }
112 
114  template<std::size_t i>
115  constexpr decltype(auto) get() && noexcept
116  {
117  static_assert(i < size_of_v<T>, "Index out of range");
118  return collections::get<i>(*std::move(t_)).get();
119  }
120 
122  template<std::size_t i>
123  constexpr decltype(auto) get() const && noexcept
124  {
125  static_assert(i < size_of_v<T>, "Index out of range");
126  return collections::get<i>(*std::move(t_)).get();
127  }
128 #endif
129 
130  private:
131 
132  T_ t_;
133 
134  };
135 
136 
142 #ifdef __cpp_concepts
143  template<viewable_tuple_like T> requires std::move_constructible<T> and std::is_object_v<T>
144  struct tuple_wrapper<T>
145 #else
146  template<typename T>
147  struct tuple_wrapper<T, std::enable_if_t<viewable_tuple_like<T> and stdex::move_constructible<T> and std::is_object_v<T>>>
148 #endif
149  {
150  private:
151 
153 
154  public:
155 
159  using type = T;
160 
161 
165  constexpr
166 #ifdef __cpp_lib_concepts
167  tuple_wrapper() noexcept(std::is_nothrow_default_constructible_v<T_>) requires std::default_initializable<T_> = default;
168 #else
169  tuple_wrapper() noexcept(std::is_nothrow_default_constructible_v<T_>) = default;
170 #endif
171 
172 
176  explicit constexpr
177  tuple_wrapper(T&& t) : t_ {std::move(t)} {}
178 
179 
183  template<std::size_t i>
184  constexpr decltype(auto) get() & noexcept
185  {
186  static_assert(i < size_of_v<T>, "Index out of range");
187  return collections::get<i>(t_.operator*());
188  }
189 
191  template<std::size_t i>
192  constexpr decltype(auto) get() const & noexcept
193  {
194  static_assert(i < size_of_v<T>, "Index out of range");
195  return collections::get<i>(t_.operator*());
196  }
197 
199  template<std::size_t i>
200  constexpr decltype(auto) get() && noexcept
201  {
202  static_assert(i < size_of_v<T>, "Index out of range");
203  return collections::get<i>(std::move(t_.operator*()));
204  }
205 
207  template<std::size_t i>
208  constexpr decltype(auto) get() const && noexcept
209  {
210  static_assert(i < size_of_v<T>, "Index out of range");
211  return collections::get<i>(std::move(t_.operator*()));
212  }
213 
214  private:
215 
216  T_ t_;
217 
218  };
219 
220 
226 #ifdef __cpp_concepts
227  template<viewable_tuple_like T>
228  struct tuple_wrapper<T&>
229 #else
230  template<typename T>
231  struct tuple_wrapper<T&, std::enable_if_t<viewable_tuple_like<T>>>
232 #endif
233  {
234  private:
235 
237 
238  public:
239 
243  using type = T&;
244 
245 
249  explicit constexpr
250  tuple_wrapper(T& t) : t_ {t} {}
251 
252 
256  template<std::size_t i>
257  constexpr decltype(auto) get() const noexcept
258  {
259  static_assert(i < size_of_v<T>, "Index out of range");
260  return collections::get<i>(t_.get());
261  }
262 
263  private:
264 
265  T_ t_;
266 
267  };
268 
269 
274  template<typename T>
276 
277 }
278 
279 
280 namespace std
281 {
282  template<typename Tup>
283  struct tuple_size<OpenKalman::collections::internal::tuple_wrapper<Tup>> : tuple_size<std::decay_t<Tup>> {};
284 
285  template<std::size_t i, typename Tup>
286  struct tuple_element<i, OpenKalman::collections::internal::tuple_wrapper<Tup>> : tuple_element<i, std::decay_t<Tup>> {};
287 }
288 
289 #endif
Definition for collections::get.
constexpr tuple_wrapper(T &t)
Construct from an lvalue reference.
Definition: tuple_wrapper.hpp:250
Definition: tuple_wrapper.hpp:39
Definition for collections::viewable_tuple_like.
The root namespace for OpenKalman.
Definition: basics.hpp:34
Tup type
The wrapped type.
Definition: tuple_wrapper.hpp:65
constexpr tuple_wrapper(T &&t) noexcept
Construct from an rvalue reference.
Definition: tuple_wrapper.hpp:83
decltype(auto) constexpr get() &noexcept
Get an element.
Definition: tuple_wrapper.hpp:99
Definition: trait_backports.hpp:64
constexpr tuple_wrapper() noexcept(std::is_nothrow_default_constructible_v< T_ >)=default
Default constructor.
Definition: tuple_like_to_tuple.hpp:24
Basic definitions for OpenKalman as a whole.
Definition: movable_wrapper.hpp:35