1 // Distributed under the Boost Software License, Version 1.0. (See 2 // accompanying file LICENSE_1_0.txt or copy at 3 // http://www.boost.org/LICENSE_1_0.txt) 4 // (C) Copyright 2007 Anthony Williams 5 // (C) Copyright 2011-2012 Vicente J. Botet Escriba 6 7 #ifndef BOOST_THREAD_LOCKABLE_TRAITS_HPP 8 #define BOOST_THREAD_LOCKABLE_TRAITS_HPP 9 10 #include <boost/thread/detail/config.hpp> 11 12 #include <boost/assert.hpp> 13 #include <boost/detail/workaround.hpp> 14 #include <boost/type_traits/integral_constant.hpp> 15 #ifdef BOOST_NO_CXX11_SFINAE_EXPR 16 #include <boost/type_traits/is_class.hpp> 17 #else 18 #include <boost/type_traits/declval.hpp> 19 #endif 20 21 #include <boost/config/abi_prefix.hpp> 22 23 // todo make use of integral_constant, true_type and false_type 24 25 namespace boost 26 { 27 namespace sync 28 { 29 30 #if defined(BOOST_NO_SFINAE) || \ 31 BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) || \ 32 BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) 33 #if ! defined BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES 34 #define BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES 35 #endif 36 #endif 37 38 #ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES 39 namespace detail 40 { 41 #ifdef BOOST_NO_CXX11_SFINAE_EXPR 42 #define BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(member_name) \ 43 template<typename T, bool=boost::is_class<T>::value> \ 44 struct has_member_called_##member_name \ 45 { \ 46 BOOST_STATIC_CONSTANT(bool, value=false); \ 47 }; \ 48 \ 49 template<typename T> \ 50 struct has_member_called_##member_name<T,true> \ 51 { \ 52 typedef char true_type; \ 53 struct false_type \ 54 { \ 55 true_type dummy[2]; \ 56 }; \ 57 \ 58 struct fallback { int member_name; }; \ 59 struct derived: \ 60 T, fallback \ 61 { \ 62 derived(); \ 63 }; \ 64 \ 65 template<int fallback::*> struct tester; \ 66 \ 67 template<typename U> \ 68 static false_type has_member(tester<&U::member_name>*); \ 69 template<typename U> \ 70 static true_type has_member(...); \ 71 \ 72 BOOST_STATIC_CONSTANT( \ 73 bool, value=sizeof(has_member<derived>(0))==sizeof(true_type)); \ 74 } 75 76 BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(lock) 77 ; BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(unlock); 78 BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(try_lock); 79 80 template<typename T,bool=has_member_called_lock<T>::value > 81 struct has_member_lock 82 { 83 BOOST_STATIC_CONSTANT(bool, value=false); 84 }; 85 86 template<typename T> 87 struct has_member_lock<T,true> 88 { 89 typedef char true_type; 90 struct false_type 91 { 92 true_type dummy[2]; 93 }; 94 95 template<typename U,typename V> 96 static true_type has_member(V (U::*)()); 97 template<typename U> 98 static false_type has_member(U); 99 100 BOOST_STATIC_CONSTANT( 101 bool,value=sizeof(has_member_lock<T>::has_member(&T::lock))==sizeof(true_type)); 102 }; 103 104 template<typename T,bool=has_member_called_unlock<T>::value > 105 struct has_member_unlock 106 { 107 BOOST_STATIC_CONSTANT(bool, value=false); 108 }; 109 110 template<typename T> 111 struct has_member_unlock<T,true> 112 { 113 typedef char true_type; 114 struct false_type 115 { 116 true_type dummy[2]; 117 }; 118 119 template<typename U,typename V> 120 static true_type has_member(V (U::*)()); 121 template<typename U> 122 static false_type has_member(U); 123 124 BOOST_STATIC_CONSTANT( 125 bool,value=sizeof(has_member_unlock<T>::has_member(&T::unlock))==sizeof(true_type)); 126 }; 127 128 template<typename T,bool=has_member_called_try_lock<T>::value > 129 struct has_member_try_lock 130 { 131 BOOST_STATIC_CONSTANT(bool, value=false); 132 }; 133 134 template<typename T> 135 struct has_member_try_lock<T,true> 136 { 137 typedef char true_type; 138 struct false_type 139 { 140 true_type dummy[2]; 141 }; 142 143 template<typename U> 144 static true_type has_member(bool (U::*)()); 145 template<typename U> 146 static false_type has_member(U); 147 148 BOOST_STATIC_CONSTANT( 149 bool,value=sizeof(has_member_try_lock<T>::has_member(&T::try_lock))==sizeof(true_type)); 150 }; 151 #else 152 template<typename T,typename Enabled=void> 153 struct has_member_lock : false_type {}; 154 155 template<typename T> 156 struct has_member_lock<T, 157 decltype(void(boost::declval<T&>().lock())) 158 > : true_type {}; 159 160 template<typename T,typename Enabled=void> 161 struct has_member_unlock : false_type {}; 162 163 template<typename T> 164 struct has_member_unlock<T, 165 decltype(void(boost::declval<T&>().unlock())) 166 > : true_type {}; 167 168 template<typename T,typename Enabled=bool> 169 struct has_member_try_lock : false_type {}; 170 171 template<typename T> 172 struct has_member_try_lock<T, 173 decltype(bool(boost::declval<T&>().try_lock())) 174 > : true_type {}; 175 #endif 176 177 } 178 179 template<typename T> 180 struct is_basic_lockable 181 { 182 BOOST_STATIC_CONSTANT(bool, value = detail::has_member_lock<T>::value && 183 detail::has_member_unlock<T>::value); 184 }; 185 template<typename T> 186 struct is_lockable 187 { 188 BOOST_STATIC_CONSTANT(bool, value = 189 is_basic_lockable<T>::value && 190 detail::has_member_try_lock<T>::value); 191 }; 192 193 #else 194 template<typename T> 195 struct is_basic_lockable 196 { 197 BOOST_STATIC_CONSTANT(bool, value = false); 198 }; 199 template<typename T> 200 struct is_lockable 201 { 202 BOOST_STATIC_CONSTANT(bool, value = false); 203 }; 204 #endif 205 206 template<typename T> 207 struct is_recursive_mutex_sur_parole 208 { 209 BOOST_STATIC_CONSTANT(bool, value = false); 210 }; 211 template<typename T> 212 struct is_recursive_mutex_sur_parolle : is_recursive_mutex_sur_parole<T> 213 { 214 }; 215 216 template<typename T> 217 struct is_recursive_basic_lockable 218 { 219 BOOST_STATIC_CONSTANT(bool, value = is_basic_lockable<T>::value && 220 is_recursive_mutex_sur_parolle<T>::value); 221 }; 222 template<typename T> 223 struct is_recursive_lockable 224 { 225 BOOST_STATIC_CONSTANT(bool, value = is_lockable<T>::value && 226 is_recursive_mutex_sur_parolle<T>::value); 227 }; 228 } 229 template<typename T> 230 struct is_mutex_type 231 { 232 BOOST_STATIC_CONSTANT(bool, value = sync::is_lockable<T>::value); 233 }; 234 235 } 236 #include <boost/config/abi_suffix.hpp> 237 238 #endif 239