ChaiScript / ChaiScript
1
// This file is distributed under the BSD License.
2
// See "license.txt" for details.
3
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
4
// Copyright 2009-2018, Jason Turner (jason@emptycrate.com)
5
// http://www.chaiscript.com
6

7
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
8
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
9

10

11
#ifndef CHAISCRIPT_EXCEPTION_SPECIFICATION_HPP_
12
#define CHAISCRIPT_EXCEPTION_SPECIFICATION_HPP_
13

14
#include <memory>
15

16
#include "../chaiscript_defines.hpp"
17
#include "boxed_cast.hpp"
18

19
namespace chaiscript {
20
class Boxed_Value;
21
namespace exception {
22
class bad_boxed_cast;
23
}  // namespace exception
24
}  // namespace chaiscript
25

26
namespace chaiscript
27
{
28
  namespace detail
29
  {
30
    struct Exception_Handler_Base
31
    {
32
      virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) = 0;
33

34 1
      virtual ~Exception_Handler_Base() = default;
35

36
      protected:
37
        template<typename T>
38 1
        static void throw_type(const Boxed_Value &bv, const Dispatch_Engine &t_engine)
39
        {
40 1
          try { T t = t_engine.boxed_cast<T>(bv); throw t; } catch (const chaiscript::exception::bad_boxed_cast &) {}
41
        }
42
    };
43

44
    template<typename ... T>
45
      struct Exception_Handler_Impl : Exception_Handler_Base
46
      {
47 1
        void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) override
48
        {
49 1
          (throw_type<T>(bv, t_engine), ...);
50
        }
51
      };
52
  }
53

54
  /// \brief Used in the automatic unboxing of exceptions thrown during script evaluation
55
  ///
56
  /// Exception specifications allow the user to tell ChaiScript what possible exceptions are expected from the script
57
  /// being executed. Exception_Handler objects are created with the chaiscript::exception_specification() function.
58
  ///
59
  /// Example:
60
  /// \code
61
  /// chaiscript::ChaiScript chai;
62
  ///
63
  /// try {
64
  ///   chai.eval("throw(runtime_error(\"error\"))", chaiscript::exception_specification<int, double, float, const std::string &, const std::exception &>());
65
  /// } catch (const double e) {
66
  /// } catch (int) {
67
  /// } catch (float) {
68
  /// } catch (const std::string &) {
69
  /// } catch (const std::exception &e) {
70
  ///   // This is the one what will be called in the specific throw() above
71
  /// }
72
  /// \endcode
73
  ///
74
  /// It is recommended that if catching the generic \c std::exception& type that you specifically catch
75
  /// the chaiscript::exception::eval_error type, so that there is no confusion.
76
  ///
77
  /// \code
78
  /// try {
79
  ///   chai.eval("throw(runtime_error(\"error\"))", chaiscript::exception_specification<const std::exception &>());
80
  /// } catch (const chaiscript::exception::eval_error &) {
81
  ///   // Error in script parsing / execution
82
  /// } catch (const std::exception &e) {
83
  ///   // Error explicitly thrown from script
84
  /// }
85
  /// \endcode
86
  ///
87
  /// Similarly, if you are using the ChaiScript::eval form that unboxes the return value, then chaiscript::exception::bad_boxed_cast
88
  /// should be handled as well.
89
  /// 
90
  /// \code
91
  /// try {
92
  ///   chai.eval<int>("1.0", chaiscript::exception_specification<const std::exception &>());
93
  /// } catch (const chaiscript::exception::eval_error &) {
94
  ///   // Error in script parsing / execution
95
  /// } catch (const chaiscript::exception::bad_boxed_cast &) {
96
  ///   // Error unboxing return value
97
  /// } catch (const std::exception &e) {
98
  ///   // Error explicitly thrown from script
99
  /// }
100
  /// \endcode
101
  ///
102
  /// \sa chaiscript::exception_specification for creation of chaiscript::Exception_Handler objects
103
  /// \sa \ref exceptions
104
  using Exception_Handler = std::shared_ptr<detail::Exception_Handler_Base>;
105

106
  /// \brief creates a chaiscript::Exception_Handler which handles one type of exception unboxing
107
  /// \sa \ref exceptions
108
  template<typename ... T>
109 1
  Exception_Handler exception_specification()
110
  {
111 1
    return std::make_shared<detail::Exception_Handler_Impl<T...>>();
112
  }
113
}
114

115

116
#endif
117

Read our documentation on viewing source code .

Loading