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/Buffer.ipp ADDED
@@ -0,0 +1,599 @@
1
+ namespace Rice
2
+ {
3
+ // ---- Buffer<T> -------
4
+ template<typename T>
5
+ inline Buffer<T>::Buffer(T* pointer) : m_buffer(pointer)
6
+ {
7
+ }
8
+
9
+ template<typename T>
10
+ inline Buffer<T>::Buffer(T* pointer, size_t size) : m_size(size), m_buffer(pointer)
11
+ {
12
+ }
13
+
14
+ template <typename T>
15
+ inline Buffer<T>::Buffer(VALUE value)
16
+ {
17
+ if constexpr (std::is_fundamental_v<T>)
18
+ {
19
+ this->fromRubyType(value);
20
+ }
21
+ else
22
+ {
23
+ this->fromDataType(value);
24
+ }
25
+ }
26
+
27
+ template <typename T>
28
+ inline void Buffer<T>::fromRubyType(VALUE value)
29
+ {
30
+ using Intrinsic_T = typename detail::intrinsic_type<T>;
31
+ using RubyType_T = typename detail::RubyType<Intrinsic_T>;
32
+ ruby_value_type valueType = rb_type(value);
33
+
34
+ switch (valueType)
35
+ {
36
+ case RUBY_T_ARRAY:
37
+ {
38
+ Array array(value);
39
+ this->m_size = array.size();
40
+ this->m_buffer = new T[this->m_size]();
41
+
42
+ String packed = array.pack<Intrinsic_T>();
43
+ memcpy(this->m_buffer, RSTRING_PTR(packed.value()), RSTRING_LEN(packed.value()));
44
+
45
+ this->m_owner = true;
46
+ break;
47
+ }
48
+ case RUBY_T_STRING:
49
+ {
50
+ this->m_size = RSTRING_LEN(value);
51
+ if constexpr (std::is_same_v<T, char>)
52
+ {
53
+ // Add 2 for null characters (string and wstring)
54
+ this->m_buffer = new T[this->m_size + 2]();
55
+ }
56
+ else
57
+ {
58
+ this->m_buffer = new T[this->m_size]();
59
+ }
60
+ memcpy(this->m_buffer, RSTRING_PTR(value), this->m_size);
61
+
62
+ this->m_owner = true;
63
+ break;
64
+ }
65
+ case RUBY_T_DATA:
66
+ {
67
+ if (Data_Type<T>::is_descendant(value))
68
+ {
69
+ this->m_size = 1;
70
+ this->m_buffer = new T[this->m_size]();
71
+ this->m_buffer[0] = *detail::unwrap<T>(value, Data_Type<T>::ruby_data_type(), false);
72
+ this->m_owner = false;
73
+ break;
74
+ }
75
+ }
76
+ default:
77
+ {
78
+ if (RubyType_T::Exact.find(valueType) != RubyType_T::Exact.end() ||
79
+ RubyType_T::Castable.find(valueType) != RubyType_T::Castable.end() ||
80
+ RubyType_T::Narrowable.find(valueType) != RubyType_T::Narrowable.end())
81
+ {
82
+ T data = detail::protect(RubyType_T::fromRuby, value);
83
+ this->m_size = 1;
84
+ this->m_buffer = new T[this->m_size]();
85
+ memcpy(this->m_buffer, &data, sizeof(T));
86
+ this->m_owner = true;
87
+ break;
88
+ }
89
+ else
90
+ {
91
+ std::string typeName = detail::typeName(typeid(T));
92
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
93
+ detail::protect(rb_obj_classname, value), typeName.c_str());
94
+ }
95
+ }
96
+ }
97
+ }
98
+
99
+ template <typename T>
100
+ inline void Buffer<T>::fromDataType(VALUE value)
101
+ {
102
+ using Intrinsic_T = typename detail::intrinsic_type<T>;
103
+
104
+ switch (rb_type(value))
105
+ {
106
+ case RUBY_T_ARRAY:
107
+ {
108
+ Array array(value);
109
+ this->m_size = array.size();
110
+
111
+ // Use operator new[] to allocate memory but not call constructors
112
+ this->m_buffer = static_cast<T*>(operator new[](sizeof(T)* this->m_size));
113
+
114
+ detail::From_Ruby<Intrinsic_T> fromRuby;
115
+
116
+ for (size_t i = 0; i < this->m_size; i++)
117
+ {
118
+ this->m_buffer[i] = fromRuby.convert(array[i].value());
119
+ }
120
+ break;
121
+ }
122
+ default:
123
+ {
124
+ std::string typeName = detail::typeName(typeid(T));
125
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
126
+ detail::protect(rb_obj_classname, value), typeName.c_str());
127
+ }
128
+ }
129
+ }
130
+
131
+ template <typename T>
132
+ inline Buffer<T>::~Buffer()
133
+ {
134
+ if constexpr (std::is_destructible_v<T>)
135
+ {
136
+ if (this->m_owner)
137
+ {
138
+ delete[] this->m_buffer;
139
+ }
140
+ }
141
+ }
142
+
143
+ template <typename T>
144
+ inline Buffer<T>::Buffer(Buffer<T>&& other) : m_owner(other.m_owner), m_size(other.m_size), m_buffer(other.m_buffer)
145
+ {
146
+ other.m_buffer = nullptr;
147
+ other.m_size = 0;
148
+ other.m_owner = false;
149
+ }
150
+
151
+ template <typename T>
152
+ inline Buffer<T>& Buffer<T>::operator=(Buffer<T>&& other)
153
+ {
154
+ this->m_buffer = other.m_buffer;
155
+ other.m_buffer = nullptr;
156
+
157
+ this->m_size = other.m_size;
158
+ other.m_size = 0;
159
+
160
+ this->m_owner = other.m_owner;
161
+ other.m_owner = false;
162
+
163
+ return *this;
164
+ }
165
+
166
+ template <typename T>
167
+ inline size_t Buffer<T>::size() const
168
+ {
169
+ return this->m_size;
170
+ }
171
+
172
+ template <typename T>
173
+ void Buffer<T>::setSize(size_t value)
174
+ {
175
+ this->m_size = value;
176
+ }
177
+
178
+ template <typename T>
179
+ inline T* Buffer<T>::ptr()
180
+ {
181
+ return this->m_buffer;
182
+ }
183
+
184
+ template <typename T>
185
+ inline T& Buffer<T>::reference()
186
+ {
187
+ return *this->m_buffer;
188
+ }
189
+
190
+ template <typename T>
191
+ inline bool Buffer<T>::isOwner() const
192
+ {
193
+ return this->m_owner;
194
+ }
195
+
196
+ template <typename T>
197
+ inline void Buffer<T>::setOwner(bool value)
198
+ {
199
+ this->m_owner = value;
200
+ }
201
+
202
+ template <typename T>
203
+ inline void Buffer<T>::release()
204
+ {
205
+ this->m_owner = false;
206
+ }
207
+
208
+ /* template<typename T>
209
+ inline VALUE Buffer<T>::toString() const
210
+ {
211
+ std::string name = detail::typeName(typeid(T));
212
+ std::string result = "Buffer<type: " + detail::cppClassName(name) + ", size: " + std::to_string(this->m_size) + ">";
213
+ return detail::To_Ruby<std::string>().convert(result);
214
+ }*/
215
+
216
+ template<typename T>
217
+ inline VALUE Buffer<T>::bytes(size_t count) const
218
+ {
219
+ if (!this->m_buffer)
220
+ {
221
+ return Qnil;
222
+ }
223
+ else
224
+ {
225
+ long length = (long)(count * sizeof(T));
226
+ return detail::protect(rb_str_new_static, (const char*)this->m_buffer, length);
227
+ }
228
+ }
229
+
230
+ template<typename T>
231
+ inline VALUE Buffer<T>::bytes() const
232
+ {
233
+ return this->bytes(this->m_size);
234
+ }
235
+
236
+ template<typename T>
237
+ inline Array Buffer<T>::toArray(size_t count) const
238
+ {
239
+ if (!this->m_buffer)
240
+ {
241
+ return Qnil;
242
+ }
243
+ else if constexpr (std::is_fundamental_v<T>)
244
+ {
245
+ VALUE string = this->bytes(count);
246
+ return String(string).unpack<T>();
247
+ }
248
+ else
249
+ {
250
+ Array result;
251
+
252
+ T* ptr = this->m_buffer;
253
+ T* end = this->m_buffer + count;
254
+
255
+ for (; ptr < end; ptr++)
256
+ {
257
+ result.push(*ptr);
258
+ }
259
+ return result;
260
+ }
261
+ }
262
+
263
+ template<typename T>
264
+ inline Array Buffer<T>::toArray() const
265
+ {
266
+ return this->toArray(this->m_size);
267
+ }
268
+
269
+ template<typename T>
270
+ inline T Buffer<T>::get(size_t index) const
271
+ {
272
+ if (index >= this->m_size)
273
+ {
274
+ throw Exception(rb_eIndexError, "index %ld outside of bounds: 0..%ld", index, this->m_size);
275
+ }
276
+
277
+ return this->m_buffer[index];
278
+ }
279
+
280
+ template<typename T>
281
+ inline void Buffer<T>::set(size_t index, T element)
282
+ {
283
+ if (index >= this->m_size)
284
+ {
285
+ throw Exception(rb_eIndexError, "index %ld outside of bounds: 0..%ld", index, this->m_size);
286
+ }
287
+
288
+ this->m_buffer[index] = element;
289
+ }
290
+
291
+ // ---- Buffer<T*> -------
292
+ template<typename T>
293
+ inline Buffer<T*>::Buffer(T** pointer) : m_outer(pointer)
294
+ {
295
+ }
296
+
297
+ template<typename T>
298
+ inline Buffer<T*>::Buffer(T** pointer, size_t size) : m_outer(pointer), m_size(size)
299
+ {
300
+ }
301
+
302
+ template <typename T>
303
+ inline Buffer<T*>::Buffer(VALUE value)
304
+ {
305
+ ruby_value_type valueType = rb_type(value);
306
+
307
+ switch (valueType)
308
+ {
309
+ case RUBY_T_ARRAY:
310
+ {
311
+ Array outer(value);
312
+ this->m_size = outer.size();
313
+ this->m_outer = new T * [this->m_size]();
314
+
315
+ for (size_t i = 0; i < this->m_size; i++)
316
+ {
317
+ // Check the inner value is also an array
318
+ Array inner(outer[i].value());
319
+
320
+ // Wrap it with a buffer and add it our list of inner buffers
321
+ Buffer<T> buffer(inner.value());
322
+
323
+ // And update the outer array
324
+ this->m_outer[i] = buffer.ptr();
325
+
326
+ // Now move the buffer into the affer, not the buffer pointer is still valid (it just got moved)
327
+ this->m_inner.push_back(std::move(buffer));
328
+ }
329
+
330
+ this->m_owner = true;
331
+ break;
332
+ }
333
+ default:
334
+ {
335
+ std::string typeName = detail::typeName(typeid(T));
336
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
337
+ detail::protect(rb_obj_classname, value), typeName.c_str());
338
+ }
339
+ }
340
+ }
341
+
342
+ template <typename T>
343
+ inline Buffer<T*>::~Buffer()
344
+ {
345
+ if (this->m_owner)
346
+ {
347
+ delete[] this->m_outer;
348
+ }
349
+ }
350
+
351
+ template <typename T>
352
+ inline Buffer<T*>::Buffer(Buffer<T*>&& other) : m_owner(other.m_owner), m_size(other.m_size),
353
+ m_outer(other.m_outer), m_inner(std::move(other.m_inner))
354
+ {
355
+ other.m_outer = nullptr;
356
+ other.m_inner.clear();
357
+ other.m_size = 0;
358
+ other.m_owner = false;
359
+ }
360
+
361
+ template <typename T>
362
+ inline Buffer<T*>& Buffer<T*>::operator=(Buffer<T*>&& other)
363
+ {
364
+ this->m_outer = other.m_outer;
365
+ other.m_outer = nullptr;
366
+
367
+ this->m_inner = std::move(other.m_inner);
368
+ other.m_inner.clear();
369
+
370
+ this->m_size = other.m_size;
371
+ other.m_size = 0;
372
+
373
+ this->m_owner = other.m_owner;
374
+ other.m_owner = false;
375
+
376
+ return *this;
377
+ }
378
+
379
+ template <typename T>
380
+ inline const Buffer<T>& Buffer<T*>::operator[](size_t index)
381
+ {
382
+ return this->m_inner[index];
383
+ }
384
+
385
+ template <typename T>
386
+ inline size_t Buffer<T*>::size() const
387
+ {
388
+ return this->m_size;
389
+ }
390
+
391
+ template <typename T>
392
+ void Buffer<T*>::setSize(size_t value)
393
+ {
394
+ this->m_size = value;
395
+ }
396
+
397
+ template <typename T>
398
+ inline T** Buffer<T*>::ptr()
399
+ {
400
+ return this->m_outer;
401
+ }
402
+
403
+ template <typename T>
404
+ inline bool Buffer<T*>::isOwner() const
405
+ {
406
+ return this->m_owner;
407
+ }
408
+
409
+ template <typename T>
410
+ inline void Buffer<T*>::setOwner(bool value)
411
+ {
412
+ this->m_owner = value;
413
+ }
414
+
415
+ template <typename T>
416
+ inline void Buffer<T*>::release()
417
+ {
418
+ this->m_owner = false;
419
+ }
420
+
421
+ /*template<typename T>
422
+ inline VALUE Buffer<T*>::toString() const
423
+ {
424
+ std::string name = detail::typeName(typeid(T*));
425
+ std::string result = "Buffer<type: " + detail::cppClassName(name) + ", size: " + std::to_string(this->m_size) + ">";
426
+ return detail::To_Ruby<std::string>().convert(result);
427
+ }*/
428
+
429
+ template<typename T>
430
+ inline VALUE Buffer<T*>::bytes(size_t count) const
431
+ {
432
+ if (!this->m_outer)
433
+ {
434
+ return Qnil;
435
+ }
436
+ else
437
+ {
438
+ T** begin = this->m_outer;
439
+ long length = (long)(count * sizeof(T*));
440
+ return detail::protect(rb_str_new_static, (const char*)*begin, length);
441
+ }
442
+ }
443
+
444
+ template<typename T>
445
+ inline VALUE Buffer<T*>::bytes() const
446
+ {
447
+ return this->bytes(this->m_size);
448
+ }
449
+
450
+ template<typename T>
451
+ inline Array Buffer<T*>::toArray(size_t count) const
452
+ {
453
+ if (!this->m_outer)
454
+ {
455
+ return Qnil;
456
+ }
457
+ else
458
+ {
459
+ Array result;
460
+
461
+ T** ptr = this->m_outer;
462
+ T** end = this->m_outer + count;
463
+
464
+ for (; ptr < end; ptr++)
465
+ {
466
+ Buffer<T> buffer(*ptr);
467
+ result.push(std::move(buffer));
468
+ }
469
+ return result;
470
+ }
471
+ }
472
+
473
+ template<typename T>
474
+ inline Array Buffer<T*>::toArray() const
475
+ {
476
+ return this->toArray(this->m_size);
477
+ }
478
+
479
+ // ---- Buffer<void> -------
480
+ inline Buffer<void>::Buffer(void* pointer) : m_buffer(pointer)
481
+ {
482
+ }
483
+
484
+ inline Buffer<void>::Buffer(Buffer<void>&& other) : m_buffer(other.m_buffer)
485
+ {
486
+ other.m_buffer = nullptr;
487
+ }
488
+
489
+ inline Buffer<void>& Buffer<void>::operator=(Buffer<void>&& other)
490
+ {
491
+ this->m_buffer = other.m_buffer;
492
+ other.m_buffer = nullptr;
493
+
494
+ return *this;
495
+ }
496
+
497
+ inline void* Buffer<void>::ptr()
498
+ {
499
+ return this->m_buffer;
500
+ }
501
+
502
+ // ------ define_buffer ----------
503
+ template<typename T>
504
+ inline Data_Type<Buffer<T>> define_buffer(std::string klassName)
505
+ {
506
+ using Buffer_T = Buffer<T>;
507
+
508
+ if (klassName.empty())
509
+ {
510
+ std::string typeName = detail::typeName(typeid(Buffer_T));
511
+ klassName = detail::rubyClassName(typeName);
512
+ }
513
+
514
+ Module rb_mRice = define_module("Rice");
515
+
516
+ if constexpr (std::is_void_v<T>)
517
+ {
518
+ return define_class_under<Buffer_T>(rb_mRice, klassName);
519
+ }
520
+ else
521
+ {
522
+ Data_Type<Buffer_T> klass = define_class_under<Buffer_T>(rb_mRice, klassName).
523
+ define_constructor(Constructor<Buffer_T, VALUE>(), Arg("value").setValue()).
524
+ define_method("size", &Buffer_T::size).
525
+ define_method("size=", &Buffer_T::setSize).
526
+ // template define_method<VALUE(Buffer_T::*)() const>("to_s", &Buffer_T::toString, Return().setValue()).
527
+ template define_method<VALUE(Buffer_T::*)(size_t) const>("bytes", &Buffer_T::bytes, Return().setValue()).
528
+ template define_method<VALUE(Buffer_T::*)() const>("bytes", &Buffer_T::bytes, Return().setValue()).
529
+ template define_method<Array(Buffer_T::*)(size_t) const>("to_ary", &Buffer_T::toArray, Return().setValue()).
530
+ template define_method<Array(Buffer_T::*)() const>("to_ary", &Buffer_T::toArray, Return().setValue());
531
+
532
+ if constexpr (!std::is_pointer_v<T>)
533
+ {
534
+ klass.
535
+ define_method("[]", [](const Buffer_T& self, size_t index) -> T
536
+ {
537
+ return self.get(index);
538
+ }).
539
+ define_method("[]=", [](Buffer_T& self, size_t index, T element) -> void
540
+ {
541
+ self.set(index, element);
542
+ });
543
+ }
544
+
545
+ return klass;
546
+ }
547
+ }
548
+
549
+ inline void define_fundamental_buffer_types()
550
+ {
551
+ define_buffer<bool>();
552
+ define_buffer<int>();
553
+ define_buffer<int*>();
554
+ define_buffer<unsigned int>();
555
+ define_buffer<unsigned int*>();
556
+ define_buffer<char>();
557
+ define_buffer<char*>();
558
+ define_buffer<unsigned char>();
559
+ define_buffer<unsigned char*>();
560
+ define_buffer<signed char>();
561
+ define_buffer<signed char*>();
562
+ define_buffer<double>();
563
+ define_buffer<double*>();
564
+ define_buffer<float>();
565
+ define_buffer<float*>();
566
+ define_buffer<long>();
567
+ define_buffer<long*>();
568
+ define_buffer<unsigned long>();
569
+ define_buffer<unsigned long*>();
570
+ define_buffer<long long>();
571
+ define_buffer<long long*>();
572
+ define_buffer<unsigned long long>();
573
+ define_buffer<unsigned long long*>();
574
+ define_buffer<short>();
575
+ define_buffer<short*>();
576
+ define_buffer<unsigned short>();
577
+ define_buffer<unsigned short*>();
578
+ define_buffer<void>();
579
+ }
580
+ }
581
+
582
+ namespace Rice::detail
583
+ {
584
+ template<typename T>
585
+ struct Type<Buffer<T>>
586
+ {
587
+ static bool verify()
588
+ {
589
+ Type<intrinsic_type<T>>::verify();
590
+
591
+ if (!Data_Type<Buffer<T>>::is_defined())
592
+ {
593
+ define_buffer<T>();
594
+ }
595
+
596
+ return true;
597
+ }
598
+ };
599
+ }
data/rice/Callback.hpp ADDED
@@ -0,0 +1,21 @@
1
+ #ifndef Rice__Callback__hpp_
2
+ #define Rice__Callback__hpp_
3
+
4
+ namespace Rice
5
+ {
6
+ //! Define a callback.
7
+ /*! When C++ invokes a C style callback, Rice automatically converts the C++ arguments
8
+ * to Ruby. However, there may be cases where you need to specify how individual arguments
9
+ * should be handled. For example, callbacks often have a user data parameter which is
10
+ * defined as a void pointer (void*). In this case, you need to tell Ruby that the parameter
11
+ * is opaque and should not be convered. For example:
12
+ *
13
+ * define_callback<void(*)(void*)>(Arg("user_data").setOpaque());
14
+ *
15
+ * \param args a list of Arg instance used to define default parameters (optional)
16
+ * \return nothing
17
+ */
18
+ template<typename Callback_T, typename...Arg_Ts>
19
+ void define_callback(const Arg_Ts&...args);
20
+ }
21
+ #endif // Rice__Callback__hpp_
data/rice/Callback.ipp ADDED
@@ -0,0 +1,13 @@
1
+ namespace Rice
2
+ {
3
+ template<typename Callback_T, typename...Arg_Ts>
4
+ void define_callback(const Arg_Ts&...args)
5
+ {
6
+ MethodInfo* methodInfo = new MethodInfo(detail::function_traits<Callback_T>::arity, args...);
7
+ #ifdef HAVE_LIBFFI
8
+ detail::NativeCallbackFFI<Callback_T>::setMethodInfo(methodInfo);
9
+ #else
10
+ detail::NativeCallbackSimple<Callback_T>::setMethodInfo(methodInfo);
11
+ #endif
12
+ }
13
+ }
data/rice/Constructor.hpp CHANGED
@@ -1,9 +1,6 @@
1
1
  #ifndef Rice__Constructor__hpp_
