1 // (C) Copyright 2013 Ruslan Baratov
2 // Copyright (C) 2014 Vicente J. Botet Escriba
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)
7 // See www.boost.org/libs/thread for documentation.
9 #ifndef BOOST_THREAD_WITH_LOCK_GUARD_HPP
10 #define BOOST_THREAD_WITH_LOCK_GUARD_HPP
12 #include <boost/thread/lock_guard.hpp>
13 #include <boost/utility/result_of.hpp>
14 //#include <boost/thread/detail/invoke.hpp>
18 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
19 !defined(BOOST_NO_CXX11_DECLTYPE) && \
20 !defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
23 * Utility to run functions in scope protected by mutex.
27 * int func(int, int&);
30 * int result = boost::with_lock_guard(m, func, 1, boost::ref(a));
32 * // using boost::bind
33 * int result = boost::with_lock_guard(
34 * m, boost::bind(func, 2, boost::ref(a))
39 * int result = boost::with_lock_guard(
48 template <class Lockable, class Function, class... Args>
49 typename boost::result_of<Function(Args...)>::type with_lock_guard(
51 BOOST_FWD_REF(Function) func,
52 BOOST_FWD_REF(Args)... args
53 ) //-> decltype(func(boost::forward<Args>(args)...))
55 boost::lock_guard<Lockable> lock(m);
56 return func(boost::forward<Args>(args)...);
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)
65 template <class Lockable, class Func>
66 typename boost::result_of<Func()>::type with_lock_guard(
68 BOOST_FWD_REF(Func) func
70 boost::lock_guard<Lockable> lock(m);
74 template <class Lockable, class Func, class Arg>
75 typename boost::result_of<Func(Arg)>::type with_lock_guard(
77 BOOST_FWD_REF(Func) func,
78 BOOST_FWD_REF(Arg) arg
80 boost::lock_guard<Lockable> lock(m);
82 boost::forward<Arg>(arg)
86 template <class Lockable, class Func, class Arg1, class Arg2>
87 typename boost::result_of<Func(Arg1, Arg2)>::type with_lock_guard(
89 BOOST_FWD_REF(Func) func,
90 BOOST_FWD_REF(Arg1) arg1,
91 BOOST_FWD_REF(Arg2) arg2
93 boost::lock_guard<Lockable> lock(m);
95 boost::forward<Arg1>(arg1),
96 boost::forward<Arg2>(arg2)
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(
103 BOOST_FWD_REF(Func) func,
104 BOOST_FWD_REF(Arg1) arg1,
105 BOOST_FWD_REF(Arg2) arg2,
106 BOOST_FWD_REF(Arg3) arg3
108 boost::lock_guard<Lockable> lock(m);
110 boost::forward<Arg1>(arg1),
111 boost::forward<Arg2>(arg2),
112 boost::forward<Arg3>(arg3)
117 class Lockable, class Func, class Arg1, class Arg2, class Arg3, class Arg4
119 typename boost::result_of<Func(Arg1, Arg2, Arg3, Arg4)>::type with_lock_guard(
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
127 boost::lock_guard<Lockable> lock(m);
129 boost::forward<Arg1>(arg1),
130 boost::forward<Arg2>(arg2),
131 boost::forward<Arg3>(arg3),
132 boost::forward<Arg4>(arg4)
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(
145 BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
147 boost::lock_guard<Lockable> lock(m);
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(
157 BOOST_FWD_REF(Arg) arg
159 BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
161 boost::lock_guard<Lockable> lock(m);
163 boost::forward<Arg>(arg)
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(
173 BOOST_FWD_REF(Arg1) arg1,
174 BOOST_FWD_REF(Arg2) arg2
176 BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
178 boost::lock_guard<Lockable> lock(m);
180 boost::forward<Arg1>(arg1),
181 boost::forward<Arg2>(arg2)
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(
191 BOOST_FWD_REF(Arg1) arg1,
192 BOOST_FWD_REF(Arg2) arg2,
193 BOOST_FWD_REF(Arg3) arg3
195 BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
197 boost::lock_guard<Lockable> lock(m);
199 boost::forward<Arg1>(arg1),
200 boost::forward<Arg2>(arg2),
201 boost::forward<Arg3>(arg3)
206 class Lockable, class Func, class Arg1, class Arg2, class Arg3, class Arg4
208 typename boost::result_of<
209 typename boost::add_pointer<Func>::type(Arg1, Arg2, Arg3, Arg4)
210 >::type with_lock_guard(
213 BOOST_FWD_REF(Arg1) arg1,
214 BOOST_FWD_REF(Arg2) arg2,
215 BOOST_FWD_REF(Arg3) arg3,
216 BOOST_FWD_REF(Arg4) arg4
218 BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
220 boost::lock_guard<Lockable> lock(m);
222 boost::forward<Arg1>(arg1),
223 boost::forward<Arg2>(arg2),
224 boost::forward<Arg3>(arg3),
225 boost::forward<Arg4>(arg4)
233 #endif // BOOST_THREAD_WITH_LOCK_GUARD_HPP