#pragma once #define DEF_SCOPED_TYPE(NAME, TYPE, UNOCCUPIED, CLEANUP_FN) \ static inline TYPE _scoped_##NAME##_unoccupied(void) { \ return (UNOCCUPIED); \ } \ static inline void _scoped_##NAME##_cleanup(TYPE *_val) { \ CLEANUP_FN(*_val); \ *_val = (UNOCCUPIED); \ } \ static inline void _scoped_##NAME##_cleanup_raw(void *_val) { \ _scoped_##NAME##_cleanup((TYPE *)_val); \ } \ static inline TYPE _scoped_##NAME##_release(TYPE *_val) { \ TYPE _released = *_val; \ *_val = (UNOCCUPIED); \ return _released; \ } #define SCOPED(NAME, TYPE, VAL) \ TYPE VAL __attribute__((cleanup(_scoped_##NAME##_cleanup_raw))) = _scoped_##NAME##_unoccupied()