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
20namespace 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