Skip to content

Instantly share code, notes, and snippets.

@alexeiz
Last active December 21, 2015 01:09
Show Gist options
  • Save alexeiz/6225788 to your computer and use it in GitHub Desktop.
Save alexeiz/6225788 to your computer and use it in GitHub Desktop.
Simple "scope exit" macro for C++03, which supports arbitrary actions on scope exit.
#include <iostream>
using namespace std;
#define JOIN(a, b) JOIN_(a, b)
#define JOIN_(a, b) a ## b
#define ARG_COUNT(...) ARG_COUNT_IMP(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define ARG_COUNT_IMP( _1,_2,_3,_4,_5,_6,_7,_8,_9, N, ...) N
#define MACRO_DISPATCH(macro, ...) MACRO_DISPATCH_(macro, ARG_COUNT(__VA_ARGS__))
#define MACRO_DISPATCH_(macro, argc) MACRO_DISPATCH__(macro, argc)
#define MACRO_DISPATCH__(macro, argc) macro ## argc
#define SCOPE_EXIT(...) MACRO_DISPATCH(SCOPE_EXIT, __VA_ARGS__) (__VA_ARGS__)
#define SCOPE_EXIT3(type1, arg1, \
code) \
class JOIN(scope_exit, __LINE__) \
{ \
public: \
JOIN(scope_exit, __LINE__) \
(type1 & arg1_par) \
: arg1(arg1_par) \
{} \
\
~ JOIN(scope_exit, __LINE__) () \
{ \
code \
} \
\
private: \
type1 & arg1; \
}; \
\
JOIN(scope_exit, __LINE__) \
JOIN(guard, __LINE__) (arg1) \
#define SCOPE_EXIT5(type1, arg1, \
type2, arg2, \
code) \
class JOIN(scope_exit, __LINE__) \
{ \
public: \
JOIN(scope_exit, __LINE__) \
(type1 & arg1_par, \
type2 & arg2_par) \
: arg1(arg1_par) \
, arg2(arg2_par) \
{} \
\
~ JOIN(scope_exit, __LINE__) () \
{ \
code \
} \
\
private: \
type1 & arg1; \
type2 & arg2; \
}; \
\
JOIN(scope_exit, __LINE__) \
JOIN(guard, __LINE__) (arg1, \
arg2) \
#define SCOPE_EXIT7(type1, arg1, \
type2, arg2, \
type3, arg3, \
code) \
class JOIN(scope_exit, __LINE__) \
{ \
public: \
JOIN(scope_exit, __LINE__) \
(type1 & arg1_par, \
type2 & arg2_par, \
type3 & arg3_par) \
: arg1(arg1_par) \
, arg2(arg2_par) \
, arg3(arg3_par) \
{} \
\
~ JOIN(scope_exit, __LINE__) () \
{ \
code \
} \
\
private: \
type1 & arg1; \
type2 & arg2; \
type3 & arg3; \
}; \
\
JOIN(scope_exit, __LINE__) \
JOIN(guard, __LINE__) (arg1, \
arg2, \
arg3) \
int main()
{
int a = 10;
SCOPE_EXIT(int, a,
{ cout << a << endl; });
bool dismissed = false;
SCOPE_EXIT(int, a,
bool, dismissed,
{ if (!dismissed)
cout << a << endl;
});
int a1 = 1;
int a2 = 2;
SCOPE_EXIT(int, a1,
int, a2,
bool, dismissed,
{
if (!dismissed)
cout << a1 << " : " << a2 << endl;
});
dismissed = true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment