1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. 2 // This source code is licensed under both the GPLv2 (found in the 3 // COPYING file in the root directory) and Apache 2.0 License 4 // (found in the LICENSE.Apache file in the root directory). 5 6 #pragma once 7 8 #include <folly/Traits.h> 9 10 #include <utility> 11 #include <type_traits> 12 13 namespace folly { 14 namespace scope_guard_detail { 15 template <typename F> 16 class ScopeGuardImpl { 17 public: ScopeGuardImpl(F && f)18 explicit ScopeGuardImpl(F&& f) : f_{std::forward<F>(f)} {} ~ScopeGuardImpl()19 ~ScopeGuardImpl() { 20 f_(); 21 } 22 23 private: 24 F f_; 25 }; 26 27 enum class ScopeGuardEnum {}; 28 template <typename Func, typename DecayedFunc = _t<std::decay<Func>>> 29 ScopeGuardImpl<DecayedFunc> operator+(ScopeGuardEnum, Func&& func) { 30 return ScopeGuardImpl<DecayedFunc>{std::forward<Func>(func)}; 31 } 32 } // namespace scope_guard_detail 33 } // namespace folly 34 35 /** 36 * FB_ANONYMOUS_VARIABLE(str) introduces an identifier starting with 37 * str and ending with a number that varies with the line. 38 */ 39 #ifndef FB_ANONYMOUS_VARIABLE 40 #define FB_CONCATENATE_IMPL(s1, s2) s1##s2 41 #define FB_CONCATENATE(s1, s2) FB_CONCATENATE_IMPL(s1, s2) 42 #ifdef __COUNTER__ 43 #define FB_ANONYMOUS_VARIABLE(str) \ 44 FB_CONCATENATE(FB_CONCATENATE(FB_CONCATENATE(str, __COUNTER__), _), __LINE__) 45 #else 46 #define FB_ANONYMOUS_VARIABLE(str) FB_CONCATENATE(str, __LINE__) 47 #endif 48 #endif 49 50 #ifndef SCOPE_EXIT 51 #define SCOPE_EXIT \ 52 auto FB_ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE) = \ 53 ::folly::scope_guard_detail::ScopeGuardEnum{} + [&]() noexcept 54 #endif 55