Last active
December 21, 2015 01:09
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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