rice 4.3.3 → 4.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +63 -26
- data/README.md +7 -2
- data/Rakefile +7 -1
- data/include/rice/rice.hpp +7291 -4430
- 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 -15
- data/rice/detail/NativeRegistry.ipp +23 -48
- 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
|
|