• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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