lockable.h
Go to the documentation of this file.00001 #ifndef _SIGX_LOCKABLE_H_
00002 #define _SIGX_LOCKABLE_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <tr1/type_traits>
00030 #include <sigx/noncopyable.h>
00031 #include <sigx/lockable_fwddecl.h>
00032 #include <sigx/const_trait.h>
00033 #include <sigx/volatile_trait.h>
00034
00035
00036 namespace sigx
00037 {
00038
00050 template<typename T_mutex>
00051 struct lockable_base: noncopyable
00052 {
00053 typedef T_mutex mutex_type;
00054
00055
00056 mutex_type& mutex() const throw()
00057 {
00058 return m_mutex;
00059 }
00060
00061 protected:
00062 lockable_base():
00063 m_mutex()
00064 {}
00065
00066
00069 mutable mutex_type m_mutex;
00070 };
00071
00072
00073
00090 template<typename T_type, typename T_mutex>
00091 struct safe_lockable: public lockable_base<T_mutex>
00092 {
00093
00094 template<locking_policy I_policy, typename T_type1, typename T_mutex1, typename T_islockable> friend class lock_acquirer;
00095
00096 typedef lockable_base<T_mutex> parent_type;
00097
00098 typedef T_type acquired_type;
00099
00100
00101 typedef typename volatile_trait<acquired_type>::add volatile_type;
00102
00103
00104 typedef typename std::tr1::add_reference<typename volatile_trait<acquired_type>::remove>::type reference_type;
00105
00106
00107 typedef typename std::tr1::add_reference<volatile_type>::type volatile_reference_type;
00108
00109
00110 typedef typename std::tr1::add_reference<typename const_trait<reference_type>::add>::type const_reference_type;
00111
00112
00113 typedef typename std::tr1::add_reference<typename const_trait<volatile_type>::add>::type cv_reference_type;
00114
00115 typedef typename std::tr1::add_reference<typename std::tr1::add_const<acquired_type>::type>::type toplevel_const_reference_type;
00116
00117
00122 safe_lockable():
00123 parent_type(),
00124 m_obj()
00125 {}
00126
00129 safe_lockable(toplevel_const_reference_type _a_value):
00130 parent_type(),
00131 m_obj(_a_value)
00132 {}
00133
00134
00135 protected:
00138 volatile_reference_type access_volatile() throw()
00139 {
00140 return m_obj;
00141 }
00142
00145 reference_type access_nonvolatile() throw()
00146 {
00147
00148 return const_cast<reference_type>(m_obj);
00149 }
00150
00153 cv_reference_type access_volatile() const throw()
00154 {
00155 return m_obj;
00156 }
00157
00160 const_reference_type access_nonvolatile() const throw()
00161 {
00162
00163 return const_cast<const_reference_type>(m_obj);
00164 }
00165
00166
00167 private:
00170 volatile_type m_obj;
00171 };
00172
00173
00176 template<typename T_type, typename T_mutex>
00177 struct lockable: public safe_lockable<T_type, T_mutex>
00178 {
00179 typedef safe_lockable<T_type, T_mutex> parent_type;
00180 typedef typename parent_type::toplevel_const_reference_type toplevel_const_reference_type;
00181
00182 public:
00187 lockable():
00188 parent_type()
00189 {}
00190
00193 lockable(toplevel_const_reference_type _a_value):
00194 parent_type(_a_value)
00195 {}
00196
00197
00198 using parent_type::access_volatile;
00199 using parent_type::access_nonvolatile;
00200 };
00201
00202
00203
00204 #if 0 // specializations for pointers
00205
00214 template<typename T_mutex>
00215 struct lockable<void*, T_mutex>: public lockable_base<T_mutex>
00216 {
00217 typedef void* acquired_type;
00218 typedef T_mutex mutex_type;
00219 typedef lockable_base<mutex_type> parent_type;
00220 typedef lockable<acquired_type, mutex_type> type;
00221 typedef typename volatile_trait<acquired_type>::add volatile_type;
00222 typedef typename std::tr1::add_reference<typename volatile_trait<acquired_type>::remove>::type reference_type;
00223 typedef typename std::tr1::add_reference<typename volatile_trait<acquired_type>::add>::type volatile_reference_type;
00224 typedef typename std::tr1::add_reference<typename std::tr1::add_const<acquired_type>::type>::type take_type;
00225
00226
00231 lockable(take_type _a_value = 0):
00232 parent_type(),
00233 m_obj(_a_value)
00234 {}
00235
00238 volatile_reference_type access_volatile()
00239 {
00240 return m_obj;
00241 }
00242
00245 reference_type access_nonvolatile()
00246 {
00247
00248 return const_cast<reference_type>(m_obj);
00249 }
00250
00251
00252 private:
00255 volatile_type m_obj;
00256 };
00257
00258
00259
00270 template<typename T_type, typename T_mutex>
00271 struct lockable<T_type*, T_mutex>: public lockable<void*, T_mutex>
00272 {
00273 typedef lockable<void*, T_mutex> parent_type;
00274 typedef T_type* acquired_type;
00275 typedef lockable<acquired_type, mutex_type> type;
00276 typedef typename volatile_trait<acquired_type>::add volatile_type;
00277 typedef typename std::tr1::add_reference<typename volatile_trait<acquired_type>::remove>::type reference_type;
00278 typedef typename std::tr1::add_reference<typename volatile_trait<acquired_type>::add>::type volatile_reference_type;
00279 typedef typename std::tr1::add_reference<typename std::tr1::add_const<acquired_type>::type>::type take_type;
00280
00281
00286 lockable(take_type _a_value = 0):
00287 parent_type((void*&) _a_value)
00288 {}
00289
00295 volatile_reference_type access_volatile()
00296 {
00297 return (volatile_reference_type) parent_type::access_volatile();
00298 }
00299
00302 reference_type access_acquiree()
00303 {
00304 return (reference_type) parent_type::access_acquiree();
00305 }
00306 };
00307 #endif
00308
00309
00310
00311
00315 }
00316
00317
00318 #endif // end file guard