libadc-cxx 1.0.0
Structured logging for scientific computing
Loading...
Searching...
No Matches
enums.ipp
Go to the documentation of this file.
1/* Copyright 2025 NTESS. See the top-level LICENSE.txt file for details.
2 *
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5#ifndef adc_builder_impl_enums_ipp_hpp
6#define adc_builder_impl_enums_ipp_hpp
7#include <mutex>
8#include <charconv>
9namespace adc {
10namespace impl {
11
12// This array must line up with the enum scalar_type in types.h
13// If it does not, test_enum_strings() will return non-zero.
14std::map< adc::scalar_type, std::string > scalar_type_name = {
15 { cp_none, "none" },
16 { cp_bool, "bool" },
17 { cp_char, "char" },
18 { cp_char16, "char16" },
19 { cp_char32, "char32" },
20 { cp_cstr, "cstr" },
21 { cp_json_str, "json_str" },
22 { cp_yaml_str, "yaml_str" },
23 { cp_xml_str, "xml_str" },
24 { cp_json, "json" },
25 { cp_path, "path" },
26 { cp_number_str, "number_str" },
27 { cp_uint8, "uint8" },
28 { cp_uint16, "uint16" },
29 { cp_uint32, "uint32" },
30 { cp_uint64, "uint64" },
31 { cp_int8, "int8" },
32 { cp_int16, "int16" },
33 { cp_int32, "int32" },
34 { cp_int64, "int64" },
35 { cp_f32, "f32" },
36 { cp_f64, "f64" },
37 { cp_f80, "f80" },
38 { cp_f128, "f128" },
39 { cp_f8_e4m3, "f8_e4m3" },
40 { cp_f8_e5m2, "f8_e5m2" },
41 { cp_f16_e5m10, "f16_e5m10" },
42 { cp_f16_e8m7, "f16_e8m7" },
43 { cp_c_f32, "c_f32" },
44 { cp_c_f64, "c_f64" },
45 { cp_c_f80, "c_f80" },
46 { cp_c_f128, "c_f128" },
47 { cp_timespec, "timespec" },
48 { cp_timeval, "timeval" },
49 { cp_epoch, "epoch" },
50 { cp_last, "last" },
51};
52
53std::map< adc::scalar_type, boost::json::kind > scalar_type_representation = { // prec fixme: adc::impl::scalar_type_representation
54 { cp_none, boost::json::kind::null },
55 { cp_bool, boost::json::kind::bool_ },
56 { cp_char, boost::json::kind::int64 },
57 { cp_char16, boost::json::kind::uint64 },
58 { cp_char32, boost::json::kind::uint64 },
59 { cp_cstr, boost::json::kind::string },
60 { cp_json_str, boost::json::kind::string },
61 { cp_yaml_str, boost::json::kind::string },
62 { cp_xml_str, boost::json::kind::string },
63 { cp_json, boost::json::kind::string },
64 { cp_path, boost::json::kind::string },
65 { cp_number_str, boost::json::kind::string },
66 { cp_uint8, boost::json::kind::uint64 },
67 { cp_uint16, boost::json::kind::uint64 },
68 { cp_uint32, boost::json::kind::uint64 },
69 { cp_uint64, boost::json::kind::string },
70 { cp_int8, boost::json::kind::int64 },
71 { cp_int16, boost::json::kind::int64 },
72 { cp_int32, boost::json::kind::int64 },
73 { cp_int64, boost::json::kind::int64 },
74 { cp_f32, boost::json::kind::double_ },
75 { cp_f64, boost::json::kind::double_ },
76 { cp_f80, boost::json::kind::null /* "f80" */ }, // prec fixme: rstring? json
77 { cp_f128, boost::json::kind::null /* "f128" */ }, // prec fixme: rstring? json
78 { cp_f8_e4m3, boost::json::kind::null /* "f8_e4m3" */ }, // prec fixme: rstring? json
79 { cp_f8_e5m2, boost::json::kind::null /* "f8_e5m2" */ }, // prec fixme: rstring? json
80 { cp_f16_e5m10, boost::json::kind::null /* "f16_e5m10" */ }, // prec fixme: rstring? json
81 { cp_f16_e8m7, boost::json::kind::null /* "f16_e8m7" */ }, // prec fixme: rstring? json
82 { cp_c_f32, boost::json::kind::double_ },
83 { cp_c_f64, boost::json::kind::double_ },
84 { cp_c_f80, boost::json::kind::null /* "c_f80" */ }, // prec fixme: rstring? json
85 { cp_c_f128, boost::json::kind::null /* "c_f128" */ }, // prec fixme: rstring? json
86 { cp_timespec, boost::json::kind::int64 }, // int64[2]
87 { cp_timeval, boost::json::kind::int64 }, // int64[2]
88 { cp_epoch, boost::json::kind::int64 },
89 { cp_last, boost::json::kind::null }
90};
91
92} // namespace adc::impl
93
94
96 if (st >= cp_none && st <= cp_last)
98 return boost::json::kind::null;
99};
100
101/* return the conversion of name to scalar type,
102 * after stripping prefix "array_" if present.
103 */
104scalar_type scalar_type_from_name(const std::string& name)
105{
106
107
108 std::string basename, prefix = "array_";
109 if (name.length() >= prefix.length() &&
110 name.substr(0, prefix.length()) == prefix) {
111 basename = name.substr(prefix.length());
112 } else {
113 basename = name;
114 }
115
116 static std::map<std::string, adc::scalar_type> type_to_name;
117 static std::mutex mtx;
118 {
119 std::lock_guard<std::mutex> guard(mtx);
120 if (type_to_name.size() == 0) {
121 for (const auto& pair : adc::impl::scalar_type_name) {
122 type_to_name[pair.second] = pair.first;
123 }
124 }
125 }
126 if (type_to_name.count(basename)) {
127 return type_to_name[basename];
128 }
129 return cp_none;
130}
131
132const std::string to_string(float f)
133{
134 const size_t size = 20;
135 char buf[size]{};
136 std::to_chars_result r = std::to_chars(buf, buf + size, f);
137
138 if (r.ec != std::errc()) {
139 std::cout << std::make_error_code(r.ec).message() << '\n';
140 return std::string("NaN_unexpected");
141 } else {
142 std::string str(buf, r.ptr - buf);
143 return str;
144 }
145}
146
147const std::string to_string(double f)
148{
149 const size_t size = 40;
150 char buf[size]{};
151 std::to_chars_result r = std::to_chars(buf, buf + size, f);
152
153 if (r.ec != std::errc()) {
154 std::cout << std::make_error_code(r.ec).message() << '\n';
155 return std::string("NaN_unexpected");
156 } else {
157 std::string str(buf, r.ptr - buf);
158 return str;
159 }
160}
161
162#define elt_to_string(CTYPE) \
163{ \
164 CTYPE *a = (CTYPE *)data; \
165 for (size_t i=0; i < count; i++) { \
166 o << a[i]; \
167 if (i < count-1) \
168 o << ", "; \
169 } \
170}
171
172#define f_elt_to_string(CTYPE) \
173{ \
174 CTYPE *a = (CTYPE *)data; \
175 for (size_t i=0; i < count; i++) { \
176 o << to_string(a[i]); \
177 if (i < count-1) \
178 o << ", "; \
179 } \
180}
181
182#define cf_elt_to_string(CTYPE) \
183{ \
184 std::complex<CTYPE> *a = (std::complex<CTYPE> *)data; \
185 for (size_t i=0; i < count; i++) { \
186 o << "{" << to_string(a[i].real()); \
187 o << ", " << to_string(a[i].imag()); \
188 o << " }"; \
189 if (i < count-1) \
190 o << ", "; \
191 } \
192}
193
194const std::string to_string(void *data, scalar_type cptype, size_t count) // prec fixme
195{
196 // [elts*count]
197 std::string s;
198 s.reserve(count*30);
199 std::ostringstream o(s);
200 o << "[";
201
202 switch (cptype) {
203 case cp_last:
204 [[fallthrough]];
205 case cp_none:
206 o << "bug1";
207 break;
208 case cp_bool:
209 {
210 bool *a = (bool *)data;
211 for (size_t i; i < count; i++) {
212 o << (a[i] ? "true" : "false");
213 if (i < count-1)
214 o << ", ";
215 }
216 }
217 break;
218 case cp_char:
219 elt_to_string(char);
220 break;
221 case cp_char16:
222 elt_to_string(char16_t);
223 break;
224 case cp_char32:
225 elt_to_string(char32_t);
226 break;
227 case cp_cstr:
228 [[fallthrough]];
229 case cp_json_str:
230 [[fallthrough]];
231 case cp_yaml_str:
232 [[fallthrough]];
233 case cp_xml_str:
234 [[fallthrough]];
235 case cp_json:
236 [[fallthrough]];
237 case cp_path:
238 [[fallthrough]];
239 case cp_number_str:
240 elt_to_string(std::string);
241 break;
242 case cp_uint8:
243 elt_to_string(uint8_t);
244 break;
245 case cp_uint16:
246 elt_to_string(uint16_t);
247 break;
248 case cp_uint32:
249 elt_to_string(uint32_t);
250 break;
251 case cp_uint64:
252 elt_to_string(uint64_t);
253 break;
254 case cp_int8:
255 elt_to_string(int8_t);
256 break;
257 case cp_int16:
258 elt_to_string(int16_t);
259 break;
260 case cp_int32:
261 elt_to_string(int32_t);
262 break;
263 case cp_int64:
264 elt_to_string(int64_t);
265 break;
266 case cp_f32:
267 f_elt_to_string(float);
268 break;
269 case cp_f64:
270 f_elt_to_string(double);
271 break;
272#if ADC_SUPPORT_EXTENDED_FLOATS
273 case cp_f80:
274 f_elt_to_string(FLOAT80);
275 break;
276#else
277 case cp_f80:
278 o << "unsupported-by-build-" << to_string(cptype);
279 break;
280#endif
281#if ADC_SUPPORT_QUAD_FLOATS
282 case cp_f128:
283 f_elt_to_string(FLOAT128);
284 break;
285#else
286 case cp_f128:
287 o << "unsupported-by-build-" << to_string(cptype);
288 break;
289#endif
290#if ADC_SUPPORT_GPU_FLOATS
291 case cp_f8_e4m3:
292 f_elt_to_string(FLOAT_4_3);
293 break;
294 case cp_f8_e5m2:
295 f_elt_to_string(FLOAT_5_2);
296 break;
297 case cp_f16_e5m10:
298 f_elt_to_string(FLOAT_5_10);
299 break;
300 case cp_f16_e8m7:
301 f_elt_to_string(FLOAT_8_7);
302 break;
303#else
304 case cp_f8_e4m3:
305 o << "unsupported-by-build-" << to_string(cptype);
306 break;
307 case cp_f8_e5m2:
308 o << "unsupported-by-build-" << to_string(cptype);
309 break;
310 case cp_f16_e5m10:
311 o << "unsupported-by-build-" << to_string(cptype);
312 break;
313 case cp_f16_e8m7:
314 o << "unsupported-by-build-" << to_string(cptype);
315 break;
316#endif
317 case cp_c_f32:
318 cf_elt_to_string(float);
319 break;
320 case cp_c_f64:
321 cf_elt_to_string(double);
322 break;
323#if ADC_SUPPORT_EXTENDED_FLOATS
324 case cp_c_f80:
325 cf_elt_to_string(std::complex<FLOAT80>);
326 break;
327#else
328 case cp_c_f80:
329 o << "unsupported-by-build-" << to_string(cptype);
330 break;
331#endif
332#if ADC_SUPPORT_QUAD_FLOATS
333 case cp_c_f128:
334 cf_elt_to_string(std::complex<FLOAT128>);
335 break;
336#else
337 case cp_c_f128:
338 o << "unsupported-by-build-" << to_string(cptype);
339 break;
340#endif
341 case cp_char8:
342 [[fallthrough]]; // when c++20 is the min
343 case cp_timespec:
344 [[fallthrough]];
345 case cp_timeval:
346 [[fallthrough]];
347 case cp_epoch: // fixme? array of epochs
348 o << "bug2";
349 break;
350 }
351 o << "]";
352 return o.str();
353}
354
355
356#define BAD_ST "UNKNOWN_scalar_type"
357
358const std::string to_string(scalar_type st) {
359 if (st >= cp_none && st <= cp_last)
361 return BAD_ST;
362};
363
365 int err = 0;
366#define check_enum(X) if (to_string(cp_##X) != #X) { err++; std::cout << "enum " << #X << " is inconsistent with " << cp_##X << " from " << to_string(cp_##X) << std::endl; }
367 check_enum(none);
368 check_enum(bool);
369 check_enum(char);
370 check_enum(char16);
371 check_enum(char32);
372 check_enum(cstr);
373 check_enum(json_str);
374 check_enum(yaml_str);
375 check_enum(xml_str);
376 check_enum(number_str);
377 check_enum(json);
378 check_enum(path);
379 check_enum(uint8);
380 check_enum(uint16);
381 check_enum(uint32);
382 check_enum(uint64);
383 check_enum(int8);
384 check_enum(int16);
385 check_enum(int32);
386 check_enum(int64);
387 check_enum(f32);
388 check_enum(f64);
389 check_enum(f80);
390 check_enum(f128);
391 check_enum(f8_e4m3);
392 check_enum(f8_e5m2);
393 check_enum(f16_e5m10);
394 check_enum(f16_e8m7);
395 check_enum(c_f32);
396 check_enum(c_f64);
397 check_enum(c_f80);
398 check_enum(c_f128);
399 check_enum(timespec);
400 check_enum(timeval);
401 check_enum(epoch);
402 check_enum(last);
403 if (to_string((enum scalar_type)1000) != BAD_ST) {
404 err++;
405 std::cout << "out of range input to to_string() returned incorrect result" << std::endl;
406 }
407 return err;
408}
409
410} // namespace adc
411#endif // adc_builder_impl_enums_ipp_hpp
#define check_enum(X)
#define f_elt_to_string(CTYPE)
Definition enums.ipp:172
#define cf_elt_to_string(CTYPE)
Definition enums.ipp:182
#define elt_to_string(CTYPE)
Definition enums.ipp:162
#define BAD_ST
Definition enums.ipp:356
int test_enum_strings()
return non-zero if to_string and enum scalar_type are inconsisent.
Definition enums.ipp:364
scalar_type scalar_type_from_name(const std::string &name)
get the enum representation of a scalar_type string
Definition enums.ipp:104
const std::string to_string(float f)
get string of float using to_chars.
Definition enums.ipp:132
scalar_type
field types for scientific data encode/decode with json.
Definition types.hpp:62
@ cp_xml_str
c null-terminated string that contains valid xml
Definition types.hpp:72
@ cp_int64
int64_t
Definition types.hpp:85
@ cp_epoch
time(NULL) seconds since the epoch (UNIX) as int64_t
Definition types.hpp:104
@ cp_f16_e8m7
16 bit bfloat (7 mantissa, 8 exponent); requires ADC_SUPPORT_GPU_FLOATS support
Definition types.hpp:95
@ cp_int32
int32_t
Definition types.hpp:84
@ cp_c_f32
complex<float>
Definition types.hpp:97
@ cp_char
char (8 bit)
Definition types.hpp:65
@ cp_path
c null-terminated string which names a file-system path
Definition types.hpp:74
@ cp_char16
char16_t
Definition types.hpp:66
@ cp_json_str
c null-terminated string that contains valid json
Definition types.hpp:70
@ cp_timespec
(second, nanosecond) as int64_t, int64_t pair from clock_gettime
Definition types.hpp:102
@ cp_timeval
gettimeofday struct timeval (second, microsecond) as int64_t pair
Definition types.hpp:103
@ cp_c_f64
complex<double>
Definition types.hpp:98
@ cp_bool
bool (true/false,1/0)
Definition types.hpp:64
@ cp_int8
int8_t
Definition types.hpp:82
@ cp_char8
unsigned 8-bit char; reserved
Definition types.hpp:106
@ cp_f128
128 bit float; requires ADC_SUPPORT_QUAD_FLOATS support
Definition types.hpp:90
@ cp_uint16
uint16_t
Definition types.hpp:78
@ cp_json
json value (object, list, etc)
Definition types.hpp:73
@ cp_c_f80
complex<extended>; requires ADC_SUPPORT_EXTENDED_FLOATS support
Definition types.hpp:99
@ cp_number_str
c null-terminated string containing an exact decimal representation of arbitrary precision
Definition types.hpp:75
@ cp_uint32
uint32_t
Definition types.hpp:79
@ cp_int16
int16_t
Definition types.hpp:83
@ cp_f64
64 bit float
Definition types.hpp:88
@ cp_f80
80 bit float; requires ADC_SUPPORT_EXTENDED_FLOATS support
Definition types.hpp:89
@ cp_none
Definition types.hpp:63
@ cp_f32
32 bit float
Definition types.hpp:87
@ cp_yaml_str
c null-terminated string that contains valid yaml
Definition types.hpp:71
@ cp_f16_e5m10
16 bit float (10 mantissa, 5 exponent); requires ADC_SUPPORT_GPU_FLOATS support
Definition types.hpp:94
@ cp_c_f128
complex<quad>; requires ADC_SUPPORT_QUAD_FLOATS support
Definition types.hpp:100
@ cp_cstr
c null-terminated string
Definition types.hpp:69
@ cp_char32
char32_t
Definition types.hpp:67
@ cp_uint64
uint64_t
Definition types.hpp:80
@ cp_uint8
uint8_t
Definition types.hpp:77
@ cp_f8_e5m2
8 bit float (2 mantissa, 5 exponent); requires ADC_SUPPORT_GPU_FLOATS support
Definition types.hpp:93
@ cp_f8_e4m3
8 bit float (3 mantissa, 4 exponent); requires ADC_SUPPORT_GPU_FLOATS support
Definition types.hpp:92
@ cp_last
Definition types.hpp:108
std::map< adc::scalar_type, boost::json::kind > scalar_type_representation
Definition enums.ipp:53
std::map< adc::scalar_type, std::string > scalar_type_name
Definition enums.ipp:14
Definition adc.hpp:82
boost::json::kind scalar_type_representation(scalar_type st)
Definition enums.ipp:95