1 /*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZEPHYR_INCLUDE_SYS_CBPRINTF_CXX_H_
8 #define ZEPHYR_INCLUDE_SYS_CBPRINTF_CXX_H_
9 #ifdef __cplusplus
10
11 /* C++ version for detecting a pointer to a string. */
z_cbprintf_cxx_is_pchar(char *,bool const_as_fixed)12 static inline int z_cbprintf_cxx_is_pchar(char *, bool const_as_fixed)
13 {
14 ARG_UNUSED(const_as_fixed);
15 return 1;
16 }
17
z_cbprintf_cxx_is_pchar(const char *,bool const_as_fixed)18 static inline int z_cbprintf_cxx_is_pchar(const char *, bool const_as_fixed)
19 {
20 return const_as_fixed ? 0 : 1;
21 }
22
z_cbprintf_cxx_is_pchar(volatile char *,bool const_as_fixed)23 static inline int z_cbprintf_cxx_is_pchar(volatile char *, bool const_as_fixed)
24 {
25 ARG_UNUSED(const_as_fixed);
26 return 1;
27 }
28
z_cbprintf_cxx_is_pchar(const volatile char *,bool const_as_fixed)29 static inline int z_cbprintf_cxx_is_pchar(const volatile char *, bool const_as_fixed)
30 {
31 ARG_UNUSED(const_as_fixed);
32 return 1;
33 }
34
z_cbprintf_cxx_is_pchar(unsigned char *,bool const_as_fixed)35 static inline int z_cbprintf_cxx_is_pchar(unsigned char *, bool const_as_fixed)
36 {
37 ARG_UNUSED(const_as_fixed);
38 return 1;
39 }
40
z_cbprintf_cxx_is_pchar(const unsigned char *,bool const_as_fixed)41 static inline int z_cbprintf_cxx_is_pchar(const unsigned char *, bool const_as_fixed)
42 {
43 return const_as_fixed ? 0 : 1;
44 }
45
z_cbprintf_cxx_is_pchar(volatile unsigned char *,bool const_as_fixed)46 static inline int z_cbprintf_cxx_is_pchar(volatile unsigned char *, bool const_as_fixed)
47 {
48 ARG_UNUSED(const_as_fixed);
49 return 1;
50 }
51
z_cbprintf_cxx_is_pchar(const volatile unsigned char *,bool const_as_fixed)52 static inline int z_cbprintf_cxx_is_pchar(const volatile unsigned char *, bool const_as_fixed)
53 {
54 ARG_UNUSED(const_as_fixed);
55 return 1;
56 }
z_cbprintf_cxx_is_pchar(wchar_t *,bool const_as_fixed)57 static inline int z_cbprintf_cxx_is_pchar(wchar_t *, bool const_as_fixed)
58 {
59 ARG_UNUSED(const_as_fixed);
60 return 1;
61 }
62
z_cbprintf_cxx_is_pchar(const wchar_t *,bool const_as_fixed)63 static inline int z_cbprintf_cxx_is_pchar(const wchar_t *, bool const_as_fixed)
64 {
65 return const_as_fixed ? 0 : 1;
66 }
67
z_cbprintf_cxx_is_pchar(volatile wchar_t *,bool const_as_fixed)68 static inline int z_cbprintf_cxx_is_pchar(volatile wchar_t *, bool const_as_fixed)
69 {
70 ARG_UNUSED(const_as_fixed);
71 return 1;
72 }
73
z_cbprintf_cxx_is_pchar(const volatile wchar_t *,bool const_as_fixed)74 static inline int z_cbprintf_cxx_is_pchar(const volatile wchar_t *, bool const_as_fixed)
75 {
76 ARG_UNUSED(const_as_fixed);
77 return 1;
78 }
79
80 template < typename T >
z_cbprintf_cxx_is_pchar(T arg,bool const_as_fixed)81 static inline int z_cbprintf_cxx_is_pchar(T arg, bool const_as_fixed)
82 {
83 ARG_UNUSED(arg);
84 _Pragma("GCC diagnostic push")
85 _Pragma("GCC diagnostic ignored \"-Wpointer-arith\"")
86 ARG_UNUSED(const_as_fixed);
87 return 0;
88 _Pragma("GCC diagnostic pop")
89 }
90
91 /* C++ version for determining if variable type is numeric and fits in 32 bit word. */
z_cbprintf_cxx_is_word_num(char)92 static inline int z_cbprintf_cxx_is_word_num(char)
93 {
94 return 1;
95 }
96
z_cbprintf_cxx_is_word_num(unsigned char)97 static inline int z_cbprintf_cxx_is_word_num(unsigned char)
98 {
99 return 1;
100 }
101
z_cbprintf_cxx_is_word_num(short)102 static inline int z_cbprintf_cxx_is_word_num(short)
103 {
104 return 1;
105 }
106
z_cbprintf_cxx_is_word_num(unsigned short)107 static inline int z_cbprintf_cxx_is_word_num(unsigned short)
108 {
109 return 1;
110 }
111
z_cbprintf_cxx_is_word_num(int)112 static inline int z_cbprintf_cxx_is_word_num(int)
113 {
114 return 1;
115 }
116
z_cbprintf_cxx_is_word_num(unsigned int)117 static inline int z_cbprintf_cxx_is_word_num(unsigned int)
118 {
119 return 1;
120 }
121
z_cbprintf_cxx_is_word_num(long)122 static inline int z_cbprintf_cxx_is_word_num(long)
123 {
124 return (sizeof(long) <= sizeof(uint32_t)) ? 1 : 0;
125 }
126
z_cbprintf_cxx_is_word_num(unsigned long)127 static inline int z_cbprintf_cxx_is_word_num(unsigned long)
128 {
129 return (sizeof(long) <= sizeof(uint32_t)) ? 1 : 0;
130 }
131
132 template < typename T >
z_cbprintf_cxx_is_word_num(T arg)133 static inline int z_cbprintf_cxx_is_word_num(T arg)
134 {
135 ARG_UNUSED(arg);
136 _Pragma("GCC diagnostic push")
137 _Pragma("GCC diagnostic ignored \"-Wpointer-arith\"")
138 return 0;
139 _Pragma("GCC diagnostic pop")
140 }
141
142 /* C++ version for determining if argument is a none character pointer. */
z_cbprintf_cxx_is_none_char_ptr(char)143 static inline int z_cbprintf_cxx_is_none_char_ptr(char)
144 {
145 return 0;
146 }
147
z_cbprintf_cxx_is_none_char_ptr(unsigned char)148 static inline int z_cbprintf_cxx_is_none_char_ptr(unsigned char)
149 {
150 return 0;
151 }
152
z_cbprintf_cxx_is_none_char_ptr(short)153 static inline int z_cbprintf_cxx_is_none_char_ptr(short)
154 {
155 return 0;
156 }
157
z_cbprintf_cxx_is_none_char_ptr(unsigned short)158 static inline int z_cbprintf_cxx_is_none_char_ptr(unsigned short)
159 {
160 return 0;
161 }
162
z_cbprintf_cxx_is_none_char_ptr(int)163 static inline int z_cbprintf_cxx_is_none_char_ptr(int)
164 {
165 return 0;
166 }
167
z_cbprintf_cxx_is_none_char_ptr(unsigned int)168 static inline int z_cbprintf_cxx_is_none_char_ptr(unsigned int)
169 {
170 return 0;
171 }
172
z_cbprintf_cxx_is_none_char_ptr(long)173 static inline int z_cbprintf_cxx_is_none_char_ptr(long)
174 {
175 return 0;
176 }
177
z_cbprintf_cxx_is_none_char_ptr(unsigned long)178 static inline int z_cbprintf_cxx_is_none_char_ptr(unsigned long)
179 {
180 return 0;
181 }
182
z_cbprintf_cxx_is_none_char_ptr(long long)183 static inline int z_cbprintf_cxx_is_none_char_ptr(long long)
184 {
185 return 0;
186 }
187
z_cbprintf_cxx_is_none_char_ptr(unsigned long long)188 static inline int z_cbprintf_cxx_is_none_char_ptr(unsigned long long)
189 {
190 return 0;
191 }
192
z_cbprintf_cxx_is_none_char_ptr(float)193 static inline int z_cbprintf_cxx_is_none_char_ptr(float)
194 {
195 return 0;
196 }
197
z_cbprintf_cxx_is_none_char_ptr(double)198 static inline int z_cbprintf_cxx_is_none_char_ptr(double)
199 {
200 return 0;
201 }
202
z_cbprintf_cxx_is_none_char_ptr(char *)203 static inline int z_cbprintf_cxx_is_none_char_ptr(char *)
204 {
205 return 0;
206 }
207
z_cbprintf_cxx_is_none_char_ptr(volatile char *)208 static inline int z_cbprintf_cxx_is_none_char_ptr(volatile char *)
209 {
210 return 0;
211 }
212
z_cbprintf_cxx_is_none_char_ptr(const char *)213 static inline int z_cbprintf_cxx_is_none_char_ptr(const char *)
214 {
215 return 0;
216 }
217
z_cbprintf_cxx_is_none_char_ptr(const volatile char *)218 static inline int z_cbprintf_cxx_is_none_char_ptr(const volatile char *)
219 {
220 return 0;
221 }
222
z_cbprintf_cxx_is_none_char_ptr(unsigned char *)223 static inline int z_cbprintf_cxx_is_none_char_ptr(unsigned char *)
224 {
225 return 0;
226 }
227
z_cbprintf_cxx_is_none_char_ptr(volatile unsigned char *)228 static inline int z_cbprintf_cxx_is_none_char_ptr(volatile unsigned char *)
229 {
230 return 0;
231 }
232
z_cbprintf_cxx_is_none_char_ptr(const unsigned char *)233 static inline int z_cbprintf_cxx_is_none_char_ptr(const unsigned char *)
234 {
235 return 0;
236 }
237
z_cbprintf_cxx_is_none_char_ptr(const volatile unsigned char *)238 static inline int z_cbprintf_cxx_is_none_char_ptr(const volatile unsigned char *)
239 {
240 return 0;
241 }
242
243 template < typename T >
z_cbprintf_cxx_is_none_char_ptr(T arg)244 static inline int z_cbprintf_cxx_is_none_char_ptr(T arg)
245 {
246 ARG_UNUSED(arg);
247
248 return 1;
249 }
250
251 /* C++ version for calculating argument size. */
z_cbprintf_cxx_arg_size(float f)252 static inline size_t z_cbprintf_cxx_arg_size(float f)
253 {
254 ARG_UNUSED(f);
255
256 return sizeof(double);
257 }
258
259 template < typename T >
z_cbprintf_cxx_arg_size(T arg)260 static inline size_t z_cbprintf_cxx_arg_size(T arg)
261 {
262 ARG_UNUSED(arg);
263
264 return MAX(sizeof(T), sizeof(int));
265 }
266
267 /* C++ version for storing arguments. */
z_cbprintf_cxx_store_arg(uint8_t * dst,float arg)268 static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, float arg)
269 {
270 double d = (double)arg;
271 void *p = &d;
272
273 z_cbprintf_wcpy((int *)dst, (int *)p, sizeof(d) / sizeof(int));
274 }
275
z_cbprintf_cxx_store_arg(uint8_t * dst,void * p)276 static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, void *p)
277 {
278 z_cbprintf_wcpy((int *)dst, (int *)&p, sizeof(p) / sizeof(int));
279 }
280
z_cbprintf_cxx_store_arg(uint8_t * dst,char arg)281 static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, char arg)
282 {
283 int tmp = arg + 0;
284
285 z_cbprintf_wcpy((int *)dst, &tmp, 1);
286 }
287
z_cbprintf_cxx_store_arg(uint8_t * dst,unsigned char arg)288 static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, unsigned char arg)
289 {
290 int tmp = arg + 0;
291
292 z_cbprintf_wcpy((int *)dst, &tmp, 1);
293 }
294
z_cbprintf_cxx_store_arg(uint8_t * dst,signed char arg)295 static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, signed char arg)
296 {
297 int tmp = arg + 0;
298
299 z_cbprintf_wcpy((int *)dst, &tmp, 1);
300 }
301
z_cbprintf_cxx_store_arg(uint8_t * dst,short arg)302 static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, short arg)
303 {
304 int tmp = arg + 0;
305
306 z_cbprintf_wcpy((int *)dst, &tmp, 1);
307 }
308
z_cbprintf_cxx_store_arg(uint8_t * dst,unsigned short arg)309 static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, unsigned short arg)
310 {
311 int tmp = arg + 0;
312
313 z_cbprintf_wcpy((int *)dst, &tmp, 1);
314 }
315
316 template < typename T >
z_cbprintf_cxx_store_arg(uint8_t * dst,T arg)317 static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, T arg)
318 {
319 size_t wlen = z_cbprintf_cxx_arg_size(arg) / sizeof(int);
320 void *p = &arg;
321
322 z_cbprintf_wcpy((int *)dst, (int *)p, wlen);
323 }
324
325 /* C++ version for long double detection. */
z_cbprintf_cxx_is_longdouble(long double arg)326 static inline int z_cbprintf_cxx_is_longdouble(long double arg)
327 {
328 ARG_UNUSED(arg);
329 return 1;
330 }
331
332 template < typename T >
z_cbprintf_cxx_is_longdouble(T arg)333 static inline int z_cbprintf_cxx_is_longdouble(T arg)
334 {
335 ARG_UNUSED(arg);
336
337 return 0;
338 }
339
340 /* C++ version for calculating argument alignment. */
z_cbprintf_cxx_alignment(float arg)341 static inline size_t z_cbprintf_cxx_alignment(float arg)
342 {
343 ARG_UNUSED(arg);
344
345 return VA_STACK_ALIGN(double);
346 }
347
z_cbprintf_cxx_alignment(double arg)348 static inline size_t z_cbprintf_cxx_alignment(double arg)
349 {
350 ARG_UNUSED(arg);
351
352 return VA_STACK_ALIGN(double);
353 }
354
z_cbprintf_cxx_alignment(long double arg)355 static inline size_t z_cbprintf_cxx_alignment(long double arg)
356 {
357 ARG_UNUSED(arg);
358
359 return VA_STACK_ALIGN(long double);
360 }
361
z_cbprintf_cxx_alignment(long long arg)362 static inline size_t z_cbprintf_cxx_alignment(long long arg)
363 {
364 ARG_UNUSED(arg);
365
366 return VA_STACK_ALIGN(long long);
367 }
368
z_cbprintf_cxx_alignment(unsigned long long arg)369 static inline size_t z_cbprintf_cxx_alignment(unsigned long long arg)
370 {
371 ARG_UNUSED(arg);
372
373 return VA_STACK_ALIGN(long long);
374 }
375
376 template < typename T >
z_cbprintf_cxx_alignment(T arg)377 static inline size_t z_cbprintf_cxx_alignment(T arg)
378 {
379 return MAX(__alignof__(arg), VA_STACK_MIN_ALIGN);
380 }
381
382 /* C++ version for checking if two arguments are same type */
383 template < typename T1, typename T2 >
384 struct z_cbprintf_cxx_is_same_type {
385 enum {
386 value = false
387 };
388 };
389
390 template < typename T >
391 struct z_cbprintf_cxx_is_same_type < T, T > {
392 enum {
393 value = true
394 };
395 };
396
397 template < typename T >
398 struct z_cbprintf_cxx_remove_reference {
399 typedef T type;
400 };
401
402 template < typename T >
403 struct z_cbprintf_cxx_remove_reference < T & > {
404 typedef T type;
405 };
406
407 #if __cplusplus >= 201103L
408 template < typename T >
409 struct z_cbprintf_cxx_remove_reference < T && > {
410 typedef T type;
411 };
412 #endif
413
414 template < typename T >
415 struct z_cbprintf_cxx_remove_cv {
416 typedef T type;
417 };
418
419 template < typename T >
420 struct z_cbprintf_cxx_remove_cv < const T > {
421 typedef T type;
422 };
423
424 template < typename T >
425 struct z_cbprintf_cxx_remove_cv < volatile T > {
426 typedef T type;
427 };
428
429 template < typename T >
430 struct z_cbprintf_cxx_remove_cv < const volatile T > {
431 typedef T type;
432 };
433
434 /* Determine if a type is an array */
435 template < typename T >
436 struct z_cbprintf_cxx_is_array {
437 enum {
438 value = false
439 };
440 };
441
442 template < typename T >
443 struct z_cbprintf_cxx_is_array < T[] > {
444 enum {
445 value = true
446 };
447 };
448
449 template < typename T, size_t N >
450 struct z_cbprintf_cxx_is_array < T[N] > {
451 enum {
452 value = true
453 };
454 };
455
456 /* Determine the type of elements in an array */
457 template < typename T >
458 struct z_cbprintf_cxx_remove_extent {
459 typedef T type;
460 };
461
462 template < typename T >
463 struct z_cbprintf_cxx_remove_extent < T[] > {
464 typedef T type;
465 };
466
467 template < typename T, size_t N >
468 struct z_cbprintf_cxx_remove_extent < T[N] > {
469 typedef T type;
470 };
471
472 #endif /* __cplusplus */
473 #endif /* ZEPHYR_INCLUDE_SYS_CBPRINTF_CXX_H_ */
474