rice 4.3.2 → 4.5.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 (151) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -25
  3. data/README.md +7 -2
  4. data/Rakefile +7 -1
  5. data/include/rice/rice.hpp +7321 -4470
  6. data/include/rice/stl.hpp +769 -222
  7. data/lib/mkmf-rice.rb +37 -95
  8. data/rice/Address_Registration_Guard.hpp +72 -3
  9. data/rice/Arg.hpp +19 -5
  10. data/rice/Arg.ipp +24 -0
  11. data/rice/Callback.hpp +21 -0
  12. data/rice/Callback.ipp +13 -0
  13. data/rice/Constructor.hpp +4 -27
  14. data/rice/Constructor.ipp +79 -0
  15. data/rice/Data_Object.hpp +74 -3
  16. data/rice/Data_Object.ipp +324 -32
  17. data/rice/Data_Type.hpp +215 -3
  18. data/rice/Data_Type.ipp +125 -64
  19. data/rice/Director.hpp +0 -2
  20. data/rice/Enum.hpp +4 -6
  21. data/rice/Enum.ipp +101 -57
  22. data/rice/Exception.hpp +62 -2
  23. data/rice/Exception.ipp +7 -12
  24. data/rice/JumpException.hpp +44 -0
  25. data/rice/JumpException.ipp +48 -0
  26. data/rice/MemoryView.hpp +11 -0
  27. data/rice/MemoryView.ipp +43 -0
  28. data/rice/Return.hpp +6 -26
  29. data/rice/Return.ipp +10 -16
  30. data/rice/detail/DefaultHandler.hpp +12 -0
  31. data/rice/detail/DefaultHandler.ipp +8 -0
  32. data/rice/detail/HandlerRegistry.hpp +5 -35
  33. data/rice/detail/HandlerRegistry.ipp +7 -11
  34. data/rice/detail/InstanceRegistry.hpp +1 -4
  35. data/rice/detail/MethodInfo.hpp +15 -5
  36. data/rice/detail/MethodInfo.ipp +78 -6
  37. data/rice/detail/Native.hpp +32 -0
  38. data/rice/detail/Native.ipp +129 -0
  39. data/rice/detail/NativeAttributeGet.hpp +51 -0
  40. data/rice/detail/NativeAttributeGet.ipp +51 -0
  41. data/rice/detail/NativeAttributeSet.hpp +43 -0
  42. data/rice/detail/NativeAttributeSet.ipp +82 -0
  43. data/rice/detail/NativeCallbackFFI.hpp +55 -0
  44. data/rice/detail/NativeCallbackFFI.ipp +151 -0
  45. data/rice/detail/NativeCallbackSimple.hpp +30 -0
  46. data/rice/detail/NativeCallbackSimple.ipp +29 -0
  47. data/rice/detail/NativeFunction.hpp +20 -21
  48. data/rice/detail/NativeFunction.ipp +199 -64
  49. data/rice/detail/NativeIterator.hpp +8 -11
  50. data/rice/detail/NativeIterator.ipp +27 -31
  51. data/rice/detail/NativeRegistry.hpp +24 -17
  52. data/rice/detail/NativeRegistry.ipp +23 -56
  53. data/rice/detail/Proc.hpp +4 -0
  54. data/rice/detail/Proc.ipp +85 -0
  55. data/rice/detail/Registries.hpp +0 -7
  56. data/rice/detail/Registries.ipp +0 -18
  57. data/rice/detail/RubyFunction.hpp +0 -3
  58. data/rice/detail/RubyFunction.ipp +4 -8
  59. data/rice/detail/RubyType.hpp +19 -0
  60. data/rice/detail/RubyType.ipp +187 -0
  61. data/rice/detail/TupleIterator.hpp +14 -0
  62. data/rice/detail/Type.hpp +5 -6
  63. data/rice/detail/Type.ipp +150 -33
  64. data/rice/detail/TypeRegistry.hpp +15 -7
  65. data/rice/detail/TypeRegistry.ipp +105 -12
  66. data/rice/detail/Wrapper.hpp +6 -5
  67. data/rice/detail/Wrapper.ipp +45 -23
  68. data/rice/detail/cpp_protect.hpp +5 -6
  69. data/rice/detail/default_allocation_func.ipp +0 -2
  70. data/rice/detail/from_ruby.hpp +37 -3
  71. data/rice/detail/from_ruby.ipp +911 -454
  72. data/rice/detail/ruby.hpp +18 -0
  73. data/rice/detail/to_ruby.hpp +41 -3
  74. data/rice/detail/to_ruby.ipp +437 -113
  75. data/rice/global_function.hpp +0 -4
  76. data/rice/global_function.ipp +1 -2
  77. data/rice/rice.hpp +105 -22
  78. data/rice/ruby_mark.hpp +4 -3
  79. data/rice/stl.hpp +4 -0
  80. data/test/embed_ruby.cpp +4 -1
  81. data/test/extconf.rb +2 -0
  82. data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
  83. data/test/test_Address_Registration_Guard.cpp +5 -0
  84. data/test/test_Array.cpp +12 -1
  85. data/test/test_Attribute.cpp +103 -21
  86. data/test/test_Builtin_Object.cpp +5 -0
  87. data/test/test_Callback.cpp +231 -0
  88. data/test/test_Class.cpp +5 -31
  89. data/test/test_Constructor.cpp +69 -6
  90. data/test/test_Data_Object.cpp +9 -4
  91. data/test/test_Data_Type.cpp +428 -64
  92. data/test/test_Director.cpp +10 -5
  93. data/test/test_Enum.cpp +152 -40
  94. data/test/test_Exception.cpp +235 -0
  95. data/test/test_File.cpp +70 -0
  96. data/test/test_From_Ruby.cpp +542 -0
  97. data/test/test_Hash.cpp +5 -0
  98. data/test/test_Identifier.cpp +5 -0
  99. data/test/test_Inheritance.cpp +6 -1
  100. data/test/test_Iterator.cpp +5 -0
  101. data/test/test_JumpException.cpp +22 -0
  102. data/test/test_Keep_Alive.cpp +6 -1
  103. data/test/test_Keep_Alive_No_Wrapper.cpp +5 -0
  104. data/test/test_Memory_Management.cpp +5 -0
  105. data/test/test_Module.cpp +118 -64
  106. data/test/test_Native_Registry.cpp +2 -33
  107. data/test/test_Object.cpp +5 -0
  108. data/test/test_Overloads.cpp +631 -0
  109. data/test/test_Ownership.cpp +67 -4
  110. data/test/test_Proc.cpp +45 -0
  111. data/test/test_Self.cpp +5 -0
  112. data/test/test_Stl_Exception.cpp +109 -0
  113. data/test/test_Stl_Map.cpp +22 -8
  114. data/test/test_Stl_Optional.cpp +5 -0
  115. data/test/test_Stl_Pair.cpp +7 -2
  116. data/test/test_Stl_Reference_Wrapper.cpp +5 -0
  117. data/test/test_Stl_SmartPointer.cpp +210 -5
  118. data/test/test_Stl_String.cpp +5 -0
  119. data/test/test_Stl_String_View.cpp +5 -0
  120. data/test/test_Stl_Type.cpp +147 -0
  121. data/test/test_Stl_Unordered_Map.cpp +18 -7
  122. data/test/test_Stl_Variant.cpp +5 -0
  123. data/test/test_Stl_Vector.cpp +130 -8
  124. data/test/test_String.cpp +5 -0
  125. data/test/test_Struct.cpp +5 -0
  126. data/test/test_Symbol.cpp +5 -0
  127. data/test/test_Template.cpp +192 -0
  128. data/test/test_To_Ruby.cpp +152 -0
  129. data/test/test_Tracking.cpp +1 -0
  130. data/test/test_Type.cpp +100 -0
  131. data/test/test_global_functions.cpp +53 -6
  132. data/test/unittest.cpp +8 -0
  133. metadata +37 -20
  134. data/lib/version.rb +0 -3
  135. data/rice/Address_Registration_Guard_defn.hpp +0 -79
  136. data/rice/Data_Object_defn.hpp +0 -84
  137. data/rice/Data_Type_defn.hpp +0 -190
  138. data/rice/Exception_defn.hpp +0 -68
  139. data/rice/HandlerRegistration.hpp +0 -15
  140. data/rice/Identifier.hpp +0 -50
  141. data/rice/Identifier.ipp +0 -29
  142. data/rice/detail/ExceptionHandler.hpp +0 -8
  143. data/rice/detail/ExceptionHandler.ipp +0 -28
  144. data/rice/detail/ExceptionHandler_defn.hpp +0 -77
  145. data/rice/detail/Jump_Tag.hpp +0 -21
  146. data/rice/detail/NativeAttribute.hpp +0 -64
  147. data/rice/detail/NativeAttribute.ipp +0 -112
  148. data/rice/detail/from_ruby_defn.hpp +0 -38
  149. data/rice/detail/to_ruby_defn.hpp +0 -48
  150. data/test/test_Jump_Tag.cpp +0 -17
  151. data/test/test_To_From_Ruby.cpp +0 -399
