]> rtime.felk.cvut.cz Git - ulut.git/blob - ulut/ul_utdefs.h
uLUt: do not include malloc.h, use stdlib.h through ul_utmalloc.h.
[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 #include <stddef.h> /* For size_t */
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 #if defined(_WIN32)&&defined(_MSC_VER)&&!defined(inline)
19 #define inline _inline
20 #endif
21
22 #if !defined(UL_BUILD_BUG_ON_MSG_LINE) && defined(__OPTIMIZE__) && \
23   ((__GNUC__ * 1000 + __GNUC_MINOR__) >= 4004)
24 #define UL_BUILD_BUG_ON_MSG_LINE_EXP1(condition, msg, line) \
25 ({ \
26   if (!!(condition)) { \
27     void compile_time_bug_on_line_ ## line (void) __attribute__((error(msg))); \
28     compile_time_bug_on_line_ ## line (); \
29   } \
30 })
31 #define UL_BUILD_BUG_ON_MSG_LINE(condition, msg, line) \
32   UL_BUILD_BUG_ON_MSG_LINE_EXP1(condition, msg, line)
33 #endif /*UL_BUILD_BUG_ON_MSG for GCC*/
34
35 #ifndef UL_BUILD_BUG_ON_MSG_LINE
36 #define UL_BUILD_BUG_ON_MSG_LINE(condition, msg, line) \
37   ((void)sizeof(char[1 - 2*!!(condition)]))
38 #endif /*UL_BUILD_BUG_ON_MSG*/
39
40 #ifndef UL_BUILD_BUG_ON_MSG
41 #define UL_BUILD_BUG_ON_MSG(condition, msg) \
42   UL_BUILD_BUG_ON_MSG_LINE(condition, msg, __LINE__)
43 #endif /*UL_BUILD_BUG_ON_MSG*/
44
45 #ifndef UL_BUILD_BUG_ON
46 #define UL_BUILD_BUG_ON(condition) \
47   UL_BUILD_BUG_ON_MSG(condition, "Build time check " #condition " failed")
48 #endif /*UL_BUILD_BUG_ON*/
49
50 #if !defined(UL_OFFSETOF) && defined(__GNUC__) && __GNUC__ >= 4
51 #define UL_OFFSETOF(_type, _member) __builtin_offsetof(_type, _member)
52 #endif /*UL_OFFSETOF*/
53
54 #ifndef UL_OFFSETOF
55 /* offset of structure field */
56 #define UL_OFFSETOF(_type,_member) \
57                 ((size_t)&(((_type*)0)->_member))
58 #endif /*UL_OFFSET*/
59
60 #ifndef UL_CONTAINEROF
61 #ifdef  __GNUC__
62 #define UL_CONTAINEROF(_ptr, _type, _member) ({ \
63         const typeof( ((_type *)0)->_member ) *__mptr = (_ptr); \
64         (_type *)( (char *)__mptr - UL_OFFSETOF(_type,_member) );})
65 #else /*!__GNUC__*/
66 #define UL_CONTAINEROF(_ptr, _type, _member) \
67         ((_type *)( (char *)_ptr - UL_OFFSETOF(_type,_member)))
68 #endif /*__GNUC__*/
69 #endif /*UL_CONTAINEROF*/
70
71 #ifndef UL_ALIGNOF_FIELD
72 #define UL_ALIGNOF_FIELD(_type) UL_OFFSETOF(struct {char _fld0; _type _fld1;}, _fld1)
73 #endif /*UL_ALIGNOF*/
74
75 #ifndef UL_ALIGNOF_TYPE
76 #ifdef  __GNUC__
77 /* The compiler provided alignment for performance can differ from ABI struct one */
78 #define UL_ALIGNOF_TYPE(_type) __alignof__(_type)
79 #else /*__GNUC__*/
80 #define UL_ALIGNOF_TYPE UL_ALIGNOF_FIELD
81 #endif /*__GNUC__*/
82 #endif /*UL_ALIGNOF*/
83
84 #ifndef UL_ALIGNOF
85 #define UL_ALIGNOF UL_ALIGNOF_FIELD
86 #endif /*UL_ALIGNOF*/
87
88
89 #ifndef UL_NOPSTATEMENT
90 #define UL_NOPSTATEMENT do { } while(0)
91 #endif
92
93 #ifndef ul_cyclic_gt
94 #define ul_cyclic_gt(x,y) \
95         ((sizeof(x)>=sizeof(long long))&&(sizeof(y)>=sizeof(long long))? \
96                 (long long)((unsigned long long)(x)-(unsigned long long)(y))>0: \
97          (sizeof(x)>=sizeof(long))&&(sizeof(y)>=sizeof(long))? \
98                 (long)((unsigned long)(x)-(unsigned long)(y))>0: \
99          (sizeof(x)>=sizeof(int))&&(sizeof(y)>=sizeof(int))? \
100                 (int)((unsigned int)(x)-(unsigned int)(y))>0: \
101          (sizeof(x)>=sizeof(short))&&(sizeof(y)>=sizeof(short))? \
102                 (short)((unsigned short)(x)-(unsigned short)(y))>0: \
103          (signed char)((unsigned char)(x)-(unsigned char)(y))>0 \
104         )
105 #endif /*ul_cyclic_gt*/
106
107 #ifndef ul_cyclic_ge
108 #define ul_cyclic_ge(x,y) \
109         ((sizeof(x)>=sizeof(long long))&&(sizeof(y)>=sizeof(long long))? \
110                 (long long)((unsigned long long)(x)-(unsigned long long)(y))>=0: \
111          (sizeof(x)>=sizeof(long))&&(sizeof(y)>=sizeof(long))? \
112                 (long)((unsigned long)(x)-(unsigned long)(y))>=0: \
113          (sizeof(x)>=sizeof(int))&&(sizeof(y)>=sizeof(int))? \
114                 (int)((unsigned int)(x)-(unsigned int)(y))>=0: \
115          (sizeof(x)>=sizeof(short))&&(sizeof(y)>=sizeof(short))? \
116                 (short)((unsigned short)(x)-(unsigned short)(y))>=0: \
117          (signed char)((unsigned char)(x)-(unsigned char)(y))>=0 \
118         )
119 #endif /*ul_cyclic_ge*/
120
121 /* GNUC neat features */
122
123 #ifdef  __GNUC__
124 #ifndef UL_ATTR_UNUSED
125 #define UL_ATTR_PRINTF( format_idx, arg_idx )   \
126   __attribute__((format (printf, format_idx, arg_idx)))
127 #define UL_ATTR_SCANF( format_idx, arg_idx )    \
128   __attribute__((format (scanf, format_idx, arg_idx)))
129 #define UL_ATTR_FORMAT( arg_idx )               \
130   __attribute__((format_arg (arg_idx)))
131 #define UL_ATTR_NORETURN                        \
132   __attribute__((noreturn))
133 #define UL_ATTR_CONST                           \
134   __attribute__((const))
135 #define UL_ATTR_UNUSED                          \
136   __attribute__((unused))
137 #define UL_ATTR_CONSTRUCTOR                     \
138   __attribute__((constructor))
139 #define UL_ATTR_DESCRUCTOR                      \
140   __attribute__((destructor))
141 #define UL_ATTR_ALWAYS_INLINE                   \
142   __attribute__((always_inline))
143 #define UL_ATTR_WEAK                            \
144   __attribute__((weak))
145 #endif  /*UL_ATTR_UNUSED*/
146 #else   /* !__GNUC__ */
147 #ifndef UL_ATTR_UNUSED
148 #define UL_ATTR_PRINTF( format_idx, arg_idx )
149 #define UL_ATTR_SCANF( format_idx, arg_idx )
150 #define UL_ATTR_FORMAT( arg_idx )
151 #define UL_ATTR_NORETURN
152 #define UL_ATTR_CONST
153 #define UL_ATTR_UNUSED
154 #define UL_ATTR_CONSTRUCTOR
155 #define UL_ATTR_DESCRUCTOR
156 #define UL_ATTR_ALWAYS_INLINE
157 #define UL_ATTR_WEAK
158 #endif  /*UL_ATTR_UNUSED*/
159 #endif  /* !__GNUC__ */
160
161 #ifndef UL_ATTR_REENTRANT
162 #if (!defined(SDCC) && !defined(__SDCC)) || defined(SDCC_z80) || defined(__SDCC_z80)
163   #define UL_ATTR_REENTRANT
164 #else
165   #define UL_ATTR_REENTRANT __reentrant
166 #endif
167 #endif /*UL_ATTR_REENTRANT*/
168
169 /* The cast idea based on libHX by Jan Engelhardt */
170 #define UL_TYPEOF_REFX(ref_asterisks, ptr_type) \
171   typeof(ref_asterisks(union { int z; typeof(ptr_type) x; }){0}.x)
172
173 /* Const and volatile qualifiers removal cast */
174 #ifdef __cplusplus
175 #define UL_CAST_UNQX(ref_asterisks, new_type, expr) \
176             (const_cast<new_type>(expr))
177 #else /* Standard C code */
178 #ifdef __GNUC__
179 #if  ((__GNUC__ * 1000 + __GNUC_MINOR__) >= 4004)
180 extern void* UL_CAST_UNQX_types_not_compatible(void)
181   __attribute__((error ("UL_CAST_UNQX types differ not only by volatile and const")));
182 #else
183 extern void UL_CAST_UNQX_types_not_compatible(void);
184 #endif
185 #define UL_CAST_UNQX(ref_asterisks, new_type, expr) ( \
186   __builtin_choose_expr(__builtin_types_compatible_p \
187     (UL_TYPEOF_REFX(ref_asterisks, expr), \
188      UL_TYPEOF_REFX(ref_asterisks, new_type)), \
189     (new_type)(expr), \
190     UL_CAST_UNQX_types_not_compatible() \
191   ) \
192 )
193 #define UL_CAST_UNQX_NULL_ALLOWED(ref_asterisks, new_type, expr) ( \
194   __builtin_choose_expr(!__builtin_types_compatible_p(void *, typeof(expr)), \
195     UL_CAST_UNQX(ref_asterisks, new_type, expr), \
196     expr \
197   ) \
198 )
199 #else /*__GNUC__*/
200 #define UL_CAST_UNQX(ref_asterisks, new_type, expr) ((new_type)(expr))
201 #endif /*__GNUC__*/
202 #endif /*__cplusplus*/
203
204 #define UL_CAST_UNQ1(new_type, expr) \
205   UL_CAST_UNQX(*, new_type, expr)
206
207 #define UL_CAST_UNQ2(new_type, expr) \
208   UL_CAST_UNQX(**, new_type, expr)
209
210 #define UL_CAST_UNQ3(new_type, expr) \
211   UL_CAST_UNQX(**, new_type, expr)
212
213 #ifndef UL_CAST_UNQX_NULL_ALLOWED
214 #define UL_CAST_UNQX_NULL_ALLOWED(ref_asterisks, new_type, expr) \
215   UL_CAST_UNQX(ref_asterisks, new_type, expr)
216 #endif /*UL_CAST_UNQX_NULL_ALLOWED*/
217
218 #define UL_CAST_UNQ1_NULL_ALLOWED(new_type, expr) \
219   UL_CAST_UNQX_NULL_ALLOWED(*, new_type, expr)
220
221 #ifdef __cplusplus
222 } /* extern "C"*/
223 #endif
224
225 #endif /* _UL_UTDEFS_H */