2 * Copyright Andrey Semashev 2007 - 2015.
3 * Distributed under the Boost Software License, Version 1.0.
4 * (See accompanying file LICENSE_1_0.txt or copy at
5 * http://www.boost.org/LICENSE_1_0.txt)
8 * \file utility/strictest_lock.hpp
9 * \author Andrey Semashev
12 * The header contains definition of the \c strictest_lock metafunction that
13 * allows to select a lock with the strictest access requirements.
16 #ifndef BOOST_LOG_UTILITY_STRICTEST_LOCK_HPP_INCLUDED_
17 #define BOOST_LOG_UTILITY_STRICTEST_LOCK_HPP_INCLUDED_
19 #include <boost/mpl/integral_c.hpp>
20 #include <boost/log/detail/config.hpp>
21 #include <boost/log/detail/locks.hpp>
22 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
23 #include <boost/preprocessor/cat.hpp>
24 #include <boost/preprocessor/arithmetic/sub.hpp>
25 #include <boost/preprocessor/arithmetic/inc.hpp>
26 #include <boost/preprocessor/arithmetic/dec.hpp>
27 #include <boost/preprocessor/repetition/enum_trailing.hpp>
28 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
29 #include <boost/log/detail/pp_identity.hpp>
31 #if defined(BOOST_LOG_BROKEN_CONSTANT_EXPRESSIONS)
32 #include <boost/mpl/less.hpp>
34 #include <boost/log/detail/header.hpp>
36 #ifdef BOOST_HAS_PRAGMA_ONCE
40 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
41 #if !defined(BOOST_LOG_STRICTEST_LOCK_LIMIT)
43 * The macro defines the maximum number of template arguments that the \c strictest_lock
44 * metafunction accepts. Should not be less than 2.
46 #define BOOST_LOG_STRICTEST_LOCK_LIMIT 10
47 #endif // BOOST_LOG_STRICTEST_LOCK_LIMIT
48 #if BOOST_LOG_STRICTEST_LOCK_LIMIT < 2
49 #error The BOOST_LOG_STRICTEST_LOCK_LIMIT macro should not be less than 2
51 #endif // defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
55 BOOST_LOG_OPEN_NAMESPACE
57 //! Access modes for different types of locks
60 unlocked_access, //!< A thread that owns this kind of lock doesn't restrict other threads in any way
61 shared_access, //!< A thread that owns this kind of lock requires that no other thread modify the locked data
62 exclusive_access //!< A thread that owns this kind of lock requires that no other thread has access to the locked data
65 //! The trait allows to select an access mode by the lock type
66 template< typename LockT >
67 struct thread_access_mode_of;
69 template< typename MutexT >
70 struct thread_access_mode_of< no_lock< MutexT > > : mpl::integral_c< lock_access_mode, unlocked_access >
74 #if !defined(BOOST_LOG_NO_THREADS)
76 template< typename MutexT >
77 struct thread_access_mode_of< lock_guard< MutexT > > : mpl::integral_c< lock_access_mode, exclusive_access >
81 template< typename MutexT >
82 struct thread_access_mode_of< shared_lock_guard< MutexT > > : mpl::integral_c< lock_access_mode, shared_access >
86 template< typename MutexT >
87 struct thread_access_mode_of< unique_lock< MutexT > > : mpl::integral_c< lock_access_mode, exclusive_access >
91 template< typename MutexT >
92 struct thread_access_mode_of< shared_lock< MutexT > > : mpl::integral_c< lock_access_mode, shared_access >
96 template< typename MutexT >
97 struct thread_access_mode_of< upgrade_lock< MutexT > > : mpl::integral_c< lock_access_mode, shared_access >
101 template< typename MutexT >
102 struct thread_access_mode_of< boost::log::aux::exclusive_lock_guard< MutexT > > : mpl::integral_c< lock_access_mode, exclusive_access >
106 template< typename MutexT >
107 struct thread_access_mode_of< boost::log::aux::shared_lock_guard< MutexT > > : mpl::integral_c< lock_access_mode, shared_access >
111 #endif // !defined(BOOST_LOG_NO_THREADS)
115 //! The metafunction selects the most strict lock type of the two
119 #if !defined(BOOST_LOG_BROKEN_CONSTANT_EXPRESSIONS)
120 bool CondV = (thread_access_mode_of< LeftLockT >::value < thread_access_mode_of< RightLockT >::value)
122 bool CondV = mpl::less< thread_access_mode_of< LeftLockT >, thread_access_mode_of< RightLockT > >::value
125 struct strictest_lock_impl
127 typedef RightLockT type;
129 template< typename LeftLockT, typename RightLockT >
130 struct strictest_lock_impl< LeftLockT, RightLockT, false >
132 typedef LeftLockT type;
137 #if defined(BOOST_LOG_DOXYGEN_PASS)
140 * \brief The metafunction selects the most strict lock type of the specified.
142 * The template supports all lock types provided by the Boost.Thread
143 * library (except for \c upgrade_to_unique_lock), plus additional
144 * pseudo-lock \c no_lock that indicates no locking at all.
145 * Exclusive locks are considered the strictest, shared locks are weaker,
146 * and \c no_lock is the weakest.
148 template< typename... LocksT >
149 struct strictest_lock
151 typedef implementation_defined type;
154 #else // defined(BOOST_LOG_DOXYGEN_PASS)
156 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
158 template< typename LockT, typename... LocksT >
159 struct strictest_lock;
161 template< typename LockT >
162 struct strictest_lock< LockT >
167 template< typename LeftLockT, typename RightLockT >
168 struct strictest_lock< LeftLockT, RightLockT >
170 typedef typename aux::strictest_lock_impl< LeftLockT, RightLockT >::type type;
173 template< typename LeftLockT, typename RightLockT, typename... LocksT >
174 struct strictest_lock< LeftLockT, RightLockT, LocksT... >
176 typedef typename strictest_lock<
177 typename aux::strictest_lock_impl< LeftLockT, RightLockT >::type,
182 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
184 # define BOOST_LOG_TYPE_INTERNAL(z, i, data) BOOST_PP_CAT(T, BOOST_PP_INC(i))
188 BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PP_DEC(BOOST_LOG_STRICTEST_LOCK_LIMIT), typename T, void)
190 struct strictest_lock
192 typedef typename strictest_lock<
193 typename boost::log::aux::strictest_lock_impl< T, T0 >::type
194 BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_LOG_STRICTEST_LOCK_LIMIT, 2), BOOST_LOG_TYPE_INTERNAL, ~)
198 template< typename T >
199 struct strictest_lock<
201 BOOST_PP_ENUM_TRAILING(BOOST_PP_DEC(BOOST_LOG_STRICTEST_LOCK_LIMIT), BOOST_LOG_PP_IDENTITY, void)
207 # undef BOOST_LOG_TYPE_INTERNAL
209 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
211 #endif // defined(BOOST_LOG_DOXYGEN_PASS)
213 BOOST_LOG_CLOSE_NAMESPACE // namespace log
217 #include <boost/log/detail/footer.hpp>
219 #endif // BOOST_LOG_UTILITY_STRICTEST_LOCK_HPP_INCLUDED_