@@ -1,5 +1,3 @@
1
- #include "RubyFunction.hpp"
2
- #include "../Return.hpp"
3
1
 
4
2
  namespace Rice
5
3
  {
@@ -9,172 +7,308 @@ namespace Rice
9
7
  class To_Ruby<void>
10
8
  {
11
9
  public:
12
- VALUE convert(void const*)
10
+ To_Ruby() = default;
11
+
12
+ explicit To_Ruby(Arg* arg) : arg_(arg)
13
+ {
14
+ }
15
+
16
+ VALUE convert(const void*)
13
17
  {
18
+ throw std::runtime_error("Converting from void pointer is not implemented");
14
19
  return Qnil;
15
20
  }
21
+
22
+ private:
23
+ Arg* arg_ = nullptr;
16
24
  };
17
25
 
18
26
  template<>
19
27
  class To_Ruby<std::nullptr_t>
20
28
  {
21
29
  public:
30
+ To_Ruby() = default;
31
+
32
+ explicit To_Ruby(Arg* arg) : arg_(arg)
33
+ {
34
+ }
35
+
22
36
  VALUE convert(std::nullptr_t const)
23
37
  {
24
38
  return Qnil;
25
39
  }
40
+
41
+ private:
42
+ Arg* arg_ = nullptr;
26
43
  };
27
44
 
28
45
  template<>
29
46
  class To_Ruby<short>
30
47
  {
31
48
  public:
32
- VALUE convert(short const& x)
49
+ To_Ruby() = default;
50
+
51
+ explicit To_Ruby(Arg* arg) : arg_(arg)
52
+ {
53
+ }
54
+
55
+ VALUE convert(const short& native)
33
56
  {
34
57
  #ifdef rb_int2num_inline
35
- return protect(rb_int2num_inline, (int)x);
58
+ return protect(rb_int2num_inline, (int)native);
36
59
  #else
37
- return RB_INT2NUM(x);
60
+ return RB_INT2NUM(native);
38
61
  #endif
39
62
  }
63
+
64
+ private:
65
+ Arg* arg_ = nullptr;
40
66
  };
41
67
 
42
68
  template<>
43
69
  class To_Ruby<short&>
44
70
  {
45
71
  public:
46
- VALUE convert(short const& x)
72
+ To_Ruby() = default;
73
+
74
+ explicit To_Ruby(Arg* arg) : arg_(arg)
75
+ {
76
+ }
77
+
78
+ VALUE convert(const short& native)
47
79
  {
48
80
  #ifdef rb_int2num_inline
49
- return protect(rb_int2num_inline, (int)x);
81
+ return protect(rb_int2num_inline, (int)native);
50
82
  #else
51
- return RB_INT2NUM(x);
83
+ return RB_INT2NUM(native);
52
84
  #endif
53
85
  }
86
+
87
+ private:
88
+ Arg* arg_ = nullptr;
54
89
  };
55
90
 
56
91
  template<>
57
92
  class To_Ruby<int>
58
93
  {
59
94
  public:
60
- VALUE convert(int const& x)
95
+ To_Ruby() = default;
96
+
97
+ explicit To_Ruby(Arg* arg) : arg_(arg)
98
+ {
99
+ }
100
+
101
+ VALUE convert(const int& native)
102
+ {
103
+ #ifdef rb_int2num_inline
104
+ return protect(rb_int2num_inline, (int)native);
105
+ #else
106
+ return RB_INT2NUM(native);
107
+ #endif
108
+ }
109
+
110
+ VALUE convert(const volatile int& native)
61
111
  {
62
112
  #ifdef rb_int2num_inline
63
- return protect(rb_int2num_inline, (int)x);
113
+ return protect(rb_int2num_inline, (int)native);
64
114
  #else
65
- return RB_INT2NUM(x);
115
+ return RB_INT2NUM(native);
66
116
  #endif
67
117
  }
118
+
119
+ private:
120
+ Arg* arg_ = nullptr;
68
121
  };
69
122
 
70
123
  template<>
71
124
  class To_Ruby<int&>
72
125
  {
73
126
  public:
74
- VALUE convert(int const& x)
127
+ To_Ruby() = default;
128
+
129
+ explicit To_Ruby(Arg* arg) : arg_(arg)
130
+ {
131
+ }
132
+
133
+ VALUE convert(const int& native)
75
134
  {
76
135
  #ifdef rb_int2num_inline
77
- return protect(rb_int2num_inline, (int)x);
136
+ return protect(rb_int2num_inline, (int)native);
78
137
  #else
79
- return RB_INT2NUM(x);
138
+ return RB_INT2NUM(native);
80
139
  #endif
81
140
  }
141
+
142
+ private:
143
+ Arg* arg_ = nullptr;
82
144
  };
83
145
 
84
146
  template<>
85
147
  class To_Ruby<long>
86
148
  {
87
149
  public:
88
- VALUE convert(long const& x)
150
+ To_Ruby() = default;
151
+
152
+ explicit To_Ruby(Arg* arg) : arg_(arg)
153
+ {
154
+ }
155
+
156
+ VALUE convert(const long& native)
89
157
  {
90
- return protect(rb_long2num_inline, x);
158
+ return protect(rb_long2num_inline, native);
91
159
  }
160
+
161
+ private:
162
+ Arg* arg_ = nullptr;
92
163
  };
93
164
 
94
165
  template<>
95
166
  class To_Ruby<long&>
96
167
  {
97
168
  public:
98
- VALUE convert(long const& x)
169
+ To_Ruby() = default;
170
+
171
+ explicit To_Ruby(Arg* arg) : arg_(arg)
99
172
  {
100
- return protect(rb_long2num_inline, x);
101
173
  }
174
+
175
+ VALUE convert(const long& native)
176
+ {
177
+ return protect(rb_long2num_inline, native);
178
+ }
179
+
180
+ private:
181
+ Arg* arg_ = nullptr;
102
182
  };
103
183
 
104
184
  template<>
105
185
  class To_Ruby<long long>
106
186
  {
107
187
  public:
108
- VALUE convert(long long const& x)
188
+ To_Ruby() = default;
189
+
190
+ explicit To_Ruby(Arg* arg) : arg_(arg)
191
+ {
192
+ }
193
+
194
+ VALUE convert(const long long& native)
109
195
  {
110
- return protect(rb_ll2inum, x);
196
+ return protect(rb_ll2inum, native);
111
197
  }
198
+
199
+ private:
200
+ Arg* arg_ = nullptr;
112
201
  };
113
202
 
114
203
  template<>
115
204
  class To_Ruby<long long&>
116
205
  {
117
206
  public:
118
- VALUE convert(long long const& x)
207
+ To_Ruby() = default;
208
+
209
+ explicit To_Ruby(Arg* arg) : arg_(arg)
119
210
  {
120
- return protect(rb_ll2inum, x);
121
211
  }
212
+
213
+ VALUE convert(const long long& native)
214
+ {
215
+ return protect(rb_ll2inum, native);
216
+ }
217
+
218
+ private:
219
+ Arg* arg_ = nullptr;
122
220
  };
123
221
 
124
222
  template<>
125
223
  class To_Ruby<unsigned short>
126
224
  {
127
225
  public:
128
- VALUE convert(unsigned short const& x)
226
+ To_Ruby() = default;
227
+
228
+ explicit To_Ruby(Arg* arg) : arg_(arg)
229
+ {
230
+ }
231
+
232
+ VALUE convert(const unsigned short& native)
129
233
  {
130
234
  #ifdef rb_int2num_inline
131
- return protect(rb_uint2num_inline, (unsigned int)x);
235
+ return protect(rb_uint2num_inline, (unsigned int)native);
132
236
  #else
133
- return RB_UINT2NUM(x);
237
+ return RB_UINT2NUM(native);
134
238
  #endif
135
239
  }
240
+
241
+ private:
242
+ Arg* arg_ = nullptr;
136
243
  };
137
244
 
138
245
  template<>
139
246
  class To_Ruby<unsigned short&>
140
247
  {
141
248
  public:
142
- VALUE convert(unsigned short const& x)
249
+ To_Ruby() = default;
250
+
251
+ explicit To_Ruby(Arg* arg) : arg_(arg)
252
+ {
253
+ }
254
+
255
+ VALUE convert(const unsigned short& native)
143
256
  {
144
257
  #ifdef rb_int2num_inline
145
- return protect(rb_uint2num_inline, (unsigned int)x);
258
+ return protect(rb_uint2num_inline, (unsigned int)native);
146
259
  #else
147
- return RB_UINT2NUM(x);
260
+ return RB_UINT2NUM(native);
148
261
  #endif
149
262
  }
263
+
264
+ private:
265
+ Arg* arg_ = nullptr;
150
266
  };
151
267
 
152
268
  template<>
153
269
  class To_Ruby<unsigned int>
154
270
  {
155
271
  public:
156
- VALUE convert(unsigned int const& x)
272
+ To_Ruby() = default;
273
+
274
+ explicit To_Ruby(Arg* arg) : arg_(arg)
275
+ {
276
+ }
277
+
278
+ VALUE convert(const unsigned int& native)
157
279
  {
158
280
  #ifdef rb_int2num_inline
159
- return protect(rb_uint2num_inline, (unsigned int)x);
281
+ return protect(rb_uint2num_inline, (unsigned int)native);
160
282
  #else
161
- return RB_UINT2NUM(x);
283
+ return RB_UINT2NUM(native);
162
284
  #endif
163
285
  }
286
+
287
+ private:
288
+ Arg* arg_ = nullptr;
164
289
  };
165
290
 
166
291
  template<>
167
292
  class To_Ruby<unsigned int&>
168
293
  {
169
294
  public:
170
- VALUE convert(unsigned int const& x)
295
+ To_Ruby() = default;
296
+
297
+ explicit To_Ruby(Arg* arg) : arg_(arg)
298
+ {
299
+ }
300
+
301
+ VALUE convert(const unsigned int& native)
171
302
  {
172
303
  #ifdef rb_int2num_inline
173
- return protect(rb_uint2num_inline, (unsigned int)x);
304
+ return protect(rb_uint2num_inline, (unsigned int)native);
174
305
  #else
175
- return RB_UINT2NUM(x);
306
+ return RB_UINT2NUM(native);
176
307
  #endif
177
308
  }
309
+
310
+ private:
311
+ Arg* arg_ = nullptr;
178
312
  };
179
313
 
180
314
  template<>
@@ -183,24 +317,24 @@ namespace Rice
183
317
  public:
184
318
  To_Ruby() = default;
185
319
 
186
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
320
+ explicit To_Ruby(Arg* arg) : arg_(arg)
187
321
  {
188
322
  }
189
323
 
190
- VALUE convert(unsigned long const& x)
324
+ VALUE convert(const unsigned long& native)
191
325
  {
192
- if (this->returnInfo_ && this->returnInfo_->isValue())
326
+ if (this->arg_ && this->arg_->isValue())
193
327
  {
194
- return x;
328
+ return native;
195
329
  }
196
330
  else
197
331
  {
198
- return protect(rb_ulong2num_inline, x);
332
+ return protect(rb_ulong2num_inline, native);
199
333
  }
200
334
  }
201
335
 
202
336
  private:
203
- Return* returnInfo_ = nullptr;
337
+ Arg* arg_ = nullptr;
204
338
  };
