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
data/rice/Data_Type.hpp CHANGED
@@ -1,7 +1,218 @@
1
1
  #ifndef Rice__Data_Type__hpp_
2
2
  #define Rice__Data_Type__hpp_
3
3
 
4
- #include "Data_Type_defn.hpp"
5
- #include "Data_Type.ipp"
4
+ #include <set>
6
5
 
7
- #endif // Rice__Data_Type__hpp_
6
+ namespace Rice
7
+ {
8
+ //! A mechanism for binding ruby types to C++ types.
9
+ /*! This class binds run-time types (Ruby VALUEs) to compile-time types
10
+ * (C++ types). The binding can occur only once.
11
+ */
12
+ template<typename T>
13
+ class Data_Type : public Class
14
+ {
15
+ static_assert(std::is_same_v<detail::intrinsic_type<T>, T>);
16
+
17
+ public:
18
+ using type = T;
19
+
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
+ //! Return the Ruby class.
34
+ /*! \return the ruby class to which the type is bound.
35
+ */
36
+ static Class klass();
37
+
38
+ //! Return the Ruby data type.
39
+ static rb_data_type_t* ruby_data_type();
40
+
41
+ //! Assignment operator which takes a Module
42
+ /*! \param klass must be the class to which this data type is already
43
+ * bound.
44
+ * \return *this
45
+ */
46
+ Data_Type& operator=(Module const & klass);
47
+
48
+ /*! Creates a singleton method allocate and an instance method called
49
+ * initialize which together create a new instance of the class. The
50
+ * allocate method allocates memory for the object reference and the
51
+ * initialize method constructs the object.
52
+ * \param constructor an object that has a static member function
53
+ * construct() that constructs a new instance of T and sets the object's data
54
+ * member to point to the new instance. A helper class Constructor
55
+ * is provided that does precisely this.
56
+ * \param args a list of Arg instance used to define default parameters (optional)
57
+ *
58
+ * For example:
59
+ * \code
60
+ * define_class<Foo>("Foo")
61
+ * .define_constructor(Constructor<Foo>());
62
+ * \endcode
63
+ */
64
+ template<typename Constructor_T, typename...Rice_Arg_Ts>
65
+ Data_Type<T>& define_constructor(Constructor_T constructor, Rice_Arg_Ts const& ...args);
66
+
67
+ /*! Runs a function that should define this Data_Types methods and attributes.
68
+ * This is useful when creating classes from a C++ class template.
69
+ *
70
+ * \param builder A function that addes methods/attributes to this class
71
+ *
72
+ * For example:
73
+ * \code
74
+ * void builder(Data_Type<Matrix<T, R, C>>& klass)
75
+ * {
76
+ * klass.define_method...
77
+ * return klass;
78
+ * }
79
+ *
80
+ * define_class<<Matrix<T, R, C>>>("Matrix")
81
+ * .build(&builder);
82
+ *
83
+ * \endcode
84
+ */
85
+ template<typename Func_T>
86
+ Data_Type<T>& define(Func_T func);
87
+
88
+ //! Register a Director class for this class.
89
+ /*! For any class that uses Rice::Director to enable polymorphism
90
+ * across the languages, you need to register that director proxy
91
+ * class with this method. Not doing so will cause the resulting
92
+ * library to die at run time when it tries to convert the base
93
+ * type into the Director proxy type.
94
+ *
95
+ * This method takes no methodInfo, just needs the type of the
96
+ * Director proxy class.
97
+ *
98
+ * For example:
99
+ * \code
100
+ * class FooDirector : public Foo, public Rice::Director {
101
+ * ...
102
+ * };
103
+ *
104
+ * define_class<Foo>("Foo")
105
+ * .define_director<FooDirector>()
106
+ * .define_constructor(Constructor<FooDirector, Rice::Object>());
107
+ * \endcode
108
+ */
109
+ template<typename Director_T>
110
+ Data_Type<T>& define_director();
111
+
112
+ //! Determine if the type is bound.
113
+ /*! \return true if the object is bound, false otherwise.
114
+ */
115
+ static bool is_bound();
116
+ static void check_is_bound();
117
+ static bool is_defined();
118
+ static bool check_defined(const std::string& name, Object parent = rb_cObject);
119
+
120
+ // This is only for testing - DO NOT USE!!!
121
+ static void unbind();
122
+
123
+ static bool is_descendant(VALUE value);
124
+
125
+ //! Define an iterator.
126
+ /*! Essentially this is a conversion from a C++-style begin/end
127
+ * iterator to a Ruby-style \#each iterator.
128
+ * \param begin a member function pointer to a function that returns
129
+ * an iterator to the beginning of the sequence.
130
+ * \param end a member function pointer to a function that returns an
131
+ * iterator to the end of the sequence.
132
+ * \param name the name of the iterator.
133
+ * \return *this
134
+ */
135
+
136
+ template<typename Iterator_Func_T>
137
+ Data_Type<T>& define_iterator(Iterator_Func_T begin, Iterator_Func_T end, std::string name = "each");
138
+
139
+ template <typename Attribute_T>
140
+ Data_Type<T>& define_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite);
141
+
142
+ template <typename Attribute_T>
143
+ Data_Type<T>& define_singleton_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite);
144
+
145
+ #include "cpp_api/shared_methods.hpp"
146
+ protected:
147
+ //! Bind a Data_Type to a VALUE.
148
+ /*! Throws an exception if the Data_Type is already bound to a
149
+ * different class. Any existing instances of the Data_Type will be
150
+ * bound after this function returns.
151
+ * \param klass the ruby type to which to bind.
152
+ * \return *this
153
+ */
154
+ template <typename Base_T = void>
155
+ static Data_Type<T> bind(const Module& klass);
156
+
157
+ template<typename T_, typename Base_T>
158
+ friend Rice::Data_Type<T_> define_class_under(Object parent, Identifier id, Class superKlass);
159
+
160
+ template<typename T_, typename Base_T>
161
+ friend Rice::Data_Type<T_> define_class_under(Object parent, char const * name);
162
+
163
+ template<typename T_, typename Base_T>
164
+ friend Rice::Data_Type<T_> define_class(char const * name);
165
+
166
+ template<bool IsMethod, typename Function_T>
167
+ void wrap_native_call(VALUE klass, std::string name, Function_T&& function, MethodInfo* methodInfo);
168
+
169
+ private:
170
+ template<typename T_>
171
+ friend class Data_Type;
172
+
173
+ static inline VALUE klass_ = Qnil;
174
+
175
+ // Typed Data support
176
+ static inline rb_data_type_t* rb_data_type_ = nullptr;
177
+
178
+ static inline std::set<Data_Type<T>*>& unbound_instances();
179
+ };
180
+
181
+ //! Define a new data class in the namespace given by module.
182
+ /*! This override allows you to specify a Ruby class as the base class versus a
183
+ * wrapped C++ class. This functionality is rarely needed - but is essential for
184
+ * creating new custom Exception classes where the Ruby superclass should be
185
+ * rb_eStandard
186
+ * \param T the C++ type of the wrapped class.
187
+ * \param module the Module in which to define the class.
188
+ * \param name the name of the new class.
189
+ * \param superKlass the Ruby super class.
190
+ * \return the new class.
191
+ */
192
+ template<typename T, typename Base_T = void>
193
+ Data_Type<T> define_class_under(Object parent, Identifier id, Class superKlass = rb_cObject);
194
+
195
+ //! Define a new data class in the namespace given by module.
196
+ /*! By default the class will inherit from Ruby's rb_cObject. This
197
+ * can be overriden via the Base_T template parameter. Note that
198
+ * Base_T must already have been registered.
199
+ * \param T the C++ type of the wrapped class.
200
+ * \param module the the Module in which to define the class.
201
+ * \return the new class.
202
+ */
203
+ template<typename T, typename Base_T = void>
204
+ Data_Type<T> define_class_under(Object parent, char const* name);
205
+
206
+ //! Define a new data class in the default namespace.
207
+ /*! By default the class will inherit from Ruby's rb_cObject. This
208
+ * can be overriden via the Base_T template parameter. Note that
209
+ * Base_T must already have been registered.
210
+ * \param T the C++ type of the wrapped class.
211
+ * \param module the the Module in which to define the class.
212
+ * \return the new class.
213
+ */
214
+ template<typename T, typename Base_T = void>
215
+ Data_Type<T> define_class(char const* name);
216
+ }
217
+
218
+ #endif // Rice__Data_Type__hpp_
data/rice/Data_Type.ipp CHANGED
@@ -1,24 +1,9 @@
1
- #ifndef Rice__Data_Type__ipp_
2
- #define Rice__Data_Type__ipp_
3
-
4
- #include "traits/attribute_traits.hpp"
5
- #include "traits/method_traits.hpp"
6
- #include "detail/NativeRegistry.hpp"
7
- #include "detail/NativeAttribute.hpp"
8
- #include "detail/default_allocation_func.hpp"
9
- #include "detail/TypeRegistry.hpp"
10
- #include "detail/Wrapper.hpp"
11
- #include "detail/NativeIterator.hpp"
12
- #include "cpp_api/Class.hpp"
13
- #include "cpp_api/String.hpp"
14
- #include "ruby_mark.hpp"
15
-
16
1
  #include <stdexcept>
