alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
Dict.hpp
Go to the documentation of this file.
1/* Copyright 2024 René Widera, Tim Hanel
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
7#include "alpaka/Tuple.hpp"
9#include "alpaka/unused.hpp"
10#include "alpaka/utility.hpp"
11
12#include <cstdio>
13#include <tuple>
14#include <utility>
15
16namespace alpaka
17{
18 namespace internal
19 {
20 // https://stackoverflow.com/a/64606884
21 template<typename X, typename T_Tuple>
22 struct KeyIdx
23 {
24 static_assert(sizeof(T_Tuple) && false);
25 };
26
27 template<typename X, template<typename...> typename T_Tuple, typename... T>
28 struct KeyIdx<X, T_Tuple<T...>>
29 {
30 template<std::size_t... idx>
31 static constexpr ssize_t find_idx(std::index_sequence<idx...>)
32 {
33 ssize_t found_idx = -1;
34 // notUsed is required to avoid warning that the expression is not used
35 [[maybe_unused]] bool notUsed
36 = ((std::is_same_v<X, typename T::KeyType> && (found_idx = idx, true)) || ...);
37 return found_idx;
38 }
39
40 public:
41 static constexpr ssize_t value = find_idx(std::index_sequence_for<T...>{});
42 };
43
44 template<typename X, template<typename...> typename T_Tuple>
45 class KeyIdx<X, T_Tuple<>>
46 {
47 static constexpr ssize_t find_idx(std::index_sequence<>)
48 {
49 return -1;
50 }
51
52 public:
53 static constexpr ssize_t value = find_idx(std::index_sequence_for<>{});
54 };
55 } // namespace internal
56
57 template<typename T_Key, typename T_Tuple>
58 inline consteval ssize_t getIdx(T_Tuple&&, T_Key const& = T_Key{})
59 {
60 constexpr auto idx = internal::KeyIdx<T_Key, std::decay_t<T_Tuple>>::value;
61 return idx;
62 }
63
64 template<typename T_Key, typename T_Tuple>
65 consteval bool hasTag(T_Tuple&&, T_Key const& = T_Key{})
66 {
67 constexpr auto idx = internal::KeyIdx<T_Key, std::decay_t<T_Tuple>>::value;
68 return idx != -1;
69 }
70
71 template<typename T_Key, typename T_Tuple>
72 inline constexpr decltype(auto) getTag(T_Tuple&& t, T_Key const& = T_Key{})
73 {
74 constexpr auto idx = internal::KeyIdx<T_Key, std::decay_t<T_Tuple>>::value;
75 static_assert(idx != -1, "Member in dict missing!");
76 static_assert(idx < std::tuple_size_v<std::decay_t<T_Tuple>>, "index out of range!");
77 return unWrapp(get<idx>(std::forward<T_Tuple>(t)).value);
78 }
79
80 template<typename T_Key, typename T_Value>
81 struct DictEntry
82 {
83 using KeyType = T_Key;
84 using ValueType = T_Value;
85
86 constexpr DictEntry(T_Key const, T_Value const& v) : value{v}
87 {
88 }
89
90 constexpr DictEntry() = default;
91
92 T_Value value;
93 };
94
95 namespace trait
96 {
97 template<typename T_Object, typename T_Sfinae = void>
99 {
100 template<typename T>
101 static constexpr auto get(T&& data)
102 {
103 return std::forward<T>(data);
104 }
105 };
106 } // namespace trait
107
108 template<typename... T_DictEntry>
109 struct Dict
110 {
111 static_assert(sizeof...(T_DictEntry) && false);
112 };
113
114 template<typename... T_Keys, typename... T_Values>
115 struct Dict<DictEntry<T_Keys, T_Values>...> : Tuple<DictEntry<T_Keys, T_Values>...>
116 {
118
119 constexpr Dict(Tuple<DictEntry<T_Keys, T_Values>...> const& data) : Tuple<DictEntry<T_Keys, T_Values>...>{data}
120 {
121 }
122
123 constexpr Dict(DictEntry<T_Keys, T_Values> const&... dictEntries)
124 : Tuple<DictEntry<T_Keys, T_Values>...>{dictEntries...}
125 {
126 }
127
128 constexpr Dict(Dict const&) = default;
129 constexpr Dict(Dict&&) = default;
130
131 static constexpr auto makeDict() requires(std::default_initializable<T_Values>, ...)
132 {
134 }
135
136 static constexpr bool hasKey(auto key)
137 {
138 constexpr auto idx = alpaka::internal::KeyIdx<ALPAKA_TYPEOF(key), Dict>::value;
139 return idx != -1;
140 }
141
143 constexpr decltype(auto) operator[](auto const tag) const
144 {
145 return getTag(*this, tag);
146 }
147
149 constexpr decltype(auto) operator[](auto const tag)
150 {
151 return getTag(*this, tag);
152 }
153 };
154
155 template<size_t T_idx>
156 constexpr decltype(auto) get(concepts::SpecializationOf<Dict> auto& t) noexcept
157 {
158 return t.template get<T_idx>();
159 }
160
161 template<size_t T_idx>
162 constexpr decltype(auto) get(concepts::SpecializationOf<Dict> auto const& t) noexcept
163 {
164 return t.template get<T_idx>();
165 }
166
167 // type deduction guide
168 template<typename... T_Keys, typename... T_Values>
170
171 template<typename... T_Keys, typename... T_Values>
173} // namespace alpaka
174
175namespace std
176{
177 template<typename... T_Keys, typename... T_Values>
178 struct tuple_size<alpaka::Dict<alpaka::DictEntry<T_Keys, T_Values>...>>
179 {
180 static constexpr std::size_t value = sizeof...(T_Keys);
181 };
182
183 template<std::size_t I, typename... T_Keys, typename... T_Values>
184 struct tuple_element<I, alpaka::Dict<alpaka::DictEntry<T_Keys, T_Values>...>>
185 {
186 using type = decltype(alpaka::get<I>(std::declval<alpaka::Tuple<alpaka::DictEntry<T_Keys, T_Values>...>>()));
187 };
188} // namespace std
189
190namespace alpaka
191{
192
193 template<std::size_t... idx0, std::size_t... idx1, typename T_Dict0, typename T_Dict1>
194 constexpr auto joinDictHelper(
195 std::index_sequence<idx0...>,
196 std::index_sequence<idx1...>,
197 T_Dict0 dict0,
198 T_Dict1 dict1)
199 {
200 return Dict{get<idx0>(dict0)..., get<idx1>(dict1)...};
201 }
202
203 template<typename... T_Entries0, typename... T_Entries1>
204 constexpr auto joinDict(Dict<T_Entries0...> const& dict0, Dict<T_Entries1...> const& dict1)
205 {
206 return joinDictHelper(
207 std::index_sequence_for<T_Entries0...>{},
208 std::index_sequence_for<T_Entries1...>{},
209 dict0,
210 dict1);
211 }
212
213 template<bool condition, typename... T_Entries0, typename... T_Entries1>
214 requires(condition == true)
215 constexpr auto conditionalAppendDict(Dict<T_Entries0...> const& dict0, Dict<T_Entries1...> const& dict1)
216 {
217 return joinDictHelper(
218 std::index_sequence_for<T_Entries0...>{},
219 std::index_sequence_for<T_Entries1...>{},
220 dict0,
221 dict1);
222 }
223
224 template<bool condition, typename... T_Entries0, typename... T_Entries1>
225 requires(condition == false)
226 constexpr auto conditionalAppendDict(Dict<T_Entries0...> const& dict0, Dict<T_Entries1...> const& dict1)
227 {
228 alpaka::unused(dict1);
229 return dict0;
230 }
231} // namespace alpaka
#define ALPAKA_FN_HOST_ACC
All functions that can be used on an accelerator have to be attributed with ALPAKA_FN_ACC or ALPAKA_F...
Definition common.hpp:32
#define ALPAKA_TYPEOF(...)
Get the type of instance.
Definition common.hpp:154
#define ALPAKA_NO_HOST_ACC_WARNING
Disable nvcc warning: 'calling a host function from host device function.' Usage: ALPAKA_NO_HOST_ACC_...
Definition common.hpp:75
Validates if T is a specialization of the unspecialized template type U.
Definition utility.hpp:118
constexpr auto alpaka
Definition fn.hpp:66
main alpaka namespace.
Definition alpaka.hpp:76
constexpr auto conditionalAppendDict(Dict< T_Entries0... > const &dict0, Dict< T_Entries1... > const &dict1)
Definition Dict.hpp:215
consteval bool hasTag(T_Tuple &&, T_Key const &=T_Key{})
Definition Dict.hpp:65
constexpr decltype(auto) unWrapp(T &&value)
Definition util.hpp:16
constexpr auto makeTuple(auto &&... args)
Definition Tuple.hpp:100
constexpr auto joinDictHelper(std::index_sequence< idx0... >, std::index_sequence< idx1... >, T_Dict0 dict0, T_Dict1 dict1)
Definition Dict.hpp:194
constexpr auto joinDict(Dict< T_Entries0... > const &dict0, Dict< T_Entries1... > const &dict1)
Definition Dict.hpp:204
ALPAKA_FN_HOST_ACC Dict(Tuple< DictEntry< T_Keys, T_Values >... > const &) -> Dict< DictEntry< T_Keys, T_Values >... >
constexpr decltype(auto) getTag(T_Tuple &&t, T_Key const &=T_Key{})
Definition Dict.hpp:72
constexpr decltype(auto) get(concepts::SpecializationOf< Dict > auto &t) noexcept
Definition Dict.hpp:156
Tuple(T_Args &&...) -> Tuple< T_Args... >
consteval ssize_t getIdx(T_Tuple &&, T_Key const &=T_Key{})
Definition Dict.hpp:58
STL namespace.
T_Value value
Definition Dict.hpp:92
constexpr DictEntry(T_Key const, T_Value const &v)
Definition Dict.hpp:86
T_Value ValueType
Definition Dict.hpp:84
constexpr DictEntry()=default
constexpr Dict(DictEntry< T_Keys, T_Values > const &... dictEntries)
Definition Dict.hpp:123
constexpr Dict(Dict const &)=default
Tuple< DictEntry< T_Keys, T_Values >... > TupleType
Definition Dict.hpp:117
constexpr Dict(Tuple< DictEntry< T_Keys, T_Values >... > const &data)
Definition Dict.hpp:119
static constexpr bool hasKey(auto key)
Definition Dict.hpp:136
basic tuple implementation
Definition Tuple.hpp:52
constexpr Tuple(T_CArgs &&... us) noexcept((std::is_nothrow_constructible_v< T_Args, T_CArgs && > &&...))
Definition Tuple.hpp:61
static constexpr auto get(T &&data)
Definition Dict.hpp:101