#ifndef MAG_DEFER_H #define MAG_DEFER_H /** * Zig-like defer macro for (gc)C and C++ * * Based on: * https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/ * - but works with gcc(C), g++ and non-gcc c++ compilers. * - so it only does not work for other C compilers. * * Rem.: This [[gnu::always_inline]] * basically means __attribute__((always_inline)) */ #ifdef __cplusplus template struct __df_st : T { [[gnu::always_inline]] inline __df_st(T g) : T(g) { // empty } [[gnu::always_inline]] inline ~__df_st() { T::operator()(); } }; #define __DEFER__(V) __df_st const V = [&](void)->void #define defer __DEFER(__COUNTER__) #define __DEFER(N) __DEFER_(N) #define __DEFER_(N) __DEFER__(__DEFER_VARIABLE_ ## N) #else #define __DEFER__(F, V) \ [[gnu::always_inline]] inline auto void F(int*); \ [[gnu::cleanup(F)]] int V; \ [[gnu::always_inline]] inline auto void F(int*) #define defer __DEFER(__COUNTER__) #define __DEFER(N) __DEFER_(N) #define __DEFER_(N) __DEFER__(__DEFER_FUNCTION_ ## N, __DEFER_VARIABLE_ ## N) #endif /* __cplusplus */ #endif /* MAG_DEFER_H */