2
2
  #define Rice__Constructor__hpp_
3
3
 
4
- #include "detail/Wrapper.hpp"
5
- #include "cpp_api/Object_defn.hpp"
6
-
7
4
  namespace Rice
8
5
  {
9
6
  //! Define a Type's Constructor and it's arguments.
@@ -13,33 +10,13 @@ namespace Rice
13
10
  .define_constructor(Constructor<Test>());
14
11
  \endcode
15
12
  *
16
- * The first template type must be the type being wrapped.
17
- * Afterwards any extra types must match the appropriate constructor
18
- * to be used in C++ when constructing the object.
13
+ * The first template argument must be the type being wrapped.
14
+ * Additional arguments must be the types of the parameters sent
15
+ * to the constructor.
19
16
  *
20
17
  * For more information, see Rice::Data_Type::define_constructor.
21
18
  */
22
19
  template<typename T, typename...Arg_Ts>
23
- class Constructor
24
- {
25
- public:
26
- static void construct(VALUE self, Arg_Ts...args)
27
- {
28
- T* data = new T(args...);
29
- detail::replace<T>(self, Data_Type<T>::ruby_data_type(), data, true);
30
- }
31
- };
32
-
33
- //! Special-case Constructor used when defining Directors.
34
- template<typename T, typename...Arg_Ts>
35
- class Constructor<T, Object, Arg_Ts...>
36
- {
37
- public:
38
- static void construct(Object self, Arg_Ts...args)
39
- {
40
- T* data = new T(self, args...);
41
- detail::replace<T>(self.value(), Data_Type<T>::ruby_data_type(), data, true);
42
- }
43
- };
20
+ class Constructor;
44
21
  }
45
22
  #endif // Rice__Constructor__hpp_