Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <cstdlib>
- #include <memory>
- #include <iostream>
- #include <string>
- template <typename Lambda>
- class ScopeGuard
- {
- public:
- ScopeGuard(Lambda&& func)
- : committed_(false) // Please one line per variable
- // Just like in normal code
- // were you declare one variable per line.
- , valid_(true)
- , rollbackFunc_(std::move(func)) // Need the move again.
- {} ~ScopeGuard() noexcept
- {
- if (valid_ && !committed_)
- rollbackFunc_();
- }
- ScopeGuard(const ScopeGuard&) = delete;
- ScopeGuard& operator=(const ScopeGuard&) = delete;
- ScopeGuard(ScopeGuard&& other) noexcept
- : committed_(false)
- , valid_(false)
- , rollbackFunc_([]() {})
- {
- swap(other);
- }
- ScopeGuard& operator=(ScopeGuard&& other) noexcept
- {
- swap(other);
- other.valid_ = false;
- return *this;
- }
- void swap(ScopeGuard& other) noexcept
- {
- using std::swap;
- swap(committed_, other.committed_);
- swap(valid_, other.valid_);
- swap(rollbackFunc_, other.rollbackFunc_);
- }
- void commit() { committed_ = true; }
- private:
- bool committed_;
- bool valid_;
- Lambda rollbackFunc_;
- };
- template <typename Lambda>
- ScopeGuard<Lambda> makeScopeGuard(Lambda&& func)
- {
- return ScopeGuard<Lambda>(std::move(func)); // Need the move here
- // a named value is not an r-value ref.
- }
- #define MY_CONCATENATE_NX(A, B) A ## B
- #define MY_CONCATENATE(A, B) MY_CONCATENATE_NX(A, B)
- #define SCOPE_EXIT(f) auto MY_CONCATENATE(EXIT, __LINE__) = makeScopeGuard(f);
- void test() {
- auto guard1 = makeScopeGuard([]() { });
- auto guard2 = makeScopeGuard([]() { });
- guard2 = guard1; // can not move assign.
- }
- int main() {
- test();
- return EXIT_SUCCESS;
- }
Add Comment
Please, Sign In to add comment