rice 4.5.0 → 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 (166) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  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/Rakefile +5 -4
  8. data/include/rice/rice.hpp +5436 -3201
  9. data/include/rice/stl.hpp +2355 -1269
  10. data/lib/make_rice_headers.rb +79 -0
  11. data/lib/mkmf-rice.rb +4 -0
  12. data/lib/rice/version.rb +3 -0
  13. data/lib/rice.rb +1 -0
  14. data/lib/rubygems/builder.rb +11 -0
  15. data/lib/rubygems/cmake_builder.rb +113 -0
  16. data/lib/rubygems_plugin.rb +9 -0
  17. data/rice/Arg.hpp +7 -1
  18. data/rice/Arg.ipp +11 -2
  19. data/rice/Buffer.hpp +123 -0
  20. data/rice/Buffer.ipp +599 -0
  21. data/rice/Constructor.ipp +3 -3
  22. data/rice/Data_Object.hpp +2 -3
  23. data/rice/Data_Object.ipp +188 -188
  24. data/rice/Data_Type.hpp +4 -5
  25. data/rice/Data_Type.ipp +42 -26
  26. data/rice/Enum.hpp +0 -1
  27. data/rice/Enum.ipp +26 -23
  28. data/rice/Init.hpp +8 -0
  29. data/rice/Init.ipp +8 -0
  30. data/rice/MemoryView.ipp +1 -41
  31. data/rice/Return.hpp +1 -1
  32. data/rice/Return.ipp +6 -0
  33. data/rice/cpp_api/Array.hpp +209 -0
  34. data/rice/cpp_api/Array.ipp +304 -0
  35. data/rice/cpp_api/Builtin_Object.hpp +31 -0
  36. data/rice/cpp_api/Builtin_Object.ipp +37 -0
  37. data/rice/cpp_api/Class.hpp +70 -0
  38. data/rice/cpp_api/Class.ipp +97 -0
  39. data/rice/cpp_api/Encoding.hpp +32 -0
  40. data/rice/cpp_api/Encoding.ipp +59 -0
  41. data/rice/cpp_api/Hash.hpp +194 -0
  42. data/rice/cpp_api/Hash.ipp +257 -0
  43. data/rice/cpp_api/Identifier.hpp +46 -0
  44. data/rice/cpp_api/Identifier.ipp +31 -0
  45. data/rice/cpp_api/Module.hpp +72 -0
  46. data/rice/cpp_api/Module.ipp +101 -0
  47. data/rice/cpp_api/Object.hpp +272 -0
  48. data/rice/cpp_api/Object.ipp +235 -0
  49. data/rice/cpp_api/String.hpp +74 -0
  50. data/rice/cpp_api/String.ipp +120 -0
  51. data/rice/cpp_api/Struct.hpp +113 -0
  52. data/rice/cpp_api/Struct.ipp +92 -0
  53. data/rice/cpp_api/Symbol.hpp +46 -0
  54. data/rice/cpp_api/Symbol.ipp +93 -0
  55. data/rice/cpp_api/shared_methods.hpp +134 -0
  56. data/rice/detail/MethodInfo.hpp +1 -9
  57. data/rice/detail/MethodInfo.ipp +5 -72
  58. data/rice/detail/Native.hpp +3 -2
  59. data/rice/detail/Native.ipp +32 -4
  60. data/rice/detail/NativeAttributeGet.hpp +3 -2
  61. data/rice/detail/NativeAttributeGet.ipp +8 -2
  62. data/rice/detail/NativeAttributeSet.hpp +3 -2
  63. data/rice/detail/NativeAttributeSet.ipp +8 -2
  64. data/rice/detail/NativeCallbackFFI.ipp +1 -1
  65. data/rice/detail/NativeFunction.hpp +17 -6
  66. data/rice/detail/NativeFunction.ipp +168 -64
  67. data/rice/detail/NativeIterator.hpp +3 -2
  68. data/rice/detail/NativeIterator.ipp +8 -2
  69. data/rice/detail/RubyType.hpp +2 -5
  70. data/rice/detail/RubyType.ipp +50 -5
  71. data/rice/detail/Type.hpp +3 -1
  72. data/rice/detail/Type.ipp +61 -31
  73. data/rice/detail/Wrapper.hpp +68 -33
  74. data/rice/detail/Wrapper.ipp +103 -113
  75. data/rice/detail/from_ruby.hpp +5 -4
  76. data/rice/detail/from_ruby.ipp +737 -365
  77. data/rice/detail/to_ruby.ipp +1092 -186
  78. data/rice/global_function.ipp +1 -1
  79. data/rice/libc/file.hpp +11 -0
  80. data/rice/libc/file.ipp +32 -0
  81. data/rice/rice.hpp +23 -16
  82. data/rice/stl/complex.hpp +6 -0
  83. data/rice/stl/complex.ipp +93 -0
  84. data/rice/stl/exception.hpp +11 -0
  85. data/rice/stl/exception.ipp +29 -0
  86. data/rice/stl/exception_ptr.hpp +6 -0
  87. data/rice/stl/exception_ptr.ipp +27 -0
  88. data/rice/stl/map.hpp +12 -0
  89. data/rice/stl/map.ipp +469 -0
  90. data/rice/stl/monostate.hpp +6 -0
  91. data/rice/stl/monostate.ipp +80 -0
  92. data/rice/stl/multimap.hpp +14 -0
  93. data/rice/stl/multimap.ipp +448 -0
  94. data/rice/stl/optional.hpp +6 -0
  95. data/rice/stl/optional.ipp +118 -0
  96. data/rice/stl/pair.hpp +13 -0
  97. data/rice/stl/pair.ipp +155 -0
  98. data/rice/stl/reference_wrapper.hpp +6 -0
  99. data/rice/stl/reference_wrapper.ipp +41 -0
  100. data/rice/stl/set.hpp +12 -0
  101. data/rice/stl/set.ipp +495 -0
  102. data/rice/stl/shared_ptr.hpp +28 -0
  103. data/rice/stl/shared_ptr.ipp +224 -0
  104. data/rice/stl/string.hpp +6 -0
  105. data/rice/stl/string.ipp +158 -0
  106. data/rice/stl/string_view.hpp +6 -0
  107. data/rice/stl/string_view.ipp +65 -0
  108. data/rice/stl/tuple.hpp +6 -0
  109. data/rice/stl/tuple.ipp +128 -0
  110. data/rice/stl/type_index.hpp +6 -0
  111. data/rice/stl/type_index.ipp +30 -0
  112. data/rice/stl/type_info.hpp +6 -0
  113. data/rice/stl/type_info.ipp +29 -0
  114. data/rice/stl/unique_ptr.hpp +22 -0
  115. data/rice/stl/unique_ptr.ipp +139 -0
  116. data/rice/stl/unordered_map.hpp +12 -0
  117. data/rice/stl/unordered_map.ipp +469 -0
  118. data/rice/stl/variant.hpp +6 -0
  119. data/rice/stl/variant.ipp +242 -0
  120. data/rice/stl/vector.hpp +12 -0
  121. data/rice/stl/vector.ipp +590 -0
  122. data/rice/stl.hpp +7 -3
  123. data/rice/traits/attribute_traits.hpp +26 -0
  124. data/rice/traits/function_traits.hpp +95 -0
  125. data/rice/traits/method_traits.hpp +47 -0
  126. data/rice/traits/rice_traits.hpp +160 -0
  127. data/rice.gemspec +85 -0
  128. data/test/embed_ruby.cpp +3 -0
  129. data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
  130. data/test/test_Array.cpp +6 -3
  131. data/test/test_Attribute.cpp +34 -1
  132. data/test/test_Buffer.cpp +285 -0
  133. data/test/test_Callback.cpp +2 -3
  134. data/test/test_Data_Object.cpp +88 -34
  135. data/test/test_Data_Type.cpp +106 -65
  136. data/test/test_Director.cpp +7 -3
  137. data/test/test_Enum.cpp +5 -2
  138. data/test/test_File.cpp +1 -1
  139. data/test/test_From_Ruby.cpp +181 -114
  140. data/test/test_Iterator.cpp +1 -1
  141. data/test/{test_JumpException.cpp → test_Jump_Exception.cpp} +1 -0
  142. data/test/test_Keep_Alive.cpp +7 -18
  143. data/test/test_Keep_Alive_No_Wrapper.cpp +0 -1
  144. data/test/test_Module.cpp +13 -6
  145. data/test/test_Native_Registry.cpp +0 -1
  146. data/test/test_Overloads.cpp +180 -5
  147. data/test/test_Ownership.cpp +100 -57
  148. data/test/test_Proc.cpp +0 -1
  149. data/test/test_Self.cpp +4 -4
  150. data/test/test_Stl_Map.cpp +37 -39
  151. data/test/test_Stl_Multimap.cpp +693 -0
  152. data/test/test_Stl_Pair.cpp +8 -8
  153. data/test/test_Stl_Reference_Wrapper.cpp +4 -2
  154. data/test/test_Stl_Set.cpp +790 -0
  155. data/test/{test_Stl_SmartPointer.cpp → test_Stl_SharedPtr.cpp} +97 -127
  156. data/test/test_Stl_Tuple.cpp +116 -0
  157. data/test/test_Stl_Type.cpp +1 -1
  158. data/test/test_Stl_UniquePtr.cpp +202 -0
  159. data/test/test_Stl_Unordered_Map.cpp +28 -34
  160. data/test/test_Stl_Variant.cpp +217 -89
  161. data/test/test_Stl_Vector.cpp +209 -83
  162. data/test/test_To_Ruby.cpp +373 -1
  163. data/test/test_Type.cpp +85 -14
  164. data/test/test_global_functions.cpp +17 -4
  165. metadata +94 -10
  166. data/rice/detail/TupleIterator.hpp +0 -14
