Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/thread/with_lock_guard.hpp @ 102:f46d142149f5
Whoops, finish that update
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:13:41 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/thread/with_lock_guard.hpp Mon Sep 07 11:13:41 2015 +0100 @@ -0,0 +1,234 @@ +// (C) Copyright 2013 Ruslan Baratov +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See www.boost.org/libs/thread for documentation. + +#ifndef BOOST_THREAD_WITH_LOCK_GUARD_HPP +#define BOOST_THREAD_WITH_LOCK_GUARD_HPP + +#include <boost/thread/lock_guard.hpp> +#include <boost/utility/result_of.hpp> +//#include <boost/thread/detail/invoke.hpp> + +namespace boost { + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ + !defined(BOOST_NO_CXX11_DECLTYPE) && \ + !defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) + +/** + * Utility to run functions in scope protected by mutex. + * + * Examples: + * + * int func(int, int&); + * boost::mutex m; + * int a; + * int result = boost::with_lock_guard(m, func, 1, boost::ref(a)); + * + * // using boost::bind + * int result = boost::with_lock_guard( + * m, boost::bind(func, 2, boost::ref(a)) + * ); + * + * // using lambda + * int a; + * int result = boost::with_lock_guard( + * m, + * [&a](int x) { + * a = 3; + * return x + 4; + * }, + * 5 + * ); + */ +template <class Lockable, class Function, class... Args> +typename boost::result_of<Function(Args...)>::type with_lock_guard( + Lockable& m, + BOOST_FWD_REF(Function) func, + BOOST_FWD_REF(Args)... args +) //-> decltype(func(boost::forward<Args>(args)...)) +{ + boost::lock_guard<Lockable> lock(m); + return func(boost::forward<Args>(args)...); +} + +#else + +// Workaround versions for compilers without c++11 variadic templates support. +// (function arguments limit: 4) +// (for lambda support define BOOST_RESULT_OF_USE_DECLTYPE may be needed) + +template <class Lockable, class Func> +typename boost::result_of<Func()>::type with_lock_guard( + Lockable& m, + BOOST_FWD_REF(Func) func +) { + boost::lock_guard<Lockable> lock(m); + return func(); +} + +template <class Lockable, class Func, class Arg> +typename boost::result_of<Func(Arg)>::type with_lock_guard( + Lockable& m, + BOOST_FWD_REF(Func) func, + BOOST_FWD_REF(Arg) arg +) { + boost::lock_guard<Lockable> lock(m); + return func( + boost::forward<Arg>(arg) + ); +} + +template <class Lockable, class Func, class Arg1, class Arg2> +typename boost::result_of<Func(Arg1, Arg2)>::type with_lock_guard( + Lockable& m, + BOOST_FWD_REF(Func) func, + BOOST_FWD_REF(Arg1) arg1, + BOOST_FWD_REF(Arg2) arg2 +) { + boost::lock_guard<Lockable> lock(m); + return func( + boost::forward<Arg1>(arg1), + boost::forward<Arg2>(arg2) + ); +} + +template <class Lockable, class Func, class Arg1, class Arg2, class Arg3> +typename boost::result_of<Func(Arg1, Arg2, Arg3)>::type with_lock_guard( + Lockable& m, + BOOST_FWD_REF(Func) func, + BOOST_FWD_REF(Arg1) arg1, + BOOST_FWD_REF(Arg2) arg2, + BOOST_FWD_REF(Arg3) arg3 +) { + boost::lock_guard<Lockable> lock(m); + return func( + boost::forward<Arg1>(arg1), + boost::forward<Arg2>(arg2), + boost::forward<Arg3>(arg3) + ); +} + +template < + class Lockable, class Func, class Arg1, class Arg2, class Arg3, class Arg4 +> +typename boost::result_of<Func(Arg1, Arg2, Arg3, Arg4)>::type with_lock_guard( + Lockable& m, + BOOST_FWD_REF(Func) func, + BOOST_FWD_REF(Arg1) arg1, + BOOST_FWD_REF(Arg2) arg2, + BOOST_FWD_REF(Arg3) arg3, + BOOST_FWD_REF(Arg4) arg4 +) { + boost::lock_guard<Lockable> lock(m); + return func( + boost::forward<Arg1>(arg1), + boost::forward<Arg2>(arg2), + boost::forward<Arg3>(arg3), + boost::forward<Arg4>(arg4) + ); +} + +// overloads for function pointer +// (if argument is not function pointer, static assert will trigger) +template <class Lockable, class Func> +typename boost::result_of< + typename boost::add_pointer<Func>::type() +>::type with_lock_guard( + Lockable& m, + Func* func +) { + BOOST_STATIC_ASSERT(boost::is_function<Func>::value); + + boost::lock_guard<Lockable> lock(m); + return func(); +} + +template <class Lockable, class Func, class Arg> +typename boost::result_of< + typename boost::add_pointer<Func>::type(Arg) +>::type with_lock_guard( + Lockable& m, + Func* func, + BOOST_FWD_REF(Arg) arg +) { + BOOST_STATIC_ASSERT(boost::is_function<Func>::value); + + boost::lock_guard<Lockable> lock(m); + return func( + boost::forward<Arg>(arg) + ); +} + +template <class Lockable, class Func, class Arg1, class Arg2> +typename boost::result_of< + typename boost::add_pointer<Func>::type(Arg1, Arg2) +>::type with_lock_guard( + Lockable& m, + Func* func, + BOOST_FWD_REF(Arg1) arg1, + BOOST_FWD_REF(Arg2) arg2 +) { + BOOST_STATIC_ASSERT(boost::is_function<Func>::value); + + boost::lock_guard<Lockable> lock(m); + return func( + boost::forward<Arg1>(arg1), + boost::forward<Arg2>(arg2) + ); +} + +template <class Lockable, class Func, class Arg1, class Arg2, class Arg3> +typename boost::result_of< + typename boost::add_pointer<Func>::type(Arg1, Arg2, Arg3) +>::type with_lock_guard( + Lockable& m, + Func* func, + BOOST_FWD_REF(Arg1) arg1, + BOOST_FWD_REF(Arg2) arg2, + BOOST_FWD_REF(Arg3) arg3 +) { + BOOST_STATIC_ASSERT(boost::is_function<Func>::value); + + boost::lock_guard<Lockable> lock(m); + return func( + boost::forward<Arg1>(arg1), + boost::forward<Arg2>(arg2), + boost::forward<Arg3>(arg3) + ); +} + +template < + class Lockable, class Func, class Arg1, class Arg2, class Arg3, class Arg4 +> +typename boost::result_of< + typename boost::add_pointer<Func>::type(Arg1, Arg2, Arg3, Arg4) +>::type with_lock_guard( + Lockable& m, + Func* func, + BOOST_FWD_REF(Arg1) arg1, + BOOST_FWD_REF(Arg2) arg2, + BOOST_FWD_REF(Arg3) arg3, + BOOST_FWD_REF(Arg4) arg4 +) { + BOOST_STATIC_ASSERT(boost::is_function<Func>::value); + + boost::lock_guard<Lockable> lock(m); + return func( + boost::forward<Arg1>(arg1), + boost::forward<Arg2>(arg2), + boost::forward<Arg3>(arg3), + boost::forward<Arg4>(arg4) + ); +} + +#endif + +} // namespace boost + +#endif // BOOST_THREAD_WITH_LOCK_GUARD_HPP +