17
2
 
18
3
  namespace Rice
19
4
  {
20
5
  template<typename T>
21
- void ruby_mark_internal(detail::Wrapper* wrapper)
6
+ inline void ruby_mark_internal(detail::WrapperBase* wrapper)
22
7
  {
23
8
  // Tell the wrapper to mark the objects its keeping alive
24
9
  wrapper->ruby_mark();
@@ -29,17 +14,23 @@ namespace Rice
29
14
  }
30
15
 
31
16
  template<typename T>
32
- void ruby_free_internal(detail::Wrapper* wrapper)
17
+ inline void ruby_free_internal(detail::WrapperBase* wrapper)
33
18
  {
34
19
  delete wrapper;
35
20
  }
36
21
 
37
22
  template<typename T>
38
- size_t ruby_size_internal(const T* data)
23
+ inline size_t ruby_size_internal(const T* data)
39
24
  {
40
25
  return sizeof(T);
41
26
  }
42
27
 
28
+ template<>
29
+ inline size_t ruby_size_internal(const void* data)
30
+ {
31
+ return sizeof(void*);
32
+ }
33
+
43
34
  template<typename T>
44
35
  template <typename Base_T>
45
36
  inline Data_Type<T> Data_Type<T>::bind(const Module& klass)
@@ -68,13 +59,12 @@ namespace Rice
68
59
  // Now register with the type registry
69
60
  detail::Registries::instance.types.add<T>(klass_, rb_data_type_);
70
61
 
71
- for (typename Instances::iterator it = unbound_instances().begin(),
72
- end = unbound_instances().end();
73
- it != end;
74
- unbound_instances().erase(it++))
75
- {
76
- (*it)->set_value(klass);
62
+ auto instances = unbound_instances();
63
+ for (auto instance: instances)
64
+ {
65
+ instance->set_value(klass);
77
66
  }
67
+ instances.clear();
78
68
 
79
69
  return Data_Type<T>();
80
70
  }
@@ -94,10 +84,24 @@ namespace Rice
94
84
  rb_data_type_ = nullptr;
95
85
  }
96
86
 
87
+ // Track unbound instances (ie, declared variables of type Data_Type<T>
88
+ // before define_class is called). We can't simply use a static inline
89
+ // member because it sometimes crashes clang and gcc (msvc seems fine)
97
90
  template<typename T>
98
- inline Data_Type<T>::Data_Type() : Class(klass_ == Qnil ? rb_cObject : klass_)
91
+ inline std::set<Data_Type<T>*>& Data_Type<T>::unbound_instances()
99
92
  {
100
- if (!is_bound())
93
+ static std::set<Data_Type<T>*> unbound_instances;
94
+ return unbound_instances;
95
+ }
96
+
97
+ template<typename T>
98
+ inline Data_Type<T>::Data_Type()
99
+ {
100
+ if (is_bound())
101
+ {
102
+ this->set_value(klass_);
103
+ }
104
+ else
101
105
  {
102
106
  unbound_instances().insert(this);
103
107
  }
@@ -109,12 +113,6 @@ namespace Rice
109
113
  this->bind(klass);
110
114
  }
111
115
 
112
- template<typename T>
113
- inline Data_Type<T>::~Data_Type()
114
- {
115
- unbound_instances().erase(this);
116
- }
117
-
118
116
  template<typename T>
119
117
  inline rb_data_type_t* Data_Type<T>::ruby_data_type()
120
118
  {
@@ -137,17 +135,50 @@ namespace Rice
137
135
  }
138
136
 
139
137
  template<typename T>
140
- template<typename Constructor_T, typename...Arg_Ts>
141
- inline Data_Type<T>& Data_Type<T>::define_constructor(Constructor_T constructor, Arg_Ts const& ...args)
138
+ template<typename Constructor_T, typename...Rice_Arg_Ts>
139
+ inline Data_Type<T>& Data_Type<T>::define_constructor(Constructor_T constructor, Rice_Arg_Ts const& ...args)
142
140
  {
143
141
  check_is_bound();
144
142
 
145
143
  // Define a Ruby allocator which creates the Ruby object
146
144
  detail::protect(rb_define_alloc_func, static_cast<VALUE>(*this), detail::default_allocation_func<T>);
147
145
 
148
- // Define an initialize function that will create the C++ object
149
- this->define_method("initialize", &Constructor_T::construct, args...);
146
+ // We can't do anything with move constructors so blow up
147
+ static_assert(!Constructor_T::isMoveConstructor(), "Rice does not support move constructors");
148
+
149
+ // If this is a copy constructor then use it to support Ruby's Object#dup and Object#clone methods.
150
+ // Otherwise if a user calls #dup or #clone an error will occur because the newly cloned Ruby
151
+ // object will have a NULL ptr because the C++ object is never copied. This also prevents having
152
+ // very unlike Ruby code of:
153
+ //
154
+ // my_object_copy = MyObject.new(my_ojbect_original).
150
155
 
156
+ if constexpr (Constructor_T::isCopyConstructor())
157
+ {
158
+ // Define initialize_copy that will copy the C++ object
159
+ this->define_method("initialize_copy", &Constructor_T::initialize_copy, args...);
160
+ }
161
+ else if constexpr (Constructor_T::isMoveConstructor())
162
+ {
163
+ throw std::runtime_error("Rice does not support move constructors");
164
+ }
165
+ else
166
+ {
167
+ // Define an initialize function that will create the C++ object
168
+ this->define_method("initialize", &Constructor_T::initialize, args...);
169
+ }
170
+
171
+ return *this;
172
+ }
173
+
174
+ template<typename T>
175
+ template<typename Function_T>
176
+ inline Data_Type<T>& Data_Type<T>::define(Function_T func)
177
+ {
178
+ // The passed in this pointer is an RValue, so we need to keep it alive by
179
+ // assigning it to a const lvalue
180
+ const auto& dummy = *this;
181
+ func(*this);
151
182
  return *this;
152
183
  }
153
184
 
@@ -155,7 +186,7 @@ namespace Rice
155
186
  template<typename Director_T>
156
187
  inline Data_Type<T>& Data_Type<T>::define_director()
