1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <utility> 20 21 namespace slicer { 22 23 // A simple and lightweight scope guard and macro 24 // (inspired by Andrei Alexandrescu's C++11 Scope Guard) 25 // 26 // Here is how it's used: 27 // 28 // FILE* file = std::fopen(...); 29 // SLICER_SCOPE_EXIT { 30 // std::fclose(file); 31 // }; 32 // 33 // "file" will be closed at the end of the enclosing scope, 34 // regardless of how the scope is exited 35 // 36 class ScopeGuardHelper 37 { 38 template<class T> 39 class ScopeGuard 40 { 41 public: ScopeGuard(T closure)42 explicit ScopeGuard(T closure) : 43 closure_(std::move(closure)) 44 { 45 } 46 ~ScopeGuard()47 ~ScopeGuard() 48 { 49 closure_(); 50 } 51 52 // move constructor only 53 ScopeGuard(ScopeGuard&&) = default; 54 ScopeGuard(const ScopeGuard&) = delete; 55 ScopeGuard& operator=(const ScopeGuard&) = delete; 56 ScopeGuard& operator=(ScopeGuard&&) = delete; 57 58 private: 59 T closure_; 60 }; 61 62 public: 63 template<class T> 64 ScopeGuard<T> operator<<(T closure) 65 { 66 return ScopeGuard<T>(std::move(closure)); 67 } 68 }; 69 70 #define SLICER_SG_MACRO_CONCAT2(a, b) a ## b 71 #define SLICER_SG_MACRO_CONCAT(a, b) SLICER_SG_MACRO_CONCAT2(a, b) 72 #define SLICER_SG_ANONYMOUS(prefix) SLICER_SG_MACRO_CONCAT(prefix, __COUNTER__) 73 74 #define SLICER_SCOPE_EXIT \ 75 auto SLICER_SG_ANONYMOUS(_scope_guard_) = slicer::ScopeGuardHelper() << [&]() 76 77 } // namespace slicer 78 79