Skip to content

Instantly share code, notes, and snippets.

@castano
Created July 24, 2013 23:49
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save castano/6075672 to your computer and use it in GitHub Desktop.
Save castano/6075672 to your computer and use it in GitHub Desktop.
Various ways to emulate D's scope statements in C++. See http://the-witness.net/news/2012/11/scopeexit-in-c11/
// For C++11 support compile with:
// clang++ -std=c++11 -stdlib=libc++ scope.cpp
#include <stdio.h>
#include <stdlib.h>
template <typename F>
struct ScopeExit {
ScopeExit(F f) : f(f) {}
~ScopeExit() { f(); }
F f;
};
template <typename F>
ScopeExit<F> MakeScopeExit(F f) {
return ScopeExit<F>(f);
};
#define STRING_JOIN2(arg1, arg2) DO_STRING_JOIN2(arg1, arg2)
#define DO_STRING_JOIN2(arg1, arg2) arg1 ## arg2
#define SCOPE_EXIT(code) auto STRING_JOIN2(scope_exit_, __LINE__) = MakeScopeExit([=](){code;})
//#if NV_CC_MSVC && __cplusplus <= 199711L
#if defined(_MSC_VER) && __cplusplus <= 199711L
struct ExitFunc {
virtual ~ExitFunc() {};
};
struct OnExit {
OnExit(ExitFunc * f) : f(f) {}
~OnExit() { delete f; }
ExitFunc * f;
};
#define EXIT_FUNC : public ExitFunc
#else
#define EXIT_FUNC
#endif
template <typename T>
struct DeleteFunc EXIT_FUNC {
DeleteFunc(T t) : t(t) {}
~DeleteFunc() { delete t; }
T t;
};
template <typename T>
DeleteFunc<T> * MakeDeleteFunc(T t) { return new DeleteFunc<T>(t); }
template <typename T>
struct DeleteArrayFunc EXIT_FUNC {
DeleteArrayFunc(T t) : t(t) {}
~DeleteArrayFunc() { delete [] t; }
T t;
};
template <typename T>
DeleteFunc<T> * MakeDeleteArrayFunc(T t) { return new DeleteArrayFunc<T>(t); }
struct FileCloseFunc EXIT_FUNC {
FileCloseFunc(FILE * fp) : fp(fp) {}
~FileCloseFunc() { fclose(fp); }
FILE * fp;
};
struct FreeFunc {
FreeFunc(void * p) : p(p) {}
~FreeFunc() { free(p); }
void * p;
};
// MSVC:
#if defined(_MSC_VER) && __cplusplus <= 199711L
#define Delete_On_Exit(p) OnExit STRING_JOIN2(on_exit_, __LINE__)(MakeDeleteFunc(p))
#define Delete_Array_On_Exit(p) OnExit STRING_JOIN2(on_exit_, __LINE__)(MakeDeleteFunc(p))
#elif __cplusplus > 199711L
// C++11:
#define Delete_On_Exit(p) DeleteFunc<decltype(p)> STRING_JOIN2(on_exit_, __LINE__)(p)
#define Delete_Array_On_Exit(p) DeleteFunc<decltype(p)> STRING_JOIN2(on_exit_, __LINE__)(p)
#else
// gcc
#define Delete_On_Exit(p) DeleteFunc<__typeof(p)> STRING_JOIN2(on_exit_, __LINE__)(p)
#define Delete_Array_On_Exit(p) DeleteFunc<__typeof(p)> STRING_JOIN2(on_exit_, __LINE__)(p)
#endif
#define Close_On_Exit(fp) FileCloseFunc STRING_JOIN2(on_exit_, __LINE__)(fp)
#define Free_On_Exit(p) FreeFunc STRING_JOIN2(on_exit_, __LINE__)(p)
int main(void)
{
int * ip = new int;
SCOPE_EXIT(delete ip);
ip = new int;
Delete_On_Exit(ip);
FILE * fp = fopen("test.out", "wb");
//SCOPE_EXIT(fclose(fp));
Close_On_Exit(fp);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment