rice 4.3.3 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -26
  3. data/CMakeLists.txt +31 -0
  4. data/CMakePresets.json +75 -0
  5. data/COPYING +3 -2
  6. data/FindRuby.cmake +437 -0
  7. data/README.md +7 -2
  8. data/Rakefile +12 -5
  9. data/include/rice/rice.hpp +9522 -4426
  10. data/include/rice/stl.hpp +2831 -1198
  11. data/lib/make_rice_headers.rb +79 -0
  12. data/lib/mkmf-rice.rb +40 -94
  13. data/lib/rice/version.rb +3 -0
  14. data/lib/rice.rb +1 -0
  15. data/lib/rubygems/builder.rb +11 -0
  16. data/lib/rubygems/cmake_builder.rb +113 -0
  17. data/lib/rubygems_plugin.rb +9 -0
  18. data/rice/Address_Registration_Guard.hpp +72 -3
  19. data/rice/Arg.hpp +26 -6
  20. data/rice/Arg.ipp +35 -2
  21. data/rice/Buffer.hpp +123 -0
  22. data/rice/Buffer.ipp +599 -0
  23. data/rice/Callback.hpp +21 -0
  24. data/rice/Callback.ipp +13 -0
  25. data/rice/Constructor.hpp +4 -27
  26. data/rice/Constructor.ipp +79 -0
  27. data/rice/Data_Object.hpp +73 -3
  28. data/rice/Data_Object.ipp +388 -96
  29. data/rice/Data_Type.hpp +214 -3
  30. data/rice/Data_Type.ipp +144 -67
  31. data/rice/Director.hpp +0 -2
  32. data/rice/Enum.hpp +4 -7
  33. data/rice/Enum.ipp +102 -55
  34. data/rice/Exception.hpp +62 -2
  35. data/rice/Exception.ipp +7 -12
  36. data/rice/Init.hpp +8 -0
  37. data/rice/Init.ipp +8 -0
  38. data/rice/JumpException.hpp +44 -0
  39. data/rice/JumpException.ipp +48 -0
  40. data/rice/MemoryView.hpp +11 -0
  41. data/rice/MemoryView.ipp +3 -0
  42. data/rice/Return.hpp +7 -27
  43. data/rice/Return.ipp +13 -13
  44. data/rice/cpp_api/Array.hpp +209 -0
  45. data/rice/cpp_api/Array.ipp +304 -0
  46. data/rice/cpp_api/Builtin_Object.hpp +31 -0
  47. data/rice/cpp_api/Builtin_Object.ipp +37 -0
  48. data/rice/cpp_api/Class.hpp +70 -0
  49. data/rice/cpp_api/Class.ipp +97 -0
  50. data/rice/cpp_api/Encoding.hpp +32 -0
  51. data/rice/cpp_api/Encoding.ipp +59 -0
  52. data/rice/cpp_api/Hash.hpp +194 -0
  53. data/rice/cpp_api/Hash.ipp +257 -0
  54. data/rice/{Identifier.hpp → cpp_api/Identifier.hpp} +2 -6
  55. data/rice/{Identifier.ipp → cpp_api/Identifier.ipp} +4 -2
  56. data/rice/cpp_api/Module.hpp +72 -0
  57. data/rice/cpp_api/Module.ipp +101 -0
  58. data/rice/cpp_api/Object.hpp +272 -0
  59. data/rice/cpp_api/Object.ipp +235 -0
  60. data/rice/cpp_api/String.hpp +74 -0
  61. data/rice/cpp_api/String.ipp +120 -0
  62. data/rice/cpp_api/Struct.hpp +113 -0
  63. data/rice/cpp_api/Struct.ipp +92 -0
  64. data/rice/cpp_api/Symbol.hpp +46 -0
  65. data/rice/cpp_api/Symbol.ipp +93 -0
  66. data/rice/cpp_api/shared_methods.hpp +134 -0
  67. data/rice/detail/DefaultHandler.hpp +12 -0
  68. data/rice/detail/DefaultHandler.ipp +8 -0
  69. data/rice/detail/HandlerRegistry.hpp +5 -35
  70. data/rice/detail/HandlerRegistry.ipp +7 -11
  71. data/rice/detail/InstanceRegistry.hpp +1 -4
  72. data/rice/detail/MethodInfo.hpp +12 -10
  73. data/rice/detail/MethodInfo.ipp +26 -21
  74. data/rice/detail/Native.hpp +33 -0
  75. data/rice/detail/Native.ipp +157 -0
  76. data/rice/detail/NativeAttributeGet.hpp +52 -0
  77. data/rice/detail/NativeAttributeGet.ipp +57 -0
  78. data/rice/detail/NativeAttributeSet.hpp +44 -0
  79. data/rice/detail/NativeAttributeSet.ipp +88 -0
  80. data/rice/detail/NativeCallbackFFI.hpp +55 -0
  81. data/rice/detail/NativeCallbackFFI.ipp +151 -0
  82. data/rice/detail/NativeCallbackSimple.hpp +30 -0
  83. data/rice/detail/NativeCallbackSimple.ipp +29 -0
  84. data/rice/detail/NativeFunction.hpp +33 -23
  85. data/rice/detail/NativeFunction.ipp +309 -70
  86. data/rice/detail/NativeIterator.hpp +9 -11
  87. data/rice/detail/NativeIterator.ipp +33 -31
  88. data/rice/detail/NativeRegistry.hpp +24 -15
  89. data/rice/detail/NativeRegistry.ipp +23 -48
  90. data/rice/detail/Proc.hpp +4 -0
  91. data/rice/detail/Proc.ipp +85 -0
  92. data/rice/detail/Registries.hpp +0 -7
  93. data/rice/detail/Registries.ipp +0 -18
  94. data/rice/detail/RubyFunction.hpp +0 -3
  95. data/rice/detail/RubyFunction.ipp +4 -8
  96. data/rice/detail/RubyType.hpp +16 -0
  97. data/rice/detail/RubyType.ipp +232 -0
  98. data/rice/detail/Type.hpp +7 -6
  99. data/rice/detail/Type.ipp +192 -45
  100. data/rice/detail/TypeRegistry.hpp +15 -7
  101. data/rice/detail/TypeRegistry.ipp +105 -12
  102. data/rice/detail/Wrapper.hpp +68 -32
  103. data/rice/detail/Wrapper.ipp +121 -109
  104. data/rice/detail/cpp_protect.hpp +5 -6
  105. data/rice/detail/default_allocation_func.ipp +0 -2
  106. data/rice/detail/from_ruby.hpp +38 -3
  107. data/rice/detail/from_ruby.ipp +1321 -492
  108. data/rice/detail/ruby.hpp +18 -0
  109. data/rice/detail/to_ruby.hpp +41 -3
  110. data/rice/detail/to_ruby.ipp +1424 -194
  111. data/rice/global_function.hpp +0 -4
  112. data/rice/global_function.ipp +0 -1
  113. data/rice/libc/file.hpp +11 -0
  114. data/rice/libc/file.ipp +32 -0
  115. data/rice/rice.hpp +116 -26
  116. data/rice/ruby_mark.hpp +4 -3
  117. data/rice/stl/complex.hpp +6 -0
  118. data/rice/stl/complex.ipp +93 -0
  119. data/rice/stl/exception.hpp +11 -0
  120. data/rice/stl/exception.ipp +29 -0
  121. data/rice/stl/exception_ptr.hpp +6 -0
  122. data/rice/stl/exception_ptr.ipp +27 -0
  123. data/rice/stl/map.hpp +12 -0
  124. data/rice/stl/map.ipp +469 -0
  125. data/rice/stl/monostate.hpp +6 -0
  126. data/rice/stl/monostate.ipp +80 -0
  127. data/rice/stl/multimap.hpp +14 -0
  128. data/rice/stl/multimap.ipp +448 -0
  129. data/rice/stl/optional.hpp +6 -0
  130. data/rice/stl/optional.ipp +118 -0
  131. data/rice/stl/pair.hpp +13 -0
  132. data/rice/stl/pair.ipp +155 -0
  133. data/rice/stl/reference_wrapper.hpp +6 -0
  134. data/rice/stl/reference_wrapper.ipp +41 -0
  135. data/rice/stl/set.hpp +12 -0
  136. data/rice/stl/set.ipp +495 -0
  137. data/rice/stl/shared_ptr.hpp +28 -0
  138. data/rice/stl/shared_ptr.ipp +224 -0
  139. data/rice/stl/string.hpp +6 -0
  140. data/rice/stl/string.ipp +158 -0
  141. data/rice/stl/string_view.hpp +6 -0
  142. data/rice/stl/string_view.ipp +65 -0
  143. data/rice/stl/tuple.hpp +6 -0
  144. data/rice/stl/tuple.ipp +128 -0
  145. data/rice/stl/type_index.hpp +6 -0
  146. data/rice/stl/type_index.ipp +30 -0
  147. data/rice/stl/type_info.hpp +6 -0
  148. data/rice/stl/type_info.ipp +29 -0
  149. data/rice/stl/unique_ptr.hpp +22 -0
  150. data/rice/stl/unique_ptr.ipp +139 -0
  151. data/rice/stl/unordered_map.hpp +12 -0
  152. data/rice/stl/unordered_map.ipp +469 -0
  153. data/rice/stl/variant.hpp +6 -0
  154. data/rice/stl/variant.ipp +242 -0
  155. data/rice/stl/vector.hpp +12 -0
  156. data/rice/stl/vector.ipp +590 -0
  157. data/rice/stl.hpp +11 -3
  158. data/rice/traits/attribute_traits.hpp +26 -0
  159. data/rice/traits/function_traits.hpp +95 -0
  160. data/rice/traits/method_traits.hpp +47 -0
  161. data/rice/traits/rice_traits.hpp +160 -0
  162. data/rice.gemspec +85 -0
  163. data/test/embed_ruby.cpp +7 -1
  164. data/test/extconf.rb +2 -0
  165. data/test/test_Address_Registration_Guard.cpp +5 -0
  166. data/test/test_Array.cpp +18 -4
  167. data/test/test_Attribute.cpp +136 -21
  168. data/test/test_Buffer.cpp +285 -0
  169. data/test/test_Builtin_Object.cpp +5 -0
  170. data/test/test_Callback.cpp +230 -0
  171. data/test/test_Class.cpp +5 -31
  172. data/test/test_Constructor.cpp +69 -6
  173. data/test/test_Data_Object.cpp +97 -38
  174. data/test/test_Data_Type.cpp +470 -65
  175. data/test/test_Director.cpp +17 -8
  176. data/test/test_Enum.cpp +155 -40
  177. data/test/test_Exception.cpp +235 -0
  178. data/test/test_File.cpp +70 -0
  179. data/test/test_From_Ruby.cpp +609 -0
  180. data/test/test_Hash.cpp +5 -0
  181. data/test/test_Identifier.cpp +5 -0
  182. data/test/test_Inheritance.cpp +6 -1
  183. data/test/test_Iterator.cpp +6 -1
  184. data/test/test_Jump_Exception.cpp +23 -0
  185. data/test/test_Keep_Alive.cpp +13 -19
  186. data/test/test_Keep_Alive_No_Wrapper.cpp +5 -1
  187. data/test/test_Memory_Management.cpp +5 -0
  188. data/test/test_Module.cpp +128 -67
  189. data/test/test_Native_Registry.cpp +2 -34
  190. data/test/test_Object.cpp +5 -0
  191. data/test/test_Overloads.cpp +806 -0
  192. data/test/test_Ownership.cpp +160 -54
  193. data/test/test_Proc.cpp +44 -0
  194. data/test/test_Self.cpp +9 -4
  195. data/test/test_Stl_Exception.cpp +109 -0
  196. data/test/test_Stl_Map.cpp +54 -42
  197. data/test/test_Stl_Multimap.cpp +693 -0
  198. data/test/test_Stl_Optional.cpp +5 -0
  199. data/test/test_Stl_Pair.cpp +14 -9
  200. data/test/test_Stl_Reference_Wrapper.cpp +9 -2
  201. data/test/test_Stl_Set.cpp +790 -0
  202. data/test/test_Stl_SharedPtr.cpp +458 -0
  203. data/test/test_Stl_String.cpp +5 -0
  204. data/test/test_Stl_String_View.cpp +5 -0
  205. data/test/test_Stl_Tuple.cpp +116 -0
  206. data/test/test_Stl_Type.cpp +147 -0
  207. data/test/test_Stl_UniquePtr.cpp +202 -0
  208. data/test/test_Stl_Unordered_Map.cpp +43 -38
  209. data/test/test_Stl_Variant.cpp +217 -84
  210. data/test/test_Stl_Vector.cpp +306 -58
  211. data/test/test_String.cpp +5 -0
  212. data/test/test_Struct.cpp +5 -0
  213. data/test/test_Symbol.cpp +5 -0
  214. data/test/test_Template.cpp +192 -0
  215. data/test/test_To_Ruby.cpp +524 -0
  216. data/test/test_Tracking.cpp +1 -0
  217. data/test/test_Type.cpp +171 -0
  218. data/test/test_global_functions.cpp +67 -7
  219. data/test/unittest.cpp +8 -0
  220. metadata +127 -26
  221. data/lib/version.rb +0 -3
  222. data/rice/Address_Registration_Guard_defn.hpp +0 -79
  223. data/rice/Data_Object_defn.hpp +0 -84
  224. data/rice/Data_Type_defn.hpp +0 -190
  225. data/rice/Exception_defn.hpp +0 -68
  226. data/rice/HandlerRegistration.hpp +0 -15
  227. data/rice/detail/ExceptionHandler.hpp +0 -8
  228. data/rice/detail/ExceptionHandler.ipp +0 -28
  229. data/rice/detail/ExceptionHandler_defn.hpp +0 -77
  230. data/rice/detail/Jump_Tag.hpp +0 -21
  231. data/rice/detail/NativeAttribute.hpp +0 -64
  232. data/rice/detail/NativeAttribute.ipp +0 -112
  233. data/rice/detail/from_ruby_defn.hpp +0 -38
  234. data/rice/detail/to_ruby_defn.hpp +0 -48
  235. data/test/test_Jump_Tag.cpp +0 -17
  236. data/test/test_Stl_SmartPointer.cpp +0 -283
  237. data/test/test_To_From_Ruby.cpp +0 -399
@@ -1,84 +0,0 @@
1
- #ifndef Rice__Data_Object_defn__hpp_
2
- #define Rice__Data_Object_defn__hpp_
3
-
4
- #include <optional>
5
-
6
- #include "detail/to_ruby.hpp"
7
- #include "detail/ruby.hpp"
8
- #include "cpp_api/Object_defn.hpp"
9
-
10
- /*! \file
11
- * \brief Provides a helper class for wrapping and unwrapping C++
12
- * objects as Ruby objects.
13
- */
14
-
15
- namespace Rice
16
- {
17
- //! A smartpointer-like wrapper for Ruby data objects.
18
- /*! A data object is a ruby object of type T_DATA, which is usually
19
- * created by using the Data_Wrap_Struct or Data_Make_Struct macro.
20
- * This class wraps creation of the data structure, providing a
21
- * type-safe object-oriented interface to the underlying C interface.
22
- * This class works in conjunction with the Data_Type class to ensure
23
- * type safety.
24
- *
25
- * Example:
26
- * \code
27
- * class Foo { };
28
- * ...
29
- * Data_Type<Foo> rb_cFoo = define_class("Foo");
30
- * ...
31
- * // Wrap:
32
- * Data_Object<Foo> foo1(new Foo);
33
- *
34
- * // Get value to return:
35
- * VALUE v = foo1.value()
36
- *
37
- * // Unwrap:
38
- * Data_Object<Foo> foo2(v, rb_cFoo);
39
- * \endcode
40
- */
41
- template<typename T>
42
- class Data_Object : public Object
43
- {
44
- static_assert(!std::is_pointer_v<T>);
45
- static_assert(!std::is_reference_v<T>);
46
- static_assert(!std::is_const_v<T>);
47
- static_assert(!std::is_volatile_v<T>);
48
-
49
- public:
50
- static T* from_ruby(VALUE value);
51
-
52
- public:
53
- //! Wrap a C++ object.
54
- /*! This constructor is analogous to calling Data_Wrap_Struct. Be
55
- * careful not to call this function more than once for the same
56
- * pointer (in general, it should only be called for newly
57
- * constructed objects that need to be managed by Ruby's garbage
58
- * collector).
59
- * \param obj the object to wrap.
60
- * \param isOwner Should the Data_Object take ownership of the object?
61
- * \param klass the Ruby class to use for the newly created Ruby
62
- * object.
63
- */
64
- Data_Object(T* obj, bool isOwner = false, Class klass = Data_Type<T>::klass());
65
- Data_Object(T& obj, bool isOwner = false, Class klass = Data_Type<T>::klass());
66
-
67
- //! Unwrap a Ruby object.
68
- /*! This constructor is analogous to calling Data_Get_Struct. Uses
69
- * Data_Type<T>::klass as the class of the object.
70
- * \param value the Ruby object to unwrap.
71
- */
72
- Data_Object(Object value);
73
-
74
- T& operator*() const; //!< Return a reference to obj_
75
- T* operator->() const; //!< Return a pointer to obj_
76
- T* get() const; //!< Return a pointer to obj_
77
-
78
- private:
79
- static void check_ruby_type(VALUE value);
80
- };
81
- } // namespace Rice
82
-
83
- #endif // Rice__Data_Object_defn__hpp_
84
-
@@ -1,190 +0,0 @@
1
- #ifndef Rice__Data_Type_defn__hpp_
2
- #define Rice__Data_Type_defn__hpp_
3
-
4
- #include "cpp_api/Class_defn.hpp"
5
- #include "detail/ruby.hpp"
6
- #include <set>
7
-
8
- namespace Rice
9
- {
10
- //! A mechanism for binding ruby types to C++ types.
11
- /*! This class binds run-time types (Ruby VALUEs) to compile-time types
12
- * (C++ types). The binding can occur only once.
13
- */
14
- template<typename T>
15
- class Data_Type : public Class
16
- {
17
- static_assert(std::is_same_v<detail::intrinsic_type<T>, T>);
18
-
19
- public:
20
- //! Default constructor which does not bind.
21
- /*! No member functions must be called on this Data_Type except bind,
22
- * until the type is bound.
23
- */
24
- Data_Type();
25
-
26
- //! Constructor which takes a Module.
27
- /*! Binds the type to the given VALUE according to the rules given
28
- * above.
29
- * \param klass the module to which to bind.
30
- */
31
- Data_Type(Module const & v);
32
-
33
- //! Destructor.
34
- virtual ~Data_Type();
35
-
36
- //! Return the Ruby class.
37
- /*! \return the ruby class to which the type is bound.
38
- */
39
- static Class klass();
40
-
41
- //! Return the Ruby data type.
42
- static rb_data_type_t* ruby_data_type();
43
-
44
- //! Assignment operator which takes a Module
45
- /*! \param klass must be the class to which this data type is already
46
- * bound.
47
- * \return *this
48
- */
49
- virtual Data_Type & operator=(Module const & klass);
50
-
51
- /*! Creates a singleton method allocate and an instance method called
52
- * initialize which together create a new instance of the class. The
53
- * allocate method allocates memory for the object reference and the
54
- * initialize method constructs the object.
55
- * \param constructor an object that has a static member function
56
- * construct() that constructs a new instance of T and sets the object's data
57
- * member to point to the new instance. A helper class Constructor
58
- * is provided that does precisely this.
59
- * \param args a list of Arg instance used to define default parameters (optional)
60
- *
61
- * For example:
62
- * \code
63
- * define_class<Foo>("Foo")
64
- * .define_constructor(Constructor<Foo>());
65
- * \endcode
66
- */
67
- template<typename Constructor_T, typename...Arg_Ts>
68
- Data_Type<T> & define_constructor(Constructor_T constructor, Arg_Ts const& ...args);
69
-
70
- //! Register a Director class for this class.
71
- /*! For any class that uses Rice::Director to enable polymorphism
72
- * across the languages, you need to register that director proxy
73
- * class with this method. Not doing so will cause the resulting
74
- * library to die at run time when it tries to convert the base
75
- * type into the Director proxy type.
76
- *
77
- * This method takes no methodInfo, just needs the type of the
78
- * Director proxy class.
79
- *
80
- * For example:
81
- * \code
82
- * class FooDirector : public Foo, public Rice::Director {
83
- * ...
84
- * };
85
- *
86
- * define_class<Foo>("Foo")
87
- * .define_director<FooDirector>()
88
- * .define_constructor(Constructor<FooDirector, Rice::Object>());
89
- * \endcode
90
- */
91
- template<typename Director_T>
92
- Data_Type<T>& define_director();
93
-
94
- //! Determine if the type is bound.
95
- /*! \return true if the object is bound, false otherwise.
96
- */
97
- static bool is_bound();
98
- static void check_is_bound();
99
-
100
- // This is only for testing - DO NOT USE!!!
101
- static void unbind();
102
-
103
- static bool is_descendant(VALUE value);
104
-
105
- //! Define an iterator.
106
- /*! Essentially this is a conversion from a C++-style begin/end
107
- * iterator to a Ruby-style \#each iterator.
108
- * \param begin a member function pointer to a function that returns
109
- * an iterator to the beginning of the sequence.
110
- * \param end a member function pointer to a function that returns an
111
- * iterator to the end of the sequence.
112
- * \param name the name of the iterator.
113
- * \return *this
114
- */
115
-
116
- template<typename Iterator_Func_T>
117
- Data_Type<T>& define_iterator(Iterator_Func_T begin, Iterator_Func_T end, std::string name = "each");
118
-
119
- template <typename Attribute_T>
120
- Data_Type<T>& define_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite);
121
-
122
- template <typename Attribute_T>
123
- Data_Type<T>& define_singleton_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite);
124
-
125
- #include "cpp_api/shared_methods.hpp"
126
-
127
- protected:
128
- //! Bind a Data_Type to a VALUE.
129
- /*! Throws an exception if the Data_Type is already bound to a
130
- * different class. Any existing instances of the Data_Type will be
131
- * bound after this function returns.
132
- * \param klass the ruby type to which to bind.
133
- * \return *this
134
- */
135
- template <typename Base_T = void>
136
- static Data_Type bind(const Module& klass);
137
-
138
- template<typename T_, typename Base_T_>
139
- friend Rice::Data_Type<T_> define_class_under(Object module, char const * name);
140
-
141
- template<typename T_, typename Base_T_>
142
- friend Rice::Data_Type<T_> define_class(char const * name);
143
-
144
- template<bool IsMethod, typename Function_T>
145
- void wrap_native_call(VALUE klass, std::string name, Function_T&& function, MethodInfo* methodInfo);
146
-
147
- private:
148
- template<typename T_>
149
- friend class Data_Type;
150
-
151
- static inline VALUE klass_ = Qnil;
152
-
153
- // Typed Data support
154
- static inline rb_data_type_t* rb_data_type_ = nullptr;
155
-
156
- typedef std::set<Data_Type<T> *> Instances;
157
-
158
- static Instances & unbound_instances()
159
- {
160
- static Instances unbound_instances;
161
- return unbound_instances;
162
- }
163
- };
164
-
165
- //! Define a new data class in the namespace given by module.
166
- /*! By default the class will inherit from Ruby's rb_cObject. This
167
- * can be overriden via the Base_T template parameter. Note that
168
- * Base_T must already have been registered.
169
- * \param T the C++ type of the wrapped class.
170
- * \param module the the Module in which to define the class.
171
- * \return the new class.
172
- */
173
- template<typename T, typename Base_T = void>
174
- Data_Type<T> define_class_under(Object module, char const* name);
175
-
176
- //! Define a new data class in the default namespace.
177
- /*! By default the class will inherit from Ruby's rb_cObject. This
178
- * can be overriden via the Base_T template parameter. Note that
179
- * Base_T must already have been registered.
180
- * \param T the C++ type of the wrapped class.
181
- * \param module the the Module in which to define the class.
182
- * \return the new class.
183
- */
184
- template<typename T, typename Base_T = void>
185
- Data_Type<T> define_class(char const* name);
186
- } // namespace Rice
187
-
188
- #include "Data_Type.ipp"
189
-
190
- #endif // Rice__Data_Type_defn__hpp_
@@ -1,68 +0,0 @@
1
- #ifndef Rice__Exception_defn__hpp_
2
- #define Rice__Exception_defn__hpp_
3
-
4
- #include <stdexcept>
5
- #include "detail/ruby.hpp"
6
-
7
- namespace Rice
8
- {
9
- //! A placeholder for Ruby exceptions.
10
- /*! You can use this to safely throw a Ruby exception using C++ syntax:
11
- * \code
12
- * VALUE foo(VALUE self) {
13
- * RUBY_TRY {
14
- * throw Rice::Exception(rb_eMyException, "uh oh!");
15
- * RUBY_CATCH
16
- * }
17
- * \endcode
18
- */
19
- class Exception
20
- : public std::exception
21
- {
22
- public:
23
- //! Construct a Exception with a Ruby exception instance
24
- explicit Exception(VALUE exception);
25
-
26
- //! Construct a Exception with printf-style formatting.
27
- /*! \param exc either an exception object or a class that inherits
28
- * from Exception.
29
- * \param fmt a printf-style format string
30
- * \param ... the arguments to the format string.
31
- */
32
- template <typename... Arg_Ts>
33
- Exception(const Exception& other, char const* fmt, Arg_Ts&&...args);
34
-
35
- //! Construct a Exception with printf-style formatting.
36
- /*! \param exc either an exception object or a class that inherits
37
- * from Exception.
38
- * \param fmt a printf-style format string
39
- * \param ... the arguments to the format string.
40
- */
41
- template <typename... Arg_Ts>
42
- Exception(const VALUE exceptionType, char const* fmt, Arg_Ts&&...args);
43
-
44
- //! Destructor
45
- virtual ~Exception() noexcept = default;
46
-
47
- //! Get message as a char const *.
48
- /*! If message is a non-string object, then this function will attempt
49
- * to throw an exception (which it can't do because of the no-throw
50
- * specification).
51
- * \return the underlying C pointer of the underlying message object.
52
- */
53
- virtual char const* what() const noexcept override;
54
-
55
- //! Returns the Ruby exception class
56
- VALUE class_of() const;
57
-
58
- //! Returns an instance of a Ruby exception
59
- VALUE value() const;
60
-
61
- private:
62
- // TODO: Do we need to tell the Ruby gc about an exception instance?
63
- mutable VALUE exception_ = Qnil;
64
- mutable std::string message_;
65
- };
66
- } // namespace Rice
67
-
68
- #endif // Rice__Exception_defn__hpp_
@@ -1,15 +0,0 @@
1
- #ifndef Rice__HandlerRegistration__hpp_
2
- #define Rice__HandlerRegistration__hpp_
3
-
4
- #include "detail/HandlerRegistry.hpp"
5
-
6
- namespace Rice
7
- {
8
- // Register exception handler
9
- template<typename Exception_T, typename Functor_T>
10
- detail::HandlerRegistry register_handler(Functor_T functor)
11
- {
12
- return detail::Registries::instance.handlers.add<Exception_T, Functor_T>(std::forward<Functor_T>(functor));
13
- }
14
- }
15
- #endif // Rice__HandlerRegistration__hpp_
@@ -1,8 +0,0 @@
1
- #ifndef Rice__detail__ExceptionHandler__hpp_
2
- #define Rice__detail__ExceptionHandler__hpp_
3
-
4
- #include "ExceptionHandler_defn.hpp"
5
- #include "ExceptionHandler.ipp"
6
-
7
- #endif // Rice__detail__ExceptionHandler__hpp_
8
-
@@ -1,28 +0,0 @@
1
- namespace Rice::detail
2
- {
3
- inline VALUE Rice::detail::DefaultExceptionHandler::handle() const
4
- {
5
- throw;
6
- }
7
-
8
- template <typename Exception_T, typename Functor_T>
9
- inline Rice::detail::CustomExceptionHandler<Exception_T, Functor_T>::
10
- CustomExceptionHandler(Functor_T handler, std::shared_ptr<ExceptionHandler> nextHandler)
11
- : handler_(handler), nextHandler_(nextHandler)
12
- {
13
- }
14
-
15
- template <typename Exception_T, typename Functor_T>
16
- inline VALUE Rice::detail::CustomExceptionHandler<Exception_T, Functor_T>::handle() const
17
- {
18
- try
19
- {
20
- return this->nextHandler_->handle();
21
- }
22
- catch (Exception_T const& ex)
23
- {
24
- handler_(ex);
25
- throw;
26
- }
27
- }
28
- }
@@ -1,77 +0,0 @@
1
- #ifndef Rice__detail__ExceptionHandler_defn__hpp_
2
- #define Rice__detail__ExceptionHandler_defn__hpp_
3
-
4
- #include <memory>
5
- #include "ruby.hpp"
6
-
7
- namespace Rice::detail
8
- {
9
- /* An abstract class for converting C++ exceptions to ruby exceptions. It's used
10
- like this:
11
-
12
- try
13
- {
14
- }
15
- catch(...)
16
- {
17
- handler->handle();
18
- }
19
-
20
- If an exception is thrown the handler will pass the exception up the
21
- chain, then the last handler in the chain will throw the exception
22
- down the chain until a lower handler can handle it, e.g.:
23
-
24
- try
25
- {
26
- return call_next_ExceptionHandler();
27
- }
28
- catch(MyException const & ex)
29
- {
30
- throw Rice::Exception(rb_cMyException, "%s", ex.what());
31
- }
32
-
33
- Memory management. Handlers are created by the ModuleBase constructor. When the
34
- module defines a new Ruby method, metadata is stored on the Ruby klass including
35
- the exception handler. Since the metadata outlives the module, handlers are stored
36
- using std::shared_ptr. Thus the Module (or its inherited children) can be destroyed
37
- without corrupting the metadata references to the shared exception handler. */
38
-
39
- class ExceptionHandler
40
- {
41
- public:
42
- ExceptionHandler() = default;
43
- virtual ~ExceptionHandler() = default;
44
-
45
- // Don't allow copying or assignment
46
- ExceptionHandler(const ExceptionHandler& other) = delete;
47
- ExceptionHandler& operator=(const ExceptionHandler& other) = delete;
48
-
49
- virtual VALUE handle() const = 0;
50
- };
51
-
52
- // The default exception handler just rethrows the exception. If there
53
- // are other handlers in the chain, they will try to handle the rethrown
54
- // exception.
55
- class DefaultExceptionHandler : public ExceptionHandler
56
- {
57
- public:
58
- virtual VALUE handle() const override;
59
- };
60
-
61
- // An exception handler that takes a functor as an argument. The
62
- // functor should throw a Rice::Exception to handle the exception. If
63
- // the functor does not handle the exception, the exception will be
64
- // re-thrown.
65
- template <typename Exception_T, typename Functor_T>
66
- class CustomExceptionHandler : public ExceptionHandler
67
- {
68
- public:
69
- CustomExceptionHandler(Functor_T handler, std::shared_ptr<ExceptionHandler> nextHandler);
70
- virtual VALUE handle() const override;
71
-
72
- private:
73
- Functor_T handler_;
74
- std::shared_ptr<ExceptionHandler> nextHandler_;
75
- };
76
- }
77
- #endif // Rice__detail__ExceptionHandler_defn__hpp_
@@ -1,21 +0,0 @@
1
- #ifndef Rice__detail__Jump_Tag__hpp_
2
- #define Rice__detail__Jump_Tag__hpp_
3
-
4
- namespace Rice
5
- {
6
- //! A placeholder for Ruby longjmp data.
7
- /*! When a Ruby exception is caught, the tag used for the longjmp is stored in
8
- * a Jump_Tag, then later passed to rb_jump_tag() when there is no more
9
- * C++ code to pass over.
10
- */
11
- struct Jump_Tag
12
- {
13
- //! Construct a Jump_Tag with tag t.
14
- Jump_Tag(int t) : tag(t) {}
15
-
16
- //! The tag being held.
17
- int tag;
18
- };
19
- } // namespace Rice
20
-
21
- #endif // Rice__detail__Jump_Tag__hpp_
@@ -1,64 +0,0 @@
1
- #ifndef Rice__detail__Native_Attribute__hpp_
2
- #define Rice__detail__Native_Attribute__hpp_
3
-
4
- #include "ruby.hpp"
5
- #include "../traits/attribute_traits.hpp"
6
-
7
- namespace Rice
8
- {
9
- enum class AttrAccess
10
- {
11
- ReadWrite,
12
- Read,
13
- Write
14
- };
15
-
16
- namespace detail
17
- {
18
- template<typename Attribute_T>
19
- class NativeAttribute
20
- {
21
- public:
22
- using NativeAttribute_T = NativeAttribute<Attribute_T>;
23
-
24
- using T = typename attribute_traits<Attribute_T>::attr_type;
25
- using T_Unqualified = remove_cv_recursive_t<T>;
26
- using Receiver_T = typename attribute_traits<Attribute_T>::class_type;
27
-
28
- public:
29
- // Register attribute getter/setter with Ruby
30
- static void define(VALUE klass, std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite);
31
-
32
- // Static member functions that Ruby calls to read an attribute value
33
- static VALUE get(VALUE self);
34
-
35
- // Static member functions that Ruby calls to write an attribute value
36
- static VALUE set(VALUE self, VALUE value);
37
-
38
- public:
39
- // Disallow creating/copying/moving
40
- NativeAttribute() = delete;
41
- NativeAttribute(const NativeAttribute_T&) = delete;
42
- NativeAttribute(NativeAttribute_T&&) = delete;
43
- void operator=(const NativeAttribute_T&) = delete;
44
- void operator=(NativeAttribute_T&&) = delete;
45
-
46
- protected:
47
- NativeAttribute(VALUE klass, std::string name, Attribute_T attr, AttrAccess access = AttrAccess::ReadWrite);
48
-
49
- // Invokes the wrapped function
50
- VALUE read(VALUE self);
51
- VALUE write(VALUE self, VALUE value);
52
-
53
- private:
54
- VALUE klass_;
55
- std::string name_;
56
- Attribute_T attribute_;
57
- AttrAccess access_;
58
- };
59
- } // detail
60
- } // Rice
61
-
62
- #include "NativeAttribute.ipp"
63
-
64
- #endif // Rice__detail__Native_Attribute__hpp_
@@ -1,112 +0,0 @@
1
- #include <array>
2
- #include <algorithm>
3
-
4
- #include "../traits/rice_traits.hpp"
5
- #include "NativeRegistry.hpp"
6
- #include "to_ruby_defn.hpp"
7
- #include "cpp_protect.hpp"
8
-
9
- namespace Rice::detail
10
- {
11
- template<typename Attribute_T>
12
- void NativeAttribute<Attribute_T>::define(VALUE klass, std::string name, Attribute_T attribute, AttrAccess access)
13
- {
14
- // Create a NativeAttribute that Ruby will call to read/write C++ variables
15
- NativeAttribute_T* native = new NativeAttribute_T(klass, name, std::forward<Attribute_T>(attribute), access);
16
-
17
- if (access == AttrAccess::ReadWrite || access == AttrAccess::Read)
18
- {
19
- // Tell Ruby to invoke the static method read to get the attribute value
20
- detail::protect(rb_define_method, klass, name.c_str(), (RUBY_METHOD_FUNC)&NativeAttribute_T::get, 0);
21
-
22
- // Add to native registry
23
- detail::Registries::instance.natives.add(klass, Identifier(name).id(), native);
24
- }
25
-
26
- if (access == AttrAccess::ReadWrite || access == AttrAccess::Write)
27
- {
28
- if (std::is_const_v<std::remove_pointer_t<T>>)
29
- {
30
- throw std::runtime_error(name + " is readonly");
31
- }
32
-
33
- // Define the write method name
34
- std::string setter = name + "=";
35
-
36
- // Tell Ruby to invoke the static method write to get the attribute value
37
- detail::protect(rb_define_method, klass, setter.c_str(), (RUBY_METHOD_FUNC)&NativeAttribute_T::set, 1);
38
-
39
- // Add to native registry
40
- detail::Registries::instance.natives.add(klass, Identifier(setter).id(), native);
41
- }
42
- }
43
-
44
- template<typename Attribute_T>
45
- inline VALUE NativeAttribute<Attribute_T>::get(VALUE self)
46
- {
47
- return cpp_protect([&]
48
- {
49
- using Native_Attr_T = NativeAttribute<Attribute_T>;
50
- Native_Attr_T* attr = detail::Registries::instance.natives.lookup<Native_Attr_T*>();
51
- return attr->read(self);
52
- });
53
- }
54
-
55
- template<typename Attribute_T>
56
- inline VALUE NativeAttribute<Attribute_T>::set(VALUE self, VALUE value)
57
- {
58
- return cpp_protect([&]
59
- {
60
- using Native_Attr_T = NativeAttribute<Attribute_T>;
61
- Native_Attr_T* attr = detail::Registries::instance.natives.lookup<Native_Attr_T*>();
62
- return attr->write(self, value);
63
- });
64
- }
65
-
66
- template<typename Attribute_T>
67
- NativeAttribute<Attribute_T>::NativeAttribute(VALUE klass, std::string name,
68
- Attribute_T attribute, AttrAccess access)
69
- : klass_(klass), name_(name), attribute_(attribute), access_(access)
70
- {
71
- }
72
-
73
- template<typename Attribute_T>
74
- inline VALUE NativeAttribute<Attribute_T>::read(VALUE self)
75
- {
76
- using T_Unqualified = remove_cv_recursive_t<T>;
77
- if constexpr (std::is_member_object_pointer_v<Attribute_T>)
78
- {
79
- Receiver_T* nativeSelf = From_Ruby<Receiver_T*>().convert(self);
80
- return To_Ruby<T_Unqualified>().convert(nativeSelf->*attribute_);
81
- }
82
- else
83
- {
84
- return To_Ruby<T_Unqualified>().convert(*attribute_);
85
- }
86
- }
87
-
88
- template<typename Attribute_T>
89
- inline VALUE NativeAttribute<Attribute_T>::write(VALUE self, VALUE value)
90
- {
91
- if constexpr (std::is_fundamental_v<intrinsic_type<T>> && std::is_pointer_v<T>)
92
- {
93
- static_assert(true, "An fundamental value, such as an integer, cannot be assigned to an attribute that is a pointer");
94
- }
95
- else if constexpr (std::is_same_v<intrinsic_type<T>, std::string> && std::is_pointer_v<T>)
96
- {
97
- static_assert(true, "An string cannot be assigned to an attribute that is a pointer");
98
- }
99
-
100
- if constexpr (!std::is_null_pointer_v<Receiver_T>)
101
- {
102
- Receiver_T* nativeSelf = From_Ruby<Receiver_T*>().convert(self);
103
- nativeSelf->*attribute_ = From_Ruby<T_Unqualified>().convert(value);
104
- }
105
- else if constexpr (!std::is_const_v<std::remove_pointer_t<T>>)
106
- {
107
- *attribute_ = From_Ruby<T_Unqualified>().convert(value);
108
- }
109
-
110
- return value;
111
- }
112
- } // Rice