]> rtime.felk.cvut.cz Git - ulut.git/blobdiff - ulut/ul_utdefs.h
Do not use standard defined __alignof__ for structure filed alignment determination.
[ulut.git] / ulut / ul_utdefs.h
index f319ea193ae2f439a152f89c6a994920a598dc77..c49630b9a6094b8f8343f2786fd633c13ee50173 100644 (file)
@@ -17,6 +17,38 @@ extern "C" {
 #define inline _inline
 #endif
 
+#if !defined(UL_BUILD_BUG_ON_MSG_LINE) && defined(__OPTIMIZE__) && \
+  ((__GNUC__ * 1000 + __GNUC_MINOR__) >= 4004)
+#define UL_BUILD_BUG_ON_MSG_LINE_EXP1(condition, msg, line) \
+({ \
+  if (!!(condition)) { \
+    void compile_time_bug_on_line_ ## line (void) __attribute__((error(msg))); \
+    compile_time_bug_on_line_ ## line (); \
+  } \
+})
+#define UL_BUILD_BUG_ON_MSG_LINE(condition, msg, line) \
+  UL_BUILD_BUG_ON_MSG_LINE_EXP1(condition, msg, line)
+#endif /*UL_BUILD_BUG_ON_MSG for GCC*/
+
+#ifndef UL_BUILD_BUG_ON_MSG_LINE
+#define UL_BUILD_BUG_ON_MSG_LINE(condition, msg, line) \
+  ((void)sizeof(char[1 - 2*!!(condition)]))
+#endif /*UL_BUILD_BUG_ON_MSG*/
+
+#ifndef UL_BUILD_BUG_ON_MSG
+#define UL_BUILD_BUG_ON_MSG(condition, msg) \
+  UL_BUILD_BUG_ON_MSG_LINE(condition, msg, __LINE__)
+#endif /*UL_BUILD_BUG_ON_MSG*/
+
+#ifndef UL_BUILD_BUG_ON
+#define UL_BUILD_BUG_ON(condition) \
+  UL_BUILD_BUG_ON_MSG(condition, "Build time check " #condition " failed")
+#endif /*UL_BUILD_BUG_ON*/
+
+#if !defined(UL_OFFSETOF) && defined(__GNUC__) && __GNUC__ >= 4
+#define UL_OFFSETOF(_type, _member) __builtin_offsetof(_type, _member)
+#endif /*UL_OFFSETOF*/
+
 #ifndef UL_OFFSETOF
 /* offset of structure field */
 #define UL_OFFSETOF(_type,_member) \
@@ -34,6 +66,24 @@ extern "C" {
 #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
@@ -41,24 +91,28 @@ extern "C" {
 #ifndef ul_cyclic_gt
 #define ul_cyclic_gt(x,y) \
        ((sizeof(x)>=sizeof(long long))&&(sizeof(y)>=sizeof(long long))? \
-               (long long)((long long)(x)-(long long)(y))>0: \
+               (long long)((unsigned long long)(x)-(unsigned long long)(y))>0: \
         (sizeof(x)>=sizeof(long))&&(sizeof(y)>=sizeof(long))? \
-               (long)((long)(x)-(long)(y))>0: /* x,y casts to suppress warnings only*/ \
-        (sizeof(x)>=sizeof(int))&&(sizeof(y)>=sizeof(int))?(int)((x)-(y))>0: \
-        (sizeof(x)>=sizeof(short))&&(sizeof(y)>=sizeof(short))?(short)((x)-(y))>0: \
-        (signed char)((x)-(y))>0 \
+               (long)((unsigned long)(x)-(unsigned long)(y))>0: \
+        (sizeof(x)>=sizeof(int))&&(sizeof(y)>=sizeof(int))? \
+               (int)((unsigned int)(x)-(unsigned int)(y))>0: \
+        (sizeof(x)>=sizeof(short))&&(sizeof(y)>=sizeof(short))? \
+               (short)((unsigned short)(x)-(unsigned short)(y))>0: \
+        (signed char)((unsigned char)(x)-(unsigned char)(y))>0 \
        )
 #endif /*ul_cyclic_gt*/
 
 #ifndef ul_cyclic_ge
 #define ul_cyclic_ge(x,y) \
        ((sizeof(x)>=sizeof(long long))&&(sizeof(y)>=sizeof(long long))? \
-               (long long)((long long)(x)-(long long)(y))>=0: \
+               (long long)((unsigned long long)(x)-(unsigned long long)(y))>=0: \
         (sizeof(x)>=sizeof(long))&&(sizeof(y)>=sizeof(long))? \
-               (long)((long)(x)-(long)(y))>=0: /* x,y casts to suppress warnings only*/ \
-        (sizeof(x)>=sizeof(int))&&(sizeof(y)>=sizeof(int))?(int)((x)-(y))>=0: \
-        (sizeof(x)>=sizeof(short))&&(sizeof(y)>=sizeof(short))?(short)((x)-(y))>=0: \
-        (signed char)((x)-(y))>=0 \
+               (long)((unsigned long)(x)-(unsigned long)(y))>=0: \
+        (sizeof(x)>=sizeof(int))&&(sizeof(y)>=sizeof(int))? \
+               (int)((unsigned int)(x)-(unsigned int)(y))>=0: \
+        (sizeof(x)>=sizeof(short))&&(sizeof(y)>=sizeof(short))? \
+               (short)((unsigned short)(x)-(unsigned short)(y))>=0: \
+        (signed char)((unsigned char)(x)-(unsigned char)(y))>=0 \
        )
 #endif /*ul_cyclic_ge*/
 
@@ -103,13 +157,65 @@ extern "C" {
 #endif /* !__GNUC__ */
 
 #ifndef UL_ATTR_REENTRANT
-#ifndef SDCC
+#if (!defined(SDCC) && !defined(__SDCC)) || defined(SDCC_z80) || defined(__SDCC_z80)
   #define UL_ATTR_REENTRANT
 #else
   #define UL_ATTR_REENTRANT __reentrant
 #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