All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
utils.h
Go to the documentation of this file.
1// BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/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
16
17namespace awkward {
18
19 // FIXME:
20 // The following helper variable templates are part of C++17,
21 // define it ourselves until we switch to it
22 template< class T >
23 constexpr bool is_integral_v = std::is_integral<T>::value;
24
25 template< class T >
26 constexpr bool is_signed_v = std::is_signed<T>::value;
27
28 template< class T, class U >
29 constexpr bool is_same_v = std::is_same<T, U>::value;
30
32 template <typename T>
33 inline const std::string
35 if (is_integral_v<T>) {
36 if (is_signed_v<T>) {
37 if (sizeof(T) == 1) {
38 return "int8";
39 }
40 else if (sizeof(T) == 2) {
41 return "int16";
42 }
43 else if (sizeof(T) == 4) {
44 return "int32";
45 }
46 else if (sizeof(T) == 8) {
47 return "int64";
48 }
49 }
50 else {
51 if (sizeof(T) == 1) {
52 return "uint8";
53 }
54 else if (sizeof(T) == 2) {
55 return "uint16";
56 }
57 else if (sizeof(T) == 4) {
58 return "uint32";
59 }
60 else if (sizeof(T) == 8) {
61 return "uint64";
62 }
63 }
64 }
65 else if (is_same_v<T, float>) {
66 return "float32";
67 }
68 else if (is_same_v<T, double>) {
69 return "float64";
70 }
71 else if (is_same_v<T, std::complex<float>>) {
72 return "complex64";
73 }
74 else if (is_same_v<T, std::complex<double>>) {
75 return "complex128";
76 }
77
78 // std::is_integral_v<T> and sizeof(T) not in (1, 2, 4, 8) can get here.
79 // Don't connect this line with the above as an 'else' clause.
80 return std::string("unsupported primitive type: ") + typeid(T).name();
81 }
82
83 template <>
84 inline const std::string
86 // This takes precedence over the unspecialized template, and therefore any
87 // 8-bit data that is not named bool will be mapped to "int8" or "uint8".
88 return "bool";
89 }
90
91 template <>
92 inline const std::string
94 // This takes precedence over the unspecialized template, and therefore any
95 // 8-bit data that is not named char will be mapped to "int8" or "uint8".
96 return "char";
97 }
98
99
102 template <typename T>
103 inline const std::string
105 return type_to_name<T>();
106 }
107
110 template <>
111 inline const std::string
113 return "u8";
114 }
115
118 template <>
119 inline const std::string
121 return "i8";
122 }
123
126 template <>
127 inline const std::string
129 return "u32";
130 }
131
134 template <>
135 inline const std::string
137 return "i32";
138 }
139
142 template <>
143 inline const std::string
145 return "i64";
146 }
147
148 template <typename, typename = void>
149 constexpr bool is_iterable{};
150
151 // FIXME:
152 // std::void_t is part of C++17, define it ourselves until we switch to it
153 template <typename...>
154 struct voider {
155 using type = void;
156 };
157
158 template <typename... T>
159 using void_t = typename voider<T...>::type;
160
161 template <typename T>
162 constexpr bool is_iterable<T,
164 decltype(std::declval<T>().end())>> = true;
165
166 template <typename Test, template <typename...> class Ref>
167 struct is_specialization : std::false_type {};
168
169 template <template <typename...> class Ref, typename... Args>
170 struct is_specialization<Ref<Args...>, Ref> : std::true_type {};
171
177 template <typename T, typename OFFSETS>
178 std::string
179 type_to_form(int64_t form_key_id) {
180 if (std::string(typeid(T).name()).find("awkward") != std::string::npos) {
181 return std::string("awkward type");
182 }
183
184 std::stringstream form_key;
185 form_key << "node" << (form_key_id++);
186
187 if (std::is_arithmetic<T>::value) {
188 std::string parameters(type_to_name<T>() + "\", ");
189 if (std::is_same<T, char>::value) {
190 parameters = std::string(
191 "uint8\", \"parameters\": { \"__array__\": \"char\" }, ");
192 }
193 return "{\"class\": \"NumpyArray\", \"primitive\": \"" + parameters +
194 "\"form_key\": \"" + form_key.str() + "\"}";
196 return "{\"class\": \"NumpyArray\", \"primitive\": \"" +
197 type_to_name<T>() + "\", \"form_key\": \"" + form_key.str() +
198 "\"}";
199 }
200
201 typedef typename T::value_type value_type;
202
203 if (is_iterable<T>) {
204 std::string parameters("");
205 if (std::is_same<value_type, char>::value) {
206 parameters =
207 std::string(" \"parameters\": { \"__array__\": \"string\" }, ");
208 }
209 return "{\"class\": \"ListOffsetArray\", \"offsets\": \"" +
210 type_to_numpy_like<OFFSETS>() + "\", "
211 "\"content\":" +
212 type_to_form<value_type, OFFSETS>(form_key_id) + ", " + parameters +
213 "\"form_key\": \"" + form_key.str() + "\"}";
214 }
215 return "unsupported type";
216 }
217
219 template <typename T>
220 bool
222 return (std::string(typeid(T).name()).find("awkward") != std::string::npos);
223 }
224
230 template <size_t INDEX>
231 struct visit_impl {
237 template <typename CONTENT, typename FUNCTION>
238 static void
239 visit(CONTENT& contents, size_t index, FUNCTION fun) {
240 if (index == INDEX - 1) {
241 fun(std::get<INDEX - 1>(contents));
242 } else {
243 visit_impl<INDEX - 1>::visit(contents, index, fun);
244 }
245 }
246 };
247
250 template <>
251 struct visit_impl<0> {
252 template <typename CONTENT, typename FUNCTION>
253 static void
254 visit(CONTENT& /* contents */, size_t /* index */, FUNCTION /* fun */) {
255 assert(false);
256 }
257 };
258
260 template <typename FUNCTION, typename... CONTENTs>
261 void
262 visit_at(std::tuple<CONTENTs...> const& contents, size_t index, FUNCTION fun) {
263 visit_impl<sizeof...(CONTENTs)>::visit(contents, index, fun);
264 }
265
267 template <typename FUNCTION, typename... CONTENTs>
268 void
269 visit_at(std::tuple<CONTENTs...>& contents, size_t index, FUNCTION fun) {
270 visit_impl<sizeof...(CONTENTs)>::visit(contents, index, fun);
271 }
272
273} // namespace awkward
274
275#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:112
constexpr bool is_signed_v
Definition utils.h:26
const std::string type_to_name< char >()
Definition utils.h:93
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:120
const std::string type_to_numpy_like()
Returns char string when the primitive type is a character.
Definition utils.h:104
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:144
bool is_awkward_type()
Check if an RDataFrame column is an Awkward Array.
Definition utils.h:221
void visit_at(std::tuple< CONTENTs... > const &contents, size_t index, FUNCTION fun)
Visits the tuple contents at index.
Definition utils.h:262
constexpr bool is_iterable
Definition utils.h:149
constexpr bool is_integral_v
Definition utils.h:23
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:179
typename voider< T... >::type void_t
Definition utils.h:159
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:128
const std::string type_to_name()
Returns the name of a primitive type as a string.
Definition utils.h:34
constexpr bool is_same_v
Definition utils.h:29
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:136
const std::string type_to_name< bool >()
Definition utils.h:85
Definition utils.h:167
static void visit(CONTENT &, size_t, FUNCTION)
Definition utils.h:254
Class to index tuple at runtime.
Definition utils.h:231
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:239
Definition utils.h:154
void type
Definition utils.h:155