205
339
 
206
340
  template<>
@@ -209,24 +343,24 @@ namespace Rice
209
343
  public:
210
344
  To_Ruby() = default;
211
345
 
212
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
346
+ explicit To_Ruby(Arg* arg) : arg_(arg)
213
347
  {
214
348
  }
215
349
 
216
- VALUE convert(unsigned long const& x)
350
+ VALUE convert(const unsigned long& native)
217
351
  {
218
- if (this->returnInfo_ && this->returnInfo_->isValue())
352
+ if (this->arg_ && this->arg_->isValue())
219
353
  {
220
- return x;
354
+ return native;
221
355
  }
222
356
  else
223
357
  {
224
- return protect(rb_ulong2num_inline, x);
358
+ return protect(rb_ulong2num_inline, native);
225
359
  }
226
360
  }
227
361
 
228
362
  private:
229
- Return* returnInfo_ = nullptr;
363
+ Arg* arg_ = nullptr;
230
364
  };
231
365
 
232
366
  template<>
@@ -235,24 +369,35 @@ namespace Rice
235
369
  public:
236
370
  To_Ruby() = default;
237
371
 
238
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
372
+ explicit To_Ruby(Arg* arg) : arg_(arg)
239
373
  {
240
374
  }
241
375
 
242
- VALUE convert(unsigned long long const& x)
376
+ VALUE convert(const unsigned long long& native)
243
377
  {
244
- if (this->returnInfo_ && this->returnInfo_->isValue())
378
+ if (this->arg_ && this->arg_->isValue())
245
379
  {
246
- return x;
380
+ return native;
247
381
  }
248
382
  else
249
383
  {
250
- return protect(rb_ull2inum, (unsigned long long)x);
384
+ return protect(rb_ull2inum, (unsigned long long)native);
251
385
  }
252
386
  }
