Make c++ defer looks like a swift one

This commit is contained in:
Bartosz Przybylski
2015-12-04 11:03:39 +01:00
parent b08610bc3e
commit 0e5c7ddfb8
6 changed files with 30 additions and 23 deletions

View File

@@ -18,11 +18,12 @@
#ifndef __SWIFT_DEFER_H
#define __SWIFT_DEFER_H
#include <type_traits>
namespace swift {
template <typename F>
class DoAtScopeExit {
F &Fn;
DoAtScopeExit(DoAtScopeExit&) = delete;
void operator=(DoAtScopeExit&) = delete;
public:
DoAtScopeExit(F &Fn) : Fn(Fn){}
@@ -30,8 +31,17 @@ namespace swift {
Fn();
}
};
namespace detail {
struct DeferTask {};
template<typename F>
DoAtScopeExit<typename std::decay<F>::type> operator+(DeferTask, F&& fn) {
return DoAtScopeExit<typename std::decay<F>::type>(fn);
}
}
}
#define DEFER_CONCAT_IMPL(x, y) x##y
#define DEFER_MACRO_CONCAT(x, y) DEFER_CONCAT_IMPL(x, y)
@@ -39,16 +49,13 @@ namespace swift {
/// This macro is used to register a function / lambda to be run on exit from a
/// scope. Its typical use looks like:
///
/// defer([&]{
/// defer {
/// stuff
/// })
/// };
///
#define defer(x) \
auto DEFER_MACRO_CONCAT(defer_func, __LINE__) = (x); \
swift::DoAtScopeExit<decltype(DEFER_MACRO_CONCAT(defer_func, __LINE__))> \
DEFER_MACRO_CONCAT(defer_local, __LINE__)\
(DEFER_MACRO_CONCAT(defer_func, __LINE__));
#define defer \
auto DEFER_MACRO_CONCAT(defer_func, __COUNTER__) = \
::swift::detail::DeferTask() + [&]()
#endif