@@ -104,6 +104,94 @@ void makeIntrinsicVariant()
104
104
  define_attr("variant_attr", &MyClass::variant_);
105
105
  }
106
106
 
107
+ namespace
108
+ {
109
+ class MyClass1
110
+ {
111
+ public:
112
+ MyClass1()
113
+ {
114
+ int a = 1;
115
+ }
116
+
117
+ std::string sayHello()
118
+ {
119
+ return "Hi from MyClass1";
120
+ }
121
+ };
122
+
123
+ class MyClass2
124
+ {
125
+ public:
126
+ MyClass2()
127
+ {
128
+ int a = 2;
129
+ }
130
+
131
+ std::string sayHello()
132
+ {
133
+ return "Hi from MyClass2";
134
+ }
135
+ };
136
+
137
+ using Variant_T = std::variant<std::monostate, MyClass1, MyClass2>;
138
+
139
+ Variant_T variant(bool myClass1)
140
+ {
141
+ if (myClass1)
142
+ {
143
+ return MyClass1();
144
+ }
145
+ else
146
+ {
147
+ return MyClass2();
148
+ }
149
+ }
150
+
151
+ Variant_T roundTripVariant(Variant_T variant)
152
+ {
153
+ return variant;
154
+ }
155
+
156
+ Variant_T& roundTripVariantRef(Variant_T& variant)
157
+ {
158
+ return variant;
159
+ }
160
+
161
+ const Variant_T& roundTripConstVariantRef(const Variant_T& variant)
162
+ {
163
+ return variant;
164
+ }
165
+ }
166
+
167
+ void makeClassVariant()
168
+ {
169
+ define_class<MyClass1>("MyClass1").
170
+ define_constructor(Constructor<MyClass1>()).
171
+ define_method("say_hello", &MyClass1::sayHello);
172
+
173
+ define_class<MyClass2>("MyClass2").
174
+ define_constructor(Constructor<MyClass2>()).
175
+ define_method("say_hello", &MyClass2::sayHello);
176
+
177
+ define_global_function("variant_class", &variant);
178
+ define_global_function("roundtrip_variant", &roundTripVariant);
179
+ define_global_function("roundtrip_variant_ref", &roundTripVariantRef);
180
+ define_global_function("roundtrip_const_variant_ref", &roundTripConstVariantRef);
181
+ }
182
+
183
+ SETUP(Variant)
184
+ {
185
+ embed_ruby();
186
+ makeIntrinsicVariant();
187
+ makeClassVariant();
188
+ }
189
+
190
+ TEARDOWN(Variant)
191
+ {
192
+ rb_gc_start();
193
+ }
194
+
107
195
  TESTCASE(IntrinsicReturns)
