1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#ifndef _LIBHX_CAST_H
#define _LIBHX_CAST_H 1
#ifdef __cplusplus
# ifndef const_cast
# define const_cast(T, x) const_cast<T>(x)
# endif
# ifndef static_cast
# define static_cast(T, x) static_cast<T>(x)
# endif
# define const_cast1(type, expr) const_cast<type>(expr)
# define const_cast2(type, expr) const_cast<type>(expr)
# define const_cast3(type, expr) const_cast<type>(expr)
template<typename new_type>
static __inline__ new_type signed_cast(const char *expr)
{
return reinterpret_cast<new_type>(expr);
}
template<typename new_type>
static __inline__ new_type signed_cast(const signed char *expr)
{
return reinterpret_cast<new_type>(expr);
}
template<typename new_type>
static __inline__ new_type signed_cast(const unsigned char *expr)
{
return reinterpret_cast<new_type>(expr);
}
template<typename new_type>
static __inline__ new_type signed_cast(char *expr)
{
return reinterpret_cast<new_type>(expr);
}
template<typename new_type>
static __inline__ new_type signed_cast(signed char *expr)
{
return reinterpret_cast<new_type>(expr);
}
template<typename new_type>
static __inline__ new_type signed_cast(unsigned char *expr)
{
return reinterpret_cast<new_type>(expr);
}
#else
/* N.B. signed_cast<> does not exist in C++. */
# define __signed_cast_compatible(a, b) \
__builtin_choose_expr( \
__builtin_types_compatible_p(b, const char *) || \
__builtin_types_compatible_p(b, const signed char *) || \
__builtin_types_compatible_p(b, const unsigned char *), \
/* if src has a const qualifier */ \
__builtin_types_compatible_p(a, const char *) || \
__builtin_types_compatible_p(a, const signed char *) || \
__builtin_types_compatible_p(a, const unsigned char *), \
/* and if it has none... */ \
__builtin_types_compatible_p(a, const char *) || \
__builtin_types_compatible_p(a, const signed char *) || \
__builtin_types_compatible_p(a, const unsigned char *) || \
__builtin_types_compatible_p(a, char *) || \
__builtin_types_compatible_p(a, signed char *) || \
__builtin_types_compatible_p(a, unsigned char *) \
)
# if defined(__GNUC__) && !defined(__clang__) && !defined(signed_cast)
# define signed_cast(type, expr) ({ \
BUILD_BUG_ON(!__signed_cast_compatible(__typeof__(type), __typeof__(expr))); \
(type)(expr); \
})
# endif
# if defined(__GNUC__) && !defined(__clang__) && !defined(static_cast)
# define static_cast(type, expr) \
((struct { type x; }){(expr)}.x)
# endif
# if defined(__GNUC__) && !defined(__clang__) && !defined(const_cast1)
/*
* The idea starts with (in abstract notation)
* typeof deref typeof expr
* To deref something, we need an object, which we can get by
* creating a temporary aggregate, such as a union, of which
* the member is accessed and dereferenced.
* *(union { __typeof__(expr) x; }){init}.x
* union has two nice properties:
* - with an additional dummy member, we do not have to
* initialize x according to its type, which, if expr is
* an array type, may want extra braces.
* - and with that dummy member, we also avoid the ugly
* "literal 0 is implicitly convertible to a pointer".
* Unfortunately, this all requires C99 compound initializers.
* That's ok - gcc and clang only treat it as a warning even
* under strict C89 - and if you still force strict C89 on
* yourself, you have a lot to answer for either way.
*/
# define __const_cast_strip(ptrs, expr) \
__typeof__(ptrs(union { int z; __typeof__(expr) x; }){0}.x)
# define __const_cast_p(ptrs, new_type, expr) ((new_type)( \
(expr) + \
BUILD_BUG_ON_EXPR(!__builtin_types_compatible_p(__const_cast_strip(ptrs, expr), __const_cast_strip(ptrs, new_type))) \
))
# define const_cast1(new_type, expr) __const_cast_p(*, new_type, expr)
# define const_cast2(new_type, expr) __const_cast_p(**, new_type, expr)
# define const_cast3(new_type, expr) __const_cast_p(***, new_type, expr)
# endif
# ifndef signed_cast
# define signed_cast(type, expr) ((type)(expr))
# endif
# ifndef static_cast
# define static_cast(type, expr) ((type)(expr))
# endif
# ifndef const_cast
# define const_cast(type, expr) ((type)(expr))
# endif
# ifndef const_cast1
# define const_cast1(type, expr) ((type)(expr))
# define const_cast2(type, expr) ((type)(expr))
# define const_cast3(type, expr) ((type)(expr))
# endif
# ifndef reinterpret_cast
# define reinterpret_cast(type, expr) ((type)(expr))
# endif
#endif
#endif /* _LIBHX_CAST_H */
|