Skip to content

Commit 8bd9b09

Browse files
committed
utils: Add a Container_of() macro.
1 parent 45afde6 commit 8bd9b09

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

src/csnip/util.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* one.
1414
*/
1515

16+
#include <stddef.h>
1617
#include <string.h>
1718
#include <stdint.h>
1819

@@ -69,6 +70,20 @@
6970
/** Length of a C static array. */
7071
#define csnip_Static_len(a) (sizeof(a) / sizeof(*(a)))
7172

73+
/** Find the containing struct of a pointer to a member.
74+
*
75+
* @param ptr
76+
* pointer to a member variable.
77+
*
78+
* @param type
79+
* The type of the container.
80+
*
81+
* @param member
82+
* The name of the container member.
83+
*/
84+
#define csnip_Container_of(ptr, type, member) \
85+
((type*)(((char*)ptr) - offsetof(type, member)))
86+
7287
/** Compute the next power of 2 of a number. */
7388
inline size_t csnip_next_pow_of_2(size_t a)
7489
{
@@ -149,6 +164,7 @@ inline size_t csnip_next_pow_of_2(size_t a)
149164
#define Max csnip_Max
150165
#define Clamp csnip_Clamp
151166
#define Static_len csnip_Static_len
167+
#define Container_of csnip_Container_of
152168
#define next_pow_of_2 csnip_next_pow_of_2
153169
#define Fill_n csnip_Fill_n
154170
#define Fill csnip_Fill

test/util_test0.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,23 @@ void test_clamp(void)
3939
CHECK(Clamp(-3, 5, 3) == 3);
4040
}
4141

42+
struct X {
43+
int u;
44+
double v;
45+
};
46+
47+
void test_container_of(void)
48+
{
49+
struct X c;
50+
CHECK(Container_of(&c.v, struct X, v) == &c);
51+
CHECK(Container_of(&c.u, struct X, u) == &c);
52+
}
53+
4254
int main(void)
4355
{
4456
test_min();
4557
test_max();
4658
test_clamp();
59+
test_container_of();
4760
return 0;
4861
}

0 commit comments

Comments
 (0)