108
196
  {
109
197
  using namespace std::complex_literals;
@@ -212,88 +300,6 @@ TESTCASE(VariantAttribute)
212
300
  ASSERT_EQUAL(78, detail::From_Ruby<int>().convert(result));
213
301
  }
214
302
 
215
- namespace
216
- {
217
- class MyClass1
218
- {
219
- public:
220
- MyClass1()
221
- {
222
- int a = 1;
223
- }
224
-
225
- std::string sayHello()
226
- {
227
- return "Hi from MyClass1";
228
- }
229
- };
230
-
231
- class MyClass2
232
- {
233
- public:
234
- MyClass2()
235
- {
236
- int a = 2;
237
- }
238
-
239
- std::string sayHello()
240
- {
241
- return "Hi from MyClass2";
242
- }
243
- };
244
-
245
- using Class_Variant_T = std::variant<std::monostate, MyClass1, MyClass2>;
246
-
247
- Class_Variant_T variantClass(bool myClass1)
248
- {
249
- if (myClass1)
250
- {
251
- return MyClass1();
252
- }
253
- else
254
- {
255
- return MyClass2();
256
- }
257
- }
258
-
259
- Class_Variant_T roundTripVariantClass(Class_Variant_T variant)
260
- {
261
- return variant;
262
- }
263
-
264
- Class_Variant_T& roundTripVariantClassRef(Class_Variant_T& variant)
265
- {
266
- return variant;
267
- }
268
- }
269
-
270
- void makeClassVariant()
271
- {
272
- define_class<MyClass1>("MyClass1").
273
- define_constructor(Constructor<MyClass1>()).
274
- define_method("say_hello", &MyClass1::sayHello);
275
-
276
- define_class<MyClass2>("MyClass2").
277
- define_constructor(Constructor<MyClass2>()).
278
- define_method("say_hello", &MyClass2::sayHello);
279
-
280
- define_global_function("variant_class", &variantClass);
281
- define_global_function("roundtrip_variant_class", &roundTripVariantClass);
282
- define_global_function("roundtrip_variant_class_ref", &roundTripVariantClassRef);
283
- }
284
-
285
- SETUP(Variant)
286
- {
287
- embed_ruby();
288
- makeIntrinsicVariant();
289
- makeClassVariant();
290
- }
291
-
292
- TEARDOWN(Variant)
293
- {
294
- rb_gc_start();
295
- }
296
-
297
303
  TESTCASE(ClassReturns)
