| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| namespace slicer { |
| |
| // A simple and lightweight scope guard and macro |
| // (inspired by Andrei Alexandrescu's C++11 Scope Guard) |
| // |
| // Here is how it's used: |
| // |
| // FILE* file = std::fopen(...); |
| // SLICER_SCOPE_EXIT { |
| // std::fclose(file); |
| // }; |
| // |
| // "file" will be closed at the end of the enclosing scope, |
| // regardless of how the scope is exited |
| // |
| class ScopeGuardHelper |
| { |
| template<class T> |
| class ScopeGuard |
| { |
| public: |
| explicit ScopeGuard(T closure) : |
| closure_(std::move(closure)) |
| { |
| } |
| |
| ~ScopeGuard() |
| { |
| closure_(); |
| } |
| |
| // move constructor only |
| ScopeGuard(ScopeGuard&&) = default; |
| ScopeGuard(const ScopeGuard&) = delete; |
| ScopeGuard& operator=(const ScopeGuard&) = delete; |
| ScopeGuard& operator=(ScopeGuard&&) = delete; |
| |
| private: |
| T closure_; |
| }; |
| |
| public: |
| template<class T> |
| ScopeGuard<T> operator<<(T closure) |
| { |
| return ScopeGuard<T>(std::move(closure)); |
| } |
| }; |
| |
| #define SLICER_SG_MACRO_CONCAT2(a, b) a ## b |
| #define SLICER_SG_MACRO_CONCAT(a, b) SLICER_SG_MACRO_CONCAT2(a, b) |
| #define SLICER_SG_ANONYMOUS(prefix) SLICER_SG_MACRO_CONCAT(prefix, __COUNTER__) |
| |
| #define SLICER_SCOPE_EXIT \ |
| auto SLICER_SG_ANONYMOUS(_scope_guard_) = slicer::ScopeGuardHelper() << [&]() |
| |
| } // namespace slicer |
| |