File indexing completed on 2025-12-15 10:09:31
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_THREAD_LOCKABLE_TRAITS_HPP
0008 #define BOOST_THREAD_LOCKABLE_TRAITS_HPP
0009
0010 #include <boost/thread/detail/config.hpp>
0011
0012 #include <boost/assert.hpp>
0013 #include <boost/detail/workaround.hpp>
0014 #include <boost/type_traits/integral_constant.hpp>
0015 #ifdef BOOST_NO_CXX11_SFINAE_EXPR
0016 #include <boost/type_traits/is_class.hpp>
0017 #else
0018 #include <boost/type_traits/declval.hpp>
0019 #endif
0020
0021 #include <boost/config/abi_prefix.hpp>
0022
0023
0024
0025 namespace boost
0026 {
0027 namespace sync
0028 {
0029
0030 #if defined(BOOST_NO_SFINAE) || \
0031 BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) || \
0032 BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
0033 #if ! defined BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
0034 #define BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
0035 #endif
0036 #endif
0037
0038 #ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
0039 namespace detail
0040 {
0041 #ifdef BOOST_NO_CXX11_SFINAE_EXPR
0042 #define BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(member_name) \
0043 template<typename T, bool=boost::is_class<T>::value> \
0044 struct has_member_called_##member_name \
0045 { \
0046 BOOST_STATIC_CONSTANT(bool, value=false); \
0047 }; \
0048 \
0049 template<typename T> \
0050 struct has_member_called_##member_name<T,true> \
0051 { \
0052 typedef char true_type; \
0053 struct false_type \
0054 { \
0055 true_type dummy[2]; \
0056 }; \
0057 \
0058 struct fallback { int member_name; }; \
0059 struct derived: \
0060 T, fallback \
0061 { \
0062 derived(); \
0063 }; \
0064 \
0065 template<int fallback::*> struct tester; \
0066 \
0067 template<typename U> \
0068 static false_type has_member(tester<&U::member_name>*); \
0069 template<typename U> \
0070 static true_type has_member(...); \
0071 \
0072 BOOST_STATIC_CONSTANT( \
0073 bool, value=sizeof(has_member<derived>(0))==sizeof(true_type)); \
0074 }
0075
0076 BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(lock)
0077 ; BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(unlock);
0078 BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(try_lock);
0079
0080 template<typename T,bool=has_member_called_lock<T>::value >
0081 struct has_member_lock
0082 {
0083 BOOST_STATIC_CONSTANT(bool, value=false);
0084 };
0085
0086 template<typename T>
0087 struct has_member_lock<T,true>
0088 {
0089 typedef char true_type;
0090 struct false_type
0091 {
0092 true_type dummy[2];
0093 };
0094
0095 template<typename U,typename V>
0096 static true_type has_member(V (U::*)());
0097 template<typename U>
0098 static false_type has_member(U);
0099
0100 BOOST_STATIC_CONSTANT(
0101 bool,value=sizeof(has_member_lock<T>::has_member(&T::lock))==sizeof(true_type));
0102 };
0103
0104 template<typename T,bool=has_member_called_unlock<T>::value >
0105 struct has_member_unlock
0106 {
0107 BOOST_STATIC_CONSTANT(bool, value=false);
0108 };
0109
0110 template<typename T>
0111 struct has_member_unlock<T,true>
0112 {
0113 typedef char true_type;
0114 struct false_type
0115 {
0116 true_type dummy[2];
0117 };
0118
0119 template<typename U,typename V>
0120 static true_type has_member(V (U::*)());
0121 template<typename U>
0122 static false_type has_member(U);
0123
0124 BOOST_STATIC_CONSTANT(
0125 bool,value=sizeof(has_member_unlock<T>::has_member(&T::unlock))==sizeof(true_type));
0126 };
0127
0128 template<typename T,bool=has_member_called_try_lock<T>::value >
0129 struct has_member_try_lock
0130 {
0131 BOOST_STATIC_CONSTANT(bool, value=false);
0132 };
0133
0134 template<typename T>
0135 struct has_member_try_lock<T,true>
0136 {
0137 typedef char true_type;
0138 struct false_type
0139 {
0140 true_type dummy[2];
0141 };
0142
0143 template<typename U>
0144 static true_type has_member(bool (U::*)());
0145 template<typename U>
0146 static false_type has_member(U);
0147
0148 BOOST_STATIC_CONSTANT(
0149 bool,value=sizeof(has_member_try_lock<T>::has_member(&T::try_lock))==sizeof(true_type));
0150 };
0151 #else
0152 template<typename T,typename Enabled=void>
0153 struct has_member_lock : false_type {};
0154
0155 template<typename T>
0156 struct has_member_lock<T,
0157 decltype(void(boost::declval<T&>().lock()))
0158 > : true_type {};
0159
0160 template<typename T,typename Enabled=void>
0161 struct has_member_unlock : false_type {};
0162
0163 template<typename T>
0164 struct has_member_unlock<T,
0165 decltype(void(boost::declval<T&>().unlock()))
0166 > : true_type {};
0167
0168 template<typename T,typename Enabled=bool>
0169 struct has_member_try_lock : false_type {};
0170
0171 template<typename T>
0172 struct has_member_try_lock<T,
0173 decltype(bool(boost::declval<T&>().try_lock()))
0174 > : true_type {};
0175 #endif
0176
0177 }
0178
0179 template<typename T>
0180 struct is_basic_lockable
0181 {
0182 BOOST_STATIC_CONSTANT(bool, value = detail::has_member_lock<T>::value &&
0183 detail::has_member_unlock<T>::value);
0184 };
0185 template<typename T>
0186 struct is_lockable
0187 {
0188 BOOST_STATIC_CONSTANT(bool, value =
0189 is_basic_lockable<T>::value &&
0190 detail::has_member_try_lock<T>::value);
0191 };
0192
0193 #else
0194 template<typename T>
0195 struct is_basic_lockable
0196 {
0197 BOOST_STATIC_CONSTANT(bool, value = false);
0198 };
0199 template<typename T>
0200 struct is_lockable
0201 {
0202 BOOST_STATIC_CONSTANT(bool, value = false);
0203 };
0204 #endif
0205
0206 template<typename T>
0207 struct is_recursive_mutex_sur_parole
0208 {
0209 BOOST_STATIC_CONSTANT(bool, value = false);
0210 };
0211 template<typename T>
0212 struct is_recursive_mutex_sur_parolle : is_recursive_mutex_sur_parole<T>
0213 {
0214 };
0215
0216 template<typename T>
0217 struct is_recursive_basic_lockable
0218 {
0219 BOOST_STATIC_CONSTANT(bool, value = is_basic_lockable<T>::value &&
0220 is_recursive_mutex_sur_parolle<T>::value);
0221 };
0222 template<typename T>
0223 struct is_recursive_lockable
0224 {
0225 BOOST_STATIC_CONSTANT(bool, value = is_lockable<T>::value &&
0226 is_recursive_mutex_sur_parolle<T>::value);
0227 };
0228 }
0229 template<typename T>
0230 struct is_mutex_type
0231 {
0232 BOOST_STATIC_CONSTANT(bool, value = sync::is_lockable<T>::value);
0233 };
0234
0235 }
0236 #include <boost/config/abi_suffix.hpp>
0237
0238 #endif