Skip to content

Commit fc0dc29

Browse files
committed
type-safe array macros
1 parent b03d6e5 commit fc0dc29

File tree

1 file changed

+37
-7
lines changed

1 file changed

+37
-7
lines changed

cores/nRF5/common_func.h

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,47 @@
3737
#ifndef _COMMON_FUNC_H_
3838
#define _COMMON_FUNC_H_
3939

40+
4041
#ifdef __cplusplus
41-
extern "C" {
42+
namespace ADAFRUIT_DETAIL
43+
{
44+
template <typename T, size_t N>
45+
constexpr size_t arrcount_fails_if_not_array(T const (&)[N]) noexcept
46+
{
47+
return N;
48+
}
49+
}
50+
extern "C" {
51+
#define arrcount(arr) ADAFRUIT_DETAIL::arrcount_fails_if_not_array(arr)
52+
#define ADA_STATIC_ASSERT(const_expr, message) static_assert(const_expr, message)
53+
#elif __STDC_VERSION__ >= 201112L
54+
// Even C can have type-safety for equivalent of ARRAY_SIZE() macro, when using GCC (which this BSP does)
55+
#define __ADA_COMPATIBLE_TYPES(a,b) __builtin_types_compatible_p(typeof(a), typeof(b)) // GCC extensions
56+
#define __ADA_BUILD_ERROR_ON_ZERO(x) (sizeof(struct { int:-!!(x)*0x1ee7;})) // if x is zero, reports "error: negative width in bit-field '<anonymous>'"
57+
#define __ADA_MUST_BE_ARRAY(x) __ADA_BUILD_ERROR_ON_ZERO(__ADA_COMPATIBLE_TYPES((x), &(*x)))
58+
#define ADA_STATIC_ASSERT(const_expr, message) _Static_assert(const_expr, message)
59+
#define arrcount(_arr) ( (sizeof(_arr) / sizeof((_arr)[0])) + __ADA_MUST_BE_ARRAY(_arr) ) // compile-time error if not an array
60+
#else
61+
#error "C Compiler must support at least C11"
62+
#endif
63+
64+
#define ADA_STRING(x) #x ///< stringify without expand
65+
#define ADA_XSTRING(x) ADA_STRING(x) ///< expand then stringify
66+
#define ADA_STRCAT(a, b) a##b ///< concat without expand
67+
#define ADA_XSTRCAT(a, b) ADA_STRCAT(a, b) ///< expand then concat
68+
69+
#if defined __COUNTER__ && __COUNTER__ != __COUNTER__
70+
#define ADA_COUNTER __COUNTER__
71+
#else
72+
#define ADA_COUNTER __LINE__
4273
#endif
4374

4475
#define COMMENT_OUT(x)
4576

4677
#define memclr(buffer, size) memset(buffer, 0, size)
4778
#define varclr(_var) memclr(_var, sizeof(*(_var)))
48-
#define arrclr(_arr) memclr(_arr, sizeof(_arr))
79+
#define arrclr(_arr) memclr(_arr, sizeof(_arr[0]) * arrcount(_arr)) // adds type-safety
4980

50-
#define arrcount(_arr) ( sizeof(_arr) / sizeof(_arr[0]) )
5181

5282
#define __swap32(x) __REV(x) ///< built-in function to swap Endian of 32-bit number
5383
#define __swap16(u16) ((uint16_t) __REV16(u16)) ///< built-in function to swap Endian of 16-bit number
@@ -117,9 +147,9 @@
117147
const char* dbg_err_str(int32_t err_id); // TODO move to other place
118148

119149
#if __cplusplus
120-
#define PRINTF ::printf
150+
#define PRINTF ::printf
121151
#else
122-
#define PRINTF printf
152+
#define PRINTF printf
123153
#endif
124154

125155

@@ -143,7 +173,7 @@ const char* dbg_err_str(int32_t err_id); // TODO move to other place
143173

144174
#define PRINT_LOCATION() PRINTF("%s: %d:\n", __PRETTY_FUNCTION__, __LINE__)
145175
#define PRINT_MESS(x) PRINTF("%s: %d: %s \n" , __FUNCTION__, __LINE__, (char*)(x))
146-
#define PRTNT_HEAP() if (CFG_DEBUG >= 3) PRINTF("\n%s: %d: Heap free: %d\n", __FUNCTION__, __LINE__, util_heap_get_free_size())
176+
#define PRINT_HEAP() if (CFG_DEBUG >= 3) PRINTF("\n%s: %d: Heap free: %d\n", __FUNCTION__, __LINE__, util_heap_get_free_size())
147177
#define PRINT_STR(x) PRINTF("%s: %d: " #x " = %s\n" , __FUNCTION__, __LINE__, (char*)(x) )
148178
#define PRINT_INT(x) PRINTF("%s: %d: " #x " = %ld\n" , __FUNCTION__, __LINE__, (uint32_t) (x) )
149179
#define PRINT_FLOAT(x) PRINTF("%s: %d: " #x " = %f\n" , __FUNCTION__, __LINE__, (float) (x) )
@@ -182,7 +212,7 @@ const char* dbg_err_str(int32_t err_id); // TODO move to other place
182212

183213
#define PRINT_LOCATION()
184214
#define PRINT_MESS(x)
185-
#define PRTNT_HEAP()
215+
#define PRINT_HEAP()
186216
#define PRINT_STR(x)
187217
#define PRINT_INT(x)
188218
#define PRINT_HEX(x)

0 commit comments

Comments
 (0)