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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +66 -25
- data/README.md +7 -2
- data/Rakefile +7 -1
- data/include/rice/rice.hpp +7321 -4470
- data/include/rice/stl.hpp +769 -222
- data/lib/mkmf-rice.rb +37 -95
- data/rice/Address_Registration_Guard.hpp +72 -3
- data/rice/Arg.hpp +19 -5
- data/rice/Arg.ipp +24 -0
- data/rice/Callback.hpp +21 -0
- data/rice/Callback.ipp +13 -0
- data/rice/Constructor.hpp +4 -27
- data/rice/Constructor.ipp +79 -0
- data/rice/Data_Object.hpp +74 -3
- data/rice/Data_Object.ipp +324 -32
- data/rice/Data_Type.hpp +215 -3
- data/rice/Data_Type.ipp +125 -64
- data/rice/Director.hpp +0 -2
- data/rice/Enum.hpp +4 -6
- data/rice/Enum.ipp +101 -57
- data/rice/Exception.hpp +62 -2
- data/rice/Exception.ipp +7 -12
- data/rice/JumpException.hpp +44 -0
- data/rice/JumpException.ipp +48 -0
- data/rice/MemoryView.hpp +11 -0
- data/rice/MemoryView.ipp +43 -0
- data/rice/Return.hpp +6 -26
- data/rice/Return.ipp +10 -16
- data/rice/detail/DefaultHandler.hpp +12 -0
- data/rice/detail/DefaultHandler.ipp +8 -0
- data/rice/detail/HandlerRegistry.hpp +5 -35
- data/rice/detail/HandlerRegistry.ipp +7 -11
- data/rice/detail/InstanceRegistry.hpp +1 -4
- data/rice/detail/MethodInfo.hpp +15 -5
- data/rice/detail/MethodInfo.ipp +78 -6
- data/rice/detail/Native.hpp +32 -0
- data/rice/detail/Native.ipp +129 -0
- data/rice/detail/NativeAttributeGet.hpp +51 -0
- data/rice/detail/NativeAttributeGet.ipp +51 -0
- data/rice/detail/NativeAttributeSet.hpp +43 -0
- data/rice/detail/NativeAttributeSet.ipp +82 -0
- data/rice/detail/NativeCallbackFFI.hpp +55 -0
- data/rice/detail/NativeCallbackFFI.ipp +151 -0
- data/rice/detail/NativeCallbackSimple.hpp +30 -0
- data/rice/detail/NativeCallbackSimple.ipp +29 -0
- data/rice/detail/NativeFunction.hpp +20 -21
- data/rice/detail/NativeFunction.ipp +199 -64
- data/rice/detail/NativeIterator.hpp +8 -11
- data/rice/detail/NativeIterator.ipp +27 -31
- data/rice/detail/NativeRegistry.hpp +24 -17
- data/rice/detail/NativeRegistry.ipp +23 -56
- data/rice/detail/Proc.hpp +4 -0
- data/rice/detail/Proc.ipp +85 -0
- data/rice/detail/Registries.hpp +0 -7
- data/rice/detail/Registries.ipp +0 -18
- data/rice/detail/RubyFunction.hpp +0 -3
- data/rice/detail/RubyFunction.ipp +4 -8
- data/rice/detail/RubyType.hpp +19 -0
- data/rice/detail/RubyType.ipp +187 -0
- data/rice/detail/TupleIterator.hpp +14 -0
- data/rice/detail/Type.hpp +5 -6
- data/rice/detail/Type.ipp +150 -33
- data/rice/detail/TypeRegistry.hpp +15 -7
- data/rice/detail/TypeRegistry.ipp +105 -12
- data/rice/detail/Wrapper.hpp +6 -5
- data/rice/detail/Wrapper.ipp +45 -23
- data/rice/detail/cpp_protect.hpp +5 -6
- data/rice/detail/default_allocation_func.ipp +0 -2
- data/rice/detail/from_ruby.hpp +37 -3
- data/rice/detail/from_ruby.ipp +911 -454
- data/rice/detail/ruby.hpp +18 -0
- data/rice/detail/to_ruby.hpp +41 -3
- data/rice/detail/to_ruby.ipp +437 -113
- data/rice/global_function.hpp +0 -4
- data/rice/global_function.ipp +1 -2
- data/rice/rice.hpp +105 -22
- data/rice/ruby_mark.hpp +4 -3
- data/rice/stl.hpp +4 -0
- data/test/embed_ruby.cpp +4 -1
- data/test/extconf.rb +2 -0
- data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
- data/test/test_Address_Registration_Guard.cpp +5 -0
- data/test/test_Array.cpp +12 -1
- data/test/test_Attribute.cpp +103 -21
- data/test/test_Builtin_Object.cpp +5 -0
- data/test/test_Callback.cpp +231 -0
- data/test/test_Class.cpp +5 -31
- data/test/test_Constructor.cpp +69 -6
- data/test/test_Data_Object.cpp +9 -4
- data/test/test_Data_Type.cpp +428 -64
- data/test/test_Director.cpp +10 -5
- data/test/test_Enum.cpp +152 -40
- data/test/test_Exception.cpp +235 -0
- data/test/test_File.cpp +70 -0
- data/test/test_From_Ruby.cpp +542 -0
- data/test/test_Hash.cpp +5 -0
- data/test/test_Identifier.cpp +5 -0
- data/test/test_Inheritance.cpp +6 -1
- data/test/test_Iterator.cpp +5 -0
- data/test/test_JumpException.cpp +22 -0
- data/test/test_Keep_Alive.cpp +6 -1
- data/test/test_Keep_Alive_No_Wrapper.cpp +5 -0
- data/test/test_Memory_Management.cpp +5 -0
- data/test/test_Module.cpp +118 -64
- data/test/test_Native_Registry.cpp +2 -33
- data/test/test_Object.cpp +5 -0
- data/test/test_Overloads.cpp +631 -0
- data/test/test_Ownership.cpp +67 -4
- data/test/test_Proc.cpp +45 -0
- data/test/test_Self.cpp +5 -0
- data/test/test_Stl_Exception.cpp +109 -0
- data/test/test_Stl_Map.cpp +22 -8
- data/test/test_Stl_Optional.cpp +5 -0
- data/test/test_Stl_Pair.cpp +7 -2
- data/test/test_Stl_Reference_Wrapper.cpp +5 -0
- data/test/test_Stl_SmartPointer.cpp +210 -5
- data/test/test_Stl_String.cpp +5 -0
- data/test/test_Stl_String_View.cpp +5 -0
- data/test/test_Stl_Type.cpp +147 -0
- data/test/test_Stl_Unordered_Map.cpp +18 -7
- data/test/test_Stl_Variant.cpp +5 -0
- data/test/test_Stl_Vector.cpp +130 -8
- data/test/test_String.cpp +5 -0
- data/test/test_Struct.cpp +5 -0
- data/test/test_Symbol.cpp +5 -0
- data/test/test_Template.cpp +192 -0
- data/test/test_To_Ruby.cpp +152 -0
- data/test/test_Tracking.cpp +1 -0
- data/test/test_Type.cpp +100 -0
- data/test/test_global_functions.cpp +53 -6
- data/test/unittest.cpp +8 -0
- metadata +37 -20
- data/lib/version.rb +0 -3
- data/rice/Address_Registration_Guard_defn.hpp +0 -79
- data/rice/Data_Object_defn.hpp +0 -84
- data/rice/Data_Type_defn.hpp +0 -190
- data/rice/Exception_defn.hpp +0 -68
- data/rice/HandlerRegistration.hpp +0 -15
- data/rice/Identifier.hpp +0 -50
- data/rice/Identifier.ipp +0 -29
- data/rice/detail/ExceptionHandler.hpp +0 -8
- data/rice/detail/ExceptionHandler.ipp +0 -28
- data/rice/detail/ExceptionHandler_defn.hpp +0 -77
- data/rice/detail/Jump_Tag.hpp +0 -21
- data/rice/detail/NativeAttribute.hpp +0 -64
- data/rice/detail/NativeAttribute.ipp +0 -112
- data/rice/detail/from_ruby_defn.hpp +0 -38
- data/rice/detail/to_ruby_defn.hpp +0 -48
- data/test/test_Jump_Tag.cpp +0 -17
- data/test/test_To_From_Ruby.cpp +0 -399
data/include/rice/stl.hpp
CHANGED
@@ -2,12 +2,86 @@
|
|
2
2
|
#define Rice__stl__hpp_
|
3
3
|
|
4
4
|
|
5
|
+
// ========= exception.hpp =========
|
6
|
+
|
7
|
+
namespace Rice::stl
|
8
|
+
{
|
9
|
+
extern Class rb_cStlException;
|
10
|
+
}
|
11
|
+
|
12
|
+
|
13
|
+
// --------- exception.ipp ---------
|
14
|
+
#include <exception>
|
15
|
+
|
16
|
+
// Libraries sometime inherit custom exception objects from std::exception,
|
17
|
+
// so define it for Ruby if necessary
|
18
|
+
namespace Rice::stl
|
19
|
+
{
|
20
|
+
inline Class rb_cStlException;
|
21
|
+
|
22
|
+
inline void define_stl_exception()
|
23
|
+
{
|
24
|
+
Module rb_mRice = define_module("Rice");
|
25
|
+
Module rb_mStd = define_module_under(rb_mRice, "Std");
|
26
|
+
rb_cStlException = define_class_under<std::exception>(rb_mStd, "Exception", rb_eStandardError).
|
27
|
+
define_constructor(Constructor<std::exception>()).
|
28
|
+
define_method("message", &std::exception::what);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
namespace Rice::detail
|
33
|
+
{
|
34
|
+
template<>
|
35
|
+
struct Type<std::exception>
|
36
|
+
{
|
37
|
+
static bool verify()
|
38
|
+
{
|
39
|
+
Rice::stl::define_stl_exception();
|
40
|
+
return true;
|
41
|
+
}
|
42
|
+
};
|
43
|
+
}
|
44
|
+
|
45
|
+
|
46
|
+
// ========= exception_ptr.hpp =========
|
47
|
+
|
48
|
+
|
49
|
+
// --------- exception_ptr.ipp ---------
|
50
|
+
#include <functional>
|
51
|
+
|
52
|
+
namespace Rice::stl
|
53
|
+
{
|
54
|
+
inline Data_Type<std::exception_ptr> define_exception_ptr()
|
55
|
+
{
|
56
|
+
Module rb_mRice = define_module("Rice");
|
57
|
+
Module rb_mStd = define_module_under(rb_mRice, "Std");
|
58
|
+
|
59
|
+
return define_class_under<std::exception_ptr>(rb_mStd, "ExceptionPtr");
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
namespace Rice::detail
|
64
|
+
{
|
65
|
+
template<>
|
66
|
+
struct Type<std::exception_ptr>
|
67
|
+
{
|
68
|
+
static bool verify()
|
69
|
+
{
|
70
|
+
if (!detail::Registries::instance.types.isDefined<std::exception_ptr>())
|
71
|
+
{
|
72
|
+
stl::define_exception_ptr();
|
73
|
+
}
|
74
|
+
|
75
|
+
return true;
|
76
|
+
}
|
77
|
+
};
|
78
|
+
}
|
79
|
+
|
80
|
+
|
5
81
|
// ========= string.hpp =========
|
6
82
|
|
7
83
|
|
8
84
|
// --------- string.ipp ---------
|
9
|
-
#include <string>
|
10
|
-
|
11
85
|
namespace Rice::detail
|
12
86
|
{
|
13
87
|
template<>
|
@@ -49,9 +123,16 @@ namespace Rice::detail
|
|
49
123
|
{
|
50
124
|
}
|
51
125
|
|
52
|
-
|
126
|
+
Convertible is_convertible(VALUE value)
|
53
127
|
{
|
54
|
-
|
128
|
+
switch (rb_type(value))
|
129
|
+
{
|
130
|
+
case RUBY_T_STRING:
|
131
|
+
return Convertible::Exact;
|
132
|
+
break;
|
133
|
+
default:
|
134
|
+
return Convertible::None;
|
135
|
+
}
|
55
136
|
}
|
56
137
|
|
57
138
|
std::string convert(VALUE value)
|
@@ -81,9 +162,16 @@ namespace Rice::detail
|
|
81
162
|
{
|
82
163
|
}
|
83
164
|
|
84
|
-
|
165
|
+
Convertible is_convertible(VALUE value)
|
85
166
|
{
|
86
|
-
|
167
|
+
switch (rb_type(value))
|
168
|
+
{
|
169
|
+
case RUBY_T_STRING:
|
170
|
+
return Convertible::Exact;
|
171
|
+
break;
|
172
|
+
default:
|
173
|
+
return Convertible::None;
|
174
|
+
}
|
87
175
|
}
|
88
176
|
|
89
177
|
std::string& convert(VALUE value)
|
@@ -109,9 +197,16 @@ namespace Rice::detail
|
|
109
197
|
class From_Ruby<std::string*>
|
110
198
|
{
|
111
199
|
public:
|
112
|
-
|
200
|
+
Convertible is_convertible(VALUE value)
|
113
201
|
{
|
114
|
-
|
202
|
+
switch (rb_type(value))
|
203
|
+
{
|
204
|
+
case RUBY_T_STRING:
|
205
|
+
return Convertible::Exact;
|
206
|
+
break;
|
207
|
+
default:
|
208
|
+
return Convertible::None;
|
209
|
+
}
|
115
210
|
}
|
116
211
|
|
117
212
|
std::string* convert(VALUE value)
|
@@ -129,9 +224,16 @@ namespace Rice::detail
|
|
129
224
|
class From_Ruby<std::string*&>
|
130
225
|
{
|
131
226
|
public:
|
132
|
-
|
227
|
+
Convertible is_convertible(VALUE value)
|
133
228
|
{
|
134
|
-
|
229
|
+
switch (rb_type(value))
|
230
|
+
{
|
231
|
+
case RUBY_T_STRING:
|
232
|
+
return Convertible::Exact;
|
233
|
+
break;
|
234
|
+
default:
|
235
|
+
return Convertible::None;
|
236
|
+
}
|
135
237
|
}
|
136
238
|
|
137
239
|
std::string* convert(VALUE value)
|
@@ -193,9 +295,16 @@ namespace Rice::detail
|
|
193
295
|
{
|
194
296
|
}
|
195
297
|
|
196
|
-
|
298
|
+
Convertible is_convertible(VALUE value)
|
197
299
|
{
|
198
|
-
|
300
|
+
switch (rb_type(value))
|
301
|
+
{
|
302
|
+
case RUBY_T_STRING:
|
303
|
+
return Convertible::Exact;
|
304
|
+
break;
|
305
|
+
default:
|
306
|
+
return Convertible::None;
|
307
|
+
}
|
199
308
|
}
|
200
309
|
|
201
310
|
std::string_view convert(VALUE value)
|
@@ -251,6 +360,18 @@ namespace Rice::detail
|
|
251
360
|
class From_Ruby<std::complex<T>>
|
252
361
|
{
|
253
362
|
public:
|
363
|
+
Convertible is_convertible(VALUE value)
|
364
|
+
{
|
365
|
+
switch (rb_type(value))
|
366
|
+
{
|
367
|
+
case RUBY_T_COMPLEX:
|
368
|
+
return Convertible::Exact;
|
369
|
+
break;
|
370
|
+
default:
|
371
|
+
return Convertible::None;
|
372
|
+
}
|
373
|
+
}
|
374
|
+
|
254
375
|
std::complex<T> convert(VALUE value)
|
255
376
|
{
|
256
377
|
VALUE real = protect(rb_funcallv, value, rb_intern("real"), 0, (const VALUE*)nullptr);
|
@@ -258,17 +379,24 @@ namespace Rice::detail
|
|
258
379
|
|
259
380
|
return std::complex<T>(From_Ruby<T>().convert(real), From_Ruby<T>().convert(imaginary));
|
260
381
|
}
|
261
|
-
|
262
|
-
bool is_convertible(VALUE value)
|
263
|
-
{
|
264
|
-
return rb_type(value) == RUBY_T_COMPLEX;
|
265
|
-
}
|
266
382
|
};
|
267
383
|
|
268
384
|
template<typename T>
|
269
385
|
class From_Ruby<std::complex<T>&>
|
270
386
|
{
|
271
387
|
public:
|
388
|
+
Convertible is_convertible(VALUE value)
|
389
|
+
{
|
390
|
+
switch (rb_type(value))
|
391
|
+
{
|
392
|
+
case RUBY_T_COMPLEX:
|
393
|
+
return Convertible::Exact;
|
394
|
+
break;
|
395
|
+
default:
|
396
|
+
return Convertible::None;
|
397
|
+
}
|
398
|
+
}
|
399
|
+
|
272
400
|
std::complex<T>& convert(VALUE value)
|
273
401
|
{
|
274
402
|
VALUE real = protect(rb_funcallv, value, rb_intern("real"), 0, (const VALUE*)nullptr);
|
@@ -278,11 +406,6 @@ namespace Rice::detail
|
|
278
406
|
return this->converted_;
|
279
407
|
}
|
280
408
|
|
281
|
-
bool is_convertible(VALUE value)
|
282
|
-
{
|
283
|
-
return rb_type(value) == RUBY_T_COMPLEX;
|
284
|
-
}
|
285
|
-
|
286
409
|
private:
|
287
410
|
std::complex<T> converted_;
|
288
411
|
};
|
@@ -354,6 +477,18 @@ namespace Rice::detail
|
|
354
477
|
class From_Ruby<std::optional<T>>
|
355
478
|
{
|
356
479
|
public:
|
480
|
+
Convertible is_convertible(VALUE value)
|
481
|
+
{
|
482
|
+
switch (rb_type(value))
|
483
|
+
{
|
484
|
+
case RUBY_T_NIL:
|
485
|
+
return Convertible::Exact;
|
486
|
+
break;
|
487
|
+
default:
|
488
|
+
return From_Ruby<T>().is_convertible(value);
|
489
|
+
}
|
490
|
+
}
|
491
|
+
|
357
492
|
std::optional<T> convert(VALUE value)
|
358
493
|
{
|
359
494
|
if (value == Qnil)
|
@@ -371,6 +506,18 @@ namespace Rice::detail
|
|
371
506
|
class From_Ruby<std::optional<T>&>
|
372
507
|
{
|
373
508
|
public:
|
509
|
+
Convertible is_convertible(VALUE value)
|
510
|
+
{
|
511
|
+
switch (rb_type(value))
|
512
|
+
{
|
513
|
+
case RUBY_T_NIL:
|
514
|
+
return Convertible::Exact;
|
515
|
+
break;
|
516
|
+
default:
|
517
|
+
return From_Ruby<T>().is_convertible(value);
|
518
|
+
}
|
519
|
+
}
|
520
|
+
|
374
521
|
std::optional<T>& convert(VALUE value)
|
375
522
|
{
|
376
523
|
if (value == Qnil)
|
@@ -383,7 +530,6 @@ namespace Rice::detail
|
|
383
530
|
}
|
384
531
|
return this->converted_;
|
385
532
|
}
|
386
|
-
|
387
533
|
private:
|
388
534
|
std::optional<T> converted_;
|
389
535
|
};
|
@@ -421,9 +567,9 @@ namespace Rice::detail
|
|
421
567
|
class From_Ruby<std::reference_wrapper<T>>
|
422
568
|
{
|
423
569
|
public:
|
424
|
-
|
570
|
+
Convertible is_convertible(VALUE value)
|
425
571
|
{
|
426
|
-
return
|
572
|
+
return this->converter_.is_convertible(value);
|
427
573
|
}
|
428
574
|
|
429
575
|
std::reference_wrapper<T> convert(VALUE value)
|
@@ -494,12 +640,11 @@ namespace Rice::detail
|
|
494
640
|
class To_Ruby<std::unique_ptr<T>>
|
495
641
|
{
|
496
642
|
public:
|
643
|
+
using Wrapper_T = WrapperSmartPointer<std::unique_ptr, T>;
|
644
|
+
|
497
645
|
VALUE convert(std::unique_ptr<T>& data)
|
498
646
|
{
|
499
647
|
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(*data);
|
500
|
-
|
501
|
-
// Use custom wrapper type
|
502
|
-
using Wrapper_T = WrapperSmartPointer<std::unique_ptr, T>;
|
503
648
|
return detail::wrap<std::unique_ptr<T>, Wrapper_T>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
504
649
|
}
|
505
650
|
};
|
@@ -508,26 +653,84 @@ namespace Rice::detail
|
|
508
653
|
class To_Ruby<std::unique_ptr<T>&>
|
509
654
|
{
|
510
655
|
public:
|
656
|
+
using Wrapper_T = WrapperSmartPointer<std::unique_ptr, T>;
|
657
|
+
|
511
658
|
VALUE convert(std::unique_ptr<T>& data)
|
512
659
|
{
|
513
660
|
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(*data);
|
514
|
-
|
515
|
-
// Use custom wrapper type
|
516
|
-
using Wrapper_T = WrapperSmartPointer<std::unique_ptr, T>;
|
517
661
|
return detail::wrap<std::unique_ptr<T>, Wrapper_T>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
518
662
|
}
|
519
663
|
};
|
520
664
|
|
665
|
+
template <typename T>
|
666
|
+
class From_Ruby<std::unique_ptr<T>>
|
667
|
+
{
|
668
|
+
public:
|
669
|
+
using Wrapper_T = WrapperSmartPointer<std::unique_ptr, T>;
|
670
|
+
|
671
|
+
Wrapper_T* is_same_smart_ptr(VALUE value)
|
672
|
+
{
|
673
|
+
Wrapper* wrapper = detail::getWrapper(value, Data_Type<T>::ruby_data_type());
|
674
|
+
return dynamic_cast<Wrapper_T*>(wrapper);
|
675
|
+
}
|
676
|
+
|
677
|
+
Convertible is_convertible(VALUE value)
|
678
|
+
{
|
679
|
+
if (!is_same_smart_ptr(value))
|
680
|
+
return Convertible::None;
|
681
|
+
|
682
|
+
switch (rb_type(value))
|
683
|
+
{
|
684
|
+
case RUBY_T_DATA:
|
685
|
+
return Convertible::Exact;
|
686
|
+
break;
|
687
|
+
default:
|
688
|
+
return Convertible::None;
|
689
|
+
}
|
690
|
+
}
|
691
|
+
|
692
|
+
std::unique_ptr<T> convert(VALUE value)
|
693
|
+
{
|
694
|
+
Wrapper_T* smartWrapper = is_same_smart_ptr(value);
|
695
|
+
if (!smartWrapper)
|
696
|
+
{
|
697
|
+
std::string message = "Invalid smart pointer wrapper";
|
698
|
+
throw std::runtime_error(message.c_str());
|
699
|
+
}
|
700
|
+
return std::move(smartWrapper->data());
|
701
|
+
}
|
702
|
+
};
|
703
|
+
|
521
704
|
template <typename T>
|
522
705
|
class From_Ruby<std::unique_ptr<T>&>
|
523
706
|
{
|
524
707
|
public:
|
525
|
-
std::unique_ptr
|
708
|
+
using Wrapper_T = WrapperSmartPointer<std::unique_ptr, T>;
|
709
|
+
|
710
|
+
Wrapper_T* is_same_smart_ptr(VALUE value)
|
526
711
|
{
|
527
712
|
Wrapper* wrapper = detail::getWrapper(value, Data_Type<T>::ruby_data_type());
|
713
|
+
return dynamic_cast<Wrapper_T*>(wrapper);
|
714
|
+
}
|
715
|
+
|
716
|
+
Convertible is_convertible(VALUE value)
|
717
|
+
{
|
718
|
+
if (!is_same_smart_ptr(value))
|
719
|
+
return Convertible::None;
|
720
|
+
|
721
|
+
switch (rb_type(value))
|
722
|
+
{
|
723
|
+
case RUBY_T_DATA:
|
724
|
+
return Convertible::Exact;
|
725
|
+
break;
|
726
|
+
default:
|
727
|
+
return Convertible::None;
|
728
|
+
}
|
729
|
+
}
|
528
730
|
|
529
|
-
|
530
|
-
|
731
|
+
std::unique_ptr<T>& convert(VALUE value)
|
732
|
+
{
|
733
|
+
Wrapper_T* smartWrapper = is_same_smart_ptr(value);
|
531
734
|
if (!smartWrapper)
|
532
735
|
{
|
533
736
|
std::string message = "Invalid smart pointer wrapper";
|
@@ -551,36 +754,68 @@ namespace Rice::detail
|
|
551
754
|
class To_Ruby<std::shared_ptr<T>>
|
552
755
|
{
|
553
756
|
public:
|
757
|
+
using Wrapper_T = WrapperSmartPointer<std::shared_ptr, T>;
|
758
|
+
|
554
759
|
VALUE convert(std::shared_ptr<T>& data)
|
555
760
|
{
|
556
761
|
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(*data);
|
557
|
-
|
558
|
-
// Use custom wrapper type
|
559
|
-
using Wrapper_T = WrapperSmartPointer<std::shared_ptr, T>;
|
560
762
|
return detail::wrap<std::shared_ptr<T>, Wrapper_T>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
561
763
|
}
|
562
764
|
};
|
563
765
|
|
766
|
+
template <>
|
767
|
+
class To_Ruby<std::shared_ptr<void>>
|
768
|
+
{
|
769
|
+
public:
|
770
|
+
using Wrapper_T = WrapperSmartPointer<std::shared_ptr, void>;
|
771
|
+
|
772
|
+
VALUE convert(std::shared_ptr<void>& data)
|
773
|
+
{
|
774
|
+
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(data.get());
|
775
|
+
return detail::wrap<std::shared_ptr<void>, Wrapper_T>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
776
|
+
}
|
777
|
+
};
|
778
|
+
|
564
779
|
template <typename T>
|
565
780
|
class From_Ruby<std::shared_ptr<T>>
|
566
781
|
{
|
567
782
|
public:
|
783
|
+
using Wrapper_T = WrapperSmartPointer<std::shared_ptr, T>;
|
784
|
+
|
568
785
|
From_Ruby() = default;
|
569
786
|
|
570
787
|
explicit From_Ruby(Arg * arg) : arg_(arg)
|
571
788
|
{
|
572
789
|
}
|
573
790
|
|
791
|
+
Wrapper_T* is_same_smart_ptr(VALUE value)
|
792
|
+
{
|
793
|
+
Wrapper* wrapper = detail::getWrapper(value, Data_Type<T>::ruby_data_type());
|
794
|
+
return dynamic_cast<Wrapper_T*>(wrapper);
|
795
|
+
}
|
796
|
+
|
797
|
+
Convertible is_convertible(VALUE value)
|
798
|
+
{
|
799
|
+
if (!is_same_smart_ptr(value))
|
800
|
+
return Convertible::None;
|
801
|
+
|
802
|
+
switch (rb_type(value))
|
803
|
+
{
|
804
|
+
case RUBY_T_DATA:
|
805
|
+
return Convertible::Exact;
|
806
|
+
break;
|
807
|
+
default:
|
808
|
+
return Convertible::None;
|
809
|
+
}
|
810
|
+
}
|
811
|
+
|
574
812
|
std::shared_ptr<T> convert(VALUE value)
|
575
813
|
{
|
576
814
|
if(value == Qnil && this->arg_ && this->arg_->hasDefaultValue()) {
|
577
815
|
return this->arg_->template defaultValue<std::shared_ptr<T>>();
|
578
816
|
}
|
579
817
|
|
580
|
-
|
581
|
-
|
582
|
-
using Wrapper_T = WrapperSmartPointer<std::shared_ptr, T>;
|
583
|
-
Wrapper_T* smartWrapper = dynamic_cast<Wrapper_T*>(wrapper);
|
818
|
+
Wrapper_T* smartWrapper = is_same_smart_ptr(value);
|
584
819
|
if (!smartWrapper)
|
585
820
|
{
|
586
821
|
std::string message = "Invalid smart pointer wrapper";
|
@@ -588,7 +823,6 @@ namespace Rice::detail
|
|
588
823
|
}
|
589
824
|
return smartWrapper->data();
|
590
825
|
}
|
591
|
-
|
592
826
|
private:
|
593
827
|
Arg* arg_ = nullptr;
|
594
828
|
};
|
@@ -597,12 +831,11 @@ namespace Rice::detail
|
|
597
831
|
class To_Ruby<std::shared_ptr<T>&>
|
598
832
|
{
|
599
833
|
public:
|
834
|
+
using Wrapper_T = WrapperSmartPointer<std::shared_ptr, T>;
|
835
|
+
|
600
836
|
VALUE convert(std::shared_ptr<T>& data)
|
601
837
|
{
|
602
838
|
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(*data);
|
603
|
-
|
604
|
-
// Use custom wrapper type
|
605
|
-
using Wrapper_T = WrapperSmartPointer<std::shared_ptr, T>;
|
606
839
|
return detail::wrap<std::shared_ptr<T>, Wrapper_T>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
607
840
|
}
|
608
841
|
};
|
@@ -611,22 +844,42 @@ namespace Rice::detail
|
|
611
844
|
class From_Ruby<std::shared_ptr<T>&>
|
612
845
|
{
|
613
846
|
public:
|
847
|
+
using Wrapper_T = WrapperSmartPointer<std::shared_ptr, T>;
|
848
|
+
|
614
849
|
From_Ruby() = default;
|
615
850
|
|
616
851
|
explicit From_Ruby(Arg * arg) : arg_(arg)
|
617
852
|
{
|
618
853
|
}
|
619
854
|
|
855
|
+
Wrapper_T* is_same_smart_ptr(VALUE value)
|
856
|
+
{
|
857
|
+
Wrapper* wrapper = detail::getWrapper(value, Data_Type<T>::ruby_data_type());
|
858
|
+
return dynamic_cast<Wrapper_T*>(wrapper);
|
859
|
+
}
|
860
|
+
|
861
|
+
Convertible is_convertible(VALUE value)
|
862
|
+
{
|
863
|
+
if (!is_same_smart_ptr(value))
|
864
|
+
return Convertible::None;
|
865
|
+
|
866
|
+
switch (rb_type(value))
|
867
|
+
{
|
868
|
+
case RUBY_T_DATA:
|
869
|
+
return Convertible::Exact;
|
870
|
+
break;
|
871
|
+
default:
|
872
|
+
return Convertible::None;
|
873
|
+
}
|
874
|
+
}
|
875
|
+
|
620
876
|
std::shared_ptr<T>& convert(VALUE value)
|
621
877
|
{
|
622
878
|
if(value == Qnil && this->arg_ && this->arg_->hasDefaultValue()) {
|
623
879
|
return this->arg_->template defaultValue<std::shared_ptr<T>>();
|
624
880
|
}
|
625
881
|
|
626
|
-
|
627
|
-
|
628
|
-
using Wrapper_T = WrapperSmartPointer<std::shared_ptr, T>;
|
629
|
-
Wrapper_T* smartWrapper = dynamic_cast<Wrapper_T*>(wrapper);
|
882
|
+
Wrapper_T* smartWrapper = is_same_smart_ptr(value);
|
630
883
|
if (!smartWrapper)
|
631
884
|
{
|
632
885
|
std::string message = "Invalid smart pointer wrapper";
|
@@ -691,9 +944,9 @@ namespace Rice::detail
|
|
691
944
|
class From_Ruby<std::monostate>
|
692
945
|
{
|
693
946
|
public:
|
694
|
-
|
947
|
+
Convertible is_convertible(VALUE value)
|
695
948
|
{
|
696
|
-
return
|
949
|
+
return Convertible::None;
|
697
950
|
}
|
698
951
|
|
699
952
|
std::monostate convert(VALUE value)
|
@@ -706,9 +959,9 @@ namespace Rice::detail
|
|
706
959
|
class From_Ruby<std::monostate&>
|
707
960
|
{
|
708
961
|
public:
|
709
|
-
|
962
|
+
Convertible is_convertible(VALUE value)
|
710
963
|
{
|
711
|
-
return
|
964
|
+
return Convertible::None;
|
712
965
|
}
|
713
966
|
|
714
967
|
std::monostate& convert(VALUE value)
|
@@ -722,6 +975,81 @@ namespace Rice::detail
|
|
722
975
|
}
|
723
976
|
|
724
977
|
|
978
|
+
// ========= type_index.hpp =========
|
979
|
+
|
980
|
+
|
981
|
+
// --------- type_index.ipp ---------
|
982
|
+
#include <typeindex>
|
983
|
+
|
984
|
+
namespace Rice::stl
|
985
|
+
{
|
986
|
+
inline Data_Type<std::type_index> define_type_index()
|
987
|
+
{
|
988
|
+
Module rb_mRice = define_module("Rice");
|
989
|
+
Module rb_mStd = define_module_under(rb_mRice, "Std");
|
990
|
+
|
991
|
+
return define_class_under<std::type_index>(rb_mStd, "TypeIndex").
|
992
|
+
define_constructor(Constructor<std::type_index, const std::type_info&>()).
|
993
|
+
define_method("hash_code", &std::type_index::hash_code).
|
994
|
+
define_method("name", &std::type_index::name);
|
995
|
+
}
|
996
|
+
}
|
997
|
+
|
998
|
+
namespace Rice::detail
|
999
|
+
{
|
1000
|
+
template<>
|
1001
|
+
struct Type<std::type_index>
|
1002
|
+
{
|
1003
|
+
static bool verify()
|
1004
|
+
{
|
1005
|
+
if (!detail::Registries::instance.types.isDefined<std::type_index>())
|
1006
|
+
{
|
1007
|
+
stl::define_type_index();
|
1008
|
+
}
|
1009
|
+
|
1010
|
+
return true;
|
1011
|
+
}
|
1012
|
+
};
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
|
1016
|
+
// ========= type_info.hpp =========
|
1017
|
+
|
1018
|
+
|
1019
|
+
// --------- type_info.ipp ---------
|
1020
|
+
#include <typeinfo>
|
1021
|
+
|
1022
|
+
namespace Rice::stl
|
1023
|
+
{
|
1024
|
+
inline Data_Type<std::type_info> define_type_info()
|
1025
|
+
{
|
1026
|
+
Module rb_mRice = define_module("Rice");
|
1027
|
+
Module rb_mStd = define_module_under(rb_mRice, "Std");
|
1028
|
+
|
1029
|
+
return define_class_under<std::type_info>(rb_mStd, "TypeInfo").
|
1030
|
+
define_method("hash_code", &std::type_info::hash_code).
|
1031
|
+
define_method("name", &std::type_info::name);
|
1032
|
+
}
|
1033
|
+
}
|
1034
|
+
|
1035
|
+
namespace Rice::detail
|
1036
|
+
{
|
1037
|
+
template<>
|
1038
|
+
struct Type<std::type_info>
|
1039
|
+
{
|
1040
|
+
static inline bool verify()
|
1041
|
+
{
|
1042
|
+
if (!detail::Registries::instance.types.isDefined<std::type_info>())
|
1043
|
+
{
|
1044
|
+
stl::define_type_info();
|
1045
|
+
}
|
1046
|
+
|
1047
|
+
return true;
|
1048
|
+
}
|
1049
|
+
};
|
1050
|
+
}
|
1051
|
+
|
1052
|
+
|
725
1053
|
// ========= variant.hpp =========
|
726
1054
|
|
727
1055
|
|
@@ -781,14 +1109,24 @@ namespace Rice::detail
|
|
781
1109
|
comma operator to return true to the fold expression. If the variant does not have
|
782
1110
|
a value for the type then return false.
|
783
1111
|
|
784
|
-
The fold operator is or (||). If an index returns false, then the next index is
|
1112
|
+
The fold operator is or (||). If an index returns false, then the next index is evaluated
|
785
1113
|
up until I.
|
786
1114
|
|
787
1115
|
Code inspired by https://www.foonathan.net/2020/05/fold-tricks/ */
|
788
1116
|
|
789
1117
|
VALUE result = Qnil;
|
1118
|
+
|
1119
|
+
#if defined(__GNUC__) || defined(__clang__)
|
1120
|
+
#pragma GCC diagnostic push
|
1121
|
+
#pragma GCC diagnostic ignored "-Wunused-value"
|
1122
|
+
#endif
|
1123
|
+
|
790
1124
|
((std::holds_alternative<std::tuple_element_t<I, Tuple_T>>(data) ?
|
791
1125
|
(result = convertElement<std::tuple_element_t<I, Tuple_T>>(data, takeOwnership), true) : false) || ...);
|
1126
|
+
|
1127
|
+
#if defined(__GNUC__) || defined(__clang__)
|
1128
|
+
#pragma GCC diagnostic pop
|
1129
|
+
#endif
|
792
1130
|
|
793
1131
|
return result;
|
794
1132
|
}
|
@@ -818,9 +1156,19 @@ namespace Rice::detail
|
|
818
1156
|
|
819
1157
|
// See comments above for explanation of this code
|
820
1158
|
VALUE result = Qnil;
|
1159
|
+
|
1160
|
+
#if defined(__GNUC__) || defined(__clang__)
|
1161
|
+
#pragma GCC diagnostic push
|
1162
|
+
#pragma GCC diagnostic ignored "-Wunused-value"
|
1163
|
+
#endif
|
1164
|
+
|
821
1165
|
((std::holds_alternative<std::tuple_element_t<I, Tuple_T>>(data) ?
|
822
1166
|
(result = convertElement<std::tuple_element_t<I, Tuple_T>>(data, takeOwnership), true) : false) || ...);
|
823
1167
|
|
1168
|
+
#if defined(__GNUC__) || defined(__clang__)
|
1169
|
+
#pragma GCC diagnostic pop
|
1170
|
+
#endif
|
1171
|
+
|
824
1172
|
return result;
|
825
1173
|
}
|
826
1174
|
|
@@ -834,83 +1182,102 @@ namespace Rice::detail
|
|
834
1182
|
template<typename...Types>
|
835
1183
|
class From_Ruby<std::variant<Types...>>
|
836
1184
|
{
|
837
|
-
private:
|
838
|
-
// Possible converters we could use for this variant
|
839
|
-
using From_Ruby_Ts = std::tuple<From_Ruby<Types>...>;
|
840
|
-
|
841
1185
|
public:
|
1186
|
+
Convertible is_convertible(VALUE value)
|
1187
|
+
{
|
1188
|
+
Convertible result = Convertible::None;
|
1189
|
+
|
1190
|
+
for_each_tuple(this->fromRubys_,
|
1191
|
+
[&](auto& fromRuby)
|
1192
|
+
{
|
1193
|
+
result = result | fromRuby.is_convertible(value);
|
1194
|
+
});
|
1195
|
+
|
1196
|
+
return result;
|
1197
|
+
}
|
1198
|
+
|
1199
|
+
// This method search through a variant's types to figure out which one the
|
1200
|
+
// currently Ruby value best matches. It then returns the index of the type.
|
1201
|
+
int figureIndex(VALUE value)
|
1202
|
+
{
|
1203
|
+
int i = 0;
|
1204
|
+
int index = -1;
|
1205
|
+
Convertible foundConversion = Convertible::None;
|
1206
|
+
|
1207
|
+
for_each_tuple(this->fromRubys_,
|
1208
|
+
[&](auto& fromRuby)
|
1209
|
+
{
|
1210
|
+
Convertible isConvertible = fromRuby.is_convertible(value);
|
1211
|
+
|
1212
|
+
if (isConvertible > foundConversion)
|
1213
|
+
{
|
1214
|
+
index = i;
|
1215
|
+
foundConversion = isConvertible;
|
1216
|
+
}
|
1217
|
+
i++;
|
1218
|
+
});
|
1219
|
+
|
1220
|
+
if (index == -1)
|
1221
|
+
{
|
1222
|
+
rb_raise(rb_eArgError, "Could not find converter for variant");
|
1223
|
+
}
|
1224
|
+
|
1225
|
+
return index;
|
1226
|
+
}
|
1227
|
+
|
842
1228
|
/* This method loops over each type in the variant, creates a From_Ruby converter,
|
843
1229
|
and then check if the converter can work with the provided Rby value (it checks
|
844
|
-
the type of the Ruby object to see if it matches the variant type).
|
1230
|
+
the type of the Ruby object to see if it matches the variant type).
|
845
1231
|
If yes, then the converter runs. If no, then the method recursively calls itself
|
846
|
-
increasing the index.
|
847
|
-
|
1232
|
+
increasing the index.
|
1233
|
+
|
848
1234
|
We use recursion, with a constexpr, to avoid having to instantiate an instance
|
849
1235
|
of the variant to store results from a fold expression like the To_Ruby code
|
850
1236
|
does above. That allows us to process variants with non default constructible
|
851
1237
|
arguments like std::reference_wrapper. */
|
852
1238
|
template <std::size_t I = 0>
|
853
|
-
std::variant<Types...> convertInternal(VALUE value)
|
1239
|
+
std::variant<Types...> convertInternal(VALUE value, int index)
|
854
1240
|
{
|
855
|
-
// Loop over each possible type in the variant.
|
856
1241
|
if constexpr (I < std::variant_size_v<std::variant<Types...>>)
|
857
1242
|
{
|
858
|
-
|
859
|
-
typename std::tuple_element_t<I, From_Ruby_Ts> converter;
|
860
|
-
|
861
|
-
// See if it will work
|
862
|
-
if (converter.is_convertible(value))
|
1243
|
+
if (I == index)
|
863
1244
|
{
|
864
|
-
|
1245
|
+
auto fromRuby = std::get<I>(this->fromRubys_);
|
1246
|
+
return fromRuby.convert(value);
|
865
1247
|
}
|
866
1248
|
else
|
867
1249
|
{
|
868
|
-
return convertInternal<I + 1>(value);
|
1250
|
+
return convertInternal<I + 1>(value, index);
|
869
1251
|
}
|
870
1252
|
}
|
871
|
-
|
1253
|
+
rb_raise(rb_eArgError, "Could not find converter for variant");
|
872
1254
|
}
|
873
1255
|
|
874
1256
|
std::variant<Types...> convert(VALUE value)
|
875
1257
|
{
|
876
|
-
|
1258
|
+
int index = this->figureIndex(value);
|
1259
|
+
return this->convertInternal(value, index);
|
877
1260
|
}
|
878
|
-
};
|
879
1261
|
|
880
|
-
template<typename...Types>
|
881
|
-
class From_Ruby<std::variant<Types...>&>
|
882
|
-
{
|
883
1262
|
private:
|
884
1263
|
// Possible converters we could use for this variant
|
885
1264
|
using From_Ruby_Ts = std::tuple<From_Ruby<Types>...>;
|
1265
|
+
From_Ruby_Ts fromRubys_;
|
1266
|
+
};
|
886
1267
|
|
1268
|
+
template<typename...Types>
|
1269
|
+
class From_Ruby<std::variant<Types...>&> : public From_Ruby<std::variant<Types...>>
|
1270
|
+
{
|
887
1271
|
public:
|
888
|
-
|
889
|
-
std::variant<Types...> convertInternal(VALUE value)
|
1272
|
+
std::variant<Types...>& convert(VALUE value)
|
890
1273
|
{
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
// Get the converter for the current index
|
895
|
-
typename std::tuple_element_t<I, From_Ruby_Ts> converter;
|
896
|
-
|
897
|
-
// See if it will work
|
898
|
-
if (converter.is_convertible(value))
|
899
|
-
{
|
900
|
-
return converter.convert(value);
|
901
|
-
}
|
902
|
-
else
|
903
|
-
{
|
904
|
-
return convertInternal<I + 1>(value);
|
905
|
-
}
|
906
|
-
}
|
907
|
-
throw std::runtime_error("Could not find converter for variant");
|
1274
|
+
int index = this->figureIndex(value);
|
1275
|
+
this->converted_ = this->convertInternal(value, index);
|
1276
|
+
return this->converted_;
|
908
1277
|
}
|
909
1278
|
|
910
|
-
|
911
|
-
|
912
|
-
return convertInternal(value);
|
913
|
-
}
|
1279
|
+
private:
|
1280
|
+
std::variant<Types...> converted_;
|
914
1281
|
};
|
915
1282
|
}
|
916
1283
|
|
@@ -924,7 +1291,7 @@ namespace Rice
|
|
924
1291
|
Data_Type<T> define_pair(std::string name);
|
925
1292
|
|
926
1293
|
template<typename T>
|
927
|
-
Data_Type<T> define_pair_under(Object
|
1294
|
+
Data_Type<T> define_pair_under(Object parent, std::string name);
|
928
1295
|
}
|
929
1296
|
|
930
1297
|
|
@@ -1044,17 +1411,17 @@ namespace Rice
|
|
1044
1411
|
} // namespace
|
1045
1412
|
|
1046
1413
|
template<typename T>
|
1047
|
-
Data_Type<T> define_pair_under(Object
|
1414
|
+
Data_Type<T> define_pair_under(Object parent, std::string name)
|
1048
1415
|
{
|
1049
1416
|
if (detail::Registries::instance.types.isDefined<T>())
|
1050
1417
|
{
|
1051
1418
|
// If the pair has been previously seen it will be registered but may
|
1052
1419
|
// not be associated with the constant Module::<name>
|
1053
|
-
|
1420
|
+
parent.const_set_maybe(name, Data_Type<T>().klass());
|
1054
1421
|
return Data_Type<T>();
|
1055
1422
|
}
|
1056
1423
|
|
1057
|
-
Data_Type<T> result = define_class_under<detail::intrinsic_type<T>>(
|
1424
|
+
Data_Type<T> result = define_class_under<detail::intrinsic_type<T>>(parent, name.c_str());
|
1058
1425
|
stl::PairHelper helper(result);
|
1059
1426
|
return result;
|
1060
1427
|
}
|
@@ -1078,10 +1445,11 @@ namespace Rice
|
|
1078
1445
|
template<typename T>
|
1079
1446
|
Data_Type<T> define_pair_auto()
|
1080
1447
|
{
|
1081
|
-
std::string
|
1448
|
+
std::string name = detail::typeName(typeid(T));
|
1449
|
+
std::string klassName = detail::makeClassName(name);
|
1082
1450
|
Module rb_mRice = define_module("Rice");
|
1083
|
-
Module
|
1084
|
-
return define_pair_under<T>(
|
1451
|
+
Module rb_mStd = define_module_under(rb_mRice, "Std");
|
1452
|
+
return define_pair_under<T>(rb_mStd, klassName);
|
1085
1453
|
}
|
1086
1454
|
|
1087
1455
|
namespace detail
|
@@ -1138,8 +1506,10 @@ namespace Rice
|
|
1138
1506
|
using Key_T = typename T::key_type;
|
1139
1507
|
using Mapped_T = typename T::mapped_type;
|
1140
1508
|
using Value_T = typename T::value_type;
|
1509
|
+
using Reference_T = typename T::reference;
|
1141
1510
|
using Size_T = typename T::size_type;
|
1142
1511
|
using Difference_T = typename T::difference_type;
|
1512
|
+
using To_Ruby_T = typename detail::remove_cv_recursive_t<Mapped_T>;
|
1143
1513
|
|
1144
1514
|
public:
|
1145
1515
|
MapHelper(Data_Type<T> klass) : klass_(klass)
|
@@ -1288,7 +1658,7 @@ namespace Rice
|
|
1288
1658
|
return std::nullopt;
|
1289
1659
|
}
|
1290
1660
|
})
|
1291
|
-
.define_method("[]=", [](T& map, Key_T key, Mapped_T value) -> Mapped_T
|
1661
|
+
.define_method("[]=", [](T& map, Key_T key, Mapped_T& value) -> Mapped_T
|
1292
1662
|
{
|
1293
1663
|
map[key] = value;
|
1294
1664
|
return value;
|
@@ -1309,10 +1679,10 @@ namespace Rice
|
|
1309
1679
|
klass_.define_method("to_h", [](T& map)
|
1310
1680
|
{
|
1311
1681
|
VALUE result = rb_hash_new();
|
1312
|
-
std::for_each(map.begin(), map.end(), [&result](const
|
1682
|
+
std::for_each(map.begin(), map.end(), [&result](const Reference_T pair)
|
1313
1683
|
{
|
1314
1684
|
VALUE key = detail::To_Ruby<Key_T&>().convert(pair.first);
|
1315
|
-
VALUE value = detail::To_Ruby<
|
1685
|
+
VALUE value = detail::To_Ruby<To_Ruby_T&>().convert(pair.second);
|
1316
1686
|
rb_hash_aset(result, key, value);
|
1317
1687
|
});
|
1318
1688
|
|
@@ -1359,17 +1729,17 @@ namespace Rice
|
|
1359
1729
|
} // namespace
|
1360
1730
|
|
1361
1731
|
template<typename T>
|
1362
|
-
Data_Type<T> define_map_under(Object
|
1732
|
+
Data_Type<T> define_map_under(Object parent, std::string name)
|
1363
1733
|
{
|
1364
1734
|
if (detail::Registries::instance.types.isDefined<T>())
|
1365
1735
|
{
|
1366
1736
|
// If the map has been previously seen it will be registered but may
|
1367
1737
|
// not be associated with the constant Module::<name>
|
1368
|
-
|
1738
|
+
parent.const_set_maybe(name, Data_Type<T>().klass());
|
1369
1739
|
return Data_Type<T>();
|
1370
1740
|
}
|
1371
1741
|
|
1372
|
-
Data_Type<T> result = define_class_under<detail::intrinsic_type<T>>(
|
1742
|
+
Data_Type<T> result = define_class_under<detail::intrinsic_type<T>>(parent, name.c_str());
|
1373
1743
|
stl::MapHelper helper(result);
|
1374
1744
|
return result;
|
1375
1745
|
}
|
@@ -1393,10 +1763,11 @@ namespace Rice
|
|
1393
1763
|
template<typename T>
|
1394
1764
|
Data_Type<T> define_map_auto()
|
1395
1765
|
{
|
1396
|
-
std::string
|
1766
|
+
std::string name = detail::typeName(typeid(T));
|
1767
|
+
std::string klassName = detail::makeClassName(name);
|
1397
1768
|
Module rb_mRice = define_module("Rice");
|
1398
|
-
Module
|
1399
|
-
return define_map_under<T>(
|
1769
|
+
Module rb_mStd = define_module_under(rb_mRice, "Std");
|
1770
|
+
return define_map_under<T>(rb_mStd, klassName);
|
1400
1771
|
}
|
1401
1772
|
|
1402
1773
|
namespace detail
|
@@ -1457,16 +1828,31 @@ namespace Rice
|
|
1457
1828
|
{
|
1458
1829
|
}
|
1459
1830
|
|
1831
|
+
Convertible is_convertible(VALUE value)
|
1832
|
+
{
|
1833
|
+
switch (rb_type(value))
|
1834
|
+
{
|
1835
|
+
case RUBY_T_DATA:
|
1836
|
+
return Convertible::Exact;
|
1837
|
+
break;
|
1838
|
+
case RUBY_T_HASH:
|
1839
|
+
return Convertible::Cast;
|
1840
|
+
break;
|
1841
|
+
default:
|
1842
|
+
return Convertible::None;
|
1843
|
+
}
|
1844
|
+
}
|
1845
|
+
|
1460
1846
|
std::map<T, U> convert(VALUE value)
|
1461
1847
|
{
|
1462
1848
|
switch (rb_type(value))
|
1463
1849
|
{
|
1464
|
-
case
|
1850
|
+
case RUBY_T_DATA:
|
1465
1851
|
{
|
1466
1852
|
// This is a wrapped map (hopefully!)
|
1467
1853
|
return *Data_Object<std::map<T, U>>::from_ruby(value);
|
1468
1854
|
}
|
1469
|
-
case
|
1855
|
+
case RUBY_T_HASH:
|
1470
1856
|
{
|
1471
1857
|
// If this an Ruby hash and the mapped type is copyable
|
1472
1858
|
if constexpr (std::is_default_constructible_v<U>)
|
@@ -1474,7 +1860,7 @@ namespace Rice
|
|
1474
1860
|
return MapFromHash<T, U>::convert(value);
|
1475
1861
|
}
|
1476
1862
|
}
|
1477
|
-
case
|
1863
|
+
case RUBY_T_NIL:
|
1478
1864
|
{
|
1479
1865
|
if (this->arg_ && this->arg_->hasDefaultValue())
|
1480
1866
|
{
|
@@ -1503,16 +1889,31 @@ namespace Rice
|
|
1503
1889
|
{
|
1504
1890
|
}
|
1505
1891
|
|
1892
|
+
Convertible is_convertible(VALUE value)
|
1893
|
+
{
|
1894
|
+
switch (rb_type(value))
|
1895
|
+
{
|
1896
|
+
case RUBY_T_DATA:
|
1897
|
+
return Convertible::Exact;
|
1898
|
+
break;
|
1899
|
+
case RUBY_T_HASH:
|
1900
|
+
return Convertible::Cast;
|
1901
|
+
break;
|
1902
|
+
default:
|
1903
|
+
return Convertible::None;
|
1904
|
+
}
|
1905
|
+
}
|
1906
|
+
|
1506
1907
|
std::map<T, U>& convert(VALUE value)
|
1507
1908
|
{
|
1508
1909
|
switch (rb_type(value))
|
1509
1910
|
{
|
1510
|
-
case
|
1911
|
+
case RUBY_T_DATA:
|
1511
1912
|
{
|
1512
1913
|
// This is a wrapped map (hopefully!)
|
1513
1914
|
return *Data_Object<std::map<T, U>>::from_ruby(value);
|
1514
1915
|
}
|
1515
|
-
case
|
1916
|
+
case RUBY_T_HASH:
|
1516
1917
|
{
|
1517
1918
|
// If this an Ruby array and the map type is copyable
|
1518
1919
|
if constexpr (std::is_default_constructible_v<std::map<T, U>>)
|
@@ -1521,7 +1922,7 @@ namespace Rice
|
|
1521
1922
|
return this->converted_;
|
1522
1923
|
}
|
1523
1924
|
}
|
1524
|
-
case
|
1925
|
+
case RUBY_T_NIL:
|
1525
1926
|
{
|
1526
1927
|
if (this->arg_ && this->arg_->hasDefaultValue())
|
1527
1928
|
{
|
@@ -1545,16 +1946,34 @@ namespace Rice
|
|
1545
1946
|
class From_Ruby<std::map<T, U>*>
|
1546
1947
|
{
|
1547
1948
|
public:
|
1949
|
+
Convertible is_convertible(VALUE value)
|
1950
|
+
{
|
1951
|
+
switch (rb_type(value))
|
1952
|
+
{
|
1953
|
+
case RUBY_T_DATA:
|
1954
|
+
return Convertible::Exact;
|
1955
|
+
break;
|
1956
|
+
case RUBY_T_NIL:
|
1957
|
+
return Convertible::Exact;
|
1958
|
+
break;
|
1959
|
+
case RUBY_T_HASH:
|
1960
|
+
return Convertible::Cast;
|
1961
|
+
break;
|
1962
|
+
default:
|
1963
|
+
return Convertible::None;
|
1964
|
+
}
|
1965
|
+
}
|
1966
|
+
|
1548
1967
|
std::map<T, U>* convert(VALUE value)
|
1549
1968
|
{
|
1550
1969
|
switch (rb_type(value))
|
1551
1970
|
{
|
1552
|
-
case
|
1971
|
+
case RUBY_T_DATA:
|
1553
1972
|
{
|
1554
1973
|
// This is a wrapped map (hopefully!)
|
1555
1974
|
return Data_Object<std::map<T, U>>::from_ruby(value);
|
1556
1975
|
}
|
1557
|
-
case
|
1976
|
+
case RUBY_T_HASH:
|
1558
1977
|
{
|
1559
1978
|
// If this an Ruby array and the map type is copyable
|
1560
1979
|
if constexpr (std::is_default_constructible_v<U>)
|
@@ -1586,7 +2005,7 @@ namespace Rice
|
|
1586
2005
|
Data_Type<U> define_unordered_map(std::string name);
|
1587
2006
|
|
1588
2007
|
template<typename U>
|
1589
|
-
Data_Type<U> define_unordered_map_under(Object
|
2008
|
+
Data_Type<U> define_unordered_map_under(Object parent, std::string name);
|
1590
2009
|
}
|
1591
2010
|
|
1592
2011
|
|
@@ -1608,8 +2027,10 @@ namespace Rice
|
|
1608
2027
|
using Key_T = typename T::key_type;
|
1609
2028
|
using Mapped_T = typename T::mapped_type;
|
1610
2029
|
using Value_T = typename T::value_type;
|
2030
|
+
using Reference_T = typename T::reference;
|
1611
2031
|
using Size_T = typename T::size_type;
|
1612
2032
|
using Difference_T = typename T::difference_type;
|
2033
|
+
using To_Ruby_T = typename detail::remove_cv_recursive_t<Mapped_T>;
|
1613
2034
|
|
1614
2035
|
public:
|
1615
2036
|
UnorderedMapHelper(Data_Type<T> klass) : klass_(klass)
|
@@ -1758,7 +2179,7 @@ namespace Rice
|
|
1758
2179
|
return std::nullopt;
|
1759
2180
|
}
|
1760
2181
|
})
|
1761
|
-
.define_method("[]=", [](T& unordered_map, Key_T key, Mapped_T value) -> Mapped_T
|
2182
|
+
.define_method("[]=", [](T& unordered_map, Key_T key, Mapped_T& value) -> Mapped_T
|
1762
2183
|
{
|
1763
2184
|
unordered_map[key] = value;
|
1764
2185
|
return value;
|
@@ -1779,10 +2200,10 @@ namespace Rice
|
|
1779
2200
|
klass_.define_method("to_h", [](T& unordered_map)
|
1780
2201
|
{
|
1781
2202
|
VALUE result = rb_hash_new();
|
1782
|
-
std::for_each(unordered_map.begin(), unordered_map.end(), [&result](const
|
2203
|
+
std::for_each(unordered_map.begin(), unordered_map.end(), [&result](const Reference_T& pair)
|
1783
2204
|
{
|
1784
|
-
VALUE key = detail::To_Ruby<Key_T
|
1785
|
-
VALUE value = detail::To_Ruby<
|
2205
|
+
VALUE key = detail::To_Ruby<Key_T&>().convert(pair.first);
|
2206
|
+
VALUE value = detail::To_Ruby<To_Ruby_T&>().convert(pair.second);
|
1786
2207
|
rb_hash_aset(result, key, value);
|
1787
2208
|
});
|
1788
2209
|
|
@@ -1829,17 +2250,17 @@ namespace Rice
|
|
1829
2250
|
} // namespace
|
1830
2251
|
|
1831
2252
|
template<typename T>
|
1832
|
-
Data_Type<T> define_unordered_map_under(Object
|
2253
|
+
Data_Type<T> define_unordered_map_under(Object parent, std::string name)
|
1833
2254
|
{
|
1834
2255
|
if (detail::Registries::instance.types.isDefined<T>())
|
1835
2256
|
{
|
1836
2257
|
// If the unordered_map has been previously seen it will be registered but may
|
1837
2258
|
// not be associated with the constant Module::<name>
|
1838
|
-
|
2259
|
+
parent.const_set_maybe(name, Data_Type<T>().klass());
|
1839
2260
|
return Data_Type<T>();
|
1840
2261
|
}
|
1841
2262
|
|
1842
|
-
Data_Type<T> result = define_class_under<detail::intrinsic_type<T>>(
|
2263
|
+
Data_Type<T> result = define_class_under<detail::intrinsic_type<T>>(parent, name.c_str());
|
1843
2264
|
stl::UnorderedMapHelper helper(result);
|
1844
2265
|
return result;
|
1845
2266
|
}
|
@@ -1863,10 +2284,11 @@ namespace Rice
|
|
1863
2284
|
template<typename T>
|
1864
2285
|
Data_Type<T> define_unordered_map_auto()
|
1865
2286
|
{
|
1866
|
-
std::string
|
2287
|
+
std::string name = detail::typeName(typeid(T));
|
2288
|
+
std::string klassName = detail::makeClassName(name);
|
1867
2289
|
Module rb_mRice = define_module("Rice");
|
1868
|
-
Module
|
1869
|
-
return define_unordered_map_under<T>(
|
2290
|
+
Module rb_mStd = define_module_under(rb_mRice, "Std");
|
2291
|
+
return define_unordered_map_under<T>(rb_mStd, klassName);
|
1870
2292
|
}
|
1871
2293
|
|
1872
2294
|
namespace detail
|
@@ -1927,16 +2349,31 @@ namespace Rice
|
|
1927
2349
|
{
|
1928
2350
|
}
|
1929
2351
|
|
2352
|
+
Convertible is_convertible(VALUE value)
|
2353
|
+
{
|
2354
|
+
switch (rb_type(value))
|
2355
|
+
{
|
2356
|
+
case RUBY_T_DATA:
|
2357
|
+
return Convertible::Exact;
|
2358
|
+
break;
|
2359
|
+
case RUBY_T_HASH:
|
2360
|
+
return Convertible::Cast;
|
2361
|
+
break;
|
2362
|
+
default:
|
2363
|
+
return Convertible::None;
|
2364
|
+
}
|
2365
|
+
}
|
2366
|
+
|
1930
2367
|
std::unordered_map<T, U> convert(VALUE value)
|
1931
2368
|
{
|
1932
2369
|
switch (rb_type(value))
|
1933
2370
|
{
|
1934
|
-
case
|
2371
|
+
case RUBY_T_DATA:
|
1935
2372
|
{
|
1936
2373
|
// This is a wrapped unordered_map (hopefully!)
|
1937
2374
|
return *Data_Object<std::unordered_map<T, U>>::from_ruby(value);
|
1938
2375
|
}
|
1939
|
-
case
|
2376
|
+
case RUBY_T_HASH:
|
1940
2377
|
{
|
1941
2378
|
// If this an Ruby hash and the unordered_mapped type is copyable
|
1942
2379
|
if constexpr (std::is_default_constructible_v<U>)
|
@@ -1944,7 +2381,7 @@ namespace Rice
|
|
1944
2381
|
return UnorderedMapFromHash<T, U>::convert(value);
|
1945
2382
|
}
|
1946
2383
|
}
|
1947
|
-
case
|
2384
|
+
case RUBY_T_NIL:
|
1948
2385
|
{
|
1949
2386
|
if (this->arg_ && this->arg_->hasDefaultValue())
|
1950
2387
|
{
|
@@ -1973,16 +2410,31 @@ namespace Rice
|
|
1973
2410
|
{
|
1974
2411
|
}
|
1975
2412
|
|
2413
|
+
Convertible is_convertible(VALUE value)
|
2414
|
+
{
|
2415
|
+
switch (rb_type(value))
|
2416
|
+
{
|
2417
|
+
case RUBY_T_DATA:
|
2418
|
+
return Convertible::Exact;
|
2419
|
+
break;
|
2420
|
+
case RUBY_T_HASH:
|
2421
|
+
return Convertible::Cast;
|
2422
|
+
break;
|
2423
|
+
default:
|
2424
|
+
return Convertible::None;
|
2425
|
+
}
|
2426
|
+
}
|
2427
|
+
|
1976
2428
|
std::unordered_map<T, U>& convert(VALUE value)
|
1977
2429
|
{
|
1978
2430
|
switch (rb_type(value))
|
1979
2431
|
{
|
1980
|
-
case
|
2432
|
+
case RUBY_T_DATA:
|
1981
2433
|
{
|
1982
2434
|
// This is a wrapped unordered_map (hopefully!)
|
1983
2435
|
return *Data_Object<std::unordered_map<T, U>>::from_ruby(value);
|
1984
2436
|
}
|
1985
|
-
case
|
2437
|
+
case RUBY_T_HASH:
|
1986
2438
|
{
|
1987
2439
|
// If this an Ruby array and the unordered_map type is copyable
|
1988
2440
|
if constexpr (std::is_default_constructible_v<std::unordered_map<T, U>>)
|
@@ -1991,7 +2443,7 @@ namespace Rice
|
|
1991
2443
|
return this->converted_;
|
1992
2444
|
}
|
1993
2445
|
}
|
1994
|
-
case
|
2446
|
+
case RUBY_T_NIL:
|
1995
2447
|
{
|
1996
2448
|
if (this->arg_ && this->arg_->hasDefaultValue())
|
1997
2449
|
{
|
@@ -2015,16 +2467,34 @@ namespace Rice
|
|
2015
2467
|
class From_Ruby<std::unordered_map<T, U>*>
|
2016
2468
|
{
|
2017
2469
|
public:
|
2470
|
+
Convertible is_convertible(VALUE value)
|
2471
|
+
{
|
2472
|
+
switch (rb_type(value))
|
2473
|
+
{
|
2474
|
+
case RUBY_T_DATA:
|
2475
|
+
return Convertible::Exact;
|
2476
|
+
break;
|
2477
|
+
case RUBY_T_NIL:
|
2478
|
+
return Convertible::Exact;
|
2479
|
+
break;
|
2480
|
+
case RUBY_T_HASH:
|
2481
|
+
return Convertible::Cast;
|
2482
|
+
break;
|
2483
|
+
default:
|
2484
|
+
return Convertible::None;
|
2485
|
+
}
|
2486
|
+
}
|
2487
|
+
|
2018
2488
|
std::unordered_map<T, U>* convert(VALUE value)
|
2019
2489
|
{
|
2020
2490
|
switch (rb_type(value))
|
2021
2491
|
{
|
2022
|
-
case
|
2492
|
+
case RUBY_T_DATA:
|
2023
2493
|
{
|
2024
2494
|
// This is a wrapped unordered_map (hopefully!)
|
2025
2495
|
return Data_Object<std::unordered_map<T, U>>::from_ruby(value);
|
2026
2496
|
}
|
2027
|
-
case
|
2497
|
+
case RUBY_T_HASH:
|
2028
2498
|
{
|
2029
2499
|
// If this an Ruby array and the unordered_map type is copyable
|
2030
2500
|
if constexpr (std::is_default_constructible_v<U>)
|
@@ -2056,7 +2526,7 @@ namespace Rice
|
|
2056
2526
|
Data_Type<T> define_vector(std::string name);
|
2057
2527
|
|
2058
2528
|
template<typename T>
|
2059
|
-
Data_Type<T> define_vector_under(Object
|
2529
|
+
Data_Type<T> define_vector_under(Object parent, std::string name);
|
2060
2530
|
}
|
2061
2531
|
|
2062
2532
|
|
@@ -2075,9 +2545,17 @@ namespace Rice
|
|
2075
2545
|
template<typename T>
|
2076
2546
|
class VectorHelper
|
2077
2547
|
{
|
2548
|
+
// We do NOT use Reference_T and instead use Parameter_T to avoid the weirdness
|
2549
|
+
// of std::vector<bool>. Reference_T is actually a proxy class that we do not
|
2550
|
+
// want to have to register with Rice nor do we want to pass it around.
|
2078
2551
|
using Value_T = typename T::value_type;
|
2079
2552
|
using Size_T = typename T::size_type;
|
2080
2553
|
using Difference_T = typename T::difference_type;
|
2554
|
+
// For To_Ruby_T however we do need to use reference type because this is what
|
2555
|
+
// will be passed by an interator to To_Ruby#convert
|
2556
|
+
using Reference_T = typename T::reference;
|
2557
|
+
using Parameter_T = std::conditional_t<std::is_pointer_v<Value_T>, Value_T, Value_T&>;
|
2558
|
+
using To_Ruby_T = detail::remove_cv_recursive_t<typename T::reference>;
|
2081
2559
|
|
2082
2560
|
public:
|
2083
2561
|
VectorHelper(Data_Type<T> klass) : klass_(klass)
|
@@ -2141,7 +2619,11 @@ namespace Rice
|
|
2141
2619
|
|
2142
2620
|
void define_constructable_methods()
|
2143
2621
|
{
|
2144
|
-
if constexpr (std::is_default_constructible_v<Value_T>)
|
2622
|
+
if constexpr (std::is_default_constructible_v<Value_T> && std::is_same_v<Value_T, bool>)
|
2623
|
+
{
|
2624
|
+
klass_.define_method("resize", static_cast<void (T::*)(const size_t, bool)>(&T::resize));
|
2625
|
+
}
|
2626
|
+
else if constexpr (std::is_default_constructible_v<Value_T>)
|
2145
2627
|
{
|
2146
2628
|
klass_.define_method("resize", static_cast<void (T::*)(const size_t)>(&T::resize));
|
2147
2629
|
}
|
@@ -2172,41 +2654,71 @@ namespace Rice
|
|
2172
2654
|
{
|
2173
2655
|
// Access methods
|
2174
2656
|
klass_.define_method("first", [](const T& vector) -> std::optional<Value_T>
|
2657
|
+
{
|
2658
|
+
if (vector.size() > 0)
|
2659
|
+
{
|
2660
|
+
return vector.front();
|
2661
|
+
}
|
2662
|
+
else
|
2663
|
+
{
|
2664
|
+
return std::nullopt;
|
2665
|
+
}
|
2666
|
+
})
|
2667
|
+
.define_method("last", [](const T& vector) -> std::optional<Value_T>
|
2175
2668
|
{
|
2176
2669
|
if (vector.size() > 0)
|
2177
2670
|
{
|
2178
|
-
return vector.
|
2671
|
+
return vector.back();
|
2179
2672
|
}
|
2180
2673
|
else
|
2181
2674
|
{
|
2182
2675
|
return std::nullopt;
|
2183
2676
|
}
|
2184
2677
|
})
|
2185
|
-
|
2678
|
+
.define_method("[]", [this](const T& vector, Difference_T index) -> std::optional<Value_T>
|
2679
|
+
{
|
2680
|
+
index = normalizeIndex(vector.size(), index);
|
2681
|
+
if (index < 0 || index >= (Difference_T)vector.size())
|
2186
2682
|
{
|
2187
|
-
|
2188
|
-
|
2189
|
-
|
2190
|
-
|
2191
|
-
|
2683
|
+
return std::nullopt;
|
2684
|
+
}
|
2685
|
+
else
|
2686
|
+
{
|
2687
|
+
return vector[index];
|
2688
|
+
}
|
2689
|
+
})
|
2690
|
+
.define_method("[]", [this](const T& vector, Difference_T start, Difference_T length) -> VALUE
|
2691
|
+
{
|
2692
|
+
start = normalizeIndex(vector.size(), start);
|
2693
|
+
if (start < 0 || start >= (Difference_T)vector.size())
|
2694
|
+
{
|
2695
|
+
return rb_ary_new();
|
2696
|
+
}
|
2697
|
+
else
|
2698
|
+
{
|
2699
|
+
auto begin = vector.begin() + start;
|
2700
|
+
|
2701
|
+
// Ruby does not throw an exception when the length is too long
|
2702
|
+
if (start + length > vector.size())
|
2192
2703
|
{
|
2193
|
-
|
2704
|
+
length = vector.size() - start;
|
2194
2705
|
}
|
2195
|
-
|
2196
|
-
|
2706
|
+
|
2707
|
+
auto finish = vector.begin() + start + length;
|
2708
|
+
T slice(begin, finish);
|
2709
|
+
|
2710
|
+
VALUE result = rb_ary_new();
|
2711
|
+
std::for_each(slice.begin(), slice.end(), [&result](const Reference_T element)
|
2197
2712
|
{
|
2198
|
-
|
2199
|
-
|
2200
|
-
{
|
2201
|
-
return std::nullopt;
|
2202
|
-
}
|
2203
|
-
else
|
2204
|
-
{
|
2205
|
-
return vector[index];
|
2206
|
-
}
|
2713
|
+
VALUE value = detail::To_Ruby<Parameter_T>().convert(element);
|
2714
|
+
rb_ary_push(result, value);
|
2207
2715
|
});
|
2208
2716
|
|
2209
|
-
|
2717
|
+
return result;
|
2718
|
+
}
|
2719
|
+
}, Return().setValue());
|
2720
|
+
|
2721
|
+
rb_define_alias(klass_, "at", "[]");
|
2210
2722
|
}
|
2211
2723
|
|
2212
2724
|
// Methods that require Value_T to support operator==
|
@@ -2214,7 +2726,7 @@ namespace Rice
|
|
2214
2726
|
{
|
2215
2727
|
if constexpr (detail::is_comparable_v<Value_T>)
|
2216
2728
|
{
|
2217
|
-
klass_.define_method("delete", [](T& vector,
|
2729
|
+
klass_.define_method("delete", [](T& vector, Parameter_T element) -> std::optional<Value_T>
|
2218
2730
|
{
|
2219
2731
|
auto iter = std::find(vector.begin(), vector.end(), element);
|
2220
2732
|
if (iter == vector.end())
|
@@ -2228,11 +2740,11 @@ namespace Rice
|
|
2228
2740
|
return result;
|
2229
2741
|
}
|
2230
2742
|
})
|
2231
|
-
.define_method("include?", [](T& vector,
|
2743
|
+
.define_method("include?", [](T& vector, Parameter_T element)
|
2232
2744
|
{
|
2233
2745
|
return std::find(vector.begin(), vector.end(), element) != vector.end();
|
2234
2746
|
})
|
2235
|
-
.define_method("index", [](T& vector,
|
2747
|
+
.define_method("index", [](T& vector, Parameter_T element) -> std::optional<Difference_T>
|
2236
2748
|
{
|
2237
2749
|
auto iter = std::find(vector.begin(), vector.end(), element);
|
2238
2750
|
if (iter == vector.end())
|
@@ -2247,15 +2759,15 @@ namespace Rice
|
|
2247
2759
|
}
|
2248
2760
|
else
|
2249
2761
|
{
|
2250
|
-
klass_.define_method("delete", [](T& vector,
|
2762
|
+
klass_.define_method("delete", [](T& vector, Parameter_T element) -> std::optional<Value_T>
|
2251
2763
|
{
|
2252
2764
|
return std::nullopt;
|
2253
2765
|
})
|
2254
|
-
.define_method("include?", [](const T& vector,
|
2766
|
+
.define_method("include?", [](const T& vector, Parameter_T element)
|
2255
2767
|
{
|
2256
2768
|
return false;
|
2257
2769
|
})
|
2258
|
-
.define_method("index", [](const T& vector,
|
2770
|
+
.define_method("index", [](const T& vector, Parameter_T element) -> std::optional<Difference_T>
|
2259
2771
|
{
|
2260
2772
|
return std::nullopt;
|
2261
2773
|
});
|
@@ -2272,7 +2784,7 @@ namespace Rice
|
|
2272
2784
|
vector.erase(iter);
|
2273
2785
|
return result;
|
2274
2786
|
})
|
2275
|
-
.define_method("insert", [this](T& vector, Difference_T index,
|
2787
|
+
.define_method("insert", [this](T& vector, Difference_T index, Parameter_T element) -> T&
|
2276
2788
|
{
|
2277
2789
|
index = normalizeIndex(vector.size(), index, true);
|
2278
2790
|
auto iter = vector.begin() + index;
|
@@ -2292,13 +2804,13 @@ namespace Rice
|
|
2292
2804
|
return std::nullopt;
|
2293
2805
|
}
|
2294
2806
|
})
|
2295
|
-
.define_method("push", [](T& vector,
|
2807
|
+
.define_method("push", [](T& vector, Parameter_T element) -> T&
|
2296
2808
|
{
|
2297
2809
|
vector.push_back(element);
|
2298
2810
|
return vector;
|
2299
2811
|
})
|
2300
2812
|
.define_method("shrink_to_fit", &T::shrink_to_fit)
|
2301
|
-
.define_method("[]=", [this](T& vector, Difference_T index,
|
2813
|
+
.define_method("[]=", [this](T& vector, Difference_T index, Parameter_T element) -> Parameter_T
|
2302
2814
|
{
|
2303
2815
|
index = normalizeIndex(vector.size(), index, true);
|
2304
2816
|
vector[index] = element;
|
@@ -2321,9 +2833,9 @@ namespace Rice
|
|
2321
2833
|
klass_.define_method("to_a", [](T& vector)
|
2322
2834
|
{
|
2323
2835
|
VALUE result = rb_ary_new();
|
2324
|
-
std::for_each(vector.begin(), vector.end(), [&result](const
|
2836
|
+
std::for_each(vector.begin(), vector.end(), [&result](const Reference_T element)
|
2325
2837
|
{
|
2326
|
-
VALUE value = detail::To_Ruby<
|
2838
|
+
VALUE value = detail::To_Ruby<Parameter_T>().convert(element);
|
2327
2839
|
rb_ary_push(result, value);
|
2328
2840
|
});
|
2329
2841
|
|
@@ -2374,18 +2886,19 @@ namespace Rice
|
|
2374
2886
|
} // namespace
|
2375
2887
|
|
2376
2888
|
template<typename T>
|
2377
|
-
Data_Type<T> define_vector_under(Object
|
2889
|
+
Data_Type<T> define_vector_under(Object parent, std::string name)
|
2378
2890
|
{
|
2379
2891
|
if (detail::Registries::instance.types.isDefined<T>())
|
2380
2892
|
{
|
2381
2893
|
// If the vector has been previously seen it will be registered but may
|
2382
2894
|
// not be associated with the constant Module::<name>
|
2383
|
-
|
2895
|
+
parent.const_set_maybe(name, Data_Type<T>().klass());
|
2384
2896
|
|
2385
2897
|
return Data_Type<T>();
|
2386
2898
|
}
|
2387
2899
|
|
2388
|
-
|
2900
|
+
Identifier id(name);
|
2901
|
+
Data_Type<T> result = define_class_under<detail::intrinsic_type<T>>(parent, id, rb_cObject);
|
2389
2902
|
stl::VectorHelper helper(result);
|
2390
2903
|
return result;
|
2391
2904
|
}
|
@@ -2410,10 +2923,11 @@ namespace Rice
|
|
2410
2923
|
template<typename T>
|
2411
2924
|
Data_Type<T> define_vector_auto()
|
2412
2925
|
{
|
2413
|
-
std::string
|
2926
|
+
std::string name = detail::typeName(typeid(T));
|
2927
|
+
std::string klassName = detail::makeClassName(name);
|
2414
2928
|
Module rb_mRice = define_module("Rice");
|
2415
|
-
Module
|
2416
|
-
return define_vector_under<T>(
|
2929
|
+
Module rb_mStd = define_module_under(rb_mRice, "Std");
|
2930
|
+
return define_vector_under<T>(rb_mStd, klassName);
|
2417
2931
|
}
|
2418
2932
|
|
2419
2933
|
namespace detail
|
@@ -2434,20 +2948,6 @@ namespace Rice
|
|
2434
2948
|
}
|
2435
2949
|
};
|
2436
2950
|
|
2437
|
-
template<typename T>
|
2438
|
-
std::vector<T> vectorFromArray(VALUE value)
|
2439
|
-
{
|
2440
|
-
long length = protect(rb_array_len, value);
|
2441
|
-
std::vector<T> result(length);
|
2442
|
-
|
2443
|
-
for (long i = 0; i < length; i++)
|
2444
|
-
{
|
2445
|
-
VALUE element = protect(rb_ary_entry, value, i);
|
2446
|
-
result[i] = From_Ruby<T>().convert(element);
|
2447
|
-
}
|
2448
|
-
|
2449
|
-
return result;
|
2450
|
-
}
|
2451
2951
|
|
2452
2952
|
template<typename T>
|
2453
2953
|
class From_Ruby<std::vector<T>>
|
@@ -2459,24 +2959,39 @@ namespace Rice
|
|
2459
2959
|
{
|
2460
2960
|
}
|
2461
2961
|
|
2962
|
+
Convertible is_convertible(VALUE value)
|
2963
|
+
{
|
2964
|
+
switch (rb_type(value))
|
2965
|
+
{
|
2966
|
+
case RUBY_T_DATA:
|
2967
|
+
return Convertible::Exact;
|
2968
|
+
break;
|
2969
|
+
case RUBY_T_ARRAY:
|
2970
|
+
return Convertible::Cast;
|
2971
|
+
break;
|
2972
|
+
default:
|
2973
|
+
return Convertible::None;
|
2974
|
+
}
|
2975
|
+
}
|
2976
|
+
|
2462
2977
|
std::vector<T> convert(VALUE value)
|
2463
2978
|
{
|
2464
2979
|
switch (rb_type(value))
|
2465
2980
|
{
|
2466
|
-
case
|
2981
|
+
case RUBY_T_DATA:
|
2467
2982
|
{
|
2468
2983
|
// This is a wrapped vector (hopefully!)
|
2469
2984
|
return *Data_Object<std::vector<T>>::from_ruby(value);
|
2470
2985
|
}
|
2471
|
-
case
|
2986
|
+
case RUBY_T_ARRAY:
|
2472
2987
|
{
|
2473
2988
|
// If this an Ruby array and the vector type is copyable
|
2474
2989
|
if constexpr (std::is_default_constructible_v<T>)
|
2475
2990
|
{
|
2476
|
-
return
|
2991
|
+
return Array(value).to_vector<T>();
|
2477
2992
|
}
|
2478
2993
|
}
|
2479
|
-
case
|
2994
|
+
case RUBY_T_NIL:
|
2480
2995
|
{
|
2481
2996
|
if (this->arg_ && this->arg_->hasDefaultValue())
|
2482
2997
|
{
|
@@ -2491,11 +3006,6 @@ namespace Rice
|
|
2491
3006
|
}
|
2492
3007
|
}
|
2493
3008
|
|
2494
|
-
bool is_convertible(VALUE value)
|
2495
|
-
{
|
2496
|
-
return rb_type(value) == RUBY_T_ARRAY;
|
2497
|
-
}
|
2498
|
-
|
2499
3009
|
private:
|
2500
3010
|
Arg* arg_ = nullptr;
|
2501
3011
|
};
|
@@ -2510,25 +3020,40 @@ namespace Rice
|
|
2510
3020
|
{
|
2511
3021
|
}
|
2512
3022
|
|
3023
|
+
Convertible is_convertible(VALUE value)
|
3024
|
+
{
|
3025
|
+
switch (rb_type(value))
|
3026
|
+
{
|
3027
|
+
case RUBY_T_DATA:
|
3028
|
+
return Convertible::Exact;
|
3029
|
+
break;
|
3030
|
+
case RUBY_T_ARRAY:
|
3031
|
+
return Convertible::Cast;
|
3032
|
+
break;
|
3033
|
+
default:
|
3034
|
+
return Convertible::None;
|
3035
|
+
}
|
3036
|
+
}
|
3037
|
+
|
2513
3038
|
std::vector<T>& convert(VALUE value)
|
2514
3039
|
{
|
2515
3040
|
switch (rb_type(value))
|
2516
3041
|
{
|
2517
|
-
case
|
3042
|
+
case RUBY_T_DATA:
|
2518
3043
|
{
|
2519
3044
|
// This is a wrapped vector (hopefully!)
|
2520
3045
|
return *Data_Object<std::vector<T>>::from_ruby(value);
|
2521
3046
|
}
|
2522
|
-
case
|
3047
|
+
case RUBY_T_ARRAY:
|
2523
3048
|
{
|
2524
3049
|
// If this an Ruby array and the vector type is copyable
|
2525
3050
|
if constexpr (std::is_default_constructible_v<T>)
|
2526
3051
|
{
|
2527
|
-
this->converted_ =
|
3052
|
+
this->converted_ = Array(value).to_vector<T>();
|
2528
3053
|
return this->converted_;
|
2529
3054
|
}
|
2530
3055
|
}
|
2531
|
-
case
|
3056
|
+
case RUBY_T_NIL:
|
2532
3057
|
{
|
2533
3058
|
if (this->arg_ && this->arg_->hasDefaultValue())
|
2534
3059
|
{
|
@@ -2543,11 +3068,6 @@ namespace Rice
|
|
2543
3068
|
}
|
2544
3069
|
}
|
2545
3070
|
|
2546
|
-
bool is_convertible(VALUE value)
|
2547
|
-
{
|
2548
|
-
return rb_type(value) == RUBY_T_ARRAY;
|
2549
|
-
}
|
2550
|
-
|
2551
3071
|
private:
|
2552
3072
|
Arg* arg_ = nullptr;
|
2553
3073
|
std::vector<T> converted_;
|
@@ -2557,21 +3077,39 @@ namespace Rice
|
|
2557
3077
|
class From_Ruby<std::vector<T>*>
|
2558
3078
|
{
|
2559
3079
|
public:
|
3080
|
+
Convertible is_convertible(VALUE value)
|
3081
|
+
{
|
3082
|
+
switch (rb_type(value))
|
3083
|
+
{
|
3084
|
+
case RUBY_T_DATA:
|
3085
|
+
return Convertible::Exact;
|
3086
|
+
break;
|
3087
|
+
case RUBY_T_NIL:
|
3088
|
+
return Convertible::Exact;
|
3089
|
+
break;
|
3090
|
+
case RUBY_T_ARRAY:
|
3091
|
+
return Convertible::Cast;
|
3092
|
+
break;
|
3093
|
+
default:
|
3094
|
+
return Convertible::None;
|
3095
|
+
}
|
3096
|
+
}
|
3097
|
+
|
2560
3098
|
std::vector<T>* convert(VALUE value)
|
2561
3099
|
{
|
2562
3100
|
switch (rb_type(value))
|
2563
3101
|
{
|
2564
|
-
case
|
3102
|
+
case RUBY_T_DATA:
|
2565
3103
|
{
|
2566
3104
|
// This is a wrapped vector (hopefully!)
|
2567
3105
|
return Data_Object<std::vector<T>>::from_ruby(value);
|
2568
3106
|
}
|
2569
|
-
case
|
3107
|
+
case RUBY_T_ARRAY:
|
2570
3108
|
{
|
2571
|
-
// If this
|
3109
|
+
// If this a Ruby array and the vector type is copyable
|
2572
3110
|
if constexpr (std::is_default_constructible_v<T>)
|
2573
3111
|
{
|
2574
|
-
this->converted_ =
|
3112
|
+
this->converted_ = Array(value).to_vector<T>();
|
2575
3113
|
return &this->converted_;
|
2576
3114
|
}
|
2577
3115
|
}
|
@@ -2583,15 +3121,24 @@ namespace Rice
|
|
2583
3121
|
}
|
2584
3122
|
}
|
2585
3123
|
|
2586
|
-
bool is_convertible(VALUE value)
|
2587
|
-
{
|
2588
|
-
return rb_type(value) == RUBY_T_ARRAY;
|
2589
|
-
}
|
2590
|
-
|
2591
3124
|
private:
|
2592
3125
|
std::vector<T> converted_;
|
2593
3126
|
};
|
2594
3127
|
}
|
3128
|
+
|
3129
|
+
// Special handling for std::vector<bool>
|
3130
|
+
namespace detail
|
3131
|
+
{
|
3132
|
+
template<>
|
3133
|
+
class To_Ruby<std::vector<bool>::reference>
|
3134
|
+
{
|
3135
|
+
public:
|
3136
|
+
VALUE convert(const std::vector<bool>::reference& value)
|
3137
|
+
{
|
3138
|
+
return value ? Qtrue : Qfalse;
|
3139
|
+
}
|
3140
|
+
};
|
3141
|
+
}
|
2595
3142
|
}
|
2596
3143
|
|
2597
3144
|
|