The Auto macro
  Auto macroI’ve been talking about this one since 2014. The contents of “Auto.h” fit comfortably on a single slide:
#pragma once
template<class L>
class AtScopeExit {
    L& m_lambda;
public:
    AtScopeExit(L& action) : m_lambda(action) {}
    ~AtScopeExit() noexcept(false) { m_lambda(); }
};
#define TOKEN_PASTEx(x, y) x ## y
#define TOKEN_PASTE(x, y) TOKEN_PASTEx(x, y)
#define Auto_INTERNAL1(lname, aname, ...) \
    auto lname = [&]() { __VA_ARGS__; }; \
    AtScopeExit<decltype(lname)> aname(lname);
#define Auto_INTERNAL2(ctr, ...) \
    Auto_INTERNAL1(TOKEN_PASTE(Auto_func_, ctr), \
        TOKEN_PASTE(Auto_instance_, ctr), __VA_ARGS__)
#define Auto(...) \
    Auto_INTERNAL2(__COUNTER__, __VA_ARGS__)
Wrap any arbitrary amount of code in Auto(...) to generate a hygienic “scope guard.”
bool Mutate(State *state)
{
    state->DisableLogging();
    Auto(state->EnableLogging());
    if (!state->AttemptOperation1()) return false;
    if (!state->AttemptOperation2()) return false;
    return true;
}
This scope guard has perfect codegen with zero overhead
(at -O2) on all major compilers. Because it requires no explicit captures, no novel
variable name, and no special treatment for this, it is highly suited for
mechanically generated code. It is portable all the way back to C++11.
void Example()
{
    Auto(
        puts("starting the first Auto");
        Auto(puts("cleaning up in the second Auto"));
        puts("getting ready to clean up in the first Auto");
    );
    puts("doing the main operation");
}

See also:
- “Feature requests for the 
Automacro” (2024-02-14) 
    Posted 2018-08-11
  
  
  
