mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-28 12:10:10 +01:00
glib-aux: add nm_arr_insert_at()/nm_arr_remove_at() helpers
The point is rather special, and the macros themselves are basically simple wrappers around memmove(). When having a sorted array (for example, a strv array that is searched using nm_strv_find_binary_search()), then we want to insert/remove elements at a particular place (via memmove()). Getting the memmove() arguments is not terribly hard, but hard enough to add two helper macros for that.
This commit is contained in:
parent
2140bbf7f5
commit
622a949ecc
1 changed files with 53 additions and 0 deletions
|
|
@ -2304,6 +2304,59 @@ int _nm_strv_cmp_n(const char *const *strv1, gssize len1, const char *const *str
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* nm_arr_insert_at() does @arr[@idx] = @value, but first memmove's
|
||||
* the elements @arr[@idx..@len-1] one element up. That means, @arr currently
|
||||
* has @len valid elements, but it must have space for one more element,
|
||||
* which will be overwritten.
|
||||
*
|
||||
* The use case is to have a sorted array (nm_strv_find_binary_search()) and
|
||||
* to insert the element at he desired index. The caller must make sure that
|
||||
* @len is large enough to contain one more element. */
|
||||
#define nm_arr_insert_at(arr, len, idx, value) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
typeof(*(arr)) *const _arr = (arr); \
|
||||
typeof(len) _len = (len); \
|
||||
typeof(idx) _idx = (idx); \
|
||||
const gsize _len2 = (_len); \
|
||||
const gsize _idx2 = (_idx); \
|
||||
\
|
||||
nm_assert(_arr); \
|
||||
nm_assert(_NM_INT_NOT_NEGATIVE(_len)); \
|
||||
nm_assert(_NM_INT_NOT_NEGATIVE(_idx)); \
|
||||
nm_assert(_idx <= _len); \
|
||||
\
|
||||
if (_idx2 != _len2) \
|
||||
memmove(&_arr[_idx2 + 1u], &_arr[_idx2], sizeof(_arr[0]) * (_len2 - _idx2)); \
|
||||
\
|
||||
_arr[_idx2] = (value); \
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
/* nm_arr_remove_at() removes the element at arr[idx], by memmove'ing
|
||||
* the elements from arr[idx+1..len-1] down. All it does is one memmove(),
|
||||
* if there is anything to move. */
|
||||
#define nm_arr_remove_at(arr, len, idx) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
typeof(*(arr)) *const _arr = (arr); \
|
||||
typeof(len) _len = (len); \
|
||||
typeof(idx) _idx = (idx); \
|
||||
const gsize _len2 = (_len); \
|
||||
const gsize _idx2 = (_idx); \
|
||||
\
|
||||
nm_assert(_arr); \
|
||||
nm_assert(_len > 0); \
|
||||
nm_assert(_NM_INT_NOT_NEGATIVE(_idx)); \
|
||||
nm_assert(_idx < _len); \
|
||||
\
|
||||
if (_idx2 != _len2 - 1u) \
|
||||
memmove(&_arr[_idx2], &_arr[_idx2 + 1u], sizeof(_arr[0]) * ((_len2 - 1u) - _idx2)); \
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_UTILS_NSEC_PER_SEC ((gint64) 1000000000)
|
||||
#define NM_UTILS_USEC_PER_SEC ((gint64) 1000000)
|
||||
#define NM_UTILS_MSEC_PER_SEC ((gint64) 1000)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue