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.

319 lines
9.1 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: comstl/error/exceptions.hpp
  3. *
  4. * Purpose: COM-related exception classes, and their policy classes
  5. *
  6. * Created: 8th December 2004
  7. * Updated: 7th March 2010
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2004-2010, 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/error/exceptions.hpp
  40. *
  41. * \brief [C++ only] Definition of the comstl::com_exception and
  42. * comstl::variant_type_exception exception classes, and the
  43. * comstl::exception_policy_base exception policy class (and the
  44. * typedefs comstl::com_exception_policy and
  45. * comstl::variant_type_exception_policy)
  46. * (\ref group__library__error "Error" Library).
  47. */
  48. #ifndef COMSTL_INCL_COMSTL_ERROR_HPP_EXCEPTIONS
  49. #define COMSTL_INCL_COMSTL_ERROR_HPP_EXCEPTIONS
  50. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  51. # define COMSTL_VER_COMSTL_ERROR_HPP_EXCEPTIONS_MAJOR 2
  52. # define COMSTL_VER_COMSTL_ERROR_HPP_EXCEPTIONS_MINOR 2
  53. # define COMSTL_VER_COMSTL_ERROR_HPP_EXCEPTIONS_REVISION 1
  54. # define COMSTL_VER_COMSTL_ERROR_HPP_EXCEPTIONS_EDIT 44
  55. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  56. /* /////////////////////////////////////////////////////////////////////////
  57. * Compatibility
  58. */
  59. /*
  60. [DocumentationStatus:Ready]
  61. */
  62. /* /////////////////////////////////////////////////////////////////////////
  63. * Includes
  64. */
  65. #ifndef COMSTL_INCL_COMSTL_H_COMSTL
  66. # include <comstl/comstl.h>
  67. #endif /* !COMSTL_INCL_COMSTL_H_COMSTL */
  68. #ifndef STLSOFT_INCL_STLSOFT_ERROR_HPP_PROJECT_EXCEPTION
  69. # include <stlsoft/error/project_exception.hpp>
  70. #endif /* !STLSOFT_INCL_STLSOFT_ERROR_HPP_PROJECT_EXCEPTION */
  71. #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_EXCEPTION_STRING
  72. # include <stlsoft/util/exception_string.hpp>
  73. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_EXCEPTION_STRING */
  74. /* /////////////////////////////////////////////////////////////////////////
  75. * Namespace
  76. */
  77. #ifndef _COMSTL_NO_NAMESPACE
  78. # if defined(_STLSOFT_NO_NAMESPACE) || \
  79. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  80. /* There is no stlsoft namespace, so must define ::comstl */
  81. namespace comstl
  82. {
  83. # else
  84. /* Define stlsoft::comstl_project */
  85. namespace stlsoft
  86. {
  87. namespace comstl_project
  88. {
  89. # endif /* _STLSOFT_NO_NAMESPACE */
  90. #endif /* !_COMSTL_NO_NAMESPACE */
  91. /* /////////////////////////////////////////////////////////////////////////
  92. * Classes
  93. */
  94. /** \brief General exception class for COM-related failures.
  95. *
  96. * \ingroup group__library__error
  97. *
  98. */
  99. class com_exception
  100. : public stlsoft_ns_qual(project_exception)
  101. {
  102. /// \name Types
  103. /// @{
  104. private:
  105. typedef stlsoft_ns_qual(exception_string) string_type;
  106. public:
  107. typedef com_exception class_type;
  108. typedef stlsoft_ns_qual(project_exception) parent_class_type;
  109. /// @}
  110. /// \name Construction
  111. /// @{
  112. public:
  113. /// \brief Constructs an instance from the given result code
  114. ///
  115. /// \param hr The result code associated with the exception
  116. ss_explicit_k com_exception(HRESULT hr)
  117. : m_reason()
  118. , m_hr(hr)
  119. {}
  120. /// \brief Constructs an instance from the given message string and result code
  121. ///
  122. /// \param reason The message code associated with the exception
  123. /// \param hr The result code associated with the exception
  124. com_exception(char const* reason, HRESULT hr)
  125. : m_reason((NULL == reason) ? "" : reason)
  126. , m_hr(hr)
  127. {}
  128. /// \brief Destructor
  129. ///
  130. /// \note This does not do have any implementation, but is required to placate
  131. /// the Comeau and GCC compilers, which otherwise complain about mismatched
  132. /// exception specifications between this class and its parent
  133. virtual ~com_exception() stlsoft_throw_0()
  134. {}
  135. /// @}
  136. /// \name Accessors
  137. /// @{
  138. public:
  139. virtual char const* what() const stlsoft_throw_0()
  140. {
  141. return m_reason.empty() ? this->real_what_(): m_reason.c_str();
  142. }
  143. /// \brief The error code associated with the exception
  144. HRESULT get_hr() const
  145. {
  146. return m_hr;
  147. }
  148. /// [DEPRECATED]
  149. ///
  150. /// \deprecated Use get_hr() instead
  151. HRESULT hr() const
  152. {
  153. return m_hr;
  154. }
  155. /// @}
  156. /// \name Implementation
  157. /// @{
  158. private:
  159. virtual char const* real_what_() const throw()
  160. {
  161. return "COM exception";
  162. }
  163. /// @}
  164. /// \name Members
  165. /// @{
  166. private:
  167. string_type m_reason;
  168. HRESULT m_hr;
  169. /// @}
  170. /// \name Not to be implemented
  171. /// @{
  172. private:
  173. class_type& operator =(class_type const&);
  174. /// @}
  175. };
  176. /** \brief Indicates variant type mismatches.
  177. *
  178. * \ingroup group__library__error
  179. *
  180. * \remarks This is thrown by comstl::safearray_sequence on variant type
  181. * mismatches.
  182. */
  183. class variant_type_exception
  184. : public com_exception
  185. {
  186. public:
  187. typedef com_exception parent_class_type;
  188. typedef variant_type_exception class_type;
  189. /// \name Construction
  190. /// @{
  191. public:
  192. ss_explicit_k variant_type_exception(HRESULT hr)
  193. : parent_class_type(hr)
  194. {}
  195. variant_type_exception(char const* reason, HRESULT hr)
  196. : parent_class_type(reason, hr)
  197. {}
  198. /// \brief Destructor
  199. ///
  200. /// \note This does not do have any implementation, but is required to placate
  201. /// the Comeau and GCC compilers, which otherwise complain about mismatched
  202. /// exception specifications between this class and its parent
  203. virtual ~variant_type_exception() stlsoft_throw_0()
  204. {}
  205. /// @}
  206. /// \name Implementation
  207. /// @{
  208. private:
  209. virtual char const* real_what_() const throw()
  210. {
  211. return "VARIANT type exception";
  212. }
  213. /// @}
  214. };
  215. /* /////////////////////////////////////////////////////////////////////////
  216. * Policies
  217. */
  218. /** \brief Policy adaptor template for exception throwing
  219. *
  220. * \ingroup group__library__error
  221. *
  222. */
  223. template <ss_typename_param_k X>
  224. // [[synesis:class:exception-policy: exception_policy_base]]
  225. struct exception_policy_base
  226. {
  227. /// \name Member Types
  228. /// @{
  229. public:
  230. /// The thrown type
  231. typedef X thrown_type;
  232. /// @}
  233. /// \name Operators
  234. /// @{
  235. public:
  236. /// Function call operator, taking no parameters
  237. void operator ()() const
  238. {
  239. STLSOFT_THROW_X(thrown_type(::GetLastError()));
  240. }
  241. /// Function call operator, taking one parameter
  242. void operator ()(HRESULT hr) const
  243. {
  244. STLSOFT_THROW_X(thrown_type(hr));
  245. }
  246. /// Function call operator, taking two parameters
  247. void operator ()(char const* reason, HRESULT hr) const
  248. {
  249. STLSOFT_THROW_X(thrown_type(reason, hr));
  250. }
  251. /// @}
  252. };
  253. /** \brief The policy class, which throws a com_exception class.
  254. *
  255. * \ingroup group__library__error
  256. *
  257. */
  258. typedef exception_policy_base<com_exception> com_exception_policy;
  259. /** \brief The policy class, which throws a com_exception class.
  260. *
  261. * \ingroup group__library__error
  262. *
  263. */
  264. typedef exception_policy_base<variant_type_exception> variant_type_exception_policy;
  265. ////////////////////////////////////////////////////////////////////////////
  266. // Unit-testing
  267. #ifdef STLSOFT_UNITTEST
  268. # include "./unittest/exceptions_unittest_.h"
  269. #endif /* STLSOFT_UNITTEST */
  270. /* ////////////////////////////////////////////////////////////////////// */
  271. #ifndef _COMSTL_NO_NAMESPACE
  272. # if defined(_STLSOFT_NO_NAMESPACE) || \
  273. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  274. } // namespace comstl
  275. # else
  276. } // namespace comstl_project
  277. } // namespace stlsoft
  278. # endif /* _STLSOFT_NO_NAMESPACE */
  279. #endif /* !_COMSTL_NO_NAMESPACE */
  280. /* ////////////////////////////////////////////////////////////////////// */
  281. #endif /* !COMSTL_INCL_COMSTL_ERROR_HPP_EXCEPTIONS */
  282. /* ///////////////////////////// end of file //////////////////////////// */