Loading...
Searching...
No Matches
utils.h
Go to the documentation of this file.
1// BSD 3-Clause License; see https://github.com/scikit-hep/awkward/blob/main/LICENSE
2
3#ifndef AWKWARD_CPP_HEADERS_UTILS_H_
4#define AWKWARD_CPP_HEADERS_UTILS_H_
5
6#include <iterator>
7#include <iostream>
8#include <complex>
9#include <type_traits>
10#include <cassert>
11#include <utility>
12#include <stdexcept>
13#include <stdint.h>
14#include <typeinfo>
15#include <map>
16#include <sstream>
17#include <vector>
18
19namespace awkward {
20
22 template <typename T>
23 inline const std::string
25 if (std::is_integral_v<T>) {
26 if (std::is_signed_v<T>) {
27 if (sizeof(T) == 1) {
28 return "int8";
29 }
30 else if (sizeof(T) == 2) {
31 return "int16";
32 }
33 else if (sizeof(T) == 4) {
34 return "int32";
35 }
36 else if (sizeof(T) == 8) {
37 return "int64";
38 }
39 }
40 else {
41 if (sizeof(T) == 1) {
42 return "uint8";
43 }
44 else if (sizeof(T) == 2) {
45 return "uint16";
46 }
47 else if (sizeof(T) == 4) {
48 return "uint32";
49 }
50 else if (sizeof(T) == 8) {
51 return "uint64";
52 }
53 }
54 }
55 else if (std::is_same_v<T, float>) {
56 return "float32";
57 }
58 else if (std::is_same_v<T, double>) {
59 return "float64";
60 }
61 else if (std::is_same_v<T, std::complex<float>>) {
62 return "complex64";
63 }
64 else if (std::is_same_v<T, std::complex<double>>) {
65 return "complex128";
66 }
67
68 // std::is_integral_v<T> and sizeof(T) not in (1, 2, 4, 8) can get here.
69 // Don't connect this line with the above as an 'else' clause.
70 return std::string("unsupported primitive type: ") + typeid(T).name();
71 }
72
73 template <>
74 inline const std::string
76 // This takes precedence over the unspecialized template, and therefore any
77 // 8-bit data that is not named bool will be mapped to "int8" or "uint8".
78 return "bool";
79 }
80
81 template <>
82 inline const std::string
84 // This takes precedence over the unspecialized template, and therefore any
85 // 8-bit data that is not named char will be mapped to "int8" or "uint8".
86 return "char";
87 }
88
89
92 template <typename T>
93 inline const std::string
95 return type_to_name<T>();
96 }
97
100 template <>
101 inline const std::string
103 return "u8";
104 }
105
108 template <>
109 inline const std::string
111 return "i8";
112 }
113
116 template <>
117 inline const std::string
119 return "u32";
120 }
121
124 template <>
125 inline const std::string
127 return "i32";
128 }
129
132 template <>
133 inline const std::string
135 return "i64";
136 }
137
138 template <typename, typename = void>
139 constexpr bool is_iterable{};
140
141 template <typename T>
142 constexpr bool is_iterable<T,
143 std::void_t<decltype(std::declval<T>().begin()),
144 decltype(std::declval<T>().end())>> = true;
145
146 template <typename Test, template <typename...> class Ref>
147 struct is_specialization : std::false_type {};
148
149 template <template <typename...> class Ref, typename... Args>
150 struct is_specialization<Ref<Args...>, Ref> : std::true_type {};
151
157 template <typename T, typename OFFSETS>
158 std::string
159 type_to_form(int64_t form_key_id) {
160 if (std::string(typeid(T).name()).find("awkward") != std::string::npos) {
161 return std::string("awkward type");
162 }
163
164 std::stringstream form_key;
165 form_key << "node" << (form_key_id++);
166
167 if constexpr (std::is_arithmetic<T>::value) {
168 std::string parameters(type_to_name<T>() + "\", ");
169 if (std::is_same<T, char>::value) {
170 parameters = std::string(
171 "uint8\", \"parameters\": { \"__array__\": \"char\" }, ");
172 }
173 return "{\"class\": \"NumpyArray\", \"primitive\": \"" + parameters +
174 "\"form_key\": \"" + form_key.str() + "\"}";
175 } else if constexpr (is_specialization<T, std::complex>::value) {
176 return "{\"class\": \"NumpyArray\", \"primitive\": \"" +
177 type_to_name<T>() + "\", \"form_key\": \"" + form_key.str() +
178 "\"}";
179 } else {
180 typedef typename T::value_type value_type;
181
182 if (is_iterable<T>) {
183 std::string parameters("");
184 if (std::is_same<value_type, char>::value) {
185 parameters =
186 std::string(" \"parameters\": { \"__array__\": \"string\" }, ");
187 }
188 return "{\"class\": \"ListOffsetArray\", \"offsets\": \"" +
190 "\"content\":" +
191 type_to_form<value_type, OFFSETS>(form_key_id) + ", " + parameters +
192 "\"form_key\": \"" + form_key.str() + "\"}";
193 }
194 return "unsupported type";
195 }
196 }
197
199 template <typename T>
200 bool
202 return (std::string(typeid(T).name()).find("awkward") != std::string::npos);
203 }
204
210 template <size_t INDEX>
211 struct visit_impl {
217 template <typename CONTENT, typename FUNCTION>
218 static void
219 visit(CONTENT& contents, size_t index, FUNCTION fun) {
220 if (index == INDEX - 1) {
221 fun(std::get<INDEX - 1>(contents));
222 } else {
223 visit_impl<INDEX - 1>::visit(contents, index, fun);
224 }
225 }
226 };
227
230 template <>
231 struct visit_impl<0> {
232 template <typename CONTENT, typename FUNCTION>
233 static void
234 visit(CONTENT& /* contents */, size_t /* index */, FUNCTION /* fun */) {
235 assert(false);
236 }
237 };
238
240 template <typename FUNCTION, typename... CONTENTs>
241 void
242 visit_at(std::tuple<CONTENTs...> const& contents, size_t index, FUNCTION fun) {
243 visit_impl<sizeof...(CONTENTs)>::visit(contents, index, fun);
244 }
245
247 template <typename FUNCTION, typename... CONTENTs>
248 void
249 visit_at(std::tuple<CONTENTs...>& contents, size_t index, FUNCTION fun) {
250 visit_impl<sizeof...(CONTENTs)>::visit(contents, index, fun);
251 }
252
256 template<typename LayoutBuilder>
257 std::vector<std::string> buffer_name_helper(const LayoutBuilder* builder) {
258 std::map <std::string, size_t> names_nbytes = {};
259 std::vector<std::string> buffer_name;
260 builder->buffer_nbytes(names_nbytes);
261 for (auto it: names_nbytes) {
262 buffer_name.push_back(it.first);
263 }
264 return buffer_name;
265 }
266
270 template<typename LayoutBuilder>
271 std::vector<size_t> buffer_size_helper(const LayoutBuilder* builder) {
272 std::map <std::string, size_t> names_nbytes = {};
273 std::vector<size_t> buffer_size;
274 builder->buffer_nbytes(names_nbytes);
275 for (auto it: names_nbytes) {
276 buffer_size.push_back(it.second);
277 }
278 return buffer_size;
279 }
280
284 template<typename LayoutBuilder>
285 size_t num_buffers_helper(const LayoutBuilder* builder) {
286 std::map <std::string, size_t> names_nbytes = {};
287 builder->buffer_nbytes(names_nbytes);
288 return names_nbytes.size();
289 }
290
291} // namespace awkward
292
293#endif // AWKWARD_CPP_HEADERS_UTILS_H_
Definition LayoutBuilder.h:23
Definition ArrayBuilder.h:14
const std::string type_to_numpy_like< uint8_t >()
Returns numpy-like character code of a primitive type as a string.
Definition utils.h:102
const std::string type_to_name< char >()
Definition utils.h:83
const std::string type_to_numpy_like< int8_t >()
Returns numpy-like character code i8, when the primitive type is an 8-bit signed integer.
Definition utils.h:110
const std::string type_to_numpy_like()
Returns char string when the primitive type is a character.
Definition utils.h:94
const std::string type_to_numpy_like< int64_t >()
Returns numpy-like character code i64, when the primitive type is a 64-bit signed integer.
Definition utils.h:134
bool is_awkward_type()
Check if an RDataFrame column is an Awkward Array.
Definition utils.h:201
void visit_at(std::tuple< CONTENTs... > const &contents, size_t index, FUNCTION fun)
Visits the tuple contents at index.
Definition utils.h:242
constexpr bool is_iterable
Definition utils.h:139
std::string type_to_form(int64_t form_key_id)
Generates a Form, which is a unique description of the Layout Builder and its contents in the form of...
Definition utils.h:159
std::vector< size_t > buffer_size_helper(const LayoutBuilder *builder)
Helper function to retrieve the sizes (in bytes) of the buffers.
Definition utils.h:271
size_t num_buffers_helper(const LayoutBuilder *builder)
Helper function to retrieve the number of the buffers.
Definition utils.h:285
const std::string type_to_numpy_like< uint32_t >()
Returns numpy-like character code u32, when the primitive type is a 32-bit unsigned integer.
Definition utils.h:118
const std::string type_to_name()
Returns the name of a primitive type as a string.
Definition utils.h:24
const std::string type_to_numpy_like< int32_t >()
Returns numpy-like character code i32, when the primitive type is a 32-bit signed integer.
Definition utils.h:126
const std::string type_to_name< bool >()
Definition utils.h:75
std::vector< std::string > buffer_name_helper(const LayoutBuilder *builder)
Helper function to retrieve the names of the buffers.
Definition utils.h:257
Definition utils.h:147
static void visit(CONTENT &, size_t, FUNCTION)
Definition utils.h:234
Class to index tuple at runtime.
Definition utils.h:211
static void visit(CONTENT &contents, size_t index, FUNCTION fun)
Accesses the tuple contents at INDEX and calls the given function on it.
Definition utils.h:219