s3-client: Remove use of cli_errstr()
[Samba/gebeck_regimport.git] / lib / ccan / cast / cast.h
blobdaebd8572391f07dfb17ae20c341c114c2507c3d
1 #ifndef CCAN_CAST_H
2 #define CCAN_CAST_H
3 #include "config.h"
4 #include <stdint.h>
5 #include <ccan/build_assert/build_assert.h>
7 /**
8 * cast_signed - cast a (const) char * to/from (const) signed/unsigned char *.
9 * @type: some char * variant.
10 * @expr: expression (of some char * variant) to cast.
12 * Some libraries insist on an unsigned char in various places; cast_signed
13 * makes sure (with suitable compiler) that the expression you are casting
14 * only differs in signed/unsigned, not in type or const-ness.
16 #define cast_signed(type, expr) \
17 ((type)(expr) \
18 + BUILD_ASSERT_OR_ZERO(cast_sign_compatible(type, (expr))))
20 /**
21 * cast_const - remove a const qualifier from a pointer.
22 * @type: some pointer type.
23 * @expr: expression to cast.
25 * This ensures that you are only removing the const qualifier from an
26 * expression. The expression must otherwise match @type.
28 * If @type is a pointer to a pointer, you must use cast_const2 (etc).
30 * Example:
31 * // Dumb open-coded strstr variant.
32 * static char *find_needle(const char *haystack)
33 * {
34 * size_t i;
35 * for (i = 0; i < strlen(haystack); i++)
36 * if (memcmp("needle", haystack+i, strlen("needle")) == 0)
37 * return cast_const(char *, haystack+i);
38 * return NULL;
39 * }
41 #define cast_const(type, expr) \
42 ((type)((intptr_t)(expr) \
43 + BUILD_ASSERT_OR_ZERO(cast_const_compat1((expr), type))))
45 /**
46 * cast_const2 - remove a const qualifier from a pointer to a pointer.
47 * @type: some pointer to pointer type.
48 * @expr: expression to cast.
50 * This ensures that you are only removing the const qualifier from an
51 * expression. The expression must otherwise match @type.
53 #define cast_const2(type, expr) \
54 ((type)((intptr_t)(expr) \
55 + BUILD_ASSERT_OR_ZERO(cast_const_compat2((expr), type))))
57 /**
58 * cast_const3 - remove a const from a pointer to a pointer to a pointer..
59 * @type: some pointer to pointer to pointer type.
60 * @expr: expression to cast.
62 * This ensures that you are only removing the const qualifier from an
63 * expression. The expression must otherwise match @type.
65 #define cast_const3(type, expr) \
66 ((type)((intptr_t)(expr) \
67 + BUILD_ASSERT_OR_ZERO(cast_const_compat3((expr), type))))
70 /**
71 * cast_static - explicit mimic of implicit cast.
72 * @type: some type.
73 * @expr: expression to cast.
75 * This ensures that the cast is not to or from a pointer: it can only be
76 * an implicit cast, such as a pointer to a similar const pointer, or between
77 * integral types.
79 #if HAVE_COMPOUND_LITERALS
80 #define cast_static(type, expr) \
81 ((struct { type x; }){(expr)}.x)
82 #else
83 #define cast_static(type, expr) \
84 ((type)(expr))
85 #endif
87 /* Herein lies the gcc magic to evoke compile errors. */
88 #if HAVE_BUILTIN_CHOOSE_EXPR && HAVE_BUILTIN_TYPES_COMPATIBLE_P && HAVE_TYPEOF
89 #define cast_sign_compatible(t, e) \
90 __builtin_choose_expr( \
91 __builtin_types_compatible_p(__typeof__(t), char *) || \
92 __builtin_types_compatible_p(__typeof__(t), signed char *) || \
93 __builtin_types_compatible_p(__typeof__(t), unsigned char *), \
94 /* if type is not const qualified */ \
95 __builtin_types_compatible_p(__typeof__(e), char *) || \
96 __builtin_types_compatible_p(__typeof__(e), signed char *) || \
97 __builtin_types_compatible_p(__typeof__(e), unsigned char *), \
98 /* and if it is... */ \
99 __builtin_types_compatible_p(__typeof__(e), const char *) || \
100 __builtin_types_compatible_p(__typeof__(e), const signed char *) || \
101 __builtin_types_compatible_p(__typeof__(e), const unsigned char *) ||\
102 __builtin_types_compatible_p(__typeof__(e), char *) || \
103 __builtin_types_compatible_p(__typeof__(e), signed char *) || \
104 __builtin_types_compatible_p(__typeof__(e), unsigned char *) \
107 #define cast_const_strip1(expr) \
108 __typeof__(*(struct { int z; __typeof__(expr) x; }){0}.x)
109 #define cast_const_strip2(expr) \
110 __typeof__(**(struct { int z; __typeof__(expr) x; }){0}.x)
111 #define cast_const_strip3(expr) \
112 __typeof__(***(struct { int z; __typeof__(expr) x; }){0}.x)
113 #define cast_const_compat1(expr, type) \
114 __builtin_types_compatible_p(cast_const_strip1(expr), \
115 cast_const_strip1(type))
116 #define cast_const_compat2(expr, type) \
117 __builtin_types_compatible_p(cast_const_strip2(expr), \
118 cast_const_strip2(type))
119 #define cast_const_compat3(expr, type) \
120 __builtin_types_compatible_p(cast_const_strip3(expr), \
121 cast_const_strip3(type))
122 #else
123 #define cast_sign_compatible(type, expr) \
124 (sizeof(*(type)0) == 1 && sizeof(*(expr)) == 1)
125 #define cast_const_compat1(expr, type) (1)
126 #define cast_const_compat2(expr, type) (1)
127 #define cast_const_compat3(expr, type) (1)
128 #endif
129 #endif /* CCAN_CAST_H */