253
387
 
388
+ VALUE convert(const volatile unsigned long long& native)
389
+ {
390
+ if (this->arg_ && this->arg_->isValue())
391
+ {
392
+ return native;
393
+ }
394
+ else
395
+ {
396
+ return protect(rb_ull2inum, (unsigned long long)native);
397
+ }
398
+ }
254
399
  private:
255
- Return* returnInfo_ = nullptr;
400
+ Arg* arg_ = nullptr;
256
401
  };
257
402
 
258
403
  template<>
@@ -261,188 +406,367 @@ namespace Rice
261
406
  public:
262
407
  To_Ruby() = default;
263
408
 
264
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
409
+ explicit To_Ruby(Arg* arg) : arg_(arg)
265
410
  {
266
411
  }
267
412
 
268
- VALUE convert(unsigned long long const& x)
413
+ VALUE convert(const unsigned long long& native)
269
414
  {
270
- if (this->returnInfo_ && this->returnInfo_->isValue())
415
+ if (this->arg_ && this->arg_->isValue())
271
416
  {
272
- return x;
417
+ return native;
273
418
  }
274
419
  else
275
420
  {
276
- return protect(rb_ull2inum, (unsigned long long)x);
421
+ return protect(rb_ull2inum, (unsigned long long)native);
277
422
  }
278
423
  }
