OpenKalman
tuple_slice.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) 2018-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_SLICE_HPP
18 #define OPENKALMAN_TUPLE_SLICE_HPP
19 
20 #include <type_traits>
21 #include <tuple>
23 
25 {
32 #ifdef __cpp_concepts
33  template<std::size_t index1, std::size_t index2, tuple_like T> requires
34  (index1 <= index2) and (index2 <= std::tuple_size_v<std::decay_t<T>>)
35 #else
36  template<std::size_t index1, std::size_t index2, typename T>
37 #endif
39  {
40  private:
41 
42  static constexpr auto base_size = std::tuple_size_v<std::decay_t<T>>;
43 
44  public:
45 
46 #ifdef __cpp_concepts
47  constexpr tuple_slice_view() requires std::default_initializable<T> = default;
48 #else
49  template<typename aT = T, std::enable_if_t<std::is_default_constructible_v<aT>, int> = 0>
50  constexpr tuple_slice_view() {};
51 #endif
52 
53 
54 #ifdef __cpp_concepts
55  template<typename Arg> requires std::constructible_from<T, Arg&&>
56 #else
57  template<typename Arg, std::enable_if_t<std::is_constructible_v<T, Arg&&>, int> = 0>
58 #endif
59  explicit constexpr tuple_slice_view(Arg&& arg) : t {std::forward<Arg>(arg)} {}
60 
61 
65 #ifdef __cpp_concepts
66  template<std::size_t i> requires (i + index1 < index2)
67 #else
68  template<std::size_t i, std::enable_if_t<(i + index1 < index2), int> = 0>
69 #endif
70  friend constexpr decltype(auto)
71  get(const tuple_slice_view& v)
72  {
73  return get(v.t, std::integral_constant<std::size_t, i + index1>{});
74  }
75 
76 
80 #ifdef __cpp_concepts
81  template<std::size_t i> requires (i + index1 < index2)
82 #else
83  template<std::size_t i, std::enable_if_t<(i + index1 < index2), int> = 0>
84 #endif
85  friend constexpr decltype(auto)
86  get(tuple_slice_view&& v)
87  {
88  return get(std::move(v).t, std::integral_constant<std::size_t, i + index1>{});
89  }
90 
91  private:
92 
93  T t;
94  };
95 
96 } // namespace OpenKalman::internal
97 
98 
99 namespace std
100 {
101  template<std::size_t index1, std::size_t index2, typename T>
102  struct tuple_size<OpenKalman::collections::tuple_slice_view<index1, index2, T>> : std::integral_constant<std::size_t, index2 - index1> {};
103 
104 
105  template<std::size_t i, std::size_t index1, std::size_t index2, typename T>
106  struct tuple_element<i, OpenKalman::collections::tuple_slice_view<index1, index2, T>>
107  {
108  static_assert(i + index1 < index2);
109  using type = std::tuple_element_t<i + index1, std::decay_t<T>>;
110  };
111 } // namespace std
112 
113 
114 namespace OpenKalman::collections
115 {
124 #ifdef __cpp_concepts
125  template<std::size_t index1, std::size_t index2, tuple_like Arg> requires
126  (index1 <= index2) and (index2 <= std::tuple_size_v<std::remove_reference_t<Arg>>)
127 #else
128  template<std::size_t index1, std::size_t index2, typename Arg, std::enable_if_t<tuple_like<Arg> and
129  (index1 <= index2) and (index2 <= std::tuple_size<std::remove_reference_t<Arg>>::value), int> = 0>
130 #endif
131  constexpr auto
132  tuple_slice(Arg&& arg)
133  {
134  return tuple_slice_view<index1, index2, Arg> {std::forward<Arg>(arg)};
135  }
136 
137 
141 #ifdef __cpp_concepts
142  template<std::size_t index1, std::size_t index2, tuple_like T> requires std::default_initializable<T>
143 #else
144  template<std::size_t index1, std::size_t index2, typename T, std::enable_if_t<
145  tuple_like<T> and std::is_default_constructible_v<T>, int> = 0>
146 #endif
147  constexpr auto
149  {
151  }
152 
153 } // namespace OpenKalman::internal
154 
155 #endif //OPENKALMAN_TUPLE_SLICE_HPP
Definition for collections::tuple_like.
Namespace for collections.
Definition: collections.hpp:27
The root namespace for OpenKalman.
Definition: basics.hpp:34
constexpr auto tuple_slice(Arg &&arg)
Takes a slice of a tuple, given an index range.
Definition: tuple_slice.hpp:132
A view to a slice of a tuple_like object.
Definition: tuple_slice.hpp:38