From 5022c1edb790066752d6e1082c12c3fb6aba6965 Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Wed, 15 Mar 2017 22:06:10 +0100 Subject: [PATCH] Add M_TYPE_FROM_FIELD --- m-core.h | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/m-core.h b/m-core.h index 8278b836..5690130a 100644 --- a/m-core.h +++ b/m-core.h @@ -562,6 +562,25 @@ (y) = tmp; \ } while (0) +/* Check if 'n' is assignable to an object of type 'type' + Return the object. + Two definitions: one with compound-literals for C, the other with static_cast for C++. + NOTE: C definition is safer than the C++ one. +*/ +#ifndef __cplusplus +# define M_ASSIGN_CAST(type, n) ((type) { 0 } = (n)) +#else +# define M_ASSIGN_CAST(type, n) static_cast(n) +#endif + +/* + * From a pointer to a 'field_type' 'field' of a 'type'structure, + * return pointer to the structure. + * NOTE: Cast Inside! + */ +#define M_TYPE_FROM_FIELD(type, ptr, field_type, field) \ + ((type *)(void*)( (char *)M_ASSIGN_CAST(field_type*, (ptr)) - offsetof(type, field) )) + /************************************************************/ /********************* HASH selection ***********************/ /************************************************************/ @@ -828,17 +847,6 @@ m_core_hash(const void *ptr, size_t s) cont && (M_GET_INIT oplist (name), true); \ (M_GET_CLEAR oplist (name), cont = false)) -/* Check if 'n' is assignable to an object of type 'type' - Return the object. - Two definitions: one with compound-literals for C, the other with static_cast for C++. - Note: C definition is safer than the C++ one. -*/ -#ifndef __cplusplus -# define M_ASSIGN_CAST(type, n) ((type) { 0 } = (n)) -#else -# define M_ASSIGN_CAST(type, n) static_cast(n) -#endif - /* By putting this after a method, we transform the argument list so that the first argument becomes a pointer to the destination. */ #define M_IPTR(...) ( & __VA_ARGS__ )