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