157
188
  {
158
- if (!detail::Registries::instance.types.isDefined<Director_T>())
189
+ if (!Data_Type<Director_T>::is_defined())
159
190
  {
160
191
  Data_Type<Director_T>::bind(*this);
161
192
  }
@@ -184,56 +215,86 @@ namespace Rice
184
215
  {
185
216
  if (!is_bound())
186
217
  {
187
- std::string message = "Type " + detail::typeName(typeid(T)) + " is not bound";
188
- throw std::runtime_error(message.c_str());
218
+ std::string message = "Type is not defined with Rice: " + detail::typeName(typeid(T));
219
+ throw std::invalid_argument(message.c_str());
189
220
  }
190
221
  }
191
222
 
192
- template<typename T, typename Base_T>
193
- inline Data_Type<T> define_class_under(Object module, char const* name)
223
+ template<typename T>
224
+ inline bool Data_Type<T>::is_defined()
225
+ {
226
+ return detail::Registries::instance.types.isDefined<T>();
227
+ }
228
+
229
+ template<typename T>
230
+ inline bool Data_Type<T>::check_defined(const std::string& name, Object parent)
194
231
  {
195
- if (detail::Registries::instance.types.isDefined<T>())
232
+ if (Data_Type<T>::is_defined())
196
233
  {
197
- return Data_Type<T>();
234
+ Data_Type<T> dataType;
235
+ parent.const_set_maybe(name, dataType.klass());
236
+ return true;
237
+ }
238
+ else
239
+ {
240
+ return false;
198
241
  }
199
-
200
- Class superKlass;
242
+ }
243
+
244
+ template<typename Base_T>
245
+ inline Class get_superklass()
246
+ {
247
+ Class result;
201
248
 
202
249
  if constexpr (std::is_void_v<Base_T>)
203
250
  {
204
- superKlass = rb_cObject;
251
+ result = rb_cObject;
205
252
  }
206
253
  else
207
254
  {
208
- superKlass = Data_Type<Base_T>::klass();
255
+ // This gives a chance for to auto-register classes such as std::exception
256
+ detail::verifyType<Base_T>();
257
+ result = Data_Type<Base_T>::klass();
209
258
  }
210
-
211
- Class c = define_class_under(module, name, superKlass);
212
- c.undef_creation_funcs();
213
- return Data_Type<T>::template bind<Base_T>(c);
259
+
260
+ return result;
214
261
  }
215
262
 
216
263
  template<typename T, typename Base_T>
217
- inline Data_Type<T> define_class(char const* name)
264
+ inline Data_Type<T> define_class_under(Object parent, Identifier id, Class superKlass)
218
265
  {
219
- if (detail::Registries::instance.types.isDefined<T>())
266
+ if (Rice::Data_Type<T>::check_defined(id.str(), parent))
220
267
  {
221
268
  return Data_Type<T>();
222
269
  }
223
270
 
224
- Class superKlass;
225
- if constexpr (std::is_void_v<Base_T>)
226
- {
227
- superKlass = rb_cObject;
228
- }
229
- else
271
+ Class klass = define_class_under(parent, id, superKlass);
272
+ klass.undef_creation_funcs();
273
+ return Data_Type<T>::template bind<Base_T>(klass);
274
+ }
275
+
276
+ template<typename T, typename Base_T>
277
+ inline Data_Type<T> define_class_under(Object parent, char const* name)
278
+ {
279
+ Identifier id(name);
280
+ Class superKlass = get_superklass<Base_T>();
281
+ return define_class_under<T, Base_T>(parent, id, superKlass);
282
+ }
283
+
284
+ template<typename T, typename Base_T>
285
+ inline Data_Type<T> define_class(char const* name)
286
+ {
287
+ std::string klassName(name);
288
+
289
+ if (Rice::Data_Type<T>::check_defined(klassName))
230
290
  {
231
- superKlass = Data_Type<Base_T>::klass();
291
+ return Data_Type<T>();
232
292
  }
233
293
 
234
- Class c = define_class(name, superKlass);
235
- c.undef_creation_funcs();
236
- return Data_Type<T>::template bind<Base_T>(c);
294
+ Class superKlass = get_superklass<Base_T>();
295
+ Class klass = define_class(name, superKlass);
296
+ klass.undef_creation_funcs();
297
+ return Data_Type<T>::template bind<Base_T>(klass);
237
298
  }
238
299
 
239
300
  template<typename T>
@@ -256,8 +317,18 @@ namespace Rice
256
317
  // Make sure the Attribute type has been previously seen by Rice
257
318
  detail::verifyType<typename detail::attribute_traits<Attribute_T>::attr_type>();
258
319
 
259
- // Define native attribute
260
- detail::NativeAttribute<Attribute_T>::define(klass_, name, std::forward<Attribute_T>(attribute), access);
320
+ // Define native attribute getter
321
+ if (access == AttrAccess::ReadWrite || access == AttrAccess::Read)
322
+ detail::NativeAttributeGet<Attribute_T>::define(klass_, name, std::forward<Attribute_T>(attribute));
323
+
324
+ using Attr_T = typename detail::NativeAttributeSet<Attribute_T>::Attr_T;
325
+ if constexpr (!std::is_const_v<Attr_T> &&
326
+ (std::is_fundamental_v<Attr_T> || std::is_assignable_v<Attr_T, Attr_T>))
327
+ {
328
+ // Define native attribute setter
329
+ if (access == AttrAccess::ReadWrite || access == AttrAccess::Write)
330
+ detail::NativeAttributeSet<Attribute_T>::define(klass_, name, std::forward<Attribute_T>(attribute));
331
+ }
261
332
 
262
333
  return *this;
263
334
  }
