Skip to content

Instantly share code, notes, and snippets.

@C0deH4cker
Created June 10, 2015 08:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save C0deH4cker/cbb972d2b360647ab5ed to your computer and use it in GitHub Desktop.
Save C0deH4cker/cbb972d2b360647ab5ed to your computer and use it in GitHub Desktop.
Python's with statement, implemented in C++ via macros
// Just like C#'s using statement and Python's with statement.
// This allows use of a resource within a code block, after which
// the declared object's destructor will clean up.
// There's nothing about `with` that doesn't work in C, but it is
// pointless in standard C as there are no destructors.
// Multiple with statements can be nested as well, so it works as
// you'd expect. If for some bizarre reason you need to put multiple
// using statements on the same line, I've added another version,
// defined below as with_inline.
//
// Example:
//
// void runOnlyTenTimes() {
// static std::mutex runCountMutex;
// static int timesRun = 0;
//
// with (std::lock_guard<std::mutex> lock(runCountMutex)) {
// if(timesRun == 10) {
// return;
// }
//
// ++timesRun;
// }
//
// actuallyRun();
// }
#define with(...) _with(__LINE__, __VA_ARGS__)
#define _with(id, ...) __with(id, __VA_ARGS__)
#define __with(id, ...) \
for(int _with_##id = 1; _with_##id; _with_##id = 0) \
for(__VA_ARGS__; _with_##id; _with_##id = 0)
// Same as with, except this version works even when multiple with
// statements are used on the same line (probably ugly code though)
#define with_inline(...) _with(__COUNTER__, __VA_ARGS__)
#include "with.h"
#include <iostream>
using namespace std;
struct A {
int val;
A(int x): val(x) {
cout << "A(" << val << ") constructed!" << endl;
}
virtual ~A() {
cout << "A(" << val << ") destroyed!" << endl;
}
};
struct B: public A {
B(int x): A(x) {
cout << "B(" << val << ") constructed!" << endl;
}
virtual ~B() {
cout << "B(" << val << ") destroyed!" << endl;
}
};
int main() {
cout << "In main()" << endl;
with(A a1(42), a2(69)) {
cout << "In with body" << endl;
}
cout << "Between with statements" << endl;
with_inline(A a(1337)) with_inline(B b(31337)) {
cout << "In with_inline body" << endl;
}
cout << "Returning from main()" << endl;
return 0;
}
/*
Output:
In main()
A(42) constructed!
A(69) constructed!
In with body
A(69) destroyed!
A(42) destroyed!
Between with statements
A(1337) constructed!
A(31337) constructed!
B(31337) constructed!
In with_inline body
B(31337) destroyed!
A(31337) destroyed!
A(1337) destroyed!
Returning from main()
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment