#ifndef _UL_UTDEFS_H
#define _UL_UTDEFS_H
+#include <stddef.h> /* For size_t */
+
#ifdef __cplusplus
extern "C" {
#endif
#endif /*__GNUC__*/
#endif /*UL_CONTAINEROF*/
+#ifndef UL_ALIGNOF_FIELD
+#define UL_ALIGNOF_FIELD(_type) UL_OFFSETOF(struct {char _fld0; _type _fld1;}, _fld1)
+#endif /*UL_ALIGNOF*/
+
+#ifndef UL_ALIGNOF_TYPE
+#ifdef __GNUC__
+/* The compiler provided alignment for performance can differ from ABI struct one */
+#define UL_ALIGNOF_TYPE(_type) __alignof__(_type)
+#else /*__GNUC__*/
+#define UL_ALIGNOF_TYPE UL_ALIGNOF_FIELD
+#endif /*__GNUC__*/
+#endif /*UL_ALIGNOF*/
+
+#ifndef UL_ALIGNOF
+#define UL_ALIGNOF UL_ALIGNOF_FIELD
+#endif /*UL_ALIGNOF*/
+
+
#ifndef UL_NOPSTATEMENT
#define UL_NOPSTATEMENT do { } while(0)
#endif
#endif
#endif /*UL_ATTR_REENTRANT*/
+/* The cast idea based on libHX by Jan Engelhardt */
+#define UL_TYPEOF_REFX(ref_asterisks, ptr_type) \
+ typeof(ref_asterisks(union { int z; typeof(ptr_type) x; }){0}.x)
+
+/* Const and volatile qualifiers removal cast */
+#ifdef __cplusplus
+#define UL_CAST_UNQX(ref_asterisks, new_type, expr) \
+ (const_cast<new_type>(expr))
+#else /* Standard C code */
+#ifdef __GNUC__
+#if ((__GNUC__ * 1000 + __GNUC_MINOR__) >= 4004)
+extern void* UL_CAST_UNQX_types_not_compatible(void)
+ __attribute__((error ("UL_CAST_UNQX types differ not only by volatile and const")));
+#else
+extern void UL_CAST_UNQX_types_not_compatible(void);
+#endif
+#define UL_CAST_UNQX(ref_asterisks, new_type, expr) ( \
+ __builtin_choose_expr(__builtin_types_compatible_p \
+ (UL_TYPEOF_REFX(ref_asterisks, expr), \
+ UL_TYPEOF_REFX(ref_asterisks, new_type)), \
+ (new_type)(expr), \
+ UL_CAST_UNQX_types_not_compatible() \
+ ) \
+)
+#define UL_CAST_UNQX_NULL_ALLOWED(ref_asterisks, new_type, expr) ( \
+ __builtin_choose_expr(!__builtin_types_compatible_p(void *, typeof(expr)), \
+ UL_CAST_UNQX(ref_asterisks, new_type, expr), \
+ expr \
+ ) \
+)
+#else /*__GNUC__*/
+#define UL_CAST_UNQX(ref_asterisks, new_type, expr) ((new_type)(expr))
+#endif /*__GNUC__*/
+#endif /*__cplusplus*/
+
+#define UL_CAST_UNQ1(new_type, expr) \
+ UL_CAST_UNQX(*, new_type, expr)
+
+#define UL_CAST_UNQ2(new_type, expr) \
+ UL_CAST_UNQX(**, new_type, expr)
+
+#define UL_CAST_UNQ3(new_type, expr) \
+ UL_CAST_UNQX(**, new_type, expr)
+
+#ifndef UL_CAST_UNQX_NULL_ALLOWED
+#define UL_CAST_UNQX_NULL_ALLOWED(ref_asterisks, new_type, expr) \
+ UL_CAST_UNQX(ref_asterisks, new_type, expr)
+#endif /*UL_CAST_UNQX_NULL_ALLOWED*/
+
+#define UL_CAST_UNQ1_NULL_ALLOWED(new_type, expr) \
+ UL_CAST_UNQX_NULL_ALLOWED(*, new_type, expr)
+
#ifdef __cplusplus
} /* extern "C"*/
#endif