]> rtime.felk.cvut.cz Git - ulut.git/blob - ulut/ul_utdefs.h
Const and volatile qualifiers removal (UL_CAST_UNQX) which supports global initializers.
[ulut.git] / ulut / ul_utdefs.h
1 /*******************************************************************
2   uLan Utilities Library - C library of basic reusable constructions
3
4   ul_utdefs.h   - common defines used in uLan utilities library
5
6  *******************************************************************/
7
8
9 #ifndef _UL_UTDEFS_H
10 #define _UL_UTDEFS_H
11
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15
16 #if defined(_WIN32)&&defined(_MSC_VER)&&!defined(inline)
17 #define inline _inline
18 #endif
19
20 #if !defined(UL_BUILD_BUG_ON_MSG_LINE) && defined(__OPTIMIZE__) && \
21   ((__GNUC__ * 1000 + __GNUC_MINOR__) >= 4004)
22 #define UL_BUILD_BUG_ON_MSG_LINE_EXP1(condition, msg, line) \
23 ({ \
24   if (!!(condition)) { \
25     void compile_time_bug_on_line_ ## line (void) __attribute__((error(msg))); \
26     compile_time_bug_on_line_ ## line (); \
27   } \
28 })
29 #define UL_BUILD_BUG_ON_MSG_LINE(condition, msg, line) \
30   UL_BUILD_BUG_ON_MSG_LINE_EXP1(condition, msg, line)
31 #endif /*UL_BUILD_BUG_ON_MSG for GCC*/
32
33 #ifndef UL_BUILD_BUG_ON_MSG_LINE
34 #define UL_BUILD_BUG_ON_MSG_LINE(condition, msg, line) \
35   ((void)sizeof(char[1 - 2*!!(condition)]))
36 #endif /*UL_BUILD_BUG_ON_MSG*/
37
38 #ifndef UL_BUILD_BUG_ON_MSG
39 #define UL_BUILD_BUG_ON_MSG(condition, msg) \
40   UL_BUILD_BUG_ON_MSG_LINE(condition, msg, __LINE__)
41 #endif /*UL_BUILD_BUG_ON_MSG*/
42
43 #ifndef UL_BUILD_BUG_ON
44 #define UL_BUILD_BUG_ON(condition) \
45   UL_BUILD_BUG_ON_MSG(condition, "Build time check " #condition " failed")
46 #endif /*UL_BUILD_BUG_ON*/
47
48 #if !defined(UL_OFFSETOF) && defined(__GNUC__) && __GNUC__ >= 4
49 #define UL_OFFSETOF(_type, _member) __builtin_offsetof(_type, _member)
50 #endif /*UL_OFFSETOF*/
51
52 #ifndef UL_OFFSETOF
53 /* offset of structure field */
54 #define UL_OFFSETOF(_type,_member) \
55                 ((size_t)&(((_type*)0)->_member))
56 #endif /*UL_OFFSET*/
57
58 #ifndef UL_CONTAINEROF
59 #ifdef  __GNUC__
60 #define UL_CONTAINEROF(_ptr, _type, _member) ({ \
61         const typeof( ((_type *)0)->_member ) *__mptr = (_ptr); \
62         (_type *)( (char *)__mptr - UL_OFFSETOF(_type,_member) );})
63 #else /*!__GNUC__*/
64 #define UL_CONTAINEROF(_ptr, _type, _member) \
65         ((_type *)( (char *)_ptr - UL_OFFSETOF(_type,_member)))
66 #endif /*__GNUC__*/
67 #endif /*UL_CONTAINEROF*/
68
69 #ifndef UL_NOPSTATEMENT
70 #define UL_NOPSTATEMENT do { } while(0)
71 #endif
72
73 #ifndef ul_cyclic_gt
74 #define ul_cyclic_gt(x,y) \
75         ((sizeof(x)>=sizeof(long long))&&(sizeof(y)>=sizeof(long long))? \
76                 (long long)((unsigned long long)(x)-(unsigned long long)(y))>0: \
77          (sizeof(x)>=sizeof(long))&&(sizeof(y)>=sizeof(long))? \
78                 (long)((unsigned long)(x)-(unsigned long)(y))>0: \
79          (sizeof(x)>=sizeof(int))&&(sizeof(y)>=sizeof(int))? \
80                 (int)((unsigned int)(x)-(unsigned int)(y))>0: \
81          (sizeof(x)>=sizeof(short))&&(sizeof(y)>=sizeof(short))? \
82                 (short)((unsigned short)(x)-(unsigned short)(y))>0: \
83          (signed char)((unsigned char)(x)-(unsigned char)(y))>0 \
84         )
85 #endif /*ul_cyclic_gt*/
86
87 #ifndef ul_cyclic_ge
88 #define ul_cyclic_ge(x,y) \
89         ((sizeof(x)>=sizeof(long long))&&(sizeof(y)>=sizeof(long long))? \
90                 (long long)((unsigned long long)(x)-(unsigned long long)(y))>=0: \
91          (sizeof(x)>=sizeof(long))&&(sizeof(y)>=sizeof(long))? \
92                 (long)((unsigned long)(x)-(unsigned long)(y))>=0: \
93          (sizeof(x)>=sizeof(int))&&(sizeof(y)>=sizeof(int))? \
94                 (int)((unsigned int)(x)-(unsigned int)(y))>=0: \
95          (sizeof(x)>=sizeof(short))&&(sizeof(y)>=sizeof(short))? \
96                 (short)((unsigned short)(x)-(unsigned short)(y))>=0: \
97          (signed char)((unsigned char)(x)-(unsigned char)(y))>=0 \
98         )
99 #endif /*ul_cyclic_ge*/
100
101 /* GNUC neat features */
102
103 #ifdef  __GNUC__
104 #ifndef UL_ATTR_UNUSED
105 #define UL_ATTR_PRINTF( format_idx, arg_idx )   \
106   __attribute__((format (printf, format_idx, arg_idx)))
107 #define UL_ATTR_SCANF( format_idx, arg_idx )    \
108   __attribute__((format (scanf, format_idx, arg_idx)))
109 #define UL_ATTR_FORMAT( arg_idx )               \
110   __attribute__((format_arg (arg_idx)))
111 #define UL_ATTR_NORETURN                        \
112   __attribute__((noreturn))
113 #define UL_ATTR_CONST                           \
114   __attribute__((const))
115 #define UL_ATTR_UNUSED                          \
116   __attribute__((unused))
117 #define UL_ATTR_CONSTRUCTOR                     \
118   __attribute__((constructor))
119 #define UL_ATTR_DESCRUCTOR                      \
120   __attribute__((destructor))
121 #define UL_ATTR_ALWAYS_INLINE                   \
122   __attribute__((always_inline))
123 #define UL_ATTR_WEAK                            \
124   __attribute__((weak))
125 #endif  /*UL_ATTR_UNUSED*/
126 #else   /* !__GNUC__ */
127 #ifndef UL_ATTR_UNUSED
128 #define UL_ATTR_PRINTF( format_idx, arg_idx )
129 #define UL_ATTR_SCANF( format_idx, arg_idx )
130 #define UL_ATTR_FORMAT( arg_idx )
131 #define UL_ATTR_NORETURN
132 #define UL_ATTR_CONST
133 #define UL_ATTR_UNUSED
134 #define UL_ATTR_CONSTRUCTOR
135 #define UL_ATTR_DESCRUCTOR
136 #define UL_ATTR_ALWAYS_INLINE
137 #define UL_ATTR_WEAK
138 #endif  /*UL_ATTR_UNUSED*/
139 #endif  /* !__GNUC__ */
140
141 #ifndef UL_ATTR_REENTRANT
142 #if (!defined(SDCC) && !defined(__SDCC)) || defined(SDCC_z80) || defined(__SDCC_z80)
143   #define UL_ATTR_REENTRANT
144 #else
145   #define UL_ATTR_REENTRANT __reentrant
146 #endif
147 #endif /*UL_ATTR_REENTRANT*/
148
149 /* The cast idea based on libHX by Jan Engelhardt */
150 #define UL_TYPEOF_REFX(ref_asterisks, ptr_type) \
151   typeof(ref_asterisks(union { int z; typeof(ptr_type) x; }){0}.x)
152
153 #ifdef  __GNUC__
154 /* Const and volatile qualifiers removal cast
155  * The expression is cast by (typeof((typeof(new_type[1])){0}[0]))
156  * which is equivalent to (new_type) cast for matching types.
157  * This quite complicated method is used because both comma operator
158  * and compound expressions are not allowed in global variables
159  * initializers.
160  */
161 #define UL_CAST_UNQX(ref_asterisks, new_type, expr) ( \
162   (typeof((typeof(new_type[1 - 2 * \
163     !__builtin_types_compatible_p \
164     (UL_TYPEOF_REFX(ref_asterisks, expr), \
165      UL_TYPEOF_REFX(ref_asterisks, new_type)) \
166     ])){0}[0]) \
167   ) \
168   (expr) \
169 )
170 #else /*__GNUC__*/
171 #define UL_CAST_UNQX(ref_asterisks, new_type, expr) ((new_type)(expr))
172 #endif /*__GNUC__*/
173
174 #define UL_CAST_UNQ1(new_type, expr) \
175   UL_CAST_UNQX(*, new_type, expr)
176
177 #define UL_CAST_UNQ2(new_type, expr) \
178   UL_CAST_UNQX(**, new_type, expr)
179
180 #define UL_CAST_UNQ3(new_type, expr) \
181   UL_CAST_UNQX(**, new_type, expr)
182
183 #ifdef __cplusplus
184 } /* extern "C"*/
185 #endif
186
187 #endif /* _UL_UTDEFS_H */