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 <vector>
17
18namespace awkward {
19
21 template <typename T>
22 inline const std::string
24 if (std::is_integral_v<T>) {
25 if (std::is_signed_v<T>) {
26 if (sizeof(T) == 1) {
27 return "int8";
28 }
29 else if (sizeof(T) == 2) {
30 return "int16";
31 }
32 else if (sizeof(T) == 4) {
33 return "int32";
34 }
35 else if (sizeof(T) == 8) {
36 return "int64";
37 }
38 }
39 else {
40 if (sizeof(T) == 1) {
41 return "uint8";
42 }
43 else if (sizeof(T) == 2) {
44 return "uint16";
45 }
46 else if (sizeof(T) == 4) {
47 return "uint32";
48 }
49 else if (sizeof(T) == 8) {
50 return "uint64";
51 }
52 }
53 }
54 else if (std::is_same_v<T, float>) {
55 return "float32";
56 }
57 else if (std::is_same_v<T, double>) {
58 return "float64";
59 }
60 else if (std::is_same_v<T, std::complex<float>>) {
61 return "complex64";
62 }
63 else if (std::is_same_v<T, std::complex<double>>) {
64 return "complex128";
65 }
66
67 // std::is_integral_v<T> and sizeof(T) not in (1, 2, 4, 8) can get here.
68 // Don't connect this line with the above as an 'else' clause.
69 return std::string("unsupported primitive type: ") + typeid(T).name();
70 }
71
72 template <>
73 inline const std::string
75 // This takes precedence over the unspecialized template, and therefore any
76 // 8-bit data that is not named bool will be mapped to "int8" or "uint8".
77 return "bool";
78 }
79
80 template <>
81 inline const std::string
83 // This takes precedence over the unspecialized template, and therefore any
84 // 8-bit data that is not named char will be mapped to "int8" or "uint8".
85 return "char";
86 }
87
88
91 template <typename T>
92 inline const std::string
94 return type_to_name<T>();
95 }
96
99 template <>
100 inline const std::string
102 return "u8";
103 }
104
107 template <>
108 inline const std::string
110 return "i8";
111 }
112
115 template <>
116 inline const std::string
118 return "u32";
119 }
120
123 template <>
124 inline const std::string
126 return "i32";
127 }
128
131 template <>
132 inline const std::string
134 return "i64";
135 }
136
137 template <typename, typename = void>
138 constexpr bool is_iterable{};
139
140 template <typename T>
141 constexpr bool is_iterable<T,
142 std::void_t<decltype(std::declval<T>().begin()),
143 decltype(std::declval<T>().end())>> = true;
144
145 template <typename Test, template <typename...> class Ref>
146 struct is_specialization : std::false_type {};
147
148 template <template <typename...> class Ref, typename... Args>
149 struct is_specialization<Ref<Args...>, Ref> : std::true_type {};
150
156 template <typename T, typename OFFSETS>
157 std::string
158 type_to_form(int64_t form_key_id) {
159 if (std::string(typeid(T).name()).find("awkward") != std::string::npos) {
160 return std::string("awkward type");
161 }
162
163 std::stringstream form_key;
164 form_key << "node" << (form_key_id++);
165
166 if constexpr (std::is_arithmetic<T>::value) {
167 std::string parameters(type_to_name<T>() + "\", ");
168 if (std::is_same<T, char>::value) {
169 parameters = std::string(
170 "uint8\", \"parameters\": { \"__array__\": \"char\" }, ");
171 }
172 return "{\"class\": \"NumpyArray\", \"primitive\": \"" + parameters +
173 "\"form_key\": \"" + form_key.str() + "\"}";
174 } else if constexpr (is_specialization<T, std::complex>::value) {
175 return "{\"class\": \"NumpyArray\", \"primitive\": \"" +
176 type_to_name<T>() + "\", \"form_key\": \"" + form_key.str() +
177 "\"}";
178 } else {
179 typedef typename T::value_type value_type;
180
181 if (is_iterable<T>) {
182 std::string parameters("");
183 if (std::is_same<value_type, char>::value) {
184 parameters =
185 std::string(" \"parameters\": { \"__array__\": \"string\" }, ");
186 }
187 return "{\"class\": \"ListOffsetArray\", \"offsets\": \"" +
189 "\"content\":" +
190 type_to_form<value_type, OFFSETS>(form_key_id) + ", " + parameters +
191 "\"form_key\": \"" + form_key.str() + "\"}";
192 }
193 return "unsupported type";
194 }
195 }
196
198 template <typename T>
199 bool
201 return (std::string(typeid(T).name()).find("awkward") != std::string::npos);
202 }
203
209 template <size_t INDEX>
210 struct visit_impl {
216 template <typename CONTENT, typename FUNCTION>
217 static void
218 visit(CONTENT& contents, size_t index, FUNCTION fun) {
219 if (index == INDEX - 1) {
220 fun(std::get<INDEX - 1>(contents));
221 } else {
222 visit_impl<INDEX - 1>::visit(contents, index, fun);
223 }
224 }
225 };
226
229 template <>
230 struct visit_impl<0> {
231 template <typename CONTENT, typename FUNCTION>
232 static void
233 visit(CONTENT& /* contents */, size_t /* index */, FUNCTION /* fun */) {
234 assert(false);
235 }
236 };
237
239 template <typename FUNCTION, typename... CONTENTs>
240 void
241 visit_at(std::tuple<CONTENTs...> const& contents, size_t index, FUNCTION fun) {
242 visit_impl<sizeof...(CONTENTs)>::visit(contents, index, fun);
243 }
244
246 template <typename FUNCTION, typename... CONTENTs>
247 void
248 visit_at(std::tuple<CONTENTs...>& contents, size_t index, FUNCTION fun) {
249 visit_impl<sizeof...(CONTENTs)>::visit(contents, index, fun);
250 }
251
255 template<typename LayoutBuilder>
256 std::vector<std::string> buffer_name_helper(const LayoutBuilder* builder) {
257 std::map <std::string, size_t> names_nbytes = {};
258 std::vector<std::string> buffer_name;
259 builder->buffer_nbytes(names_nbytes);
260 for (auto it: names_nbytes) {
261 buffer_name.push_back(it.first);
262 }
263 return buffer_name;
264 }
265
269 template<typename LayoutBuilder>
270 std::vector<size_t> buffer_size_helper(const LayoutBuilder* builder) {
271 std::map <std::string, size_t> names_nbytes = {};
272 std::vector<size_t> buffer_size;
273 builder->buffer_nbytes(names_nbytes);
274 for (auto it: names_nbytes) {
275 buffer_size.push_back(it.second);
276 }
277 return buffer_size;
278 }
279
283 template<typename LayoutBuilder>
284 size_t num_buffers_helper(const LayoutBuilder* builder) {
285 std::map <std::string, size_t> names_nbytes = {};
286 builder->buffer_nbytes(names_nbytes);
287 return names_nbytes.size();
288 }
289
290} // namespace awkward
291
292#endif // AWKWARD_CPP_HEADERS_UTILS_H_
Definition LayoutBuilder.h:22
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:101
const std::string type_to_name< char >()
Definition utils.h:82
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:109
const std::string type_to_numpy_like()
Returns char string when the primitive type is a character.
Definition utils.h:93
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:133
bool is_awkward_type()
Check if an RDataFrame column is an Awkward Array.
Definition utils.h:200
void visit_at(std::tuple< CONTENTs... > const &contents, size_t index, FUNCTION fun)
Visits the tuple contents at index.
Definition utils.h:241
constexpr bool is_iterable
Definition utils.h:138
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:158
std::vector< size_t > buffer_size_helper(const LayoutBuilder *builder)
Helper function to retrieve the sizes (in bytes) of the buffers.
Definition utils.h:270
size_t num_buffers_helper(const LayoutBuilder *builder)
Helper function to retrieve the number of the buffers.
Definition utils.h:284
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:117
const std::string type_to_name()
Returns the name of a primitive type as a string.
Definition utils.h:23
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:125
const std::string type_to_name< bool >()
Definition utils.h:74
std::vector< std::string > buffer_name_helper(const LayoutBuilder *builder)
Helper function to retrieve the names of the buffers.
Definition utils.h:256
Definition utils.h:146
static void visit(CONTENT &, size_t, FUNCTION)
Definition utils.h:233
Class to index tuple at runtime.
Definition utils.h:210
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:218