diff options
| author | Lexi Winter <ivy@FreeBSD.org> | 2025-05-13 14:17:40 +0100 |
|---|---|---|
| committer | Lexi Winter <ivy@FreeBSD.org> | 2025-05-13 14:17:40 +0100 |
| commit | 7de7af9042f3b4196478a86cd273b3b7f63c42f6 (patch) | |
| tree | feb277747effbd5b09af65584af950a45bacb4db | |
| parent | 313713b24c6d2a3061972c4f431515c4f1b01c77 (diff) | |
sys/cdefs.h: add __const_castlf/dev/const-cast
| -rw-r--r-- | sys/sys/cdefs.h | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h index e79cf2972f3f..b3c055301f61 100644 --- a/sys/sys/cdefs.h +++ b/sys/sys/cdefs.h @@ -832,4 +832,44 @@ #define __align_down(x, y) __builtin_align_down(x, y) #define __is_aligned(x, y) __builtin_is_aligned(x, y) +/* + * __const_cast: a const-safe cast. + * + * Use it like this: + * + * __const_cast(type, pointer, return-type, expression) + * + * 'pointer' should be a pointer to an object of type 'type'. If 'pointer' + * points to a const 'type', then the return value will be cast to + * 'const return-type', otherwise the return value will be cast to + * 'return-type'. In either case, the return value is 'expression'. + * + * For example, a const-safe macro to cast a pointer to an array of char to a + * pointer to an array of uint8_t: + * + * #define GETBYTES(s) __const_cast(char, (s), uint8_t, (s)) + */ + +#ifdef __cplusplus +template<typename... _Ts> +struct __const_cast_visitor : _Ts... { using _Ts::operator()...; }; +template<typename... _Ts> +__const_cast_visitor(_Ts...) -> __const_cast_visitor<_Ts...>; +#define __const_cast(T, p, U, expr) \ + (__const_cast_visitor{ \ + [&](const T *) -> const U { \ + return reinterpret_cast<const U>(expr); \ + }, \ + [&](T *) -> U { \ + return reinterpret_cast<U>(expr); \ + } \ + })(p) +#else +#define __const_cast(T, p, U, expr) \ + _Generic((p), \ + const T *: (const U)expr, \ + T *: (U)expr \ + ) +#endif + #endif /* !_SYS_CDEFS_H_ */ |
