Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
71 lines (53 sloc) 1.37 KB
#pragma once
/**
* A golang like DEFER macro.
*
* Usage:
*
* You could use the DEFER macro for deferred actions e.g. for a file closing:
*
* FILE* file = fopen("sample.txt", "rb");
* DEFER {
* fclose(file);
* };
*/
/* Based on: http://blog.memsql.com/c-error-handling-with-auto/ */
#include <utility>
namespace defer_internal {
template <class DeferCallback>
class DeferMonitor {
public:
explicit DeferMonitor(DeferCallback&& callback)
: enabled_(true)
, callback_(std::move(callback))
{ }
DeferMonitor(DeferMonitor&& right)
: enabled_(true)
, callback_(std::move(right.callback_))
{
right.enabled_ = false;
}
~DeferMonitor()
{
if (enabled_) {
callback_();
}
}
private:
bool enabled_;
DeferCallback callback_;
};
struct MakeDeferMonitor {
MakeDeferMonitor()
{ }
template <class DeferCallback>
DeferMonitor<DeferCallback> operator== (DeferCallback&& callback) const
{
return DeferMonitor<DeferCallback>(std::move(callback));
}
};
const MakeDeferMonitor MAKE_DEFER_MONITOR;
} // namespace defer_internal
#define DEFER_PP__CONCAT(x, y) x ## y
#define DEFER_PP_CONCAT(x, y) DEFER_PP__CONCAT(x, y)
#define DEFER const auto DEFER_PP_CONCAT(defer_monitor_, __COUNTER__) = ::defer_internal::MAKE_DEFER_MONITOR == [&]()->void