@@ -271,7 +342,14 @@ namespace Rice
271
342
 
272
343
  // Define native attribute
273
344
  VALUE singleton = detail::protect(rb_singleton_class, this->value());
274
- detail::NativeAttribute<Attribute_T>::define(singleton, name, std::forward<Attribute_T>(attribute), access);
345
+
346
+ // Define native attribute getter
347
+ if (access == AttrAccess::ReadWrite || access == AttrAccess::Read)
348
+ detail::NativeAttributeGet<Attribute_T>::define(singleton, name, std::forward<Attribute_T>(attribute));
349
+
350
+ // Define native attribute setter
351
+ if (access == AttrAccess::ReadWrite || access == AttrAccess::Write)
352
+ detail::NativeAttributeSet<Attribute_T>::define(singleton, name, std::forward<Attribute_T>(attribute));
275
353
 
276
354
  return *this;
277
355
  }
@@ -289,4 +367,3 @@ namespace Rice
289
367
  detail::NativeFunction<T, Function_T, IsMethod>::define(klass, name, std::forward<Function_T>(function), methodInfo);
290
368
  }
291
369
  }
292
- #endif
data/rice/Director.hpp CHANGED
@@ -1,8 +1,6 @@
1
1
  #ifndef Rice__Director__hpp_
2
2
  #define Rice__Director__hpp_
3
3
 
4
- #include "cpp_api/Object.hpp"
5
-
6
4
  namespace Rice
7
5
  {
8
6
  /**
data/rice/Enum.hpp CHANGED
@@ -1,9 +1,6 @@
1
1
  #ifndef Rice__Enum__hpp_
2
2
  #define Rice__Enum__hpp_
3
3
 
4
- #include "Data_Type.hpp"
5
- #include <map>
6
-
7
4
  namespace Rice
8
5
  {
9
6
  /*!
@@ -33,7 +30,6 @@ namespace Rice
33
30
  using Underlying_T = std::underlying_type_t<Enum_T>;
34
31
 
35
32
  public:
36
-
37
33
  Enum() = default;
38
34
 
39
35
  //! Construct and initialize.
@@ -59,9 +55,10 @@ namespace Rice
59
55
  };
60
56
 
61
57
  template<typename T>
62
- Enum<T> define_enum(char const* name, Module module = rb_cObject);
63
- } // namespace Rice
58
+ Enum<T> define_enum(char const* name);
64
59
 
65
- #include "Enum.ipp"
60
+ template<typename T>
61
+ Enum<T> define_enum_under(char const* name, Module module );
62
+ } // namespace Rice
66
63
 
67
64
  #endif // Rice__Enum__hpp_