rice 4.7.1 → 4.8.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 (153) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -1
  3. data/CMakeLists.txt +14 -22
  4. data/CMakePresets.json +203 -75
  5. data/FindRuby.cmake +358 -123
  6. data/bin/rice-doc.rb +56 -141
  7. data/include/rice/api.hpp +248 -0
  8. data/include/rice/rice.hpp +2237 -1657
  9. data/include/rice/stl.hpp +346 -443
  10. data/lib/rice/doc/config.rb +70 -0
  11. data/lib/rice/doc/cpp_reference.rb +1 -4
  12. data/lib/rice/doc/mkdocs.rb +58 -20
  13. data/lib/rice/doc/rice.rb +20 -0
  14. data/lib/rice/doc.rb +1 -0
  15. data/lib/rice/make_rice_headers.rb +7 -0
  16. data/lib/rice/native_registry.rb +2 -2
  17. data/lib/rice/rbs.rb +2 -2
  18. data/lib/rice/version.rb +1 -1
  19. data/lib/rubygems_plugin.rb +12 -9
  20. data/rice/Arg.hpp +12 -6
  21. data/rice/Arg.ipp +14 -7
  22. data/rice/Buffer.ipp +44 -40
  23. data/rice/Callback.hpp +1 -1
  24. data/rice/Callback.ipp +2 -7
  25. data/rice/Constructor.hpp +1 -1
  26. data/rice/Constructor.ipp +11 -11
  27. data/rice/Data_Object.ipp +15 -15
  28. data/rice/Data_Type.hpp +9 -10
  29. data/rice/Data_Type.ipp +22 -25
  30. data/rice/Director.hpp +1 -0
  31. data/rice/Enum.ipp +58 -39
  32. data/rice/Exception.hpp +4 -4
  33. data/rice/Exception.ipp +7 -7
  34. data/rice/NoGVL.hpp +13 -0
  35. data/rice/Reference.hpp +56 -0
  36. data/rice/Reference.ipp +96 -0
  37. data/rice/Return.hpp +4 -1
  38. data/rice/Return.ipp +0 -6
  39. data/rice/cpp_api/Array.hpp +41 -4
  40. data/rice/cpp_api/Array.ipp +105 -9
  41. data/rice/cpp_api/Class.hpp +2 -2
  42. data/rice/cpp_api/Class.ipp +4 -4
  43. data/rice/cpp_api/Hash.ipp +7 -4
  44. data/rice/cpp_api/Module.hpp +4 -4
  45. data/rice/cpp_api/Module.ipp +12 -10
  46. data/rice/cpp_api/Object.hpp +4 -4
  47. data/rice/cpp_api/Object.ipp +15 -12
  48. data/rice/cpp_api/String.hpp +2 -2
  49. data/rice/cpp_api/String.ipp +11 -8
  50. data/rice/cpp_api/Symbol.ipp +7 -7
  51. data/rice/cpp_api/shared_methods.hpp +5 -9
  52. data/rice/detail/InstanceRegistry.hpp +0 -2
  53. data/rice/detail/Native.hpp +31 -21
  54. data/rice/detail/Native.ipp +282 -130
  55. data/rice/detail/NativeAttributeGet.hpp +5 -7
  56. data/rice/detail/NativeAttributeGet.ipp +26 -26
  57. data/rice/detail/NativeAttributeSet.hpp +2 -4
  58. data/rice/detail/NativeAttributeSet.ipp +20 -16
  59. data/rice/detail/NativeCallback.hpp +77 -0
  60. data/rice/detail/NativeCallback.ipp +280 -0
  61. data/rice/detail/NativeFunction.hpp +11 -21
  62. data/rice/detail/NativeFunction.ipp +58 -119
  63. data/rice/detail/NativeInvoker.hpp +4 -4
  64. data/rice/detail/NativeInvoker.ipp +7 -7
  65. data/rice/detail/NativeIterator.hpp +2 -4
  66. data/rice/detail/NativeIterator.ipp +18 -14
  67. data/rice/detail/NativeMethod.hpp +10 -20
  68. data/rice/detail/NativeMethod.ipp +54 -114
  69. data/rice/detail/NativeProc.hpp +5 -7
  70. data/rice/detail/NativeProc.ipp +39 -28
  71. data/rice/detail/NativeRegistry.hpp +0 -1
  72. data/rice/detail/Parameter.hpp +15 -8
  73. data/rice/detail/Parameter.ipp +102 -43
  74. data/rice/detail/Proc.ipp +14 -28
  75. data/rice/detail/RubyType.ipp +2 -53
  76. data/rice/detail/Type.hpp +23 -7
  77. data/rice/detail/Type.ipp +73 -93
  78. data/rice/detail/TypeRegistry.ipp +5 -4
  79. data/rice/detail/Wrapper.hpp +1 -1
  80. data/rice/detail/Wrapper.ipp +18 -10
  81. data/rice/detail/from_ruby.hpp +8 -6
  82. data/rice/detail/from_ruby.ipp +306 -173
  83. data/rice/detail/ruby.hpp +23 -0
  84. data/rice/libc/file.hpp +4 -4
  85. data/rice/rice.hpp +6 -8
  86. data/rice/rice_api/Native.ipp +5 -1
  87. data/rice/rice_api/Parameter.ipp +1 -1
  88. data/rice/ruby_mark.hpp +2 -1
  89. data/rice/stl/complex.ipp +12 -8
  90. data/rice/stl/map.ipp +27 -22
  91. data/rice/stl/monostate.ipp +16 -12
  92. data/rice/stl/multimap.hpp +0 -2
  93. data/rice/stl/multimap.ipp +27 -22
  94. data/rice/stl/optional.ipp +27 -11
  95. data/rice/stl/pair.ipp +5 -5
  96. data/rice/stl/reference_wrapper.ipp +5 -4
  97. data/rice/stl/set.ipp +16 -16
  98. data/rice/stl/shared_ptr.hpp +0 -16
  99. data/rice/stl/shared_ptr.ipp +34 -190
  100. data/rice/stl/string.ipp +18 -18
  101. data/rice/stl/string_view.ipp +1 -1
  102. data/rice/stl/tuple.ipp +15 -36
  103. data/rice/stl/unique_ptr.ipp +18 -8
  104. data/rice/stl/unordered_map.ipp +20 -15
  105. data/rice/stl/variant.ipp +37 -21
  106. data/rice/stl/vector.ipp +41 -36
  107. data/rice/traits/function_traits.hpp +19 -19
  108. data/rice/traits/method_traits.hpp +4 -4
  109. data/rice/traits/rice_traits.hpp +162 -39
  110. data/rice.gemspec +1 -3
  111. data/test/test_Array.cpp +261 -3
  112. data/test/test_Attribute.cpp +6 -3
  113. data/test/test_Buffer.cpp +6 -42
  114. data/test/test_Callback.cpp +77 -23
  115. data/test/test_Data_Object.cpp +1 -1
  116. data/test/test_Data_Type.cpp +21 -22
  117. data/test/test_Director.cpp +2 -4
  118. data/test/test_Enum.cpp +34 -5
  119. data/test/test_File.cpp +9 -5
  120. data/test/test_From_Ruby.cpp +4 -3
  121. data/test/test_GVL.cpp +3 -3
  122. data/test/test_Hash.cpp +1 -1
  123. data/test/test_Iterator.cpp +54 -22
  124. data/test/test_Keep_Alive.cpp +1 -1
  125. data/test/test_Keep_Alive_No_Wrapper.cpp +1 -1
  126. data/test/test_Module.cpp +5 -5
  127. data/test/test_Overloads.cpp +345 -48
  128. data/test/test_Proc.cpp +54 -0
  129. data/test/test_Reference.cpp +181 -0
  130. data/test/test_Self.cpp +2 -2
  131. data/test/test_Stl_Set.cpp +6 -6
  132. data/test/test_Stl_SharedPtr.cpp +54 -30
  133. data/test/test_Stl_String_View.cpp +4 -2
  134. data/test/test_Stl_Tuple.cpp +1 -1
  135. data/test/test_Stl_Variant.cpp +6 -14
  136. data/test/test_Stl_Vector.cpp +61 -30
  137. data/test/test_String.cpp +4 -2
  138. data/test/test_Struct.cpp +1 -1
  139. data/test/test_Symbol.cpp +1 -1
  140. data/test/test_To_Ruby.cpp +1 -0
  141. data/test/test_Type.cpp +36 -35
  142. data/test/test_global_functions.cpp +1 -1
  143. data/test/unittest.cpp +1 -1
  144. data/test/unittest.hpp +5 -5
  145. metadata +10 -10
  146. data/rice/Function.hpp +0 -17
  147. data/rice/Function.ipp +0 -13
  148. data/rice/detail/MethodInfo.hpp +0 -48
  149. data/rice/detail/MethodInfo.ipp +0 -99
  150. data/rice/detail/NativeCallbackFFI.hpp +0 -55
  151. data/rice/detail/NativeCallbackFFI.ipp +0 -152
  152. data/rice/detail/NativeCallbackSimple.hpp +0 -30
  153. data/rice/detail/NativeCallbackSimple.ipp +0 -29
@@ -2,57 +2,128 @@
2
2
  #include <optional>
3
3
  #include <stdexcept>
4
4
 
5
- /* This file implements conversions from Ruby to native values fo fundamental types
5
+ /* This file implements conversions from Ruby to native values fo fundamental types
6
6
  such as bool, int, float, etc. It also includes conversions for chars and strings */
7
7
  namespace Rice::detail
8
8
  {
9
- inline Convertible operator&(Convertible left, Convertible right)
9
+ // Get precision bits for a Ruby numeric value
10
+ inline int rubyPrecisionBits(VALUE value)
10
11
  {
11
- return static_cast<Convertible>(static_cast<uint8_t>(left) & static_cast<uint8_t>(right));
12
- }
12
+ switch (rb_type(value))
13
+ {
14
+ // Ruby fixnums fit in long long (63 bits)
15
+ case RUBY_T_FIXNUM:
16
+ return std::numeric_limits<long long>::digits;
13
17
 
14
- inline Convertible operator|(Convertible left, Convertible right)
15
- {
16
- return static_cast<Convertible>(static_cast<uint8_t>(left) | static_cast<uint8_t>(right));
18
+ // Ruby bignums can be arbitrarily large - return actual size
19
+ case RUBY_T_BIGNUM:
20
+ {
21
+ int nlz = 0;
22
+ size_t bytes = protect(rb_absint_size, value, &nlz);
23
+ return static_cast<int>(bytes * CHAR_BIT - nlz);
24
+ }
25
+
26
+ // Ruby floats are C doubles (53 bit mantissa)
27
+ case RUBY_T_FLOAT:
28
+ return std::numeric_limits<double>::digits;
29
+
30
+ // Everything else...
31
+ default:
32
+ return 0;
33
+ }
17
34
  }
18
35
 
19
- inline bool operator<(Convertible left, Convertible right)
36
+ // Precision score for converting Ruby numeric value to C++ type T
37
+ template<typename T>
38
+ inline double precisionScore(VALUE value)
20
39
  {
21
- return static_cast<uint8_t>(left) < static_cast<uint8_t>(right);
40
+ int sourceBits = rubyPrecisionBits(value);
41
+ if (sourceBits == 0)
42
+ {
43
+ return Convertible::None;
44
+ }
45
+
46
+ constexpr int targetBits = std::numeric_limits<T>::digits;
47
+ return (targetBits >= sourceBits) ? Convertible::Exact : static_cast<double>(targetBits) / sourceBits;
22
48
  }
23
49
 
24
- // =========== Helpers ============
25
- template<typename T>
50
+ // Primary template for integral types
51
+ template<typename T, typename Enable = void>
26
52
  class FromRubyFundamental
27
53
  {
28
54
  public:
29
- using RubyType_T = RubyType<T>;
30
-
31
- static Convertible is_convertible(VALUE value)
55
+ static double is_convertible(VALUE value)
32
56
  {
33
- ruby_value_type valueType = rb_type(value);
34
-
35
- if (RubyType_T::Exact.find(valueType) != RubyType_T::Exact.end())
36
- {
37
- return Convertible::Exact;
38
- }
39
- else if (RubyType_T::Castable.find(valueType) != RubyType_T::Castable.end())
57
+ double score = precisionScore<T>(value);
58
+ if (score > Convertible::None)
40
59
  {
41
- return Convertible::Cast;
60
+ switch (rb_type(value))
61
+ {
62
+ case RUBY_T_BIGNUM:
63
+ {
64
+ constexpr int targetBits = std::numeric_limits<T>::digits;
65
+ int sourceBits = rubyPrecisionBits(value);
66
+ if (sourceBits > targetBits)
67
+ {
68
+ return Convertible::None;
69
+ }
70
+ [[fallthrough]];
71
+ }
72
+ case RUBY_T_FIXNUM:
73
+ {
74
+ if constexpr (std::is_unsigned_v<T>)
75
+ {
76
+ score *= Convertible::SignedToUnsigned;
77
+ }
78
+ break;
79
+ }
80
+ case RUBY_T_FLOAT:
81
+ {
82
+ score *= Convertible::FloatToInt;
83
+ break;
84
+ }
85
+ default:
86
+ break;
87
+ }
88
+
89
+ return score;
42
90
  }
43
- else if (RubyType_T::Narrowable.find(valueType) != RubyType_T::Narrowable.end())
91
+
92
+ if constexpr (is_char_type_v<T>)
44
93
  {
45
- return Convertible::Narrow;
94
+ if (rb_type(value) == RUBY_T_STRING)
95
+ {
96
+ return Convertible::Exact;
97
+ }
46
98
  }
47
- else
99
+
100
+ return Convertible::None;
101
+ }
102
+
103
+ static T convert(VALUE value)
104
+ {
105
+ return (T)protect(RubyType<T>::fromRuby, value);
106
+ }
107
+ };
108
+
109
+ // Specialization for floating point types
110
+ template<typename T>
111
+ class FromRubyFundamental<T, std::enable_if_t<std::is_floating_point_v<T>>>
112
+ {
113
+ public:
114
+ static double is_convertible(VALUE value)
115
+ {
116
+ double score = precisionScore<T>(value);
117
+ if (score > Convertible::None && rb_type(value) != RUBY_T_FLOAT)
48
118
  {
49
- return Convertible::None;
119
+ score *= Convertible::IntToFloat;
50
120
  }
121
+ return score;
51
122
  }
52
123
 
53
124
  static T convert(VALUE value)
54
125
  {
55
- return (T)protect(RubyType_T::fromRuby, value);
126
+ return (T)protect(RubyType<T>::fromRuby, value);
56
127
  }
57
128
  };
58
129
 
@@ -60,7 +131,7 @@ namespace Rice::detail
60
131
  class FromRubyFundamental<T*>
61
132
  {
62
133
  public:
63
- static Convertible is_convertible(VALUE value)
134
+ static double is_convertible(VALUE value)
64
135
  {
65
136
  ruby_value_type valueType = rb_type(value);
66
137
 
@@ -69,7 +140,6 @@ namespace Rice::detail
69
140
  case RUBY_T_NIL:
70
141
  {
71
142
  return Convertible::Exact;
72
- break;
73
143
  }
74
144
  case RUBY_T_DATA:
75
145
  {
@@ -108,7 +178,7 @@ namespace Rice::detail
108
178
  {
109
179
  detail::TypeMapper<Pointer<T>> typeMapper;
110
180
  std::string expected = typeMapper.rubyName();
111
- throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
181
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
112
182
  detail::protect(rb_obj_classname, value), expected.c_str());
113
183
  }
114
184
  }
@@ -119,7 +189,7 @@ namespace Rice::detail
119
189
  class FromRubyFundamental<T**>
120
190
  {
121
191
  public:
122
- static Convertible is_convertible(VALUE value)
192
+ static double is_convertible(VALUE value)
123
193
  {
124
194
  ruby_value_type valueType = rb_type(value);
125
195
 
@@ -128,7 +198,6 @@ namespace Rice::detail
128
198
  case RUBY_T_NIL:
129
199
  {
130
200
  return Convertible::Exact;
131
- break;
132
201
  }
133
202
  case RUBY_T_DATA:
134
203
  {
@@ -167,7 +236,7 @@ namespace Rice::detail
167
236
  {
168
237
  detail::TypeMapper<Pointer<T*>> typeMapper;
169
238
  std::string expected = typeMapper.rubyName();
170
- throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
239
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
171
240
  detail::protect(rb_obj_classname, value), expected.c_str());
172
241
  }
173
242
  }
@@ -185,14 +254,22 @@ namespace Rice::detail
185
254
  {
186
255
  }
187
256
 
188
- Convertible is_convertible(VALUE value)
257
+ double is_convertible(VALUE value)
189
258
  {
190
- return FromRubyFundamental<bool>::is_convertible(value);
259
+ switch (rb_type(value))
260
+ {
261
+ case RUBY_T_TRUE:
262
+ case RUBY_T_FALSE:
263
+ case RUBY_T_NIL:
264
+ return Convertible::Exact;
265
+ default:
266
+ return Convertible::None;
267
+ }
191
268
  }
192
269
 
193
270
  bool convert(VALUE value)
194
271
  {
195
- return FromRubyFundamental<bool>::convert(value);
272
+ return protect(RubyType<bool>::fromRuby, value);
196
273
  }
197
274
 
198
275
  private:
@@ -203,7 +280,7 @@ namespace Rice::detail
203
280
  class From_Ruby<bool&>
204
281
  {
205
282
  public:
206
- using Pointer_T = Pointer<bool>;
283
+ using Reference_T = Reference<bool>;
207
284
 
208
285
  From_Ruby() = default;
209
286
 
@@ -211,13 +288,13 @@ namespace Rice::detail
211
288
  {
212
289
  }
213
290
 
214
- Convertible is_convertible(VALUE value)
291
+ double is_convertible(VALUE value)
215
292
  {
216
293
  switch (rb_type(value))
217
294
  {
218
295
  case RUBY_T_DATA:
219
296
  {
220
- if (Data_Type<Pointer_T>::is_descendant(value))
297
+ if (Data_Type<Reference_T>::is_descendant(value))
221
298
  {
222
299
  return Convertible::Exact;
223
300
  }
@@ -225,7 +302,7 @@ namespace Rice::detail
225
302
  }
226
303
  default:
227
304
  {
228
- return FromRubyFundamental<bool>::is_convertible(value);
305
+ return this->from_.is_convertible(value);
229
306
  }
230
307
  }
231
308
  }
@@ -236,23 +313,25 @@ namespace Rice::detail
236
313
  {
237
314
  case RUBY_T_DATA:
238
315
  {
239
- if (Data_Type<Pointer_T>::is_descendant(value))
316
+ if (Data_Type<Reference_T>::is_descendant(value))
240
317
  {
241
- return (bool&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
318
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
319
+ return reference->get();
242
320
  }
243
321
  [[fallthrough]];
244
322
  }
245
323
  default:
246
324
  {
247
- this->converted_ = FromRubyFundamental<bool>::convert(value);
248
- return this->converted_;
325
+ this->reference_ = Reference<bool>(value);
326
+ return this->reference_.get();
249
327
  }
250
328
  }
251
329
  }
252
330
 
253
331
  private:
332
+ From_Ruby<bool> from_;
254
333
  Arg* arg_ = nullptr;
255
- bool converted_ = false;
334
+ Reference<bool> reference_;
256
335
  };
257
336
 
258
337
  // =========== char ============
@@ -266,7 +345,7 @@ namespace Rice::detail
266
345
  {
267
346
  }
268
347
 
269
- Convertible is_convertible(VALUE value)
348
+ double is_convertible(VALUE value)
270
349
  {
271
350
  return FromRubyFundamental<char>::is_convertible(value);
272
351
  }
@@ -284,7 +363,7 @@ namespace Rice::detail
284
363
  class From_Ruby<char&>
285
364
  {
286
365
  public:
287
- using Pointer_T = Pointer<char>;
366
+ using Reference_T = Reference<char>;
288
367
 
289
368
  From_Ruby() = default;
290
369
 
@@ -292,13 +371,13 @@ namespace Rice::detail
292
371
  {
293
372
  }
294
373
 
295
- Convertible is_convertible(VALUE value)
374
+ double is_convertible(VALUE value)
296
375
  {
297
376
  switch (rb_type(value))
298
377
  {
299
378
  case RUBY_T_DATA:
300
379
  {
301
- if (Data_Type<Pointer_T>::is_descendant(value))
380
+ if (Data_Type<Reference_T>::is_descendant(value))
302
381
  {
303
382
  return Convertible::Exact;
304
383
  }
@@ -317,25 +396,26 @@ namespace Rice::detail
317
396
  {
318
397
  case RUBY_T_DATA:
319
398
  {
320
- if (Data_Type<Pointer_T>::is_descendant(value))
399
+ if (Data_Type<Reference_T>::is_descendant(value))
321
400
  {
322
- return (char&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
401
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
402
+ return reference->get();
323
403
  }
324
404
  [[fallthrough]];
325
405
  }
326
406
  default:
327
407
  {
328
- this->converted_ = FromRubyFundamental<char>::convert(value);
329
- return this->converted_;
408
+ this->reference_ = Reference<char>(value);
409
+ return this->reference_.get();
330
410
  }
331
411
  }
332
412
  }
333
413
 
334
414
  private:
335
415
  Arg* arg_ = nullptr;
336
- char converted_ = 0;
416
+ Reference<char> reference_;
337
417
  };
338
-
418
+
339
419
  template<>
340
420
  class From_Ruby<char*>
341
421
  {
@@ -346,7 +426,7 @@ namespace Rice::detail
346
426
  {
347
427
  }
348
428
 
349
- Convertible is_convertible(VALUE value)
429
+ double is_convertible(VALUE value)
350
430
  {
351
431
  switch (rb_type(value))
352
432
  {
@@ -402,7 +482,7 @@ namespace Rice::detail
402
482
  {
403
483
  }
404
484
 
405
- Convertible is_convertible(VALUE value)
485
+ double is_convertible(VALUE value)
406
486
  {
407
487
  return FromRubyFundamental<unsigned char>::is_convertible(value);
408
488
  }
@@ -420,7 +500,7 @@ namespace Rice::detail
420
500
  class From_Ruby<unsigned char&>
421
501
  {
422
502
  public:
423
- using Pointer_T = Pointer<unsigned char>;
503
+ using Reference_T = Reference<unsigned char>;
424
504
 
425
505
  From_Ruby() = default;
426
506
 
@@ -428,13 +508,13 @@ namespace Rice::detail
428
508
  {
429
509
  }
430
510
 
431
- Convertible is_convertible(VALUE value)
511
+ double is_convertible(VALUE value)
432
512
  {
433
513
  switch (rb_type(value))
434
514
  {
435
515
  case RUBY_T_DATA:
436
516
  {
437
- if (Data_Type<Pointer_T>::is_descendant(value))
517
+ if (Data_Type<Reference_T>::is_descendant(value))
438
518
  {
439
519
  return Convertible::Exact;
440
520
  }
@@ -453,23 +533,24 @@ namespace Rice::detail
453
533
  {
454
534
  case RUBY_T_DATA:
455
535
  {
456
- if (Data_Type<Pointer_T>::is_descendant(value))
536
+ if (Data_Type<Reference_T>::is_descendant(value))
457
537
  {
458
- return (unsigned char&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
538
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
539
+ return reference->get();
459
540
  }
460
541
  [[fallthrough]];
461
542
  }
462
543
  default:
463
544
  {
464
- this->converted_ = FromRubyFundamental<unsigned char>::convert(value);
465
- return this->converted_;
545
+ this->reference_ = Reference<unsigned char>(value);
546
+ return this->reference_.get();
466
547
  }
467
548
  }
468
549
  }
469
550
 
470
551
  private:
471
552
  Arg* arg_ = nullptr;
472
- unsigned char converted_ = 0;
553
+ Reference<unsigned char> reference_;
473
554
  };
474
555
 
475
556
  // =========== signed char ============
@@ -483,7 +564,7 @@ namespace Rice::detail
483
564
  {
484
565
  }
485
566
 
486
- Convertible is_convertible(VALUE value)
567
+ double is_convertible(VALUE value)
487
568
  {
488
569
  return FromRubyFundamental<signed char>::is_convertible(value);
489
570
  }
@@ -501,7 +582,7 @@ namespace Rice::detail
501
582
  class From_Ruby<signed char&>
502
583
  {
503
584
  public:
504
- using Pointer_T = Pointer<signed char>;
585
+ using Reference_T = Reference<signed char>;
505
586
 
506
587
  From_Ruby() = default;
507
588
 
@@ -509,13 +590,13 @@ namespace Rice::detail
509
590
  {
510
591
  }
511
592
 
512
- Convertible is_convertible(VALUE value)
593
+ double is_convertible(VALUE value)
513
594
  {
514
595
  switch (rb_type(value))
515
596
  {
516
597
  case RUBY_T_DATA:
517
598
  {
518
- if (Data_Type<Pointer_T>::is_descendant(value))
599
+ if (Data_Type<Reference_T>::is_descendant(value))
519
600
  {
520
601
  return Convertible::Exact;
521
602
  }
@@ -534,23 +615,24 @@ namespace Rice::detail
534
615
  {
535
616
  case RUBY_T_DATA:
536
617
  {
537
- if (Data_Type<Pointer_T>::is_descendant(value))
618
+ if (Data_Type<Reference_T>::is_descendant(value))
538
619
  {
539
- return (signed char&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
620
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
621
+ return reference->get();
540
622
  }
541
623
  [[fallthrough]];
542
624
  }
543
625
  default:
544
626
  {
545
- this->converted_ = FromRubyFundamental<signed char>::convert(value);
546
- return this->converted_;
627
+ this->reference_ = Reference<signed char>(value);
628
+ return this->reference_.get();
547
629
  }
548
630
  }
549
631
  }
550
632
 
551
633
  private:
552
634
  Arg* arg_ = nullptr;
553
- signed char converted_ = 0;
635
+ Reference<signed char> reference_;
554
636
  };
555
637
 
556
638
  // =========== double ============
@@ -564,7 +646,7 @@ namespace Rice::detail
564
646
  {
565
647
  }
566
648
 
567
- Convertible is_convertible(VALUE value)
649
+ double is_convertible(VALUE value)
568
650
  {
569
651
  return FromRubyFundamental<double>::is_convertible(value);
570
652
  }
@@ -582,7 +664,7 @@ namespace Rice::detail
582
664
  class From_Ruby<double&>
583
665
  {
584
666
  public:
585
- using Pointer_T = Pointer<double>;
667
+ using Reference_T = Reference<double>;
586
668
 
587
669
  From_Ruby() = default;
588
670
 
@@ -590,13 +672,13 @@ namespace Rice::detail
590
672
  {
591
673
  }
592
674
 
593
- Convertible is_convertible(VALUE value)
675
+ double is_convertible(VALUE value)
594
676
  {
595
677
  switch (rb_type(value))
596
678
  {
597
679
  case RUBY_T_DATA:
598
680
  {
599
- if (Data_Type<Pointer_T>::is_descendant(value))
681
+ if (Data_Type<Reference_T>::is_descendant(value))
600
682
  {
601
683
  return Convertible::Exact;
602
684
  }
@@ -615,23 +697,24 @@ namespace Rice::detail
615
697
  {
616
698
  case RUBY_T_DATA:
617
699
  {
618
- if (Data_Type<Pointer_T>::is_descendant(value))
700
+ if (Data_Type<Reference_T>::is_descendant(value))
619
701
  {
620
- return (double&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
702
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
703
+ return reference->get();
621
704
  }
622
705
  [[fallthrough]];
623
706
  }
624
707
  default:
625
708
  {
626
- this->converted_ = FromRubyFundamental<double>::convert(value);
627
- return this->converted_;
709
+ this->reference_ = Reference<double>(value);
710
+ return this->reference_.get();
628
711
  }
629
712
  }
630
713
  }
631
714
 
632
715
  private:
633
716
  Arg* arg_ = nullptr;
634
- double converted_;
717
+ Reference<double> reference_;
635
718
  };
636
719
 
637
720
  // =========== float ============
@@ -645,7 +728,7 @@ namespace Rice::detail
645
728
  {
646
729
  }
647
730
 
648
- Convertible is_convertible(VALUE value)
731
+ double is_convertible(VALUE value)
649
732
  {
650
733
  return FromRubyFundamental<float>::is_convertible(value);
651
734
  }
@@ -663,7 +746,7 @@ namespace Rice::detail
663
746
  class From_Ruby<float&>
664
747
  {
665
748
  public:
666
- using Pointer_T = Pointer<float>;
749
+ using Reference_T = Reference<float>;
667
750
 
668
751
  From_Ruby() = default;
669
752
 
@@ -671,13 +754,13 @@ namespace Rice::detail
671
754
  {
672
755
  }
673
756
 
674
- Convertible is_convertible(VALUE value)
757
+ double is_convertible(VALUE value)
675
758
  {
676
759
  switch (rb_type(value))
677
760
  {
678
761
  case RUBY_T_DATA:
679
762
  {
680
- if (Data_Type<Pointer_T>::is_descendant(value))
763
+ if (Data_Type<Reference_T>::is_descendant(value))
681
764
  {
682
765
  return Convertible::Exact;
683
766
  }
@@ -696,23 +779,24 @@ namespace Rice::detail
696
779
  {
697
780
  case RUBY_T_DATA:
698
781
  {
699
- if (Data_Type<Pointer_T>::is_descendant(value))
782
+ if (Data_Type<Reference_T>::is_descendant(value))
700
783
  {
701
- return (float&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
784
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
785
+ return reference->get();
702
786
  }
703
787
  [[fallthrough]];
704
788
  }
705
789
  default:
706
790
  {
707
- this->converted_ = FromRubyFundamental<float>::convert(value);
708
- return this->converted_;
791
+ this->reference_ = Reference<float>(value);
792
+ return this->reference_.get();
709
793
  }
710
794
  }
711
795
  }
712
796
 
713
797
  private:
714
798
  Arg* arg_ = nullptr;
715
- float converted_;
799
+ Reference<float> reference_;
716
800
  };
717
801
 
718
802
  // =========== int ============
@@ -726,9 +810,9 @@ namespace Rice::detail
726
810
  {
727
811
  }
728
812
 
729
- Convertible is_convertible(VALUE value)
813
+ double is_convertible(VALUE value)
730
814
  {
731
- Convertible result = FromRubyFundamental<int>::is_convertible(value);
815
+ double result = FromRubyFundamental<int>::is_convertible(value);
732
816
 
733
817
  // Is this an enum? If so we want to support converting it to an integer
734
818
  if (result == Convertible::None && rb_type(value) == RUBY_T_DATA)
@@ -736,7 +820,7 @@ namespace Rice::detail
736
820
  static ID id = protect(rb_intern, "to_int");
737
821
  if (protect(rb_respond_to, value, id))
738
822
  {
739
- result = Convertible::Cast;
823
+ result = Convertible::Exact;
740
824
  }
741
825
  }
742
826
  return result;
@@ -746,7 +830,7 @@ namespace Rice::detail
746
830
  {
747
831
  return FromRubyFundamental<int>::convert(value);
748
832
  }
749
-
833
+
750
834
  private:
751
835
  Arg* arg_ = nullptr;
752
836
  };
@@ -755,7 +839,7 @@ namespace Rice::detail
755
839
  class From_Ruby<int&>
756
840
  {
757
841
  public:
758
- using Pointer_T = Pointer<int>;
842
+ using Reference_T = Reference<int>;
759
843
 
760
844
  From_Ruby() = default;
761
845
 
@@ -763,13 +847,13 @@ namespace Rice::detail
763
847
  {
764
848
  }
765
849
 
766
- Convertible is_convertible(VALUE value)
850
+ double is_convertible(VALUE value)
767
851
  {
768
852
  switch (rb_type(value))
769
853
  {
770
854
  case RUBY_T_DATA:
771
855
  {
772
- if (Data_Type<Pointer_T>::is_descendant(value))
856
+ if (Data_Type<Reference_T>::is_descendant(value))
773
857
  {
774
858
  return Convertible::Exact;
775
859
  }
@@ -788,23 +872,24 @@ namespace Rice::detail
788
872
  {
789
873
  case RUBY_T_DATA:
790
874
  {
791
- if (Data_Type<Pointer_T>::is_descendant(value))
875
+ if (Data_Type<Reference_T>::is_descendant(value))
792
876
  {
793
- return (int&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
877
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
878
+ return reference->get();
794
879
  }
795
880
  [[fallthrough]];
796
881
  }
797
882
  default:
798
883
  {
799
- this->converted_ = FromRubyFundamental<int>::convert(value);
800
- return this->converted_;
884
+ this->reference_ = Reference<int>(value);
885
+ return this->reference_.get();
801
886
  }
802
887
  }
803
888
  }
804
889
 
805
890
  private:
806
891
  Arg* arg_ = nullptr;
807
- int converted_ = 0;
892
+ Reference<int> reference_;
808
893
  };
809
894
 
810
895
  // =========== unsigned int ============
@@ -818,7 +903,7 @@ namespace Rice::detail
818
903
  {
819
904
  }
820
905
 
821
- Convertible is_convertible(VALUE value)
906
+ double is_convertible(VALUE value)
822
907
  {
823
908
  return FromRubyFundamental<unsigned int>::is_convertible(value);
824
909
  }
@@ -836,7 +921,7 @@ namespace Rice::detail
836
921
  class From_Ruby<unsigned int&>
837
922
  {
838
923
  public:
839
- using Pointer_T = Pointer<unsigned int>;
924
+ using Reference_T = Reference<unsigned int>;
840
925
 
841
926
  From_Ruby() = default;
842
927
 
@@ -844,13 +929,13 @@ namespace Rice::detail
844
929
  {
845
930
  }
846
931
 
847
- Convertible is_convertible(VALUE value)
932
+ double is_convertible(VALUE value)
848
933
  {
849
934
  switch (rb_type(value))
850
935
  {
851
936
  case RUBY_T_DATA:
852
937
  {
853
- if (Data_Type<Pointer_T>::is_descendant(value))
938
+ if (Data_Type<Reference_T>::is_descendant(value))
854
939
  {
855
940
  return Convertible::Exact;
856
941
  }
@@ -869,23 +954,24 @@ namespace Rice::detail
869
954
  {
870
955
  case RUBY_T_DATA:
871
956
  {
872
- if (Data_Type<Pointer_T>::is_descendant(value))
957
+ if (Data_Type<Reference_T>::is_descendant(value))
873
958
  {
874
- return (unsigned int&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
959
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
960
+ return reference->get();
875
961
  }
876
962
  [[fallthrough]];
877
963
  }
878
964
  default:
879
965
  {
880
- this->converted_ = FromRubyFundamental<unsigned int>::convert(value);
881
- return this->converted_;
966
+ this->reference_ = Reference<unsigned int>(value);
967
+ return this->reference_.get();
882
968
  }
883
969
  }
884
970
  }
885
971
 
886
972
  private:
887
973
  Arg* arg_ = nullptr;
888
- unsigned int converted_ = 0;
974
+ Reference<unsigned int> reference_;
889
975
  };
890
976
 
891
977
  // =========== long ============
@@ -899,7 +985,7 @@ namespace Rice::detail
899
985
  {
900
986
  }
901
987
 
902
- Convertible is_convertible(VALUE value)
988
+ double is_convertible(VALUE value)
903
989
  {
904
990
  return FromRubyFundamental<long>::is_convertible(value);
905
991
  }
@@ -917,7 +1003,7 @@ namespace Rice::detail
917
1003
  class From_Ruby<long&>
918
1004
  {
919
1005
  public:
920
- using Pointer_T = Pointer<long>;
1006
+ using Reference_T = Reference<long>;
921
1007
 
922
1008
  From_Ruby() = default;
923
1009
 
@@ -925,13 +1011,13 @@ namespace Rice::detail
925
1011
  {
926
1012
  }
927
1013
 
928
- Convertible is_convertible(VALUE value)
1014
+ double is_convertible(VALUE value)
929
1015
  {
930
1016
  switch (rb_type(value))
931
1017
  {
932
1018
  case RUBY_T_DATA:
933
1019
  {
934
- if (Data_Type<Pointer_T>::is_descendant(value))
1020
+ if (Data_Type<Reference_T>::is_descendant(value))
935
1021
  {
936
1022
  return Convertible::Exact;
937
1023
  }
@@ -950,23 +1036,24 @@ namespace Rice::detail
950
1036
  {
951
1037
  case RUBY_T_DATA:
952
1038
  {
953
- if (Data_Type<Pointer_T>::is_descendant(value))
1039
+ if (Data_Type<Reference_T>::is_descendant(value))
954
1040
  {
955
- return (long&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
1041
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
1042
+ return reference->get();
956
1043
  }
957
1044
  [[fallthrough]];
958
1045
  }
959
1046
  default:
960
1047
  {
961
- this->converted_ = FromRubyFundamental<long>::convert(value);
962
- return this->converted_;
1048
+ this->reference_ = Reference<long>(value);
1049
+ return this->reference_.get();
963
1050
  }
964
1051
  }
965
1052
  }
966
1053
 
967
1054
  private:
968
1055
  Arg* arg_ = nullptr;
969
- long converted_ = 0;
1056
+ Reference<long> reference_;
970
1057
  };
971
1058
 
972
1059
  // =========== unsigned long ============
@@ -980,7 +1067,7 @@ namespace Rice::detail
980
1067
  {
981
1068
  }
982
1069
 
983
- Convertible is_convertible(VALUE value)
1070
+ double is_convertible(VALUE value)
984
1071
  {
985
1072
  return FromRubyFundamental<unsigned long>::is_convertible(value);
986
1073
  }
@@ -1005,7 +1092,7 @@ namespace Rice::detail
1005
1092
  class From_Ruby<unsigned long&>
1006
1093
  {
1007
1094
  public:
1008
- using Pointer_T = Pointer<unsigned long>;
1095
+ using Reference_T = Reference<unsigned long>;
1009
1096
 
1010
1097
  From_Ruby() = default;
1011
1098
 
@@ -1013,13 +1100,13 @@ namespace Rice::detail
1013
1100
  {
1014
1101
  }
1015
1102
 
1016
- Convertible is_convertible(VALUE value)
1103
+ double is_convertible(VALUE value)
1017
1104
  {
1018
1105
  switch (rb_type(value))
1019
1106
  {
1020
1107
  case RUBY_T_DATA:
1021
1108
  {
1022
- if (Data_Type<Pointer_T>::is_descendant(value))
1109
+ if (Data_Type<Reference_T>::is_descendant(value))
1023
1110
  {
1024
1111
  return Convertible::Exact;
1025
1112
  }
@@ -1038,23 +1125,24 @@ namespace Rice::detail
1038
1125
  {
1039
1126
  case RUBY_T_DATA:
1040
1127
  {
1041
- if (Data_Type<Pointer_T>::is_descendant(value))
1128
+ if (Data_Type<Reference_T>::is_descendant(value))
1042
1129
  {
1043
- return (unsigned long&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
1130
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
1131
+ return reference->get();
1044
1132
  }
1045
1133
  [[fallthrough]];
1046
1134
  }
1047
1135
  default:
1048
1136
  {
1049
- this->converted_ = FromRubyFundamental<unsigned long>::convert(value);
1050
- return this->converted_;
1137
+ this->reference_ = Reference<unsigned long>(value);
1138
+ return this->reference_.get();
1051
1139
  }
1052
1140
  }
1053
1141
  }
1054
1142
 
1055
1143
  private:
1056
1144
  Arg* arg_ = nullptr;
1057
- unsigned long converted_ = 0;
1145
+ Reference<unsigned long> reference_;
1058
1146
  };
1059
1147
 
1060
1148
  // =========== unsigned long long ============
@@ -1068,7 +1156,7 @@ namespace Rice::detail
1068
1156
  {
1069
1157
  }
1070
1158
 
1071
- Convertible is_convertible(VALUE value)
1159
+ double is_convertible(VALUE value)
1072
1160
  {
1073
1161
  return FromRubyFundamental<unsigned long long>::is_convertible(value);
1074
1162
  }
@@ -1093,7 +1181,7 @@ namespace Rice::detail
1093
1181
  class From_Ruby<unsigned long long&>
1094
1182
  {
1095
1183
  public:
1096
- using Pointer_T = Pointer<unsigned long long>;
1184
+ using Reference_T = Reference<unsigned long long>;
1097
1185
 
1098
1186
  From_Ruby() = default;
1099
1187
 
@@ -1101,13 +1189,13 @@ namespace Rice::detail
1101
1189
  {
1102
1190
  }
1103
1191
 
1104
- Convertible is_convertible(VALUE value)
1192
+ double is_convertible(VALUE value)
1105
1193
  {
1106
1194
  switch (rb_type(value))
1107
1195
  {
1108
1196
  case RUBY_T_DATA:
1109
1197
  {
1110
- if (Data_Type<Pointer_T>::is_descendant(value))
1198
+ if (Data_Type<Reference_T>::is_descendant(value))
1111
1199
  {
1112
1200
  return Convertible::Exact;
1113
1201
  }
@@ -1126,9 +1214,10 @@ namespace Rice::detail
1126
1214
  {
1127
1215
  case RUBY_T_DATA:
1128
1216
  {
1129
- if (Data_Type<Pointer_T>::is_descendant(value))
1217
+ if (Data_Type<Reference_T>::is_descendant(value))
1130
1218
  {
1131
- return (unsigned long long&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
1219
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
1220
+ return reference->get();
1132
1221
  }
1133
1222
  [[fallthrough]];
1134
1223
  }
@@ -1144,7 +1233,7 @@ namespace Rice::detail
1144
1233
  Arg* arg_ = nullptr;
1145
1234
  unsigned long long converted_ = 0;
1146
1235
  };
1147
-
1236
+
1148
1237
  // =========== long long ============
1149
1238
  template<>
1150
1239
  class From_Ruby<long long>
@@ -1156,7 +1245,7 @@ namespace Rice::detail
1156
1245
  {
1157
1246
  }
1158
1247
 
1159
- Convertible is_convertible(VALUE value)
1248
+ double is_convertible(VALUE value)
1160
1249
  {
1161
1250
  return FromRubyFundamental<long long>::is_convertible(value);
1162
1251
  }
@@ -1174,7 +1263,7 @@ namespace Rice::detail
1174
1263
  class From_Ruby<long long&>
1175
1264
  {
1176
1265
  public:
1177
- using Pointer_T = Pointer<long long>;
1266
+ using Reference_T = Reference<long long>;
1178
1267
 
1179
1268
  From_Ruby() = default;
1180
1269
 
@@ -1182,13 +1271,13 @@ namespace Rice::detail
1182
1271
  {
1183
1272
  }
1184
1273
 
1185
- Convertible is_convertible(VALUE value)
1274
+ double is_convertible(VALUE value)
1186
1275
  {
1187
1276
  switch (rb_type(value))
1188
1277
  {
1189
1278
  case RUBY_T_DATA:
1190
1279
  {
1191
- if (Data_Type<Pointer_T>::is_descendant(value))
1280
+ if (Data_Type<Reference_T>::is_descendant(value))
1192
1281
  {
1193
1282
  return Convertible::Exact;
1194
1283
  }
@@ -1207,23 +1296,24 @@ namespace Rice::detail
1207
1296
  {
1208
1297
  case RUBY_T_DATA:
1209
1298
  {
1210
- if (Data_Type<Pointer_T>::is_descendant(value))
1299
+ if (Data_Type<Reference_T>::is_descendant(value))
1211
1300
  {
1212
- return (long long&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
1301
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
1302
+ return reference->get();
1213
1303
  }
1214
1304
  [[fallthrough]];
1215
1305
  }
1216
1306
  default:
1217
1307
  {
1218
- this->converted_ = FromRubyFundamental<long long>::convert(value);
1219
- return this->converted_;
1308
+ this->reference_ = Reference<long long>(value);
1309
+ return this->reference_.get();
1220
1310
  }
1221
1311
  }
1222
1312
  }
1223
1313
 
1224
1314
  private:
1225
1315
  Arg* arg_ = nullptr;
1226
- long long converted_ = 0;
1316
+ Reference<long long> reference_;
1227
1317
  };
1228
1318
 
1229
1319
  // =========== short ============
@@ -1237,7 +1327,7 @@ namespace Rice::detail
1237
1327
  {
1238
1328
  }
1239
1329
 
1240
- Convertible is_convertible(VALUE value)
1330
+ double is_convertible(VALUE value)
1241
1331
  {
1242
1332
  return FromRubyFundamental<short>::is_convertible(value);
1243
1333
  }
@@ -1255,7 +1345,7 @@ namespace Rice::detail
1255
1345
  class From_Ruby<short&>
1256
1346
  {
1257
1347
  public:
1258
- using Pointer_T = Pointer<short>;
1348
+ using Reference_T = Reference<short>;
1259
1349
 
1260
1350
  From_Ruby() = default;
1261
1351
 
@@ -1263,13 +1353,13 @@ namespace Rice::detail
1263
1353
  {
1264
1354
  }
1265
1355
 
1266
- Convertible is_convertible(VALUE value)
1356
+ double is_convertible(VALUE value)
1267
1357
  {
1268
1358
  switch (rb_type(value))
1269
1359
  {
1270
1360
  case RUBY_T_DATA:
1271
1361
  {
1272
- if (Data_Type<Pointer_T>::is_descendant(value))
1362
+ if (Data_Type<Reference_T>::is_descendant(value))
1273
1363
  {
1274
1364
  return Convertible::Exact;
1275
1365
  }
@@ -1288,23 +1378,24 @@ namespace Rice::detail
1288
1378
  {
1289
1379
  case RUBY_T_DATA:
1290
1380
  {
1291
- if (Data_Type<Pointer_T>::is_descendant(value))
1381
+ if (Data_Type<Reference_T>::is_descendant(value))
1292
1382
  {
1293
- return (short&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
1383
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
1384
+ return reference->get();
1294
1385
  }
1295
1386
  [[fallthrough]];
1296
1387
  }
1297
1388
  default:
1298
1389
  {
1299
- this->converted_ = FromRubyFundamental<short>::convert(value);
1300
- return this->converted_;
1390
+ this->reference_ = Reference<short>(value);
1391
+ return this->reference_.get();
1301
1392
  }
1302
1393
  }
1303
1394
  }
1304
1395
 
1305
1396
  private:
1306
1397
  Arg* arg_ = nullptr;
1307
- short converted_ = 0;
1398
+ Reference<short> reference_;
1308
1399
  };
1309
1400
 
1310
1401
  // =========== unsigned short ============
@@ -1318,7 +1409,7 @@ namespace Rice::detail
1318
1409
  {
1319
1410
  }
1320
1411
 
1321
- Convertible is_convertible(VALUE value)
1412
+ double is_convertible(VALUE value)
1322
1413
  {
1323
1414
  return FromRubyFundamental<unsigned short>::is_convertible(value);
1324
1415
  }
@@ -1336,7 +1427,7 @@ namespace Rice::detail
1336
1427
  class From_Ruby<unsigned short&>
1337
1428
  {
1338
1429
  public:
1339
- using Pointer_T = Pointer<unsigned short>;
1430
+ using Reference_T = Reference<unsigned short>;
1340
1431
 
1341
1432
  From_Ruby() = default;
1342
1433
 
@@ -1344,13 +1435,13 @@ namespace Rice::detail
1344
1435
  {
1345
1436
  }
1346
1437
 
1347
- Convertible is_convertible(VALUE value)
1438
+ double is_convertible(VALUE value)
1348
1439
  {
1349
1440
  switch (rb_type(value))
1350
1441
  {
1351
1442
  case RUBY_T_DATA:
1352
1443
  {
1353
- if (Data_Type<Pointer_T>::is_descendant(value))
1444
+ if (Data_Type<Reference_T>::is_descendant(value))
1354
1445
  {
1355
1446
  return Convertible::Exact;
1356
1447
  }
@@ -1369,23 +1460,24 @@ namespace Rice::detail
1369
1460
  {
1370
1461
  case RUBY_T_DATA:
1371
1462
  {
1372
- if (Data_Type<Pointer_T>::is_descendant(value))
1463
+ if (Data_Type<Reference_T>::is_descendant(value))
1373
1464
  {
1374
- return (unsigned short&)*unwrap<Pointer_T>(value, Data_Type<Pointer_T>::ruby_data_type(), false);
1465
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
1466
+ return reference->get();
1375
1467
  }
1376
1468
  [[fallthrough]];
1377
1469
  }
1378
1470
  default:
1379
1471
  {
1380
- this->converted_ = FromRubyFundamental<unsigned short>::convert(value);
1381
- return this->converted_;
1472
+ this->reference_ = Reference<unsigned short>(value);
1473
+ return this->reference_.get();
1382
1474
  }
1383
1475
  }
1384
1476
  }
1385
1477
 
1386
1478
  private:
1387
1479
  Arg* arg_ = nullptr;
1388
- unsigned short converted_ = 0;
1480
+ Reference<unsigned short> reference_;
1389
1481
  };
1390
1482
 
1391
1483
  // =========== std::nullptr_t ============
@@ -1403,7 +1495,7 @@ namespace Rice::detail
1403
1495
  }
1404
1496
  }
1405
1497
 
1406
- Convertible is_convertible(VALUE value)
1498
+ double is_convertible(VALUE value)
1407
1499
  {
1408
1500
  if (this->arg_ && this->arg_->isOpaque())
1409
1501
  {
@@ -1445,7 +1537,7 @@ namespace Rice::detail
1445
1537
  }
1446
1538
  default:
1447
1539
  {
1448
- throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
1540
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
1449
1541
  detail::protect(rb_obj_classname, value), "nil");
1450
1542
  }
1451
1543
  }
@@ -1455,6 +1547,46 @@ namespace Rice::detail
1455
1547
  };
1456
1548
 
1457
1549
  // =========== void ============
1550
+ template<>
1551
+ class From_Ruby<void>
1552
+ {
1553
+ public:
1554
+ From_Ruby()
1555
+ {
1556
+ };
1557
+
1558
+ explicit From_Ruby(Arg* arg) : arg_(arg)
1559
+ {
1560
+ if (this->arg_->isOwner())
1561
+ {
1562
+ throw Exception(rb_eTypeError, "Cannot transfer ownership of C++ void pointer");
1563
+ }
1564
+ }
1565
+
1566
+ double is_convertible(VALUE value)
1567
+ {
1568
+ switch (rb_type(value))
1569
+ {
1570
+ case RUBY_T_NIL:
1571
+ {
1572
+ return Convertible::Exact;
1573
+ break;
1574
+ }
1575
+ default:
1576
+ {
1577
+ return Convertible::None;
1578
+ }
1579
+ }
1580
+ }
1581
+
1582
+ void convert(VALUE)
1583
+ {
1584
+ // Nothing to do
1585
+ }
1586
+ private:
1587
+ Arg* arg_ = nullptr;
1588
+ };
1589
+
1458
1590
  template<>
1459
1591
  class From_Ruby<void*>
1460
1592
  {
@@ -1471,7 +1603,7 @@ namespace Rice::detail
1471
1603
  }
1472
1604
  }
1473
1605
 
1474
- Convertible is_convertible(VALUE value)
1606
+ double is_convertible(VALUE value)
1475
1607
  {
1476
1608
  if (this->arg_ && this->arg_->isOpaque())
1477
1609
  {
@@ -1482,21 +1614,22 @@ namespace Rice::detail
1482
1614
  {
1483
1615
  case RUBY_T_DATA:
1484
1616
  {
1485
- return Convertible::Cast;
1486
- break;
1617
+ return Convertible::Exact;
1487
1618
  }
1488
1619
  case RUBY_T_STRING:
1489
1620
  {
1490
1621
  if (RB_ENCODING_IS_ASCII8BIT(value))
1622
+ {
1491
1623
  return Convertible::Exact;
1624
+ }
1492
1625
  else
1626
+ {
1493
1627
  return Convertible::None;
1494
- break;
1628
+ }
1495
1629
  }
1496
1630
  case RUBY_T_NIL:
1497
1631
  {
1498
1632
  return Convertible::Exact;
1499
- break;
1500
1633
  }
1501
1634
  default:
1502
1635
  {
@@ -1550,7 +1683,7 @@ namespace Rice::detail
1550
1683
  }
1551
1684
  default:
1552
1685
  {
1553
- throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
1686
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
1554
1687
  detail::protect(rb_obj_classname, value), "pointer");
1555
1688
  }
1556
1689
  }