Skip to content

Instantly share code, notes, and snippets.

@killwing
Created February 6, 2013 09:44
Show Gist options
  • Save killwing/4721462 to your computer and use it in GitHub Desktop.
Save killwing/4721462 to your computer and use it in GitHub Desktop.
[ScopeGuard] encapsulates scoped control flow from @andrei
#ifndef SCOPEGUARD_H
#define SCOPEGUARD_H
template <typename Fun>
class ScopeGuard {
public:
ScopeGuard(Fun f) : f_(std::move(f)), active_(true) {}
~ScopeGuard() {
if (active_) {
f_();
}
}
void dismiss() { active_ = false; }
ScopeGuard() = delete;
ScopeGuard(const ScopeGuard&) = delete;
ScopeGuard& operator=(const ScopeGuard&) = delete;
ScopeGuard(ScopeGuard&& rhs) : f_(std::move(rhs.f_)), active_(rhs.active_) {
rhs.dismiss();
}
private:
Fun f_;
bool active_;
};
template <typename Fun>
ScopeGuard<Fun> scopeGuard(Fun f) {
return ScopeGuard<Fun>(std::move(f));
}
namespace detail {
enum class ScopeGuardOnExit {};
template <typename Fun>
ScopeGuard<Fun> operator+(ScopeGuardOnExit, Fun&& fn) {
return ScopeGuard<Fun>(std::forward<Fun>(fn));
}
}
#define SCOPE_EXIT \
auto ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE) = ::detail::ScopeGuardOnExit() + [&]()
#define CONCATENATE_IMPL(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2)
#ifdef __COUNTER__
#define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __COUNTER__)
#else
#define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
#endif
#endif // SCOPEGUARD_H
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "ScopeGuard.h"
using namespace std;
int main() {
char name[] = "/tmp/deleteme.XXXXXX";
auto fd = mkstemp(name);
auto g1 = scopeGuard([&] {
close(fd);
unlink(name);
cout << "close & unlink" << endl;
});
auto g2 = scopeGuard([] {
cout << "not called" << endl;
});
auto buf = malloc(1024 * 1024);
SCOPE_EXIT {
free(buf);
cout << "free" << endl;
};
// ... use fd and buf ...
g2.dismiss();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment