Initialize Tizen 2.3
[framework/web/wrt-commons.git] / modules / core / include / dpl / scope_guard.h
1 /*
2  * Copyright 2013 Facebook, Inc.
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  * @file        scope_guard.h
18  * @author      Zbigniew Kostrzewa (z.kostrzewa@samsung.com)
19  * @version     1.0
20  * @brief       This file is the implementation file of scope guard RAII
21  */
22 #ifndef DPL_SCOPE_GUARD_H_
23 #define DPL_SCOPE_GUARD_H_
24
25 #include <cstddef>
26 #include <utility>
27 #include <new>
28 #include <type_traits>
29 #include <dpl/preprocessor.h>
30
31 namespace DPL {
32 template<typename FunctionType>
33 class ScopeGuard
34 {
35   public:
36     explicit ScopeGuard(const FunctionType& function)
37         : m_function{function},
38           m_released{false}
39     {}
40
41     explicit ScopeGuard(FunctionType&& function)
42         : m_function{std::move(function)},
43           m_released{false}
44     {}
45
46     ScopeGuard(ScopeGuard&& other)
47         : m_function{std::move(other.m_function)},
48           m_released{other.m_released}
49     {
50         other.Release();
51     }
52
53     ScopeGuard(const ScopeGuard&) = delete;
54
55     ~ScopeGuard()
56     {
57         if (!m_released)
58         {
59             Execute();
60         }
61     }
62
63     ScopeGuard& operator=(const ScopeGuard&) = delete;
64
65     void Release()
66     {
67         m_released = true;
68     }
69
70     void* operator new(size_t) = delete;
71
72   private:
73     // FIXME change to noexcept when available
74     void Execute()
75     {
76         try {
77             m_function();
78         } catch(...) {}
79     }
80
81     FunctionType m_function;
82     bool m_released;
83 };
84
85 template<typename FunctionType>
86 inline ScopeGuard<typename std::decay<FunctionType>::type>
87 MakeScopeGuard(FunctionType&& function)
88 {
89   return ScopeGuard<typename std::decay<FunctionType>::type>(
90           std::forward<FunctionType>(function));
91 }
92
93 namespace detail {
94 enum class ScopeGuardOnExit {};
95
96 template <typename FunctionType>
97 inline ScopeGuard<typename std::decay<FunctionType>::type>
98 operator+(detail::ScopeGuardOnExit, FunctionType&& function)
99 {
100   return ScopeGuard<typename std::decay<FunctionType>::type>(
101           std::forward<FunctionType>(function));
102 }
103 }
104 }
105
106 // FIXME provide support for compilers not supporting variadic macros;
107 //       instead of using variadic macros (for compatibility) we could
108 //       capture all by '&' (only referenced variables would be captured)
109 #define DPL_SCOPE_EXIT(...) \
110     auto DPL_ANONYMOUS_VARIABLE(DPL_SCOPE_EXIT_STATE) \
111     = ::DPL::detail::ScopeGuardOnExit() + [__VA_ARGS__]()
112
113 #endif // DPL_SCOPE_GUARD_H_