]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/thread/with_lock_guard.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / thread / with_lock_guard.hpp
1 // (C) Copyright 2013 Ruslan Baratov
2 // Copyright (C) 2014 Vicente J. Botet Escriba
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 // See www.boost.org/libs/thread for documentation.
8
9 #ifndef BOOST_THREAD_WITH_LOCK_GUARD_HPP
10 #define BOOST_THREAD_WITH_LOCK_GUARD_HPP
11
12 #include <boost/thread/lock_guard.hpp>
13 #include <boost/utility/result_of.hpp>
14 //#include <boost/thread/detail/invoke.hpp>
15
16 namespace boost {
17
18 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
19 !defined(BOOST_NO_CXX11_DECLTYPE) && \
20 !defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
21
22 /**
23 * Utility to run functions in scope protected by mutex.
24 *
25 * Examples:
26 *
27 * int func(int, int&);
28 * boost::mutex m;
29 * int a;
30 * int result = boost::with_lock_guard(m, func, 1, boost::ref(a));
31 *
32 * // using boost::bind
33 * int result = boost::with_lock_guard(
34 * m, boost::bind(func, 2, boost::ref(a))
35 * );
36 *
37 * // using lambda
38 * int a;
39 * int result = boost::with_lock_guard(
40 * m,
41 * [&a](int x) {
42 * a = 3;
43 * return x + 4;
44 * },
45 * 5
46 * );
47 */
48 template <class Lockable, class Function, class... Args>
49 typename boost::result_of<Function(Args...)>::type with_lock_guard(
50 Lockable& m,
51 BOOST_FWD_REF(Function) func,
52 BOOST_FWD_REF(Args)... args
53 ) //-> decltype(func(boost::forward<Args>(args)...))
54 {
55 boost::lock_guard<Lockable> lock(m);
56 return func(boost::forward<Args>(args)...);
57 }
58
59 #else
60
61 // Workaround versions for compilers without c++11 variadic templates support.
62 // (function arguments limit: 4)
63 // (for lambda support define BOOST_RESULT_OF_USE_DECLTYPE may be needed)
64
65 template <class Lockable, class Func>
66 typename boost::result_of<Func()>::type with_lock_guard(
67 Lockable& m,
68 BOOST_FWD_REF(Func) func
69 ) {
70 boost::lock_guard<Lockable> lock(m);
71 return func();
72 }
73
74 template <class Lockable, class Func, class Arg>
75 typename boost::result_of<Func(Arg)>::type with_lock_guard(
76 Lockable& m,
77 BOOST_FWD_REF(Func) func,
78 BOOST_FWD_REF(Arg) arg
79 ) {
80 boost::lock_guard<Lockable> lock(m);
81 return func(
82 boost::forward<Arg>(arg)
83 );
84 }
85
86 template <class Lockable, class Func, class Arg1, class Arg2>
87 typename boost::result_of<Func(Arg1, Arg2)>::type with_lock_guard(
88 Lockable& m,
89 BOOST_FWD_REF(Func) func,
90 BOOST_FWD_REF(Arg1) arg1,
91 BOOST_FWD_REF(Arg2) arg2
92 ) {
93 boost::lock_guard<Lockable> lock(m);
94 return func(
95 boost::forward<Arg1>(arg1),
96 boost::forward<Arg2>(arg2)
97 );
98 }
99
100 template <class Lockable, class Func, class Arg1, class Arg2, class Arg3>
101 typename boost::result_of<Func(Arg1, Arg2, Arg3)>::type with_lock_guard(
102 Lockable& m,
103 BOOST_FWD_REF(Func) func,
104 BOOST_FWD_REF(Arg1) arg1,
105 BOOST_FWD_REF(Arg2) arg2,
106 BOOST_FWD_REF(Arg3) arg3
107 ) {
108 boost::lock_guard<Lockable> lock(m);
109 return func(
110 boost::forward<Arg1>(arg1),
111 boost::forward<Arg2>(arg2),
112 boost::forward<Arg3>(arg3)
113 );
114 }
115
116 template <
117 class Lockable, class Func, class Arg1, class Arg2, class Arg3, class Arg4
118 >
119 typename boost::result_of<Func(Arg1, Arg2, Arg3, Arg4)>::type with_lock_guard(
120 Lockable& m,
121 BOOST_FWD_REF(Func) func,
122 BOOST_FWD_REF(Arg1) arg1,
123 BOOST_FWD_REF(Arg2) arg2,
124 BOOST_FWD_REF(Arg3) arg3,
125 BOOST_FWD_REF(Arg4) arg4
126 ) {
127 boost::lock_guard<Lockable> lock(m);
128 return func(
129 boost::forward<Arg1>(arg1),
130 boost::forward<Arg2>(arg2),
131 boost::forward<Arg3>(arg3),
132 boost::forward<Arg4>(arg4)
133 );
134 }
135
136 // overloads for function pointer
137 // (if argument is not function pointer, static assert will trigger)
138 template <class Lockable, class Func>
139 typename boost::result_of<
140 typename boost::add_pointer<Func>::type()
141 >::type with_lock_guard(
142 Lockable& m,
143 Func* func
144 ) {
145 BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
146
147 boost::lock_guard<Lockable> lock(m);
148 return func();
149 }
150
151 template <class Lockable, class Func, class Arg>
152 typename boost::result_of<
153 typename boost::add_pointer<Func>::type(Arg)
154 >::type with_lock_guard(
155 Lockable& m,
156 Func* func,
157 BOOST_FWD_REF(Arg) arg
158 ) {
159 BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
160
161 boost::lock_guard<Lockable> lock(m);
162 return func(
163 boost::forward<Arg>(arg)
164 );
165 }
166
167 template <class Lockable, class Func, class Arg1, class Arg2>
168 typename boost::result_of<
169 typename boost::add_pointer<Func>::type(Arg1, Arg2)
170 >::type with_lock_guard(
171 Lockable& m,
172 Func* func,
173 BOOST_FWD_REF(Arg1) arg1,
174 BOOST_FWD_REF(Arg2) arg2
175 ) {
176 BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
177
178 boost::lock_guard<Lockable> lock(m);
179 return func(
180 boost::forward<Arg1>(arg1),
181 boost::forward<Arg2>(arg2)
182 );
183 }
184
185 template <class Lockable, class Func, class Arg1, class Arg2, class Arg3>
186 typename boost::result_of<
187 typename boost::add_pointer<Func>::type(Arg1, Arg2, Arg3)
188 >::type with_lock_guard(
189 Lockable& m,
190 Func* func,
191 BOOST_FWD_REF(Arg1) arg1,
192 BOOST_FWD_REF(Arg2) arg2,
193 BOOST_FWD_REF(Arg3) arg3
194 ) {
195 BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
196
197 boost::lock_guard<Lockable> lock(m);
198 return func(
199 boost::forward<Arg1>(arg1),
200 boost::forward<Arg2>(arg2),
201 boost::forward<Arg3>(arg3)
202 );
203 }
204
205 template <
206 class Lockable, class Func, class Arg1, class Arg2, class Arg3, class Arg4
207 >
208 typename boost::result_of<
209 typename boost::add_pointer<Func>::type(Arg1, Arg2, Arg3, Arg4)
210 >::type with_lock_guard(
211 Lockable& m,
212 Func* func,
213 BOOST_FWD_REF(Arg1) arg1,
214 BOOST_FWD_REF(Arg2) arg2,
215 BOOST_FWD_REF(Arg3) arg3,
216 BOOST_FWD_REF(Arg4) arg4
217 ) {
218 BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
219
220 boost::lock_guard<Lockable> lock(m);
221 return func(
222 boost::forward<Arg1>(arg1),
223 boost::forward<Arg2>(arg2),
224 boost::forward<Arg3>(arg3),
225 boost::forward<Arg4>(arg4)
226 );
227 }
228
229 #endif
230
231 } // namespace boost
232
233 #endif // BOOST_THREAD_WITH_LOCK_GUARD_HPP
234