exception_specification.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // This file is distributed under the BSD License.
  2. // See "license.txt" for details.
  3. // Copyright 2009-2012, Jonathan Turner ([email protected])
  4. // Copyright 2009-2017, Jason Turner ([email protected])
  5. // http://www.chaiscript.com
  6. // This is an open source non-commercial project. Dear PVS-Studio, please check it.
  7. // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
  8. #ifndef CHAISCRIPT_EXCEPTION_SPECIFICATION_HPP_
  9. #define CHAISCRIPT_EXCEPTION_SPECIFICATION_HPP_
  10. #include <memory>
  11. #include "../chaiscript_defines.hpp"
  12. #include "boxed_cast.hpp"
  13. namespace chaiscript {
  14. class Boxed_Value;
  15. namespace exception {
  16. class bad_boxed_cast;
  17. } // namespace exception
  18. } // namespace chaiscript
  19. namespace chaiscript
  20. {
  21. namespace detail
  22. {
  23. struct Exception_Handler_Base
  24. {
  25. virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) = 0;
  26. virtual ~Exception_Handler_Base() = default;
  27. protected:
  28. template<typename T>
  29. static void throw_type(const Boxed_Value &bv, const Dispatch_Engine &t_engine)
  30. {
  31. try { T t = t_engine.boxed_cast<T>(bv); throw t; } catch (const chaiscript::exception::bad_boxed_cast &) {}
  32. }
  33. };
  34. template<typename ... T>
  35. struct Exception_Handler_Impl : Exception_Handler_Base
  36. {
  37. void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) override
  38. {
  39. (void)std::initializer_list<int>{(throw_type<T>(bv, t_engine), 0)...};
  40. }
  41. };
  42. }
  43. /// \brief Used in the automatic unboxing of exceptions thrown during script evaluation
  44. ///
  45. /// Exception specifications allow the user to tell ChaiScript what possible exceptions are expected from the script
  46. /// being executed. Exception_Handler objects are created with the chaiscript::exception_specification() function.
  47. ///
  48. /// Example:
  49. /// \code
  50. /// chaiscript::ChaiScript chai;
  51. ///
  52. /// try {
  53. /// chai.eval("throw(runtime_error(\"error\"))", chaiscript::exception_specification<int, double, float, const std::string &, const std::exception &>());
  54. /// } catch (const double e) {
  55. /// } catch (int) {
  56. /// } catch (float) {
  57. /// } catch (const std::string &) {
  58. /// } catch (const std::exception &e) {
  59. /// // This is the one what will be called in the specific throw() above
  60. /// }
  61. /// \endcode
  62. ///
  63. /// It is recommended that if catching the generic \c std::exception& type that you specifically catch
  64. /// the chaiscript::exception::eval_error type, so that there is no confusion.
  65. ///
  66. /// \code
  67. /// try {
  68. /// chai.eval("throw(runtime_error(\"error\"))", chaiscript::exception_specification<const std::exception &>());
  69. /// } catch (const chaiscript::exception::eval_error &) {
  70. /// // Error in script parsing / execution
  71. /// } catch (const std::exception &e) {
  72. /// // Error explicitly thrown from script
  73. /// }
  74. /// \endcode
  75. ///
  76. /// Similarly, if you are using the ChaiScript::eval form that unboxes the return value, then chaiscript::exception::bad_boxed_cast
  77. /// should be handled as well.
  78. ///
  79. /// \code
  80. /// try {
  81. /// chai.eval<int>("1.0", chaiscript::exception_specification<const std::exception &>());
  82. /// } catch (const chaiscript::exception::eval_error &) {
  83. /// // Error in script parsing / execution
  84. /// } catch (const chaiscript::exception::bad_boxed_cast &) {
  85. /// // Error unboxing return value
  86. /// } catch (const std::exception &e) {
  87. /// // Error explicitly thrown from script
  88. /// }
  89. /// \endcode
  90. ///
  91. /// \sa chaiscript::exception_specification for creation of chaiscript::Exception_Handler objects
  92. /// \sa \ref exceptions
  93. typedef std::shared_ptr<detail::Exception_Handler_Base> Exception_Handler;
  94. /// \brief creates a chaiscript::Exception_Handler which handles one type of exception unboxing
  95. /// \sa \ref exceptions
  96. template<typename ... T>
  97. Exception_Handler exception_specification()
  98. {
  99. return std::make_shared<detail::Exception_Handler_Impl<T...>>();
  100. }
  101. }
  102. #endif