You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

398 lines
12 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: comstl/smartptr/interface_ptr.hpp (originally MLRelItf.h; ::SynesisCom)
  3. *
  4. * Purpose: Interface management helper classes.
  5. *
  6. * Created: 2nd November 1994
  7. * Updated: 10th August 2009
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 1994-2009, Matthew Wilson and Synesis Software
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright notice, this
  18. * list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  23. * any contributors may be used to endorse or promote products derived from
  24. * this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  30. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * ////////////////////////////////////////////////////////////////////// */
  39. /** \file comstl/smartptr/interface_ptr.hpp
  40. *
  41. * \brief [C++ only] Definition of the comstl::interface_ptr smart
  42. * pointer class template
  43. * (\ref group__library__smart_pointers "Smart Pointers" Library).
  44. */
  45. #ifndef COMSTL_INCL_COMSTL_SMARTPTR_HPP_INTERFACE_PTR
  46. #define COMSTL_INCL_COMSTL_SMARTPTR_HPP_INTERFACE_PTR
  47. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  48. # define COMSTL_VER_COMSTL_SMARTPTR_HPP_INTERFACE_PTR_MAJOR 7
  49. # define COMSTL_VER_COMSTL_SMARTPTR_HPP_INTERFACE_PTR_MINOR 2
  50. # define COMSTL_VER_COMSTL_SMARTPTR_HPP_INTERFACE_PTR_REVISION 2
  51. # define COMSTL_VER_COMSTL_SMARTPTR_HPP_INTERFACE_PTR_EDIT 498
  52. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  53. /* /////////////////////////////////////////////////////////////////////////
  54. * Includes
  55. */
  56. #ifndef COMSTL_INCL_COMSTL_H_COMSTL
  57. # include <comstl/comstl.h>
  58. #endif /* !COMSTL_INCL_COMSTL_H_COMSTL */
  59. #ifdef STLSOFT_CF_PRAGMA_MESSAGE_SUPPORT
  60. # pragma message("This file (comstl/smartptr/interface_ptr.hpp) is now obsolete. Include stlsoft/smartptr/ref_ptr.hpp and use stlsoft::ref_ptr<>")
  61. #endif /* STLSOFT_CF_PRAGMA_MESSAGE_SUPPORT */
  62. #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_OPERATOR_BOOL
  63. # include <stlsoft/util/operator_bool.hpp>
  64. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_OPERATOR_BOOL */
  65. #ifndef STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_REF_PTR
  66. # include <stlsoft/smartptr/ref_ptr.hpp>
  67. #endif /* !STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_REF_PTR */
  68. /* /////////////////////////////////////////////////////////////////////////
  69. * Namespace
  70. */
  71. #ifndef _COMSTL_NO_NAMESPACE
  72. # if defined(_STLSOFT_NO_NAMESPACE) || \
  73. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  74. /* There is no stlsoft namespace, so must define ::comstl */
  75. namespace comstl
  76. {
  77. # else
  78. /* Define stlsoft::comstl_project */
  79. namespace stlsoft
  80. {
  81. namespace comstl_project
  82. {
  83. # endif /* _STLSOFT_NO_NAMESPACE */
  84. #endif /* !_COMSTL_NO_NAMESPACE */
  85. /* /////////////////////////////////////////////////////////////////////////
  86. * Classes
  87. */
  88. /** \brief [DEPRECATED] Manages a COM interface pointer, ensuring that it is released
  89. *
  90. * \deprecated Instead use stlsoft::ref_ptr
  91. *
  92. * \ingroup group__library__smart_pointers
  93. */
  94. template <ss_typename_param_k T>
  95. class interface_ptr
  96. : public stlsoft_ns_qual(ref_ptr)<T>
  97. {
  98. /// \name Types
  99. /// @{
  100. private:
  101. typedef stlsoft_ns_qual(ref_ptr)<T> parent_class_type;
  102. public:
  103. typedef interface_ptr<T> class_type;
  104. typedef T value_type;
  105. typedef value_type* pointer;
  106. typedef value_type const* const_pointer;
  107. typedef value_type& reference;
  108. typedef value_type const& const_reference;
  109. /// @}
  110. /// \name Construction
  111. /// @{
  112. public:
  113. interface_ptr();
  114. interface_ptr(pointer p, cs_bool_t bAddRef);
  115. interface_ptr(reference r, cs_bool_t bAddRef);
  116. interface_ptr(class_type const& rhs);
  117. ~interface_ptr() stlsoft_throw_0();
  118. class_type& operator =(class_type const& rhs);
  119. /// @}
  120. /// \name Operations
  121. /// @{
  122. public:
  123. void set(pointer p, cs_bool_t bAddRef);
  124. void set(reference r, cs_bool_t bAddRef);
  125. void release();
  126. void release(cs_bool_t bDecRef /* = true */);
  127. pointer detach();
  128. void swap(class_type& rhs);
  129. /// @}
  130. /// \name Comparison
  131. /// @{
  132. public:
  133. cs_bool_t operator ==(class_type const& rhs) const;
  134. cs_bool_t operator !=(class_type const& rhs) const;
  135. /// @}
  136. /// \name State
  137. /// @{
  138. private:
  139. STLSOFT_DEFINE_OPERATOR_BOOL_TYPES_T(class_type, operator_bool_generator_type, operator_bool_type);
  140. public:
  141. operator operator_bool_type() const;
  142. // cs_bool_t operator !() const;
  143. /// @}
  144. /// \name Accessors
  145. /// @{
  146. public:
  147. pointer get_interface_ptr() const;
  148. /// @}
  149. };
  150. /* /////////////////////////////////////////////////////////////////////////
  151. * swapping
  152. */
  153. template <ss_typename_param_k T>
  154. inline void swap(interface_ptr<T>& lhs, interface_ptr<T>& rhs)
  155. {
  156. lhs.swap(rhs);
  157. }
  158. /* /////////////////////////////////////////////////////////////////////////
  159. * Deprecated Shims
  160. */
  161. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  162. template <ss_typename_param_k T>
  163. inline cs_bool_t is_empty(interface_ptr<T> const& p)
  164. {
  165. return NULL == p.get_interface_ptr();
  166. }
  167. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  168. /* /////////////////////////////////////////////////////////////////////////
  169. * Shims
  170. */
  171. /** \brief
  172. * \ingroup group__concept__shim__pointer_attribute__get_ptr
  173. */
  174. template <ss_typename_param_k T>
  175. inline T* get_ptr(interface_ptr<T> const& p)
  176. {
  177. return p.get_interface_ptr();
  178. }
  179. /* /////////////////////////////////////////////////////////////////////////
  180. * Unit-testing
  181. */
  182. #ifdef STLSOFT_UNITTEST
  183. # include "./unittest/interface_ptr_unittest_.h"
  184. #endif /* STLSOFT_UNITTEST */
  185. /* /////////////////////////////////////////////////////////////////////////
  186. * Implementation
  187. */
  188. // interface_ptr
  189. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  190. template <ss_typename_param_k T>
  191. inline void interface_ptr<T>::swap(interface_ptr<T>& rhs)
  192. {
  193. parent_class_type::swap(rhs);
  194. }
  195. template <ss_typename_param_k T>
  196. inline interface_ptr<T>::interface_ptr()
  197. : parent_class_type()
  198. {}
  199. template <ss_typename_param_k T>
  200. inline interface_ptr<T>::interface_ptr(ss_typename_type_k interface_ptr<T>::pointer p, cs_bool_t bAddRef)
  201. : parent_class_type(p, bAddRef)
  202. {}
  203. template <ss_typename_param_k T>
  204. inline interface_ptr<T>::interface_ptr(ss_typename_type_k interface_ptr<T>::reference r, cs_bool_t bAddRef)
  205. : parent_class_type(&r, bAddRef)
  206. {}
  207. template <ss_typename_param_k T>
  208. inline interface_ptr<T>::interface_ptr(ss_typename_type_k interface_ptr<T>::class_type const& rhs)
  209. : parent_class_type(rhs)
  210. {}
  211. template <ss_typename_param_k T>
  212. inline void interface_ptr<T>::release()
  213. {
  214. parent_class_type::close();
  215. }
  216. template <ss_typename_param_k T>
  217. inline void interface_ptr<T>::release(cs_bool_t bDecRef /* = true */)
  218. {
  219. bDecRef ? parent_class_type::close() : static_cast<void>(parent_class_type::detach());
  220. }
  221. template <ss_typename_param_k T>
  222. inline interface_ptr<T>::~interface_ptr() stlsoft_throw_0()
  223. {
  224. release();
  225. }
  226. template <ss_typename_param_k T>
  227. inline ss_typename_type_ret_k interface_ptr<T>::class_type& interface_ptr<T>::operator =(ss_typename_type_k interface_ptr<T>::class_type const& rhs)
  228. {
  229. class_type t(rhs);
  230. swap(t);
  231. return *this;
  232. }
  233. template <ss_typename_param_k T>
  234. inline void interface_ptr<T>::set(ss_typename_type_k interface_ptr<T>::pointer p, cs_bool_t bAddRef)
  235. {
  236. class_type t(p, bAddRef);
  237. swap(t);
  238. }
  239. template <ss_typename_param_k T>
  240. inline void interface_ptr<T>::set(ss_typename_type_k interface_ptr<T>::reference r, cs_bool_t bAddRef)
  241. {
  242. COMSTL_MESSAGE_ASSERT("Attempting to dereference a null pointer", &r != NULL);
  243. class_type t(&r, bAddRef);
  244. swap(t);
  245. }
  246. template <ss_typename_param_k T>
  247. inline ss_typename_type_ret_k interface_ptr<T>::pointer interface_ptr<T>::detach()
  248. {
  249. return parent_class_type::detach();
  250. }
  251. template <ss_typename_param_k T>
  252. inline cs_bool_t interface_ptr<T>::operator ==(ss_typename_type_k interface_ptr<T>::class_type const& rhs) const
  253. {
  254. return parent_class_type::equal(rhs);
  255. }
  256. template <ss_typename_param_k T>
  257. inline cs_bool_t interface_ptr<T>::operator !=(ss_typename_type_k interface_ptr<T>::class_type const& rhs) const
  258. {
  259. return !parent_class_type::equal(rhs);
  260. }
  261. template <ss_typename_param_k T>
  262. inline interface_ptr<T>::operator ss_typename_type_k interface_ptr<T>::operator_bool_type() const
  263. {
  264. return operator_bool_generator_type::translate(parent_class_type::empty());
  265. }
  266. template <ss_typename_param_k T>
  267. inline ss_typename_type_ret_k interface_ptr<T>::pointer interface_ptr<T>::get_interface_ptr() const
  268. {
  269. return parent_class_type::get();
  270. }
  271. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  272. /* ////////////////////////////////////////////////////////////////////// */
  273. #ifndef _COMSTL_NO_NAMESPACE
  274. # if defined(_STLSOFT_NO_NAMESPACE) || \
  275. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  276. } // namespace comstl
  277. # else
  278. } // namespace comstl_project
  279. } // namespace stlsoft
  280. # endif /* _STLSOFT_NO_NAMESPACE */
  281. #endif /* !_COMSTL_NO_NAMESPACE */
  282. /* /////////////////////////////////////////////////////////////////////////
  283. * Namespace
  284. *
  285. * The string access shims exist either in the stlsoft namespace, or in the
  286. * global namespace. This is required by the lookup rules.
  287. *
  288. */
  289. #ifndef _COMSTL_NO_NAMESPACE
  290. # if !defined(_STLSOFT_NO_NAMESPACE) && \
  291. !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  292. namespace stlsoft
  293. {
  294. # else /* ? _STLSOFT_NO_NAMESPACE */
  295. /* There is no stlsoft namespace, so must define in the global namespace */
  296. # endif /* !_STLSOFT_NO_NAMESPACE */
  297. using ::comstl::get_ptr;
  298. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  299. using ::comstl::is_empty;
  300. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  301. # if !defined(_STLSOFT_NO_NAMESPACE) && \
  302. !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  303. } // namespace stlsoft
  304. # else /* ? _STLSOFT_NO_NAMESPACE */
  305. /* There is no stlsoft namespace, so must define in the global namespace */
  306. # endif /* !_STLSOFT_NO_NAMESPACE */
  307. #endif /* !_COMSTL_NO_NAMESPACE */
  308. /* In the special case of Intel behaving as VC++ 7.0 or earlier on Win32, we
  309. * illegally insert into the std namespace.
  310. */
  311. #if defined(STLSOFT_CF_std_NAMESPACE)
  312. # if ( ( defined(STLSOFT_COMPILER_IS_INTEL) && \
  313. defined(_MSC_VER))) && \
  314. _MSC_VER < 1310
  315. namespace std
  316. {
  317. template <ss_typename_param_k T>
  318. inline void swap(comstl_ns_qual(interface_ptr)<T>& lhs, comstl_ns_qual(interface_ptr)<T>& rhs)
  319. {
  320. lhs.swap(rhs);
  321. }
  322. } // namespace std
  323. # endif /* INTEL && _MSC_VER < 1310 */
  324. #endif /* STLSOFT_CF_std_NAMESPACE */
  325. /* ////////////////////////////////////////////////////////////////////// */
  326. #endif /* !COMSTL_INCL_COMSTL_SMARTPTR_HPP_INTERFACE_PTR */
  327. /* ///////////////////////////// end of file //////////////////////////// */