solidc
Robust collection of general-purpose cross-platform C libraries and data structures designed for rapid and safe development in C
Loading...
Searching...
No Matches
defer.h
Go to the documentation of this file.
1
62#ifndef __DEFER__H
63#define __DEFER__H
64
65#include <stddef.h>
66
67#ifdef _WIN32
68#define ATTR_UNUSED
69#else
70#define ATTR_UNUSED __attribute__((__unused__))
71#endif
72
73// Macro helpers
74#define _DEFER_CONCAT_IMPL(a, b) a##b
75#define _DEFER_CONCAT(a, b) _DEFER_CONCAT_IMPL(a, b)
76
77//******************************************************************************
78//* *
79//* C++ IMPLEMENTATION *
80//* *
81//******************************************************************************
82
83#ifdef __cplusplus
84
85#include <utility>
86
87// 1. The RAII Holder that runs the lambda on destruction
88template <typename F>
89struct Deferrer {
90 F f;
91 Deferrer(F&& func) : f(std::forward<F>(func)) {}
92 ~Deferrer() { f(); }
93 Deferrer(const Deferrer&) = delete;
94 Deferrer& operator=(const Deferrer&) = delete;
95};
96
97// 2. A dummy helper tag to trigger operator overloading
98struct DeferHelper {};
99
100// 3. Operator+ overload to capture the lambda
101// This allows the syntax: DeferHelper() + [&](){ ... }
102template <typename F>
103Deferrer<F> operator+(DeferHelper, F&& f) {
104 return Deferrer<F>(std::forward<F>(f));
105}
106
107// 4. The Macro
108// Expands to: auto _var_N = DeferHelper() + [&]() { user_code };
109#define defer auto _DEFER_CONCAT(__defer_var_, __COUNTER__) = DeferHelper() + [&]()
110
111//******************************************************************************
112//* *
113//* C IMPLEMENTATION - GCC *
114//* *
115//******************************************************************************
116
117#elif defined(__GNUC__) && !defined(__clang__)
136#define __DEFER(N) __DEFER_(N)
137#define __DEFER_(N) __DEFER__(_DEFER_CONCAT(__defer_fn_, N), _DEFER_CONCAT(__defer_var_, N))
138
149#define __DEFER__(F, V) \
150 auto void F(int*); \
151 [[gnu::cleanup(F)]] ATTR_UNUSED int V; \
152 auto void F(int* _unused ATTR_UNUSED)
153
162#define defer __DEFER(__COUNTER__)
163
164//******************************************************************************
165//* *
166//* C IMPLEMENTATION - CLANG *
167//* *
168//******************************************************************************
169
170#elif defined(__clang__)
171
192#include <Block.h>
193
197typedef void (^defer_block)(void);
198
203static inline void __defer_cleanup(defer_block* ptr) {
204 if (ptr && *ptr) {
205 (*ptr)();
206 }
207}
208
209// Macro helpers
210#define _DEFER_CONCAT_IMPL(a, b) a##b
211#define _DEFER_CONCAT(a, b) _DEFER_CONCAT_IMPL(a, b)
212
223#define defer \
224 __attribute__((cleanup(__defer_cleanup))) ATTR_UNUSED defer_block _DEFER_CONCAT(__defer_var_, __COUNTER__) = ^
225
226//******************************************************************************
227//* *
228//* C IMPLEMENTATION - MSVC *
229//* *
230//******************************************************************************
231
232#elif defined(_MSC_VER)
233
268#elif defined(_MSC_VER)
269
270// Uses SEH __try/__finally
271// Expands to: __try { } __finally { user_code }
272#define defer \
273 __try { \
274 } __finally
275
276#else
277#error "Unsupported compiler"
278#endif
279
280#endif // __DEFER__H