Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:09:32

0001 // (C) Copyright 2013 Ruslan Baratov
0002 // Copyright (C) 2014 Vicente J. Botet Escriba
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 //  See www.boost.org/libs/thread for documentation.
0008 
0009 #ifndef BOOST_THREAD_WITH_LOCK_GUARD_HPP
0010 #define BOOST_THREAD_WITH_LOCK_GUARD_HPP
0011 
0012 #include <boost/thread/lock_guard.hpp>
0013 #include <boost/utility/result_of.hpp>
0014 //#include <boost/thread/detail/invoke.hpp>
0015 
0016 namespace boost {
0017 
0018 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
0019     !defined(BOOST_NO_CXX11_DECLTYPE) && \
0020     !defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
0021 
0022 /**
0023  * Utility to run functions in scope protected by mutex.
0024  *
0025  * Examples:
0026  *
0027  *     int func(int, int&);
0028  *     boost::mutex m;
0029  *     int a;
0030  *     int result = boost::with_lock_guard(m, func, 1, boost::ref(a));
0031  *
0032  *     // using boost::bind
0033  *     int result = boost::with_lock_guard(
0034  *         m, boost::bind(func, 2, boost::ref(a))
0035  *     );
0036  *
0037  *     // using lambda
0038  *     int a;
0039  *     int result = boost::with_lock_guard(
0040  *         m,
0041  *         [&a](int x) {
0042  *           a = 3;
0043  *           return x + 4;
0044  *         },
0045  *         5
0046  *     );
0047  */
0048 template <class Lockable, class Function, class... Args>
0049 typename boost::result_of<Function(Args...)>::type with_lock_guard(
0050     Lockable& m,
0051     BOOST_FWD_REF(Function) func,
0052     BOOST_FWD_REF(Args)... args
0053 ) //-> decltype(func(boost::forward<Args>(args)...))
0054 {
0055   boost::lock_guard<Lockable> lock(m);
0056   return func(boost::forward<Args>(args)...);
0057 }
0058 
0059 #else
0060 
0061 // Workaround versions for compilers without c++11 variadic templates support.
0062 // (function arguments limit: 4)
0063 // (for lambda support define BOOST_RESULT_OF_USE_DECLTYPE may be needed)
0064 
0065 template <class Lockable, class Func>
0066 typename boost::result_of<Func()>::type with_lock_guard(
0067     Lockable& m,
0068     BOOST_FWD_REF(Func) func
0069 ) {
0070   boost::lock_guard<Lockable> lock(m);
0071   return func();
0072 }
0073 
0074 template <class Lockable, class Func, class Arg>
0075 typename boost::result_of<Func(Arg)>::type with_lock_guard(
0076     Lockable& m,
0077     BOOST_FWD_REF(Func) func,
0078     BOOST_FWD_REF(Arg) arg
0079 ) {
0080   boost::lock_guard<Lockable> lock(m);
0081   return func(
0082       boost::forward<Arg>(arg)
0083   );
0084 }
0085 
0086 template <class Lockable, class Func, class Arg1, class Arg2>
0087 typename boost::result_of<Func(Arg1, Arg2)>::type with_lock_guard(
0088     Lockable& m,
0089     BOOST_FWD_REF(Func) func,
0090     BOOST_FWD_REF(Arg1) arg1,
0091     BOOST_FWD_REF(Arg2) arg2
0092 ) {
0093   boost::lock_guard<Lockable> lock(m);
0094   return func(
0095       boost::forward<Arg1>(arg1),
0096       boost::forward<Arg2>(arg2)
0097   );
0098 }
0099 
0100 template <class Lockable, class Func, class Arg1, class Arg2, class Arg3>
0101 typename boost::result_of<Func(Arg1, Arg2, Arg3)>::type with_lock_guard(
0102     Lockable& m,
0103     BOOST_FWD_REF(Func) func,
0104     BOOST_FWD_REF(Arg1) arg1,
0105     BOOST_FWD_REF(Arg2) arg2,
0106     BOOST_FWD_REF(Arg3) arg3
0107 ) {
0108   boost::lock_guard<Lockable> lock(m);
0109   return func(
0110       boost::forward<Arg1>(arg1),
0111       boost::forward<Arg2>(arg2),
0112       boost::forward<Arg3>(arg3)
0113   );
0114 }
0115 
0116 template <
0117     class Lockable, class Func, class Arg1, class Arg2, class Arg3, class Arg4
0118 >
0119 typename boost::result_of<Func(Arg1, Arg2, Arg3, Arg4)>::type with_lock_guard(
0120     Lockable& m,
0121     BOOST_FWD_REF(Func) func,
0122     BOOST_FWD_REF(Arg1) arg1,
0123     BOOST_FWD_REF(Arg2) arg2,
0124     BOOST_FWD_REF(Arg3) arg3,
0125     BOOST_FWD_REF(Arg4) arg4
0126 ) {
0127   boost::lock_guard<Lockable> lock(m);
0128   return func(
0129       boost::forward<Arg1>(arg1),
0130       boost::forward<Arg2>(arg2),
0131       boost::forward<Arg3>(arg3),
0132       boost::forward<Arg4>(arg4)
0133   );
0134 }
0135 
0136 // overloads for function pointer
0137 // (if argument is not function pointer, static assert will trigger)
0138 template <class Lockable, class Func>
0139 typename boost::result_of<
0140     typename boost::add_pointer<Func>::type()
0141 >::type with_lock_guard(
0142     Lockable& m,
0143     Func* func
0144 ) {
0145   BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
0146 
0147   boost::lock_guard<Lockable> lock(m);
0148   return func();
0149 }
0150 
0151 template <class Lockable, class Func, class Arg>
0152 typename boost::result_of<
0153     typename boost::add_pointer<Func>::type(Arg)
0154 >::type with_lock_guard(
0155     Lockable& m,
0156     Func* func,
0157     BOOST_FWD_REF(Arg) arg
0158 ) {
0159   BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
0160 
0161   boost::lock_guard<Lockable> lock(m);
0162   return func(
0163       boost::forward<Arg>(arg)
0164   );
0165 }
0166 
0167 template <class Lockable, class Func, class Arg1, class Arg2>
0168 typename boost::result_of<
0169     typename boost::add_pointer<Func>::type(Arg1, Arg2)
0170 >::type with_lock_guard(
0171     Lockable& m,
0172     Func* func,
0173     BOOST_FWD_REF(Arg1) arg1,
0174     BOOST_FWD_REF(Arg2) arg2
0175 ) {
0176   BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
0177 
0178   boost::lock_guard<Lockable> lock(m);
0179   return func(
0180       boost::forward<Arg1>(arg1),
0181       boost::forward<Arg2>(arg2)
0182   );
0183 }
0184 
0185 template <class Lockable, class Func, class Arg1, class Arg2, class Arg3>
0186 typename boost::result_of<
0187     typename boost::add_pointer<Func>::type(Arg1, Arg2, Arg3)
0188 >::type with_lock_guard(
0189     Lockable& m,
0190     Func* func,
0191     BOOST_FWD_REF(Arg1) arg1,
0192     BOOST_FWD_REF(Arg2) arg2,
0193     BOOST_FWD_REF(Arg3) arg3
0194 ) {
0195   BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
0196 
0197   boost::lock_guard<Lockable> lock(m);
0198   return func(
0199       boost::forward<Arg1>(arg1),
0200       boost::forward<Arg2>(arg2),
0201       boost::forward<Arg3>(arg3)
0202   );
0203 }
0204 
0205 template <
0206     class Lockable, class Func, class Arg1, class Arg2, class Arg3, class Arg4
0207 >
0208 typename boost::result_of<
0209     typename boost::add_pointer<Func>::type(Arg1, Arg2, Arg3, Arg4)
0210 >::type with_lock_guard(
0211     Lockable& m,
0212     Func* func,
0213     BOOST_FWD_REF(Arg1) arg1,
0214     BOOST_FWD_REF(Arg2) arg2,
0215     BOOST_FWD_REF(Arg3) arg3,
0216     BOOST_FWD_REF(Arg4) arg4
0217 ) {
0218   BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
0219 
0220   boost::lock_guard<Lockable> lock(m);
0221   return func(
0222       boost::forward<Arg1>(arg1),
0223       boost::forward<Arg2>(arg2),
0224       boost::forward<Arg3>(arg3),
0225       boost::forward<Arg4>(arg4)
0226   );
0227 }
0228 
0229 #endif
0230 
0231 } // namespace boost
0232 
0233 #endif // BOOST_THREAD_WITH_LOCK_GUARD_HPP
0234