summaryrefslogtreecommitdiff
path: root/source/kit/defer.h
diff options
context:
space:
mode:
Diffstat (limited to 'source/kit/defer.h')
-rw-r--r--source/kit/defer.h39
1 files changed, 39 insertions, 0 deletions
diff --git a/source/kit/defer.h b/source/kit/defer.h
new file mode 100644
index 0000000..bb78b69
--- /dev/null
+++ b/source/kit/defer.h
@@ -0,0 +1,39 @@
+// Requres GCC or Clang with `-fblocks` option available.
+//
+
+#ifndef KIT_DEFER_H
+#define KIT_DEFER_H
+
+#if !defined(__clang__) && !defined(__APPLE__)
+# error C blocks support required
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunused-function"
+# pragma GCC diagnostic ignored "-Wunknown-pragmas"
+#endif
+
+static void kit_defer_cleanup_(void (^*b)(void)) { (*b)(); }
+
+#define kit_defer_merge_(a,b) a##b
+#define kit_defer_varname_(a) \
+ kit_defer_merge_(kit_defer_scopevar_,a)
+#define defer \
+ __attribute__((unused, cleanup(kit_defer_cleanup_))) \
+ void (^kit_defer_varname_(__COUNTER__))(void) = ^
+#define defer_ref __block
+
+#if defined(__GNUC__) || defined(__clang__)
+# pragma GCC diagnostic pop
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif