lockable_traits.hpp 7.7 KB

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