std-aux: implement NM_PTRARRAY_LEN() macro via static function

We use NM_PTRARRAY_LEN(), and I find it a bit ugly that a macro does so
much. Maybe, it's better to have it as a function.

But the macro currently lives in "libnm-std-aux/nm-std-aux.h", which
is header-only. To add it to a C source file, we would have to move
it to another header, but "libnm-std-aux/nm-std-aux.h" is nice because
it gets included by default already.

Keep it in "libnm-std-aux/nm-std-aux.h", but implement it as an inline
function.

The macro now only does (as before) some type checking shenanigans to ensure
that the argument is a pointer to pointers.

In practice, there is probably very little difference compared to
the macro before, likely the code will anyway be inlined.
This commit is contained in:
Thomas Haller 2021-07-23 15:41:45 +02:00
parent f0ec3d5a56
commit 4547b4a893
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728

View file

@ -316,22 +316,28 @@ nm_mult_clamped_u(unsigned a, unsigned b)
/* macro to return strlen() of a compile time string. */
#define NM_STRLEN(str) (sizeof("" str "") - 1u)
static inline size_t
_nm_ptrarray_len_impl(const void *const *array)
{
size_t n = 0;
if (array) {
while (array[n])
n++;
}
return n;
}
/* returns the length of a NULL terminated array of pointers,
* like g_strv_length() does. The difference is:
* - it operates on arrays of pointers (of any kind, requiring no cast).
* - it accepts NULL to return zero. */
#define NM_PTRARRAY_LEN(array) \
({ \
typeof(*(array)) *const _array = (array); \
size_t _n = 0; \
\
if (_array) { \
_nm_unused const void *_type_check_is_pointer = _array[0]; \
\
while (_array[_n]) \
_n++; \
} \
_n; \
#define NM_PTRARRAY_LEN(array) \
({ \
typeof(*(array)) *const _array = (array); \
_nm_unused const void * _type_check_is_pointer = 0 ? _array[0] : NULL; \
\
_nm_ptrarray_len_impl((const void *const *) _array); \
})
/*****************************************************************************/