Initialize Tizen 2.3
[framework/web/wrt-commons.git] / modules_mobile / 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() throw()
75     {
76         m_function();
77     }
78
79     FunctionType m_function;
80     bool m_released;
81 };
82
83 template<typename FunctionType>
84 inline ScopeGuard<typename std::decay<FunctionType>::type>
85 MakeScopeGuard(FunctionType&& function)
86 {
87   return ScopeGuard<typename std::decay<FunctionType>::type>(
88           std::forward<FunctionType>(function));
89 }
90
91 namespace detail {
92 enum class ScopeGuardOnExit {};
93
94 template <typename FunctionType>
95 inline ScopeGuard<typename std::decay<FunctionType>::type>
96 operator+(detail::ScopeGuardOnExit, FunctionType&& function)
97 {
98   return ScopeGuard<typename std::decay<FunctionType>::type>(
99           std::forward<FunctionType>(function));
100 }
101 }
102 }
103
104 // FIXME provide support for compilers not supporting variadic macros;
105 //       instead of using variadic macros (for compatibility) we could
106 //       capture all by '&' (only referenced variables would be captured)
107 #define DPL_SCOPE_EXIT(...) \
108     auto DPL_ANONYMOUS_VARIABLE(DPL_SCOPE_EXIT_STATE) \
109     = ::DPL::detail::ScopeGuardOnExit() + [__VA_ARGS__]()
110
111 #endif // DPL_SCOPE_GUARD_H_