279
424
 
280
425
  private:
281
- Return* returnInfo_ = nullptr;
426
+ Arg* arg_ = nullptr;
282
427
  };
283
428
 
284
429
  template<>
285
430
  class To_Ruby<float>
286
431
  {
287
432
  public:
288
- VALUE convert(float const& x)
433
+ To_Ruby() = default;
434
+
435
+ explicit To_Ruby(Arg* arg) : arg_(arg)
289
436
  {
290
- return protect(rb_float_new, (double)x);
291
437
  }
438
+
439
+ VALUE convert(const float& native)
440
+ {
441
+ return protect(rb_float_new, (double)native);
442
+ }
443
+
444
+ private:
445
+ Arg* arg_ = nullptr;
292
446
  };
293
447
 
294
448
  template<>
295
449
  class To_Ruby<float&>
296
450
  {
297
451
  public:
298
- VALUE convert(float const& x)
452
+ To_Ruby() = default;
453
+
454
+ explicit To_Ruby(Arg* arg) : arg_(arg)
455
+ {
456
+ }
457
+
458
+ VALUE convert(const float& native)
299
459
  {
300
- return protect(rb_float_new, (double)x);
460
+ return protect(rb_float_new, (double)native);
301
461
  }
462
+
463
+ private:
464
+ Arg* arg_ = nullptr;
302
465
  };
