PageRenderTime 30ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/ThirdParty/SmartPtr/scoped_any.h

#
C Header | 257 lines | 165 code | 37 blank | 55 comment | 5 complexity | 035420ad23bd79d69e27747559ec5c5a MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-3.0, MIT, CC-BY-SA-3.0, GPL-2.0
  1. //+---------------------------------------------------------------------------
  2. //
  3. // Copyright ( C ) Microsoft, 2002.
  4. //
  5. // File: scoped_any.h
  6. //
  7. // Contents: automatic resource management, a-la std::scoped_ptr
  8. //
  9. // Classes: scoped_any<> and various typedefs
  10. //
  11. // Functions: get
  12. // reset
  13. // release
  14. // valid
  15. // address
  16. //
  17. // Author: Eric Niebler ( ericne@microsoft.com )
  18. //
  19. //----------------------------------------------------------------------------
  20. #ifndef SCOPED_ANY
  21. #define SCOPED_ANY
  22. #include <cassert>
  23. #include "smart_any_fwd.h"
  24. #pragma warning(push)
  25. // 4284 warning for operator-> returning non-pointer;
  26. // compiler issues it even if -> is not used for the specific instance
  27. #pragma warning(disable: 4284)
  28. namespace detail
  29. {
  30. // friend function definitions go in scoped_any_helper
  31. template<typename T,class close_policy,class invalid_value,int unique>
  32. struct scoped_any_helper;
  33. }
  34. // wrap a resource to enforce strict ownership and ensure proper cleanup
  35. template<typename T,class close_policy,class invalid_value,int unique>
  36. class scoped_any
  37. {
  38. // disallow copy and assignment
  39. scoped_any( scoped_any<T,close_policy,invalid_value,unique> const & );
  40. scoped_any<T,close_policy,invalid_value,unique> & operator=(
  41. scoped_any<T,close_policy,invalid_value,unique> const & );
  42. // disallow comparison of scoped_any's
  43. bool operator==( detail::safe_bool ) const;
  44. bool operator!=( detail::safe_bool ) const;
  45. typedef detail::safe_types<T,close_policy> safe_types;
  46. public:
  47. typedef typename detail::holder<T>::type element_type;
  48. typedef close_policy close_policy_type;
  49. typedef typename safe_types::pointer_type pointer_type;
  50. typedef typename safe_types::reference_type reference_type;
  51. // Fix-up the invalid_value type on older compilers
  52. typedef typename detail::fixup_invalid_value<invalid_value>::
  53. template rebind<T>::type invalid_value_type;
  54. friend struct detail::scoped_any_helper<T,close_policy,invalid_value,unique>;
  55. // construct from object pointer
  56. explicit scoped_any( T t = invalid_value_type() )
  57. : m_t( t )
  58. {
  59. }
  60. // destroy the object
  61. ~scoped_any()
  62. {
  63. if( valid() )
  64. {
  65. close_policy::close( m_t );
  66. }
  67. }
  68. // return pointer to class object (assume pointer)
  69. pointer_type operator->() const
  70. {
  71. #ifdef SMART_ANY_PTS
  72. // You better not be applying operator-> to a handle!
  73. static detail::static_assert_macro<!detail::is_handle<T>::value> const cannot_dereference_a_handle;
  74. #endif
  75. assert( valid() );
  76. return safe_types::to_pointer( m_t );
  77. }
  78. // for use when scoped_any appears in a conditional
  79. operator detail::safe_bool() const
  80. {
  81. return valid() ? detail::safe_true : detail::safe_false;
  82. }
  83. // for use when scoped_any appears in a conditional
  84. bool operator!() const
  85. {
  86. return ! valid();
  87. }
  88. #ifdef SMART_ANY_PTS
  89. // if this scoped_any is managing an array, we can use operator[] to index it
  90. typename detail::deref<T>::type operator[]( int i ) const
  91. {
  92. static detail::static_assert_macro<!detail::is_handle<T>::value> const cannot_dereference_a_handle;
  93. static detail::static_assert_macro<!detail::is_delete<close_policy>::value> const accessed_like_an_array_but_not_deleted_like_an_array;
  94. assert( valid() );
  95. return m_t[ i ];
  96. }
  97. // unary operator* lets you write code like:
  98. // scoped_any<foo*,close_delete> pfoo( new foo );
  99. // foo & f = *pfoo;
  100. reference_type operator*() const
  101. {
  102. static detail::static_assert_macro<!detail::is_handle<T>::value> const cannot_dereference_a_handle;
  103. assert( valid() );
  104. return smart_types::to_reference( m_t );
  105. }
  106. #endif
  107. private:
  108. bool valid() const
  109. {
  110. // see if the managed resource is in the invalid state.
  111. return m_t != static_cast<T>( invalid_value_type() );
  112. }
  113. // the wrapped object
  114. element_type m_t;
  115. };
  116. namespace detail
  117. {
  118. // friend function definitions go in scoped_any_helper
  119. template<typename T,class close_policy,class invalid_value,int unique>
  120. struct scoped_any_helper
  121. {
  122. // return wrapped pointer
  123. static T get( scoped_any<T,close_policy,invalid_value,unique> const & t )
  124. {
  125. return t.m_t;
  126. }
  127. // return wrapped pointer and give up ownership
  128. static T release( scoped_any<T,close_policy,invalid_value,unique> & t )
  129. {
  130. // Fix-up the invalid_value type on older compilers
  131. typedef typename detail::fixup_invalid_value<invalid_value>::
  132. template rebind<T>::type invalid_value_type;
  133. T tmpT = t.m_t;
  134. t.m_t = static_cast<T>( invalid_value_type() );
  135. return tmpT;
  136. }
  137. // destroy designated object and store new pointer
  138. static void reset( scoped_any<T,close_policy,invalid_value,unique> & t, T newT )
  139. {
  140. if( t.m_t != newT )
  141. {
  142. if( t.valid() )
  143. {
  144. close_policy::close( t.m_t );
  145. }
  146. t.m_t = newT;
  147. }
  148. }
  149. typedef typename scoped_any<T,close_policy,invalid_value,unique>::element_type element_type;
  150. // return the address of the wrapped pointer
  151. static element_type* address( scoped_any<T,close_policy,invalid_value,unique> & t )
  152. {
  153. // check to make sure the wrapped object is in the invalid state
  154. assert( !t.valid() );
  155. return address_of( t.m_t );
  156. }
  157. };
  158. }
  159. // return wrapped resource
  160. template<typename T,class close_policy,class invalid_value,int unique>
  161. inline T get( scoped_any<T,close_policy,invalid_value,unique> const & t )
  162. {
  163. return detail::scoped_any_helper<T,close_policy,invalid_value,unique>::get( t );
  164. }
  165. // return true if the scoped_any contains a currently valid resource
  166. template<typename T,class close_policy,class invalid_value,int unique>
  167. inline bool valid( scoped_any<T,close_policy,invalid_value,unique> const & t )
  168. {
  169. return t;
  170. }
  171. // return wrapped resource and give up ownership
  172. template<typename T,class close_policy,class invalid_value,int unique>
  173. inline T release( scoped_any<T,close_policy,invalid_value,unique> & t )
  174. {
  175. return detail::scoped_any_helper<T,close_policy,invalid_value,unique>::release( t );
  176. }
  177. // destroy designated object and store new resource
  178. template<typename T,class close_policy,class invalid_value,int unique>
  179. inline void reset( scoped_any<T,close_policy,invalid_value,unique> & t )
  180. {
  181. typedef typename detail::fixup_invalid_value<invalid_value>::
  182. template rebind<T>::type invalid_value_type;
  183. detail::scoped_any_helper<T,close_policy,invalid_value,unique>::reset( t, invalid_value_type() );
  184. }
  185. // destroy designated object and store new resource
  186. template<typename T,class close_policy,class invalid_value,int unique,typename U>
  187. inline void reset( scoped_any<T,close_policy,invalid_value,unique> & t, U newT )
  188. {
  189. detail::scoped_any_helper<T,close_policy,invalid_value,unique>::reset( t, newT );
  190. }
  191. // return the address of the wrapped resource
  192. // WARNING: this will assert if the value of the resource is
  193. // anything other than invalid_value.
  194. template<typename T,class close_policy,class invalid_value,int unique>
  195. inline typename scoped_any<T,close_policy,invalid_value,unique>::element_type*
  196. address( scoped_any<T,close_policy,invalid_value,unique> & t )
  197. {
  198. return detail::scoped_any_helper<T,close_policy,invalid_value,unique>::address( t );
  199. }
  200. #pragma warning(pop)
  201. #endif
  202. // This causes the scoped_* typedefs to be defined
  203. DECLARE_SMART_ANY_TYPEDEFS(scoped)
  204. #if defined(_OBJBASE_H_) & !defined(SCOPED_ANY_CO_INIT)
  205. # define SCOPED_ANY_CO_INIT
  206. typedef scoped_any<HRESULT,close_co,co_not_init> scoped_co_close;
  207. // Helper class for balancing calls to CoInitialize and CoUninitialize
  208. struct scoped_co_init
  209. {
  210. explicit scoped_co_init( DWORD dwCoInit = COINIT_APARTMENTTHREADED )
  211. : m_hr( smart_co_init_helper( dwCoInit ) )
  212. {
  213. }
  214. HRESULT hresult() const
  215. {
  216. return get(m_hr);
  217. }
  218. scoped_co_close const m_hr;
  219. };
  220. #endif