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
20 // FIXME:
21 // The following helper variable templates are part of C++17,
22 // define it ourselves until we switch to it
23 template< class T >
24 constexpr bool is_integral_v = std::is_integral<T>::value;
25
26 template< class T >
27 constexpr bool is_signed_v = std::is_signed<T>::value;
28
29 template< class T, class U >
30 constexpr bool is_same_v = std::is_same<T, U>::value;
31
33 template <typename T>
34 inline const std::string
36 if (is_integral_v<T>) {
37 if (is_signed_v<T>) {
38 if (sizeof(T) == 1) {
39 return "int8";
40 }
41 else if (sizeof(T) == 2) {
42 return "int16";
43 }
44 else if (sizeof(T) == 4) {
45 return "int32";
46 }
47 else if (sizeof(T) == 8) {
48 return "int64";
49 }
50 }
51 else {
52 if (sizeof(T) == 1) {
53 return "uint8";
54 }
55 else if (sizeof(T) == 2) {
56 return "uint16";
57 }
58 else if (sizeof(T) == 4) {
59 return "uint32";
60 }
61 else if (sizeof(T) == 8) {
62 return "uint64";
63 }
64 }
65 }
66 else if (is_same_v<T, float>) {
67 return "float32";
68 }
69 else if (is_same_v<T, double>) {
70 return "float64";
71 }
72 else if (is_same_v<T, std::complex<float>>) {
73 return "complex64";
74 }
75 else if (is_same_v<T, std::complex<double>>) {
76 return "complex128";
77 }
78
79 // std::is_integral_v<T> and sizeof(T) not in (1, 2, 4, 8) can get here.
80 // Don't connect this line with the above as an 'else' clause.
81 return std::string("unsupported primitive type: ") + typeid(T).name();
82 }
83
84 template <>
85 inline const std::string
87 // This takes precedence over the unspecialized template, and therefore any
88 // 8-bit data that is not named bool will be mapped to "int8" or "uint8".
89 return "bool";
90 }
91
92 template <>
93 inline const std::string
95 // This takes precedence over the unspecialized template, and therefore any
96 // 8-bit data that is not named char will be mapped to "int8" or "uint8".
97 return "char";
98 }
99
100
103 template <typename T>
104 inline const std::string
106 return type_to_name<T>();
107 }
108
111 template <>
112 inline const std::string
114 return "u8";
115 }
116
119 template <>
120 inline const std::string
122 return "i8";
123 }
124
127 template <>
128 inline const std::string
130 return "u32";
131 }
132
135 template <>
136 inline const std::string
138 return "i32";
139 }
140
143 template <>
144 inline const std::string
146 return "i64";
147 }
148
149 template <typename, typename = void>
150 constexpr bool is_iterable{};
151
152 // FIXME:
153 // std::void_t is part of C++17, define it ourselves until we switch to it
154 template <typename...>
155 struct voider {
156 using type = void;
157 };
158
159 template <typename... T>
160 using void_t = typename voider<T...>::type;
161
162 template <typename T>
163 constexpr bool is_iterable<T,
165 decltype(std::declval<T>().end())>> = true;
166
167 template <typename Test, template <typename...> class Ref>
168 struct is_specialization : std::false_type {};
169
170 template <template <typename...> class Ref, typename... Args>
171 struct is_specialization<Ref<Args...>, Ref> : std::true_type {};
172
178 template <typename T, typename OFFSETS>
179 std::string
180 type_to_form(int64_t form_key_id) {
181 if (std::string(typeid(T).name()).find("awkward") != std::string::npos) {
182 return std::string("awkward type");
183 }
184
185 std::stringstream form_key;
186 form_key << "node" << (form_key_id++);
187
188 if (std::is_arithmetic<T>::value) {
189 std::string parameters(type_to_name<T>() + "\", ");
190 if (std::is_same<T, char>::value) {
191 parameters = std::string(
192 "uint8\", \"parameters\": { \"__array__\": \"char\" }, ");
193 }
194 return "{\"class\": \"NumpyArray\", \"primitive\": \"" + parameters +
195 "\"form_key\": \"" + form_key.str() + "\"}";
197 return "{\"class\": \"NumpyArray\", \"primitive\": \"" +
198 type_to_name<T>() + "\", \"form_key\": \"" + form_key.str() +
199 "\"}";
200 }
201
202 typedef typename T::value_type value_type;
203
204 if (is_iterable<T>) {
205 std::string parameters("");
206 if (std::is_same<value_type, char>::value) {
207 parameters =
208 std::string(" \"parameters\": { \"__array__\": \"string\" }, ");
209 }
210 return "{\"class\": \"ListOffsetArray\", \"offsets\": \"" +
212 "\"content\":" +
213 type_to_form<value_type, OFFSETS>(form_key_id) + ", " + parameters +
214 "\"form_key\": \"" + form_key.str() + "\"}";
215 }
216 return "unsupported type";
217 }
218
220 template <typename T>
221 bool
223 return (std::string(typeid(T).name()).find("awkward") != std::string::npos);
224 }
225
231 template <size_t INDEX>
232 struct visit_impl {
238 template <typename CONTENT, typename FUNCTION>
239 static void
240 visit(CONTENT& contents, size_t index, FUNCTION fun) {
241 if (index == INDEX - 1) {
242 fun(std::get<INDEX - 1>(contents));
243 } else {
244 visit_impl<INDEX - 1>::visit(contents, index, fun);
245 }
246 }
247 };
248
251 template <>
252 struct visit_impl<0> {
253 template <typename CONTENT, typename FUNCTION>
254 static void
255 visit(CONTENT& /* contents */, size_t /* index */, FUNCTION /* fun */) {
256 assert(false);
257 }
258 };
259
261 template <typename FUNCTION, typename... CONTENTs>
262 void
263 visit_at(std::tuple<CONTENTs...> const& contents, size_t index, FUNCTION fun) {
264 visit_impl<sizeof...(CONTENTs)>::visit(contents, index, fun);
265 }
266
268 template <typename FUNCTION, typename... CONTENTs>
269 void
270 visit_at(std::tuple<CONTENTs...>& contents, size_t index, FUNCTION fun) {
271 visit_impl<sizeof...(CONTENTs)>::visit(contents, index, fun);
272 }
273
277 template<typename LayoutBuilder>
278 std::vector<std::string> buffer_name_helper(const LayoutBuilder* builder) {
279 std::map <std::string, size_t> names_nbytes = {};
280 std::vector<std::string> buffer_name;
281 builder->buffer_nbytes(names_nbytes);
282 for (auto it: names_nbytes) {
283 buffer_name.push_back(it.first);
284 }
285 return buffer_name;
286 }
287
291 template<typename LayoutBuilder>
292 std::vector<size_t> buffer_size_helper(const LayoutBuilder* builder) {
293 std::map <std::string, size_t> names_nbytes = {};
294 std::vector<size_t> buffer_size;
295 builder->buffer_nbytes(names_nbytes);
296 for (auto it: names_nbytes) {
297 buffer_size.push_back(it.second);
298 }
299 return buffer_size;
300 }
301
305 template<typename LayoutBuilder>
306 size_t num_buffers_helper(const LayoutBuilder* builder) {
307 std::map <std::string, size_t> names_nbytes = {};
308 builder->buffer_nbytes(names_nbytes);
309 return names_nbytes.size();
310 }
311
312} // namespace awkward
313
314#endif // AWKWARD_CPP_HEADERS_UTILS_H_
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:113
constexpr bool is_signed_v
Definition utils.h:27
const std::string type_to_name< char >()
Definition utils.h:94
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:121
const std::string type_to_numpy_like()
Returns char string when the primitive type is a character.
Definition utils.h:105
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:145
bool is_awkward_type()
Check if an RDataFrame column is an Awkward Array.
Definition utils.h:222
void visit_at(std::tuple< CONTENTs... > const &contents, size_t index, FUNCTION fun)
Visits the tuple contents at index.
Definition utils.h:263
constexpr bool is_iterable
Definition utils.h:150
constexpr bool is_integral_v
Definition utils.h:24
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:180
std::vector< size_t > buffer_size_helper(const LayoutBuilder *builder)
Helper function to retrieve the sizes (in bytes) of the buffers.
Definition utils.h:292
size_t num_buffers_helper(const LayoutBuilder *builder)
Helper function to retrieve the number of the buffers.
Definition utils.h:306
typename voider< T... >::type void_t
Definition utils.h:160
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:129
const std::string type_to_name()
Returns the name of a primitive type as a string.
Definition utils.h:35
constexpr bool is_same_v
Definition utils.h:30
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:137
const std::string type_to_name< bool >()
Definition utils.h:86
std::vector< std::string > buffer_name_helper(const LayoutBuilder *builder)
Helper function to retrieve the names of the buffers.
Definition utils.h:278
Definition utils.h:168
static void visit(CONTENT &, size_t, FUNCTION)
Definition utils.h:255
Class to index tuple at runtime.
Definition utils.h:232
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:240
Definition utils.h:155
void type
Definition utils.h:156