11#ifndef EIGEN_TUPLE_GPU
12#define EIGEN_TUPLE_GPU
24template <
size_t N,
typename... Types>
28template <
size_t N,
typename T1,
typename... Ts>
29class TupleImpl<N, T1, Ts...> {
32 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
35 template <
typename U1 = T1,
36 typename EnableIf = std::enable_if_t<std::is_default_constructible<U1>::value &&
37 reduce_all<std::is_default_constructible<Ts>::value...>::value>>
38 constexpr EIGEN_DEVICE_FUNC TupleImpl() : m_head{}, m_tail{} {}
41 template <
typename U1,
typename... Us,
43 typename EnableIf = std::enable_if_t<
45 sizeof...(Us) ==
sizeof...(Ts) && (
47 N > 1 || std::is_convertible<U1, T1>::value)>>
48 constexpr EIGEN_DEVICE_FUNC TupleImpl(U1&& arg1, Us&&... args)
49 : m_head(std::forward<U1>(arg1)), m_tail(std::forward<Us>(args)...) {}
52 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T1& head() {
return m_head; }
54 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
const T1& head()
const {
return m_head; }
57 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE TupleImpl<N - 1, Ts...>& tail() {
return m_tail; }
59 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
const TupleImpl<N - 1, Ts...>& tail()
const {
return m_tail; }
61 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void swap(TupleImpl& other) {
63 swap(m_head, other.m_head);
64 swap(m_tail, other.m_tail);
67 template <
typename... UTypes>
68 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TupleImpl& operator=(
const TupleImpl<N, UTypes...>& other) {
69 m_head = other.m_head;
70 m_tail = other.m_tail;
74 template <
typename... UTypes>
75 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TupleImpl& operator=(TupleImpl<N, UTypes...>&& other) {
76 m_head = std::move(other.m_head);
77 m_tail = std::move(other.m_tail);
83 template <
size_t M,
typename... UTypes>
84 friend class TupleImpl;
87 TupleImpl<N - 1, Ts...> m_tail;
92class TupleImpl<size_t(0)> {};
94template <
typename TupleType>
95struct is_tuple : std::false_type {};
97template <
typename... Types>
98struct is_tuple<TupleImpl<sizeof...(Types), Types...>> : std::true_type {};
101template <
size_t Idx,
typename T1,
typename... Ts>
102struct tuple_get_impl {
103 using TupleType = TupleImpl<
sizeof...(Ts) + 1, T1, Ts...>;
104 using ReturnType =
typename tuple_get_impl<Idx - 1, Ts...>::ReturnType;
106 static constexpr EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE ReturnType& run(TupleType& tuple) {
107 return tuple_get_impl<Idx - 1, Ts...>::run(tuple.tail());
110 static constexpr EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
const ReturnType& run(
const TupleType& tuple) {
111 return tuple_get_impl<Idx - 1, Ts...>::run(tuple.tail());
116template <
typename T1,
typename... Ts>
117struct tuple_get_impl<0, T1, Ts...> {
118 using TupleType = TupleImpl<
sizeof...(Ts) + 1, T1, Ts...>;
119 using ReturnType = T1;
121 static constexpr EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T1& run(TupleType& tuple) {
return tuple.head(); }
123 static constexpr EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
const T1& run(
const TupleType& tuple) {
return tuple.head(); }
127template <
size_t NTuples,
typename... Tuples>
128struct tuple_cat_impl;
130template <
size_t NTuples,
size_t N1,
typename... Args1,
size_t N2,
typename... Args2,
typename... Tuples>
131struct tuple_cat_impl<NTuples, TupleImpl<N1, Args1...>, TupleImpl<N2, Args2...>, Tuples...> {
132 using TupleType1 = TupleImpl<N1, Args1...>;
133 using TupleType2 = TupleImpl<N2, Args2...>;
134 using MergedTupleType = TupleImpl<N1 + N2, Args1..., Args2...>;
136 using ReturnType =
typename tuple_cat_impl<NTuples - 1, MergedTupleType, Tuples...>::ReturnType;
140 template <
typename Tuple1,
size_t... I1s,
typename Tuple2,
size_t... I2s,
typename... MoreTuples>
141 static constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ReturnType run(Tuple1&& tuple1, std::index_sequence<I1s...>,
142 Tuple2&& tuple2, std::index_sequence<I2s...>,
143 MoreTuples&&... tuples) {
144 return tuple_cat_impl<NTuples - 1, MergedTupleType, Tuples...>::run(
145 MergedTupleType(tuple_get_impl<I1s, Args1...>::run(std::forward<Tuple1>(tuple1))...,
146 tuple_get_impl<I2s, Args2...>::run(std::forward<Tuple2>(tuple2))...),
147 std::forward<MoreTuples>(tuples)...);
151 template <
typename Tuple1,
typename Tuple2,
typename... MoreTuples>
152 static constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ReturnType run(Tuple1&& tuple1, Tuple2&& tuple2,
153 MoreTuples&&... tuples) {
154 return run(std::forward<Tuple1>(tuple1), std::make_index_sequence<N1>{}, std::forward<Tuple2>(tuple2),
155 std::make_index_sequence<N2>{}, std::forward<MoreTuples>(tuples)...);
160template <
size_t N,
typename... Args>
161struct tuple_cat_impl<1, TupleImpl<N, Args...>> {
162 using ReturnType = TupleImpl<N, Args...>;
164 template <
typename Tuple1>
165 static constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ReturnType run(Tuple1&& tuple1) {
172struct tuple_cat_impl<0> {
173 using ReturnType = TupleImpl<0>;
174 static constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ReturnType run() {
return ReturnType{}; }
179struct unwrap_reference_wrapper {
184struct unwrap_reference_wrapper<std::reference_wrapper<T>> {
191 using type =
typename unwrap_reference_wrapper<std::decay_t<T>>::type;
197template <
typename Tuple>
200template <
typename... Types>
201struct tuple_size<TupleImpl<sizeof...(Types), Types...>> : std::integral_constant<size_t, sizeof...(Types)> {};
210template <
size_t Idx,
typename... Types>
211constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const typename tuple_get_impl<Idx, Types...>::ReturnType& get(
212 const TupleImpl<
sizeof...(Types), Types...>& tuple) {
213 return tuple_get_impl<Idx, Types...>::run(tuple);
216template <
size_t Idx,
typename... Types>
217constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
typename tuple_get_impl<Idx, Types...>::ReturnType& get(
218 TupleImpl<
sizeof...(Types), Types...>& tuple) {
219 return tuple_get_impl<Idx, Types...>::run(tuple);
227template <
typename... Tuples,
228 typename EnableIf = std::enable_if_t<internal::reduce_all<is_tuple<std::decay_t<Tuples>>::value...>::value>>
229constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
230 typename tuple_cat_impl<
sizeof...(Tuples), std::decay_t<Tuples>...>::ReturnType
231 tuple_cat(Tuples&&... tuples) {
232 return tuple_cat_impl<
sizeof...(Tuples), std::decay_t<Tuples>...>::run(std::forward<Tuples>(tuples)...);
238template <
typename... Args,
typename ReturnType = TupleImpl<
sizeof...(Args), Args&...>>
239constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ReturnType tie(Args&... args)
noexcept {
240 return ReturnType{args...};
246template <
typename... Args,
typename ReturnType = TupleImpl<
sizeof...(Args),
typename unwrap_decay<Args>::type...>>
247constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ReturnType make_tuple(Args&&... args) {
248 return ReturnType{std::forward<Args>(args)...};
254template <
typename... Args>
255constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TupleImpl<
sizeof...(Args), Args...> forward_as_tuple(Args&&... args) {
256 return TupleImpl<
sizeof...(Args), Args...>(std::forward<Args>(args)...);
262template <
typename... Types>
263using tuple = TupleImpl<
sizeof...(Types), Types...>;