303
466
 
304
467
  template<>
305
468
  class To_Ruby<double>
306
469
  {
307
470
  public:
308
- VALUE convert(double const& x)
471
+ To_Ruby() = default;
472
+
473
+ explicit To_Ruby(Arg* arg) : arg_(arg)
309
474
  {
310
- return protect(rb_float_new, x);
311
475
  }
476
+
477
+ VALUE convert(const double& native)
478
+ {
479
+ return protect(rb_float_new, native);
480
+ }
481
+
482
+ private:
483
+ Arg* arg_ = nullptr;
312
484
  };
313
485
 
314
486
  template<>
315
487
  class To_Ruby<double&>
316
488
  {
317
489
  public:
318
- VALUE convert(double const& x)
490
+ To_Ruby() = default;
491
+
492
+ explicit To_Ruby(Arg* arg) : arg_(arg)
493
+ {
494
+ }
495
+
496
+ VALUE convert(const double& native)
319
497
  {
320
- return protect(rb_float_new, x);
498
+ return protect(rb_float_new, native);
321
499
  }
500
+
501
+ private:
502
+ Arg* arg_ = nullptr;
322
503
  };
323
504
 
324
505
  template<>
325
506
  class To_Ruby<bool>
326
507
  {
327
508
  public:
328
- VALUE convert(bool const& x)
509
+ To_Ruby() = default;
510
+
511
+ explicit To_Ruby(Arg* arg) : arg_(arg)
512
+ {
513
+ }
514
+
515
+ VALUE convert(const bool& native)
329
516
  {
330
- return x ? Qtrue : Qfalse;
517
+ return native ? Qtrue : Qfalse;
331
518
  }
519
+
520
+ private:
521
+ Arg* arg_ = nullptr;
332
522
  };
333
523
 
334
524
  template<>
335
525
  class To_Ruby<bool&>
336
526
  {
337
527
  public:
338
- VALUE convert(bool const& x)
528
+ To_Ruby() = default;
529
+
530
+ explicit To_Ruby(Arg* arg) : arg_(arg)
339
531
  {
340
- return x ? Qtrue : Qfalse;
341
532
  }
533
+
534
+ VALUE convert(const bool& native)
535
+ {
536
+ return native ? Qtrue : Qfalse;
537
+ }
538
+
539
+ private:
540
+ Arg* arg_ = nullptr;
342
541
  };
343
542
 
344
543
  template<>
345
544
  class To_Ruby<char>
346
545
  {
347
546
  public:
348
- VALUE convert(char const& x)
547
+ To_Ruby() = default;
548
+
549
+ explicit To_Ruby(Arg* arg) : arg_(arg)
349
550
  {
350
- return To_Ruby<int>().convert(x);
351
551
  }
552
+
553
+ VALUE convert(const char& native)
554
+ {
555
+ return To_Ruby<int>().convert(native);
556
+ }
557
+
558
+ private:
559
+ Arg* arg_ = nullptr;
352
560
  };
353
561
 
354
562
  template<>
355
563
  class To_Ruby<char&>
356
564
  {
357
565
  public:
358
- VALUE convert(char const& x)
566
+ To_Ruby() = default;
567
+
568
+ explicit To_Ruby(Arg* arg) : arg_(arg)
359
569
  {
360
- return To_Ruby<int>().convert(x);
361
570
  }
571
+
572
+ VALUE convert(const char& native)
573
+ {
574
+ return To_Ruby<int>().convert(native);
575
+ }
576
+
577
+ private:
578
+ Arg* arg_ = nullptr;
362
579
  };
363
580
 
364
581
  template<>
365
- class To_Ruby<unsigned char>
582
+ class To_Ruby<char*>
366
583
  {
367
584
  public:
368
- VALUE convert(unsigned char const& x)
585
+ To_Ruby() = default;
586
+
587
+ explicit To_Ruby(Arg* arg) : arg_(arg)
588
+ {
589
+ }
590
+
591
+ VALUE convert(const char* buffer)
369
592
  {
370
- return To_Ruby<unsigned int>().convert(x);
593
+ if (!buffer)
594
+ {
595
+ return Qnil;
596
+ }
597
+ else if (strlen(buffer) > 0 && buffer[0] == ':')
598
+ {
599
+ size_t symbolLength = strlen(buffer) - 1;
600
+ char* symbol = new char[symbolLength];
601
+ strncpy(symbol, buffer + 1, symbolLength);
602
+ ID id = protect(rb_intern2, symbol, (long)symbolLength);
603
+ delete[] symbol;
604
+ return protect(rb_id2sym, id);
605
+ }
606
+ else if (this->arg_ && this->arg_->isOwner())
607
+ {
608
+ // This copies the buffer but does not free it. So Ruby is not really
609
+ // taking ownership of it. But there isn't a Ruby API for creating a string
610
+ // from an existing buffer and later freeing it.
611
+ return protect(rb_usascii_str_new_cstr, buffer);
612
+ }
613
+ else
614
+ {
615
+ // Does NOT copy the passed in buffer and does NOT free it when the string is GCed
616
+ long size = (long)strlen(buffer);
617
+ return protect(rb_usascii_str_new_static, buffer, size);
618
+ }
371
619
  }
620
+
621
+ private:
622
+ Arg* arg_ = nullptr;
623
+ };
624
+
625
+ template<int N>
626
+ class To_Ruby<char[N]>
627
+ {
628
+ public:
629
+ To_Ruby() = default;
630
+
631
+ explicit To_Ruby(Arg* arg) : arg_(arg)
632
+ {
633
+ }
634
+
635
+ VALUE convert(const char buffer[])
636
+ {
637
+ if (N > 0 && buffer[0] == ':')
638
+ {
639
+ // N count includes a NULL character at the end of the string
640
+ constexpr size_t symbolLength = N - 1;
641
+ char symbol[symbolLength];
642
+ strncpy(symbol, buffer + 1, symbolLength);
643
+ ID id = protect(rb_intern, symbol);
644
+ return protect(rb_id2sym, id);
645
+ }
646
+ else
647
+ {
648
+ long size = (long)strlen(buffer);
649
+ return protect(rb_usascii_str_new_static, buffer, size);
650
+ }
651
+ }
652
+
653
+ private:
654
+ Arg* arg_ = nullptr;
372
655
  };
373
656
 
374
657
  template<>
375
- class To_Ruby<unsigned char&>
658
+ class To_Ruby<unsigned char>
376
659
  {
377
660
  public:
378
- VALUE convert(unsigned char const& x)
661
+ To_Ruby() = default;
662
+
663
+ explicit To_Ruby(Arg* arg) : arg_(arg)
379
664
  {
380
- return To_Ruby<unsigned int>().convert(x);
381
665
  }
666
+
667
+ VALUE convert(const unsigned char& native)
668
+ {
669
+ return To_Ruby<unsigned int>().convert(native);
670
+ }
671
+
672
+ private:
673
+ Arg* arg_ = nullptr;
382
674
  };
383
675
 
384
676
  template<>
385
- class To_Ruby<signed char>
677
+ class To_Ruby<unsigned char&>
386
678
  {
387
679
  public:
388
- VALUE convert(signed char const& x)
680
+ To_Ruby() = default;
681
+
682
+ explicit To_Ruby(Arg* arg) : arg_(arg)
389
683
  {
390
- return To_Ruby<signed int>().convert(x);
391
684
  }
685
+
686
+ VALUE convert(const unsigned char& native)
687
+ {
688
+ return To_Ruby<unsigned int>().convert(native);
689
+ }
690
+
691
+ private:
692
+ Arg* arg_ = nullptr;
392
693
  };
393
694
 
394
695
  template<>
395
- class To_Ruby<signed char&>
696
+ class To_Ruby<signed char>
396
697
  {
397
698
  public:
398
- VALUE convert(signed char const& x)
699
+ To_Ruby() = default;
700
+
701
+ explicit To_Ruby(Arg* arg) : arg_(arg)
399
702
  {
400
- return To_Ruby<signed int>().convert(x);
401
703
  }
704
+
705
+ VALUE convert(const signed char& native)
706
+ {
707
+ return To_Ruby<signed int>().convert(native);
708
+ }
709
+
710
+ private:
711
+ Arg* arg_ = nullptr;
402
712
  };
403
713
 
404
714
  template<>
405
- class To_Ruby<char*>
715
+ class To_Ruby<signed char&>
406
716
  {
407
717
  public:
408
- VALUE convert(char const* x)
718
+ To_Ruby() = default;
719
+
720
+ explicit To_Ruby(Arg* arg) : arg_(arg)
409
721
  {
410
- if (strlen(x) > 0 && x[0] == ':')
411
- {
412
- size_t symbolLength = strlen(x) - 1;
413
- char* symbol = new char[symbolLength];
414
- strncpy(symbol, x + 1, symbolLength);
415
- ID id = protect(rb_intern2, symbol, (long)symbolLength);
416
- delete[] symbol;
417
- return protect(rb_id2sym, id);
418
- }
419
- else
420
- {
421
- return protect(rb_str_new2, x);
422
- }
423
722
  }
723
+
724
+ VALUE convert(const signed char& native)
725
+ {
726
+ return To_Ruby<signed int>().convert(native);
727
+ }
728
+
729
+ private:
730
+ Arg* arg_ = nullptr;
424
731
  };
425
732
 
426
- template<int N>
427
- class To_Ruby<char[N]>
733
+ template <>
734
+ class To_Ruby<void*>
428
735
  {
429
736
  public:
430
- VALUE convert(char const x[])
737
+ To_Ruby() = default;
738
+
739
+ explicit To_Ruby(Arg* arg) : arg_(arg)
740
+ {
741
+ }
742
+
743
+ VALUE convert(void* data)
431
744
  {
432
- if (N > 0 && x[0] == ':')
745
+ if (this->arg_ && this->arg_->isOpaque())
433
746
  {
434
- // N count includes a NULL character at the end of the string
435
- constexpr size_t symbolLength = N - 1;
436
- char symbol[symbolLength];
437
- strncpy(symbol, x + 1, symbolLength);
438
- ID id = protect(rb_intern, symbol);
439
- return protect(rb_id2sym, id);
747
+ return VALUE(data);
748
+ }
749
+ else if (data)
750
+ {
751
+ // Note that T could be a pointer or reference to a base class while data is in fact a
752
+ // child class. Lookup the correct type so we return an instance of the correct Ruby class
753
+ std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(data);
754
+ bool isOwner = this->arg_ && this->arg_->isOwner();
755
+ return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
440
756
  }
441
757
  else
442
758
  {
443
- return protect(rb_str_new2, x);
759
+ return Qnil;
444
760
  }
445
761
  }
762
+
763
+ VALUE convert(const void* data)
764
+ {
765
+ return convert((void*)data);
766
+ }
767
+
768
+ private:
769
+ Arg* arg_ = nullptr;
446
770
  };
447
771
  }
448
772
  }