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