Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@IMelker
Last active May 17, 2021 06: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 IMelker/7516849e0ca7e5d9bb243aa8c5df19bd to your computer and use it in GitHub Desktop.
Save IMelker/7516849e0ca7e5d9bb243aa8c5df19bd to your computer and use it in GitHub Desktop.
RAI Initializer for C style inits
#ifndef SCOPEEXEC_H_
#define SCOPEEXEC_H_
#include <type_traits>
template <typename OnCreate, typename OnExit, class Enable = void>
class ScopeExec {
using OnCreateResultType = typename std::result_of_t<OnCreate(void)>;
public:
explicit ScopeExec(OnCreate onCreate, OnExit onExit)
: onCreate(onCreate), onExit(onExit) {
rc = onCreate();
};
~ScopeExec() { reset(); }
auto creteResult() const { return rc; };
void reset() {
if (!exitEmitted) {
exitEmitted = true;
onExit();
}
}
private:
OnCreate onCreate;
OnExit onExit;
OnCreateResultType rc;
bool exitEmitted = false;
};
template <typename OnCreate, typename OnExit>
class ScopeExec<OnCreate, OnExit, typename std::enable_if_t<std::is_void_v<std::result_of_t<OnCreate(void)>>>> {
public:
ScopeExec(OnCreate onCreate, OnExit onExit) : onCreate(onCreate), onExit(onExit) { onCreate(); }
~ScopeExec() { reset(); }
void reset() {
if (!exitEmitted) {
exitEmitted = true;
onExit();
}
}
private:
OnCreate onCreate;
OnExit onExit;
bool exitEmitted = false;
};
#endif // SCOPEEXEC_H_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment