From a1b0dae953f0dde5f614f828710bcee78b5f2b78 Mon Sep 17 00:00:00 2001 From: Haru Date: Sun, 27 Dec 2015 17:35:25 +0100 Subject: Introduced the BL_UCAST() macro as an alternative to explicit casts - The benefit of using BL_UCAST() instead of an explicit cast is that it produces a compiler error if the argument is not a block_list. - The benefit of using BL_UCAST() instead of BL_CAST() is that the block_list argument is guaranteed to be evaluated only once. As such it can be used in places where the argument is a function. - No block_list type checking is done. As such, if a different block_list type is passed, behavior is undefined. The user should do the checking beforehand. Signed-off-by: Haru --- src/map/map.h | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/map/map.h b/src/map/map.h index 7047feab6..f785ddc83 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -828,8 +828,47 @@ typedef struct homun_data TBL_HOM; typedef struct mercenary_data TBL_MER; typedef struct elemental_data TBL_ELEM; +/** + * Casts a block list to a specific type. + * + * @remark + * The `bl` argument may be evaluated more than once. + * + * @param type_ The block list type (using symbols from enum bl_type). + * @param bl The source block list to cast. + * @return The block list, cast to the correct type. + * @retval NULL if bl is the wrong type or NULL. + */ #define BL_CAST(type_, bl) \ - ( ((bl) == (struct block_list*)NULL || (bl)->type != (type_)) ? (T ## type_ *)NULL : (T ## type_ *)(bl) ) + ( ((bl) == (struct block_list *)NULL || (bl)->type != (type_)) ? (T ## type_ *)NULL : (T ## type_ *)(bl) ) + +/** + * Helper function for `BL_UCAST`. + * + * @warning + * This function shouldn't be called on it own. + * + * The purpose of this function is to produce a compile-timer error if a non-bl + * object is passed to BL_UCAST. It's declared as static inline to let the + * compiler optimize out the function call overhead. + */ +static inline struct block_list *BL_UCAST_(struct block_list *bl) +{ + return bl; +} + +/** + * Casts a block list to a specific type, without performing any type checks. + * + * @remark + * The `bl` argument is guaranteed to be evaluated once and only once. + * + * @param type_ The block list type (using symbols from enum bl_type). + * @param bl The source block list to cast. + * @return The block list, cast to the correct type. + */ +#define BL_UCAST(type_, bl) \ + ((T ## type_ *)BL_UCAST_(bl)) struct charid_request { struct charid_request* next; -- cgit v1.2.3-70-g09d2