Skip to content

Instantly share code, notes, and snippets.

@nitrix
Created January 11, 2021 18:54
Show Gist options
  • Save nitrix/4add19fe1ecf84bbab574ebefd2824d3 to your computer and use it in GitHub Desktop.
Save nitrix/4add19fe1ecf84bbab574ebefd2824d3 to your computer and use it in GitHub Desktop.
defer attempt
#ifndef DEFER_H
#define DEFER_H
struct guard_metadata {
int labels[32];
size_t label_count;
bool run_mode;
int at;
};
#define concat(x, y) x##y
#define concat2(x, y) concat(x, y)
#define leave \
_guard_ptr->run_mode = 1; \
continue
#define guard \
struct guard_metadata concat2(_guard_, __LINE__) = {{0}, 0, false, 0}; \
struct guard_metadata *_guard_ptr = &concat2(_guard_, __LINE__); \
goto concat2(_into_, __LINE__); \
while ((_guard_ptr->run_mode = true) && _guard_ptr->at < _guard_ptr->label_count) \
switch (_guard_ptr->labels[_guard_ptr->at]) \
concat2(_into_, __LINE__) :
#define defer \
_guard_ptr->labels[_guard_ptr->label_count++] = __LINE__; \
case __LINE__: \
goto concat2(_skip_bail_switch, __LINE__); \
concat2(_bail_switch, __LINE__) : break; \
concat2(_skip_bail_switch, __LINE__) : while (_guard_ptr->run_mode) if (_guard_ptr->labels[_guard_ptr->at] != __LINE__) { \
goto concat2(_bail_switch, __LINE__); \
} \
else if (_guard_ptr->at++, _guard_ptr->run_mode)
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment