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"
27 
29 {
36 #ifdef __cpp_concepts
37  template<viewable_tuple_like T>
38 #else
39  template<typename T, typename = void>
40 #endif
42  {
43  private:
44 
45 #ifndef __cpp_concepts
46  static_assert(viewable_tuple_like<T>);
47 #endif
48 
49  using Seq = std::make_index_sequence<size_of_v<T>>;
50 
51 
52  template<typename U, std::size_t...i>
53  static constexpr decltype(auto)
54  fill_tuple(U&& u, std::index_sequence<i...>)
55  {
56  return std::tuple { movable_wrapper {collections::get<i>(std::forward<U>(u))}...};
57  }
58 
59 
61 
62  public:
63 
67  using type = T;
68 
69 
73  constexpr
74 #ifdef __cpp_lib_concepts
75  tuple_wrapper() noexcept(std::is_nothrow_default_constructible_v<T_>) requires std::default_initializable<T_> = default;
76 #else
77  tuple_wrapper() noexcept(std::is_nothrow_default_constructible_v<T_>) = default;
78 #endif
79 
80 
84  explicit constexpr
85  tuple_wrapper(T&& t) noexcept : t_ {fill_tuple(std::forward<T>(t), Seq{})} {}
86 
87 
91 #ifdef __cpp_explicit_this_parameter
92  template<std::size_t i>
93  constexpr decltype(auto)
94  get(this auto&& self) noexcept
95  {
96  static_assert(i < size_of_v<T>, "Index out of range");
97  return collections::get<i>(*(std::forward<decltype(self)>(self).t_).get());
98  }
99 #else
100  template<std::size_t i>
101  constexpr decltype(auto) get() & noexcept
102  {
103  static_assert(i < size_of_v<T>, "Index out of range");
104  return collections::get<i>(*t_).get();
105  }
106 
108  template<std::size_t i>
109  constexpr decltype(auto) get() const & noexcept
110  {
111  static_assert(i < size_of_v<T>, "Index out of range");
112  return collections::get<i>(*t_).get();
113  }
114 
116  template<std::size_t i>
117  constexpr decltype(auto) get() && noexcept
118  {
119  static_assert(i < size_of_v<T>, "Index out of range");
120  return collections::get<i>(*std::move(t_)).get();
121  }
122 
124  template<std::size_t i>
125  constexpr decltype(auto) get() const && noexcept
126  {
127  static_assert(i < size_of_v<T>, "Index out of range");
128  return collections::get<i>(*std::move(t_)).get();
129  }
130 #endif
131 
132  private:
133 
134  T_ t_;
135 
136  };
137 
138 
144 #ifdef __cpp_concepts
145  template<viewable_tuple_like T> requires std::move_constructible<T> and std::is_object_v<T>
146  struct tuple_wrapper<T>
147 #else
148  template<typename T>
149  struct tuple_wrapper<T, std::enable_if_t<viewable_tuple_like<T> and stdex::move_constructible<T> and std::is_object_v<T>>>
150 #endif
151  {
152  private:
153 
155 
156  public:
157 
161  using type = T;
162 
163 
167  constexpr
168 #ifdef __cpp_lib_concepts
169  tuple_wrapper() noexcept(std::is_nothrow_default_constructible_v<T_>) requires std::default_initializable<T_> = default;
170 #else
171  tuple_wrapper() noexcept(std::is_nothrow_default_constructible_v<T_>) = default;
172 #endif
173 
174 
178  explicit constexpr
179  tuple_wrapper(T&& t) : t_ {std::move(t)} {}
180 
181 
185  template<std::size_t i>
186  constexpr decltype(auto) get() & noexcept
187  {
188  static_assert(i < size_of_v<T>, "Index out of range");
189  return collections::get<i>(t_.operator*());
190  }
191 
193  template<std::size_t i>
194  constexpr decltype(auto) get() const & noexcept
195  {
196  static_assert(i < size_of_v<T>, "Index out of range");
197  return collections::get<i>(t_.operator*());
198  }
199 
201  template<std::size_t i>
202  constexpr decltype(auto) get() && noexcept
203  {
204  static_assert(i < size_of_v<T>, "Index out of range");
205  return collections::get<i>(std::move(t_.operator*()));
206  }
207 
209  template<std::size_t i>
210  constexpr decltype(auto) get() const && noexcept
211  {
212  static_assert(i < size_of_v<T>, "Index out of range");
213  return collections::get<i>(std::move(t_.operator*()));
214  }
215 
216  private:
217 
218  T_ t_;
219 
220  };
221 
222 
228 #ifdef __cpp_concepts
229  template<viewable_tuple_like T>
230  struct tuple_wrapper<T&>
231 #else
232  template<typename T>
233  struct tuple_wrapper<T&, std::enable_if_t<viewable_tuple_like<T>>>
234 #endif
235  {
236  private:
237 
239 
240  public:
241 
245  using type = T&;
246 
247 
251  explicit constexpr
252  tuple_wrapper(T& t) : t_ {t} {}
253 
254 
258  template<std::size_t i>
259  constexpr decltype(auto) get() const noexcept
260  {
261  static_assert(i < size_of_v<T>, "Index out of range");
262  return collections::get<i>(t_.get());
263  }
264 
265  private:
266 
267  T_ t_;
268 
269  };
270 
271 
276  template<typename T>
278 
279 }
280 
281 
282 namespace std
283 {
284  template<typename Tup>
285  struct tuple_size<OpenKalman::collections::internal::tuple_wrapper<Tup>>
286  : OpenKalman::collections::size_of<std::decay_t<Tup>> {};
287 
288  template<std::size_t i, typename Tup>
289  struct tuple_element<i, OpenKalman::collections::internal::tuple_wrapper<Tup>>
290  : OpenKalman::collections::collection_element<i, std::decay_t<Tup>> {};
291 }
292 
293 #endif
Definition for collections::get.
constexpr tuple_wrapper(T &t)
Construct from an lvalue reference.
Definition: tuple_wrapper.hpp:252
Definition: tuple_wrapper.hpp:41
Definition for collections::size_of.
The size of a sized object (including a collection).
Definition: size_of.hpp:33
Definition for collections::viewable_tuple_like.
The root namespace for OpenKalman.
Definition: basics.hpp:34
Tup type
The wrapped type.
Definition: tuple_wrapper.hpp:67
constexpr tuple_wrapper(T &&t) noexcept
Construct from an rvalue reference.
Definition: tuple_wrapper.hpp:85
The type of the element at a given index, if it can be determined at compile time.
Definition: collection_element.hpp:48
decltype(auto) constexpr get() &noexcept
Get an element.
Definition: tuple_wrapper.hpp:101
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 for collections::collection_element.
Definition: movable_wrapper.hpp:35