throw_exception.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED
  2. #define BOOST_THROW_EXCEPTION_HPP_INCLUDED
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. //
  8. // boost/throw_exception.hpp
  9. //
  10. // Copyright (c) 2002, 2018, 2019 Peter Dimov
  11. // Copyright (c) 2008-2009 Emil Dotchevski and Reverge Studios, Inc.
  12. //
  13. // Distributed under the Boost Software License, Version 1.0. (See
  14. // accompanying file LICENSE_1_0.txt or copy at
  15. // http://www.boost.org/LICENSE_1_0.txt)
  16. //
  17. // http://www.boost.org/libs/throw_exception
  18. //
  19. #include <boost/exception/exception.hpp>
  20. #include <boost/assert/source_location.hpp>
  21. #include <boost/config.hpp>
  22. #include <boost/config/workaround.hpp>
  23. #include <exception>
  24. #if !defined( BOOST_EXCEPTION_DISABLE ) && defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x593) )
  25. # define BOOST_EXCEPTION_DISABLE
  26. #endif
  27. namespace boost
  28. {
  29. #if defined( BOOST_NO_EXCEPTIONS )
  30. BOOST_NORETURN void throw_exception( std::exception const & e ); // user defined
  31. BOOST_NORETURN void throw_exception( std::exception const & e, boost::source_location const & loc ); // user defined
  32. #endif
  33. // boost::wrapexcept<E>
  34. namespace detail
  35. {
  36. typedef char (&wrapexcept_s1)[ 1 ];
  37. typedef char (&wrapexcept_s2)[ 2 ];
  38. template<class T> wrapexcept_s1 wrapexcept_is_convertible( T* );
  39. template<class T> wrapexcept_s2 wrapexcept_is_convertible( void* );
  40. template<class E, class B, int I = sizeof( wrapexcept_is_convertible<B>( static_cast< E* >( 0 ) ) ) > struct wrapexcept_add_base;
  41. template<class E, class B> struct wrapexcept_add_base<E, B, 1>
  42. {
  43. struct type {};
  44. };
  45. template<class E, class B> struct wrapexcept_add_base<E, B, 2>
  46. {
  47. typedef B type;
  48. };
  49. } // namespace detail
  50. template<class E> struct BOOST_SYMBOL_VISIBLE wrapexcept:
  51. public detail::wrapexcept_add_base<E, boost::exception_detail::clone_base>::type,
  52. public E,
  53. public detail::wrapexcept_add_base<E, boost::exception>::type
  54. {
  55. private:
  56. struct deleter
  57. {
  58. wrapexcept * p_;
  59. ~deleter() { delete p_; }
  60. };
  61. private:
  62. void copy_from( void const* )
  63. {
  64. }
  65. void copy_from( boost::exception const* p )
  66. {
  67. static_cast<boost::exception&>( *this ) = *p;
  68. }
  69. public:
  70. explicit wrapexcept( E const & e ): E( e )
  71. {
  72. copy_from( &e );
  73. }
  74. explicit wrapexcept( E const & e, boost::source_location const & loc ): E( e )
  75. {
  76. copy_from( &e );
  77. set_info( *this, throw_file( loc.file_name() ) );
  78. set_info( *this, throw_line( loc.line() ) );
  79. set_info( *this, throw_function( loc.function_name() ) );
  80. }
  81. virtual boost::exception_detail::clone_base const * clone() const BOOST_OVERRIDE
  82. {
  83. wrapexcept * p = new wrapexcept( *this );
  84. deleter del = { p };
  85. boost::exception_detail::copy_boost_exception( p, this );
  86. del.p_ = 0;
  87. return p;
  88. }
  89. virtual void rethrow() const BOOST_OVERRIDE
  90. {
  91. #if defined( BOOST_NO_EXCEPTIONS )
  92. boost::throw_exception( *this );
  93. #else
  94. throw *this;
  95. #endif
  96. }
  97. };
  98. // All boost exceptions are required to derive from std::exception,
  99. // to ensure compatibility with BOOST_NO_EXCEPTIONS.
  100. inline void throw_exception_assert_compatibility( std::exception const & ) {}
  101. // boost::throw_exception
  102. #if !defined( BOOST_NO_EXCEPTIONS )
  103. #if defined( BOOST_EXCEPTION_DISABLE )
  104. template<class E> BOOST_NORETURN void throw_exception( E const & e )
  105. {
  106. throw_exception_assert_compatibility( e );
  107. throw e;
  108. }
  109. template<class E> BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & )
  110. {
  111. throw_exception_assert_compatibility( e );
  112. throw e;
  113. }
  114. #else // defined( BOOST_EXCEPTION_DISABLE )
  115. template<class E> BOOST_NORETURN void throw_exception( E const & e )
  116. {
  117. throw_exception_assert_compatibility( e );
  118. throw wrapexcept<E>( e );
  119. }
  120. template<class E> BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & loc )
  121. {
  122. throw_exception_assert_compatibility( e );
  123. throw wrapexcept<E>( e, loc );
  124. }
  125. #endif // defined( BOOST_EXCEPTION_DISABLE )
  126. #endif // !defined( BOOST_NO_EXCEPTIONS )
  127. } // namespace boost
  128. // BOOST_THROW_EXCEPTION
  129. #define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x, BOOST_CURRENT_LOCATION)
  130. #endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED