alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
Tuple.hpp
Go to the documentation of this file.
1/* Copyright 2025 Tapish Narwal, René Widera
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
8#include "alpaka/utility.hpp"
9
10#include <tuple>
11#include <type_traits>
12#include <utility>
13
14namespace alpaka
15{
16 template<typename... T_Args>
17 struct Tuple;
18
19 namespace detail
20 {
21 template<std::size_t I, typename T>
22 struct TupleLeaf
23 {
24 using type = T;
26 };
27
28 template<typename IndexSequence, typename... T_Args>
29 struct TupleImpl;
30
31 template<std::size_t... Is, typename... T_Args>
32 struct TupleImpl<std::index_sequence<Is...>, T_Args...> : TupleLeaf<Is, T_Args>...
33 {
34 template<typename... T_CArgs>
35 constexpr TupleImpl(T_CArgs&&... us) noexcept((std::is_nothrow_constructible_v<T_Args, T_CArgs&&> && ...))
36 : TupleLeaf<Is, T_Args>{std::forward<T_CArgs>(us)}...
37 {
38 }
39
40 constexpr TupleImpl() requires(std::is_default_constructible_v<T_Args> && ...)
41 = default;
42 };
43 } // namespace detail
44
45 /** basic tuple implementation
46 *
47 * This class is trivially copyable if all members are trivially copyable too and can therefore be used for a
48 * collection to pass arguments into kernels. You should use @see alpaka::apply to apply operation to the tuple.
49 */
50 template<typename... T_Args>
51 struct Tuple : detail::TupleImpl<std::make_index_sequence<sizeof...(T_Args)>, T_Args...>
52 {
53 using StdTuple = std::tuple<T_Args...>;
54 using Base = detail::TupleImpl<std::make_index_sequence<sizeof...(T_Args)>, T_Args...>;
55
56 template<typename... T_CArgs>
57 requires(
58 sizeof...(T_Args) == sizeof...(T_CArgs) && sizeof...(T_Args) > 0
59 && (!std::is_same_v<std::remove_cvref_t<std::tuple_element_t<0, std::tuple<T_CArgs...>>>, Tuple>)
60 && (std::is_constructible_v<T_Args, T_CArgs &&> && ...))
61 constexpr Tuple(T_CArgs&&... us) noexcept((std::is_nothrow_constructible_v<T_Args, T_CArgs&&> && ...))
62 : Base(std::forward<T_CArgs>(us)...)
63 {
64 }
65
66 constexpr Tuple() requires(std::is_default_constructible_v<T_Args> && ...)
67 = default;
68
69 /** get element by index
70 *
71 * @tparam I index which should not be larger than the number of elements -1
72 * @{
73 */
74 template<size_t I>
75 constexpr auto const& get() const
76 {
77 static_assert(I < sizeof...(T_Args), "Index is outside of the allowed range.");
78 return static_cast<detail::TupleLeaf<I, std::tuple_element_t<I, StdTuple>> const&>(*this).value;
79 }
80
81 template<size_t I>
82 constexpr auto& get()
83 {
84 static_assert(I < sizeof...(T_Args), "Index is outside of the allowed range.");
86 }
87
88 /** @} */
89 };
90
91 template<typename... T_Args>
92 Tuple(T_Args&&...) -> Tuple<T_Args...>;
93
94 template<size_t T_idx>
95 constexpr decltype(auto) get(concepts::SpecializationOf<Tuple> auto&& t) noexcept
96 {
97 return ALPAKA_FORWARD(t).template get<T_idx>();
98 }
99
100 constexpr auto makeTuple(auto&&... args)
101 {
102 return Tuple{ALPAKA_FORWARD(args)...};
103 }
104} // namespace alpaka
105
106namespace std
107{
108 // Specialization of tuple_size for our custom Tuple
109 template<typename... T_Args>
110 struct tuple_size<alpaka::Tuple<T_Args...>> : std::integral_constant<std::size_t, sizeof...(T_Args)>
111 {
112 };
113
114 template<std::size_t I, typename... T_Args>
115 struct tuple_element<I, alpaka::Tuple<T_Args...>>
116 {
117 using type = typename std::tuple_element_t<I, typename alpaka::Tuple<T_Args...>::StdTuple>;
118 };
119} // namespace std
#define ALPAKA_FORWARD(instance)
Perfectly forward an instance as argument.
Definition common.hpp:148
Validates if T is a specialization of the unspecialized template type U.
Definition utility.hpp:118
main alpaka namespace.
Definition alpaka.hpp:76
constexpr auto makeTuple(auto &&... args)
Definition Tuple.hpp:100
constexpr decltype(auto) get(concepts::SpecializationOf< Dict > auto &t) noexcept
Definition Dict.hpp:156
Tuple(T_Args &&...) -> Tuple< T_Args... >
STL namespace.
basic tuple implementation
Definition Tuple.hpp:52
detail::TupleImpl< std::make_index_sequence< sizeof...(T_Args)>, T_Args... > Base
Definition Tuple.hpp:54
constexpr Tuple()=default
constexpr Tuple(T_CArgs &&... us) noexcept((std::is_nothrow_constructible_v< T_Args, T_CArgs && > &&...))
Definition Tuple.hpp:61
constexpr auto const & get() const
get element by index
Definition Tuple.hpp:75
constexpr auto & get()
get element by index
Definition Tuple.hpp:82
constexpr TupleImpl(T_CArgs &&... us) noexcept((std::is_nothrow_constructible_v< T_Args, T_CArgs && > &&...))
Definition Tuple.hpp:35
typename std::tuple_element_t< I, typename alpaka::Tuple< T_Args... >::StdTuple > type
Definition Tuple.hpp:117