298
304
  {
299
305
  Module m = define_module("Testing");
@@ -307,19 +313,22 @@ TESTCASE(ClassReturns)
307
313
  ASSERT_EQUAL("Hi from MyClass2", detail::From_Ruby<std::string>().convert(hello));
308
314
  }
309
315
 
310
- TESTCASE(ClassRoundtrip)
316
+ TESTCASE(Roundtrip)
311
317
  {
312
318
  Module m = define_module("Testing");
313
319
 
314
320
  Object instance = m.module_eval("MyClass1.new");
315
- Object instance2 = m.call("roundtrip_variant_class", instance);
321
+ Object instance2 = m.call("roundtrip_variant", instance);
316
322
  String hello = instance2.call("say_hello");
317
323
  ASSERT_EQUAL("Hi from MyClass1", detail::From_Ruby<std::string>().convert(hello));
318
324
 
319
325
  instance = m.module_eval("MyClass2.new");
320
- instance2 = m.call("roundtrip_variant_class", instance);
326
+ instance2 = m.call("roundtrip_variant", instance);
321
327
  hello = instance2.call("say_hello");
322
328
  ASSERT_EQUAL("Hi from MyClass2", detail::From_Ruby<std::string>().convert(hello));
329
+
330
+ instance2 = m.call("roundtrip_variant", nullptr);
331
+ ASSERT_EQUAL(Qnil, instance2.value());
323
332
  }
324
333
 
325
334
  /* This test case runs successfully on MSVC but not g++. Having stepped through the code with
@@ -331,21 +340,140 @@ TESTCASE(ClassRoundtrip)
331
340
  std::tuple with one element, a reference to a variant. So it doesn't change and the address
332
341
  of the variable doesn't change. But for some reason g++ resets the
333
342
  the std::variant index to 0 thus breaking the test. Maybe something to do with storing
334
- a refernence to a variant in a tuple? */
343
+ a reference to a variant in a tuple? */
335
344
 
336
345
  #ifdef _MSC_VER
337
- TESTCASE(ClassRoundtripRef)
346
+ TESTCASE(RoundtripRef)
338
347
  {
339
348
  Module m = define_module("Testing");
340
349
 
341
350
  Object instance = m.module_eval("MyClass1.new");
342
- Object instance2 = m.call("roundtrip_variant_class_ref", instance);
351
+ Object instance2 = m.call("roundtrip_variant_ref", instance);
343
352
  String hello = instance2.call("say_hello");
344
353
  ASSERT_EQUAL("Hi from MyClass1", detail::From_Ruby<std::string>().convert(hello));
345
354
 
346
355
  instance = m.module_eval("MyClass2.new");
347
- instance2 = m.call("roundtrip_variant_class_ref", instance);
356
+ instance2 = m.call("roundtrip_variant_ref", instance);
348
357
  hello = instance2.call("say_hello");
349
358
  ASSERT_EQUAL("Hi from MyClass2", detail::From_Ruby<std::string>().convert(hello));
359
+
360
+ instance2 = m.call("roundtrip_variant_ref", nullptr);
361
+ ASSERT_EQUAL(Qnil, instance2.value());
350
362
  }
351
363
  #endif
364
+
365
+ TESTCASE(RoundtripConstRef)
366
+ {
367
+ Module m = define_module("Testing");
368
+
369
+ Object instance = m.module_eval("MyClass1.new");
370
+ Object instance2 = m.call("roundtrip_const_variant_ref", instance);
371
+ String hello = instance2.call("say_hello");
372
+ ASSERT_EQUAL("Hi from MyClass1", detail::From_Ruby<std::string>().convert(hello));
373
+
374
+ instance = m.module_eval("MyClass2.new");
375
+ instance2 = m.call("roundtrip_const_variant_ref", instance);
376
+ hello = instance2.call("say_hello");
377
+ ASSERT_EQUAL("Hi from MyClass2", detail::From_Ruby<std::string>().convert(hello));
378
+
379
+ instance2 = m.call("roundtrip_const_variant_ref", nullptr);
380
+ ASSERT_EQUAL(Qnil, instance2.value());
381
+ }
382
+
383
+ namespace
384
+ {
385
+ class MyClass4
386
+ {
387
+ public:
388
+ size_t variantIndex(std::variant<std::vector<std::string>, std::vector<int>> variant)
389
+ {
390
+ return variant.index();
391
+ }
392
+ };
393
+ }
394
+
395
+ TESTCASE(VariantWithTwoVectors)
396
+ {
397
+ using namespace std::complex_literals;
398
+
399
+ define_class<MyClass4>("MyClass4").
400
+ define_constructor(Constructor<MyClass4>()).
401
+ define_method("variant_index", &MyClass4::variantIndex);
402
+
403
+ Module m = define_module("Testing");
404
+
405
+ std::string code = R"(vector = Std::Vector≺string≻.new
406
+ vector << "a" << "b" << "c"
407
+ my_class = MyClass4.new
408
+ my_class.variant_index(vector))";
409
+
410
+ Object result = m.module_eval(code);
411
+ ASSERT_EQUAL(0, detail::From_Ruby<size_t>().convert(result));
412
+
413
+ code = R"(vector = Std::Vector≺int≻.new
414
+ vector.push_back(4)
415
+ my_class = MyClass4.new
416
+ my_class.variant_index(vector))";
417
+ result = m.module_eval(code);
418
+ ASSERT_EQUAL(1, detail::From_Ruby<size_t>().convert(result));
419
+
420
+ code = R"(my_class = MyClass4.new
421
+ my_class.variant_index(["x", "y", "z"]))";
422
+ result = m.module_eval(code);
423
+ ASSERT_EQUAL(0, detail::From_Ruby<size_t>().convert(result));
424
+
425
+ code = R"(my_class = MyClass4.new
426
+ my_class.variant_index([5, 6]))";
427
+
428
+ ASSERT_EXCEPTION_CHECK(
429
+ Exception,
430
+ m.module_eval(code),
431
+ ASSERT_EQUAL("wrong argument type Integer (expected String)", ex.what())
432
+ );
433
+ }
434
+
435
+ namespace
436
+ {
437
+ class MyClass5
438
+ {
439
+ public:
440
+ static inline int a = 10;
441
+ static inline float b = 11.0;
442
+ public:
443
+ std::variant<Buffer<int>, Buffer<float>> variantBuffer(int index)
444
+ {
445
+ if (index == 0)
446
+ {
447
+ return Buffer<int>(&a);
448
+ }
449
+ else
450
+ {
451
+ return Buffer<float>(&b);
452
+ }
453
+ }
454
+ };
455
+ }
456
+
457
+ TESTCASE(Buffer)
458
+ {
459
+ define_buffer<int>();
460
+ define_buffer<float>();
461
+ using namespace std::complex_literals;
462
+
463
+ define_class<MyClass5>("MyClass5").
464
+ define_constructor(Constructor<MyClass5>()).
465
+ define_method("buffer", &MyClass5::variantBuffer);
466
+
467
+ Module m = define_module("Testing");
468
+
469
+ std::string code = R"(myclass = MyClass5.new
470
+ myclass.buffer(0).to_ary(1).first)";
471
+
472
+ Object result = m.module_eval(code);
473
+ ASSERT_EQUAL(10, detail::From_Ruby<int>().convert(result));
474
+
475
+ code = R"(myclass = MyClass5.new
476
+ myclass.buffer(1).to_ary(1).first)";
477
+ result = m.module_eval(code);
478
+ ASSERT_EQUAL(11.0, detail::From_Ruby<float>().convert(result));
479
+ }