Skip to content

Instantly share code, notes, and snippets.

@nlyan
Last active January 18, 2016 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nlyan/7319c7b2a6328460ce9c to your computer and use it in GitHub Desktop.
Save nlyan/7319c7b2a6328460ce9c to your computer and use it in GitHub Desktop.
Pythons 'with' statement in C++
#include <type_traits>
template <template <typename...> class With, typename T> inline
decltype(auto)
make_with_guard (T& value) {
return With<T>(value);
}
#define PP_CAT(A, B) PP_CAT_X(A, B)
#define PP_CAT_X(A, B) A ## B
#define PP_UNIQUE(BASE) PP_CAT(BASE, __LINE__)
#define WITH_IMPL(T, OBJ, GUARD) \
struct PP_CAT(GUARD,_t) { \
T<std::remove_reference<decltype(OBJ)>::type> guard; \
operator bool() const noexcept { return false; } \
}; \
if (PP_CAT(GUARD,_t) GUARD = {make_with_guard<T>(OBJ)}) { \
(void) GUARD; \
} else
#define WITH(T,OBJ) WITH_IMPL(T, OBJ, \
PP_UNIQUE(with_guard_for_line_))
/*
* Example usage
*/
#include <iostream>
template <typename T>
struct inc_dec {
T& x;
inc_dec(T& r): x(r) { ++x; }
~inc_dec() { --x; }
};
int main() {
int i = 0;
std::cout << i << std::endl;
WITH (inc_dec, i) {
std::cout << i << std::endl;
}
std::cout << i << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment