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/is_class.hpp> 15 16 #include <boost/config/abi_prefix.hpp> 17 18 // todo make use of integral_constant, true_type and false_type 19 20 namespace boost 21 { 22 namespace sync 23 { 24 25 #if defined(BOOST_NO_SFINAE) || \ 26 BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) || \ 27 BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) 28 #if ! defined BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES 29 #define BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES 30 #endif 31 #endif 32 33 #ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES 34 namespace detail 35 { 36 #define BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(member_name) \ 37 template<typename T, bool=boost::is_class<T>::value> \ 38 struct has_member_called_##member_name \ 39 { \ 40 BOOST_STATIC_CONSTANT(bool, value=false); \ 41 }; \ 42 \ 43 template<typename T> \ 44 struct has_member_called_##member_name<T,true> \ 45 { \ 46 typedef char true_type; \ 47 struct false_type \ 48 { \ 49 true_type dummy[2]; \ 50 }; \ 51 \ 52 struct fallback { int member_name; }; \ 53 struct derived: \ 54 T, fallback \ 55 { \ 56 derived(); \ 57 }; \ 58 \ 59 template<int fallback::*> struct tester; \ 60 \ 61 template<typename U> \ 62 static false_type has_member(tester<&U::member_name>*); \ 63 template<typename U> \ 64 static true_type has_member(...); \ 65 \ 66 BOOST_STATIC_CONSTANT( \ 67 bool, value=sizeof(has_member<derived>(0))==sizeof(true_type)); \ 68 } 69 70 BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(lock) 71 ; BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(unlock); 72 BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(try_lock); 73 74 template<typename T,bool=has_member_called_lock<T>::value > 75 struct has_member_lock 76 { 77 BOOST_STATIC_CONSTANT(bool, value=false); 78 }; 79 80 template<typename T> 81 struct has_member_lock<T,true> 82 { 83 typedef char true_type; 84 struct false_type 85 { 86 true_type dummy[2]; 87 }; 88 89 template<typename U,typename V> 90 static true_type has_member(V (U::*)()); 91 template<typename U> 92 static false_type has_member(U); 93 94 BOOST_STATIC_CONSTANT( 95 bool,value=sizeof(has_member_lock<T>::has_member(&T::lock))==sizeof(true_type)); 96 }; 97 98 template<typename T,bool=has_member_called_unlock<T>::value > 99 struct has_member_unlock 100 { 101 BOOST_STATIC_CONSTANT(bool, value=false); 102 }; 103 104 template<typename T> 105 struct has_member_unlock<T,true> 106 { 107 typedef char true_type; 108 struct false_type 109 { 110 true_type dummy[2]; 111 }; 112 113 template<typename U,typename V> 114 static true_type has_member(V (U::*)()); 115 template<typename U> 116 static false_type has_member(U); 117 118 BOOST_STATIC_CONSTANT( 119 bool,value=sizeof(has_member_unlock<T>::has_member(&T::unlock))==sizeof(true_type)); 120 }; 121 122 template<typename T,bool=has_member_called_try_lock<T>::value > 123 struct has_member_try_lock 124 { 125 BOOST_STATIC_CONSTANT(bool, value=false); 126 }; 127 128 template<typename T> 129 struct has_member_try_lock<T,true> 130 { 131 typedef char true_type; 132 struct false_type 133 { 134 true_type dummy[2]; 135 }; 136 137 template<typename U> 138 static true_type has_member(bool (U::*)()); 139 template<typename U> 140 static false_type has_member(U); 141 142 BOOST_STATIC_CONSTANT( 143 bool,value=sizeof(has_member_try_lock<T>::has_member(&T::try_lock))==sizeof(true_type)); 144 }; 145 146 } 147 148 template<typename T> 149 struct is_basic_lockable 150 { 151 BOOST_STATIC_CONSTANT(bool, value = detail::has_member_lock<T>::value && 152 detail::has_member_unlock<T>::value); 153 }; 154 template<typename T> 155 struct is_lockable 156 { 157 BOOST_STATIC_CONSTANT(bool, value = 158 is_basic_lockable<T>::value && 159 detail::has_member_try_lock<T>::value); 160 }; 161 162 #else 163 template<typename T> 164 struct is_basic_lockable 165 { 166 BOOST_STATIC_CONSTANT(bool, value = false); 167 }; 168 template<typename T> 169 struct is_lockable 170 { 171 BOOST_STATIC_CONSTANT(bool, value = false); 172 }; 173 #endif 174 175 template<typename T> 176 struct is_recursive_mutex_sur_parole 177 { 178 BOOST_STATIC_CONSTANT(bool, value = false); 179 }; 180 template<typename T> 181 struct is_recursive_mutex_sur_parolle : is_recursive_mutex_sur_parole<T> 182 { 183 }; 184 185 template<typename T> 186 struct is_recursive_basic_lockable 187 { 188 BOOST_STATIC_CONSTANT(bool, value = is_basic_lockable<T>::value && 189 is_recursive_mutex_sur_parolle<T>::value); 190 }; 191 template<typename T> 192 struct is_recursive_lockable 193 { 194 BOOST_STATIC_CONSTANT(bool, value = is_lockable<T>::value && 195 is_recursive_mutex_sur_parolle<T>::value); 196 }; 197 } 198 template<typename T> 199 struct is_mutex_type 200 { 201 BOOST_STATIC_CONSTANT(bool, value = sync::is_lockable<T>::value); 202 }; 203 204 } 205 #include <boost/config/abi_suffix.hpp> 206 207 #endif 208