rice 4.0.4 → 4.2.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 +37 -0
- data/CONTRIBUTORS.md +2 -0
- data/Rakefile +1 -1
- data/include/rice/rice.hpp +2851 -1955
- data/include/rice/stl.hpp +1654 -287
- data/lib/mkmf-rice.rb +5 -2
- data/lib/version.rb +1 -1
- data/rice/Arg.hpp +6 -6
- data/rice/Arg.ipp +8 -9
- data/rice/Constructor.hpp +2 -2
- data/rice/Data_Object.ipp +69 -15
- data/rice/Data_Object_defn.hpp +1 -15
- data/rice/Data_Type.ipp +56 -86
- data/rice/Data_Type_defn.hpp +14 -17
- data/rice/Director.hpp +0 -1
- data/rice/Enum.ipp +31 -22
- data/rice/Exception.ipp +2 -3
- data/rice/Exception_defn.hpp +5 -5
- data/rice/HandlerRegistration.hpp +15 -0
- data/rice/Return.hpp +5 -4
- data/rice/Return.ipp +8 -3
- data/rice/detail/ExceptionHandler.hpp +8 -0
- data/rice/detail/ExceptionHandler.ipp +28 -0
- data/rice/detail/{Exception_Handler_defn.hpp → ExceptionHandler_defn.hpp} +17 -21
- data/rice/detail/HandlerRegistry.hpp +51 -0
- data/rice/detail/HandlerRegistry.ipp +20 -0
- data/rice/detail/InstanceRegistry.hpp +34 -0
- data/rice/detail/InstanceRegistry.ipp +50 -0
- data/rice/detail/MethodInfo.ipp +1 -1
- data/rice/detail/NativeAttribute.hpp +26 -15
- data/rice/detail/NativeAttribute.ipp +76 -47
- data/rice/detail/NativeFunction.hpp +64 -14
- data/rice/detail/NativeFunction.ipp +138 -86
- data/rice/detail/NativeIterator.hpp +49 -0
- data/rice/detail/NativeIterator.ipp +102 -0
- data/rice/detail/NativeRegistry.hpp +31 -0
- data/rice/detail/{method_data.ipp → NativeRegistry.ipp} +20 -16
- data/rice/detail/Registries.hpp +26 -0
- data/rice/detail/Registries.ipp +23 -0
- data/rice/detail/RubyFunction.hpp +6 -11
- data/rice/detail/RubyFunction.ipp +10 -22
- data/rice/detail/Type.hpp +1 -1
- data/rice/detail/Type.ipp +2 -2
- data/rice/detail/TypeRegistry.hpp +8 -11
- data/rice/detail/TypeRegistry.ipp +3 -28
- data/rice/detail/Wrapper.hpp +0 -2
- data/rice/detail/Wrapper.ipp +74 -24
- data/rice/detail/cpp_protect.hpp +93 -0
- data/rice/detail/default_allocation_func.ipp +1 -1
- data/rice/detail/from_ruby.ipp +206 -2
- data/rice/detail/to_ruby.ipp +39 -5
- data/rice/detail/to_ruby_defn.hpp +1 -1
- data/rice/forward_declares.ipp +6 -0
- data/rice/global_function.hpp +0 -4
- data/rice/global_function.ipp +0 -6
- data/rice/rice.hpp +29 -24
- data/rice/stl.hpp +6 -1
- data/sample/callbacks/extconf.rb +0 -1
- data/sample/enum/extconf.rb +0 -1
- data/sample/inheritance/extconf.rb +0 -1
- data/sample/map/extconf.rb +0 -1
- data/test/embed_ruby.cpp +6 -15
- data/test/ext/t1/extconf.rb +0 -1
- data/test/ext/t2/extconf.rb +0 -1
- data/test/extconf.rb +0 -1
- data/test/test_Array.cpp +20 -24
- data/test/test_Attribute.cpp +6 -6
- data/test/test_Class.cpp +8 -47
- data/test/test_Constructor.cpp +0 -2
- data/test/test_Data_Object.cpp +25 -11
- data/test/test_Data_Type.cpp +124 -28
- data/test/test_Director.cpp +12 -13
- data/test/test_Enum.cpp +65 -26
- data/test/test_Inheritance.cpp +9 -9
- data/test/test_Iterator.cpp +134 -5
- data/test/test_Keep_Alive.cpp +7 -7
- data/test/test_Keep_Alive_No_Wrapper.cpp +80 -0
- data/test/test_Memory_Management.cpp +1 -1
- data/test/test_Module.cpp +25 -62
- data/test/test_Object.cpp +75 -3
- data/test/test_Ownership.cpp +12 -13
- data/test/test_Self.cpp +12 -13
- data/test/test_Stl_Map.cpp +696 -0
- data/test/test_Stl_Optional.cpp +3 -3
- data/test/test_Stl_Pair.cpp +38 -2
- data/test/test_Stl_Reference_Wrapper.cpp +102 -0
- data/test/test_Stl_SmartPointer.cpp +49 -9
- data/test/test_Stl_String.cpp +5 -2
- data/test/test_Stl_Unordered_Map.cpp +697 -0
- data/test/test_Stl_Variant.cpp +346 -0
- data/test/test_Stl_Vector.cpp +200 -41
- data/test/test_Struct.cpp +3 -3
- data/test/test_To_From_Ruby.cpp +8 -2
- data/test/test_Tracking.cpp +239 -0
- data/test/unittest.hpp +21 -4
- metadata +24 -13
- data/rice/detail/Exception_Handler.hpp +0 -8
- data/rice/detail/Exception_Handler.ipp +0 -28
- data/rice/detail/Iterator.hpp +0 -23
- data/rice/detail/Iterator.ipp +0 -47
- data/rice/detail/function_traits.hpp +0 -124
- data/rice/detail/method_data.hpp +0 -29
- data/rice/detail/rice_traits.hpp +0 -116
- data/rice/ruby_try_catch.hpp +0 -86
@@ -0,0 +1,346 @@
|
|
1
|
+
#include "unittest.hpp"
|
2
|
+
#include "embed_ruby.hpp"
|
3
|
+
#include <rice/rice.hpp>
|
4
|
+
#include <rice/stl.hpp>
|
5
|
+
|
6
|
+
#include <variant>
|
7
|
+
#include <complex>
|
8
|
+
|
9
|
+
using namespace Rice;
|
10
|
+
|
11
|
+
TESTSUITE(Variant);
|
12
|
+
|
13
|
+
namespace
|
14
|
+
{
|
15
|
+
using Intrinsic_Variant_T = std::variant<
|
16
|
+
std::string,
|
17
|
+
std::complex<double>,
|
18
|
+
std::vector<int>,
|
19
|
+
double,
|
20
|
+
bool,
|
21
|
+
int
|
22
|
+
>;
|
23
|
+
|
24
|
+
inline std::ostream& operator<<(std::ostream& stream, Intrinsic_Variant_T const& variant)
|
25
|
+
{
|
26
|
+
stream << "Variant(" << "index: " << variant.index() << ")";
|
27
|
+
return stream;
|
28
|
+
}
|
29
|
+
|
30
|
+
class MyClass
|
31
|
+
{
|
32
|
+
public:
|
33
|
+
Intrinsic_Variant_T variantString()
|
34
|
+
{
|
35
|
+
// Need to tell compiler this is std::string and not a const char[8]. Because that
|
36
|
+
// becomes const char* which sets the boolean field to true. Oops. https://stackoverflow.com/a/44086312
|
37
|
+
Intrinsic_Variant_T result { std::string("a string") };
|
38
|
+
return result;
|
39
|
+
}
|
40
|
+
|
41
|
+
Intrinsic_Variant_T variantComplex()
|
42
|
+
{
|
43
|
+
using namespace std::complex_literals;
|
44
|
+
Intrinsic_Variant_T result { 1i };
|
45
|
+
return result;
|
46
|
+
}
|
47
|
+
|
48
|
+
Intrinsic_Variant_T variantVector()
|
49
|
+
{
|
50
|
+
Intrinsic_Variant_T result { std::vector<int>{1, 2, 3} };
|
51
|
+
return result;
|
52
|
+
}
|
53
|
+
|
54
|
+
Intrinsic_Variant_T variantDouble()
|
55
|
+
{
|
56
|
+
Intrinsic_Variant_T result { 3.3 };
|
57
|
+
return result;
|
58
|
+
}
|
59
|
+
|
60
|
+
Intrinsic_Variant_T variantBoolTrue()
|
61
|
+
{
|
62
|
+
Intrinsic_Variant_T result { true };
|
63
|
+
return result;
|
64
|
+
}
|
65
|
+
|
66
|
+
Intrinsic_Variant_T variantBoolFalse()
|
67
|
+
{
|
68
|
+
Intrinsic_Variant_T result{ false };
|
69
|
+
return result;
|
70
|
+
}
|
71
|
+
|
72
|
+
Intrinsic_Variant_T variantInt()
|
73
|
+
{
|
74
|
+
Intrinsic_Variant_T result { 5 };
|
75
|
+
return result;
|
76
|
+
}
|
77
|
+
|
78
|
+
Intrinsic_Variant_T variantRoundtrip(Intrinsic_Variant_T variant)
|
79
|
+
{
|
80
|
+
return variant;
|
81
|
+
}
|
82
|
+
|
83
|
+
Intrinsic_Variant_T variantRoundtripReference(Intrinsic_Variant_T variant)
|
84
|
+
{
|
85
|
+
return variant;
|
86
|
+
}
|
87
|
+
|
88
|
+
Intrinsic_Variant_T variant_ = std::string("Initial value");
|
89
|
+
};
|
90
|
+
}
|
91
|
+
|
92
|
+
void makeIntrinsicVariant()
|
93
|
+
{
|
94
|
+
define_class<MyClass>("MyClass").
|
95
|
+
define_constructor(Constructor<MyClass>()).
|
96
|
+
define_method("variant_string", &MyClass::variantString).
|
97
|
+
define_method("variant_complex", &MyClass::variantComplex).
|
98
|
+
define_method("variant_vector", &MyClass::variantVector).
|
99
|
+
define_method("variant_double", &MyClass::variantDouble).
|
100
|
+
define_method("variant_bool_true", &MyClass::variantBoolTrue).
|
101
|
+
define_method("variant_bool_false", &MyClass::variantBoolFalse).
|
102
|
+
define_method("variant_int", &MyClass::variantInt).
|
103
|
+
define_method("roundtrip", &MyClass::variantRoundtrip).
|
104
|
+
define_attr("variant_attr", &MyClass::variant_);
|
105
|
+
}
|
106
|
+
|
107
|
+
TESTCASE(IntrinsicReturns)
|
108
|
+
{
|
109
|
+
using namespace std::complex_literals;
|
110
|
+
|
111
|
+
Module m = define_module("Testing");
|
112
|
+
Object myClass = m.module_eval("MyClass.new");
|
113
|
+
|
114
|
+
Object result = myClass.call("variant_string");
|
115
|
+
ASSERT_EQUAL("a string", detail::From_Ruby<std::string>().convert(result));
|
116
|
+
|
117
|
+
result = myClass.call("variant_complex");
|
118
|
+
ASSERT_EQUAL(1i, detail::From_Ruby<std::complex<double>>().convert(result));
|
119
|
+
|
120
|
+
result = myClass.call("variant_vector");
|
121
|
+
std::vector<int> converted = detail::From_Ruby<std::vector<int>>().convert(result);
|
122
|
+
ASSERT_EQUAL(3, converted.size());
|
123
|
+
|
124
|
+
result = myClass.call("variant_double");
|
125
|
+
ASSERT_EQUAL(3.3, detail::From_Ruby<double>().convert(result));
|
126
|
+
|
127
|
+
result = myClass.call("variant_bool_true");
|
128
|
+
ASSERT(detail::From_Ruby<bool>().convert(result));
|
129
|
+
|
130
|
+
result = myClass.call("variant_bool_false");
|
131
|
+
ASSERT(!detail::From_Ruby<bool>().convert(result));
|
132
|
+
|
133
|
+
result = myClass.call("variant_int");
|
134
|
+
ASSERT_EQUAL(5, detail::From_Ruby<int>().convert(result));
|
135
|
+
}
|
136
|
+
|
137
|
+
TESTCASE(IntrinsicRoundtrip)
|
138
|
+
{
|
139
|
+
using namespace std::complex_literals;
|
140
|
+
|
141
|
+
Module m = define_module("Testing");
|
142
|
+
Object myClass = m.module_eval("MyClass.new");
|
143
|
+
|
144
|
+
std::string code = R"(my_class = MyClass.new
|
145
|
+
my_class.roundtrip("roundtrip string"))";
|
146
|
+
Object result = m.module_eval(code);
|
147
|
+
ASSERT_EQUAL("roundtrip string", detail::From_Ruby<std::string>().convert(result));
|
148
|
+
|
149
|
+
code = R"(my_class = MyClass.new
|
150
|
+
my_class.roundtrip(Complex(2, 3)))";
|
151
|
+
result = m.module_eval(code);
|
152
|
+
ASSERT_EQUAL((2.0 + 3i), detail::From_Ruby<std::complex<double>>().convert(result));
|
153
|
+
|
154
|
+
code = R"(my_class = MyClass.new
|
155
|
+
my_class.roundtrip([1, 2, 3]))";
|
156
|
+
result = m.module_eval(code);
|
157
|
+
std::vector<int> expected = {1, 2, 3};
|
158
|
+
ASSERT_EQUAL(expected, detail::From_Ruby<std::vector<int>>().convert(result));
|
159
|
+
|
160
|
+
code = R"(my_class = MyClass.new
|
161
|
+
my_class.roundtrip(44.4))";
|
162
|
+
result = m.module_eval(code);
|
163
|
+
ASSERT_EQUAL(44.4, detail::From_Ruby<double>().convert(result));
|
164
|
+
|
165
|
+
code = R"(my_class = MyClass.new
|
166
|
+
my_class.roundtrip(true))";
|
167
|
+
result = m.module_eval(code);
|
168
|
+
ASSERT(detail::From_Ruby<bool>().convert(result));
|
169
|
+
|
170
|
+
code = R"(my_class = MyClass.new
|
171
|
+
my_class.roundtrip(false))";
|
172
|
+
result = m.module_eval(code);
|
173
|
+
ASSERT(!detail::From_Ruby<bool>().convert(result));
|
174
|
+
|
175
|
+
code = R"(my_class = MyClass.new
|
176
|
+
my_class.roundtrip(45))";
|
177
|
+
result = m.module_eval(code);
|
178
|
+
ASSERT_EQUAL(45, detail::From_Ruby<int>().convert(result));
|
179
|
+
}
|
180
|
+
|
181
|
+
TESTCASE(VariantAttribute)
|
182
|
+
{
|
183
|
+
Module m = define_module("Testing");
|
184
|
+
Object myClass = m.module_eval("MyClass.new");
|
185
|
+
|
186
|
+
Object result = myClass.call("variant_attr");
|
187
|
+
ASSERT_EQUAL("Initial value", detail::From_Ruby<std::string>().convert(result));
|
188
|
+
|
189
|
+
result = myClass.call("variant_attr=", "Second value");
|
190
|
+
ASSERT_EQUAL("Second value", detail::From_Ruby<std::string>().convert(result));
|
191
|
+
result = myClass.call("variant_attr");
|
192
|
+
ASSERT_EQUAL("Second value", detail::From_Ruby<std::string>().convert(result));
|
193
|
+
|
194
|
+
result = myClass.call("variant_attr=", 77.7);
|
195
|
+
ASSERT_EQUAL(77.7, detail::From_Ruby<double>().convert(result));
|
196
|
+
result = myClass.call("variant_attr");
|
197
|
+
ASSERT_EQUAL(77.7, detail::From_Ruby<double>().convert(result));
|
198
|
+
|
199
|
+
result = myClass.call("variant_attr=", true);
|
200
|
+
ASSERT(detail::From_Ruby<bool>().convert(result));
|
201
|
+
result = myClass.call("variant_attr");
|
202
|
+
ASSERT(detail::From_Ruby<bool>().convert(result));
|
203
|
+
|
204
|
+
result = myClass.call("variant_attr=", false);
|
205
|
+
ASSERT(!detail::From_Ruby<bool>().convert(result));
|
206
|
+
result = myClass.call("variant_attr");
|
207
|
+
ASSERT(!detail::From_Ruby<bool>().convert(result));
|
208
|
+
|
209
|
+
result = myClass.call("variant_attr=", 78);
|
210
|
+
ASSERT_EQUAL(78, detail::From_Ruby<int>().convert(result));
|
211
|
+
result = myClass.call("variant_attr");
|
212
|
+
ASSERT_EQUAL(78, detail::From_Ruby<int>().convert(result));
|
213
|
+
}
|
214
|
+
|
215
|
+
namespace
|
216
|
+
{
|
217
|
+
class MyClass1
|
218
|
+
{
|
219
|
+
public:
|
220
|
+
MyClass1()
|
221
|
+
{
|
222
|
+
int a = 1;
|
223
|
+
}
|
224
|
+
|
225
|
+
std::string sayHello()
|
226
|
+
{
|
227
|
+
return "Hi from MyClass1";
|
228
|
+
}
|
229
|
+
};
|
230
|
+
|
231
|
+
class MyClass2
|
232
|
+
{
|
233
|
+
public:
|
234
|
+
MyClass2()
|
235
|
+
{
|
236
|
+
int a = 2;
|
237
|
+
}
|
238
|
+
|
239
|
+
std::string sayHello()
|
240
|
+
{
|
241
|
+
return "Hi from MyClass2";
|
242
|
+
}
|
243
|
+
};
|
244
|
+
|
245
|
+
using Class_Variant_T = std::variant<std::monostate, MyClass1, MyClass2>;
|
246
|
+
|
247
|
+
Class_Variant_T variantClass(bool myClass1)
|
248
|
+
{
|
249
|
+
if (myClass1)
|
250
|
+
{
|
251
|
+
return MyClass1();
|
252
|
+
}
|
253
|
+
else
|
254
|
+
{
|
255
|
+
return MyClass2();
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
Class_Variant_T roundTripVariantClass(Class_Variant_T variant)
|
260
|
+
{
|
261
|
+
return variant;
|
262
|
+
}
|
263
|
+
|
264
|
+
Class_Variant_T& roundTripVariantClassRef(Class_Variant_T& variant)
|
265
|
+
{
|
266
|
+
return variant;
|
267
|
+
}
|
268
|
+
}
|
269
|
+
|
270
|
+
void makeClassVariant()
|
271
|
+
{
|
272
|
+
define_class<MyClass1>("MyClass1").
|
273
|
+
define_constructor(Constructor<MyClass1>()).
|
274
|
+
define_method("say_hello", &MyClass1::sayHello);
|
275
|
+
|
276
|
+
define_class<MyClass2>("MyClass2").
|
277
|
+
define_constructor(Constructor<MyClass2>()).
|
278
|
+
define_method("say_hello", &MyClass2::sayHello);
|
279
|
+
|
280
|
+
define_global_function("variant_class", &variantClass);
|
281
|
+
define_global_function("roundtrip_variant_class", &roundTripVariantClass);
|
282
|
+
define_global_function("roundtrip_variant_class_ref", &roundTripVariantClassRef);
|
283
|
+
}
|
284
|
+
|
285
|
+
SETUP(Variant)
|
286
|
+
{
|
287
|
+
embed_ruby();
|
288
|
+
makeIntrinsicVariant();
|
289
|
+
makeClassVariant();
|
290
|
+
}
|
291
|
+
|
292
|
+
TESTCASE(ClassReturns)
|
293
|
+
{
|
294
|
+
Module m = define_module("Testing");
|
295
|
+
|
296
|
+
Data_Object<MyClass1> myclass1 = m.module_eval("variant_class(true)");
|
297
|
+
String hello = myclass1.call("say_hello");
|
298
|
+
ASSERT_EQUAL("Hi from MyClass1", detail::From_Ruby<std::string>().convert(hello));
|
299
|
+
|
300
|
+
Data_Object<MyClass2> myclass2 = m.module_eval("variant_class(false)");
|
301
|
+
hello = myclass2.call("say_hello");
|
302
|
+
ASSERT_EQUAL("Hi from MyClass2", detail::From_Ruby<std::string>().convert(hello));
|
303
|
+
}
|
304
|
+
|
305
|
+
TESTCASE(ClassRoundtrip)
|
306
|
+
{
|
307
|
+
Module m = define_module("Testing");
|
308
|
+
|
309
|
+
Object instance = m.module_eval("MyClass1.new");
|
310
|
+
Object instance2 = m.call("roundtrip_variant_class", instance);
|
311
|
+
String hello = instance2.call("say_hello");
|
312
|
+
ASSERT_EQUAL("Hi from MyClass1", detail::From_Ruby<std::string>().convert(hello));
|
313
|
+
|
314
|
+
instance = m.module_eval("MyClass2.new");
|
315
|
+
instance2 = m.call("roundtrip_variant_class", instance);
|
316
|
+
hello = instance2.call("say_hello");
|
317
|
+
ASSERT_EQUAL("Hi from MyClass2", detail::From_Ruby<std::string>().convert(hello));
|
318
|
+
}
|
319
|
+
|
320
|
+
/* This test case runs successfully on MSVC but not g++. Having stepped through the code with
|
321
|
+
GDB, this sure seems due to a bug with g++. The issue is this variable in created operator():
|
322
|
+
|
323
|
+
Arg_Ts nativeValues = this->getNativeValues(rubyValues, indices);
|
324
|
+
|
325
|
+
And is then passed to invokeNativeFunction as a const Arg_Ts& nativeArgs where Arg_Ts& is
|
326
|
+
std::tuple with one element, a reference to a variant. So it doesn't change and the address
|
327
|
+
of the variable doesn't change. But for some reason g++ resets the
|
328
|
+
the std::variant index to 0 thus breaking the test. Maybe something to do with storing
|
329
|
+
a refernence to a variant in a tuple? */
|
330
|
+
|
331
|
+
#ifdef _MSC_VER
|
332
|
+
TESTCASE(ClassRoundtripRef)
|
333
|
+
{
|
334
|
+
Module m = define_module("Testing");
|
335
|
+
|
336
|
+
Object instance = m.module_eval("MyClass1.new");
|
337
|
+
Object instance2 = m.call("roundtrip_variant_class_ref", instance);
|
338
|
+
String hello = instance2.call("say_hello");
|
339
|
+
ASSERT_EQUAL("Hi from MyClass1", detail::From_Ruby<std::string>().convert(hello));
|
340
|
+
|
341
|
+
instance = m.module_eval("MyClass2.new");
|
342
|
+
instance2 = m.call("roundtrip_variant_class_ref", instance);
|
343
|
+
hello = instance2.call("say_hello");
|
344
|
+
ASSERT_EQUAL("Hi from MyClass2", detail::From_Ruby<std::string>().convert(hello));
|
345
|
+
}
|
346
|
+
#endif
|
data/test/test_Stl_Vector.cpp
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
#include <complex>
|
2
|
-
#include <memory>
|
3
2
|
|
4
3
|
#include "unittest.hpp"
|
5
4
|
#include "embed_ruby.hpp"
|
@@ -31,7 +30,7 @@ namespace
|
|
31
30
|
|
32
31
|
Class makeVectorClass()
|
33
32
|
{
|
34
|
-
Class c= define_class<MyClass>("MyClass").
|
33
|
+
Class c = define_class<MyClass>("MyClass").
|
35
34
|
define_constructor(Constructor<MyClass>()).
|
36
35
|
define_method("stringVector", &MyClass::stringVector);
|
37
36
|
|
@@ -44,15 +43,15 @@ TESTCASE(StringVector)
|
|
44
43
|
|
45
44
|
Class c = define_vector<std::vector<std::string>>("StringVector");
|
46
45
|
|
47
|
-
Object vec = m.
|
46
|
+
Object vec = m.module_eval("$vector = StringVector.new");
|
48
47
|
Object result = vec.call("size");
|
49
48
|
ASSERT_EQUAL(0, detail::From_Ruby<int32_t>().convert(result));
|
50
49
|
|
51
|
-
m.
|
50
|
+
m.module_eval("$vector << 'one' << 'two' << 'two' << 'three'");
|
52
51
|
result = vec.call("size");
|
53
52
|
ASSERT_EQUAL(4, detail::From_Ruby<int32_t>().convert(result));
|
54
53
|
|
55
|
-
m.
|
54
|
+
m.module_eval("$vector.append('four')");
|
56
55
|
result = vec.call("size");
|
57
56
|
ASSERT_EQUAL(5, detail::From_Ruby<int32_t>().convert(result));
|
58
57
|
|
@@ -69,10 +68,10 @@ TESTCASE(WrongType)
|
|
69
68
|
|
70
69
|
Class c = define_vector<std::vector<std::string>>("StringVector");
|
71
70
|
|
72
|
-
Object vec = m.
|
71
|
+
Object vec = m.module_eval("$vector = StringVector.new");
|
73
72
|
ASSERT_EXCEPTION_CHECK(
|
74
73
|
Exception,
|
75
|
-
m.
|
74
|
+
m.module_eval("$vector << 1"),
|
76
75
|
ASSERT_EQUAL("wrong argument type Integer (expected String)", ex.what()));
|
77
76
|
}
|
78
77
|
|
@@ -261,24 +260,6 @@ TESTCASE(Copy)
|
|
261
260
|
ASSERT_NOT_EQUAL(vec.size(), vecCopy.size());
|
262
261
|
}
|
263
262
|
|
264
|
-
TESTCASE(Iterate)
|
265
|
-
{
|
266
|
-
Module m = define_module("Testing");
|
267
|
-
Class c = define_vector<std::vector<double>>("DoubleVector");
|
268
|
-
|
269
|
-
std::string code = R"(vector = DoubleVector.new
|
270
|
-
vector << 5.0 << 6.0 << 7.0
|
271
|
-
updated = vector.map do |value|
|
272
|
-
value * 2.0
|
273
|
-
end)";
|
274
|
-
|
275
|
-
Array result = m.instance_eval(code);
|
276
|
-
ASSERT_EQUAL(3, result.size());
|
277
|
-
ASSERT_EQUAL(10.0, detail::From_Ruby<double>().convert(result[0].value()));
|
278
|
-
ASSERT_EQUAL(12.0, detail::From_Ruby<double>().convert(result[1].value()));
|
279
|
-
ASSERT_EQUAL(14.0, detail::From_Ruby<double>().convert(result[2].value()));
|
280
|
-
}
|
281
|
-
|
282
263
|
namespace
|
283
264
|
{
|
284
265
|
class NotComparable
|
@@ -308,7 +289,7 @@ TESTCASE(NotComparable)
|
|
308
289
|
ASSERT_EQUAL(Qnil, result.value());
|
309
290
|
|
310
291
|
result = vec.call("length");
|
311
|
-
ASSERT_EQUAL(
|
292
|
+
ASSERT_EQUAL(3u, detail::From_Ruby<size_t>().convert(result));
|
312
293
|
|
313
294
|
result = vec.call("include?", NotComparable(2));
|
314
295
|
ASSERT_EQUAL(Qfalse, result.value());
|
@@ -437,13 +418,13 @@ TESTCASE(Printable)
|
|
437
418
|
|
438
419
|
namespace
|
439
420
|
{
|
440
|
-
std::vector<std::complex<
|
421
|
+
std::vector<std::complex<double>> returnComplexVector()
|
441
422
|
{
|
442
|
-
std::complex<
|
443
|
-
std::complex<
|
444
|
-
std::complex<
|
423
|
+
std::complex<double> complex1(1, 1);
|
424
|
+
std::complex<double> complex2(2, 2);
|
425
|
+
std::complex<double> complex3(3, 3);
|
445
426
|
|
446
|
-
std::vector<std::complex<
|
427
|
+
std::vector<std::complex<double>> result;
|
447
428
|
result.push_back(complex1);
|
448
429
|
result.push_back(complex2);
|
449
430
|
result.push_back(complex3);
|
@@ -461,15 +442,27 @@ TESTCASE(AutoRegisterReturn)
|
|
461
442
|
define_global_function("return_complex_vector", &returnComplexVector);
|
462
443
|
|
463
444
|
Module m = define_module("Testing");
|
464
|
-
Object vec = m.
|
465
|
-
ASSERT_EQUAL("Rice::Std::
|
445
|
+
Object vec = m.module_eval("return_complex_vector");
|
446
|
+
ASSERT_EQUAL("Rice::Std::Vector__complex__double___allocator__complex__double______", vec.class_name().str());
|
466
447
|
|
467
448
|
std::string code = R"(vector = return_complex_vector
|
468
449
|
complex = vector.last
|
469
450
|
complex == Complex(3, 3))";
|
470
451
|
|
471
|
-
Object result = m.
|
452
|
+
Object result = m.module_eval(code);
|
472
453
|
ASSERT_EQUAL(Qtrue, result.value());
|
454
|
+
|
455
|
+
// Now register this same vector
|
456
|
+
define_vector<std::vector<std::complex<double>>>("ComplexVector");
|
457
|
+
code = R"(vector = ComplexVector.new)";
|
458
|
+
result = m.module_eval(code);
|
459
|
+
ASSERT(result.is_instance_of(vec.class_of()));
|
460
|
+
|
461
|
+
// Now register it again in the module
|
462
|
+
define_vector_under<std::vector<std::complex<double>>>(m, "ComplexVector2");
|
463
|
+
code = R"(vector = Testing::ComplexVector2.new)";
|
464
|
+
result = m.module_eval(code);
|
465
|
+
ASSERT(result.is_instance_of(vec.class_of()));
|
473
466
|
}
|
474
467
|
|
475
468
|
TESTCASE(AutoRegisterParameter)
|
@@ -482,7 +475,7 @@ TESTCASE(AutoRegisterParameter)
|
|
482
475
|
pass_complex_vector(vector))";
|
483
476
|
|
484
477
|
Module m = define_module("Testing");
|
485
|
-
Object vec = m.
|
478
|
+
Object vec = m.module_eval(code);
|
486
479
|
|
487
480
|
Object result = vec.call("size");
|
488
481
|
ASSERT_EQUAL("Rice::Std::Vector__complex__double___allocator__complex__double______", vec.class_name().str());
|
@@ -507,7 +500,7 @@ TESTCASE(DefaultValue)
|
|
507
500
|
define_global_function("default_vector", &defaultVector, Arg("strings") = std::vector<std::string> { "one", "two", "three" });
|
508
501
|
|
509
502
|
Module m = define_module("Testing");
|
510
|
-
Object result = m.
|
503
|
+
Object result = m.module_eval("default_vector");
|
511
504
|
std::vector<std::string> actual = detail::From_Ruby<std::vector<std::string>>().convert(result);
|
512
505
|
|
513
506
|
std::vector<std::string> expected{ "one", "two", "three" };
|
@@ -518,6 +511,27 @@ TESTCASE(DefaultValue)
|
|
518
511
|
ASSERT_EQUAL(expected[2], actual[2]);
|
519
512
|
}
|
520
513
|
|
514
|
+
TESTCASE(ToArray)
|
515
|
+
{
|
516
|
+
Module m = define_module("Testing");
|
517
|
+
|
518
|
+
Class c = define_vector<std::vector<std::string>>("StringVector").
|
519
|
+
define_constructor(Constructor<std::vector<std::string>>());
|
520
|
+
|
521
|
+
std::string code = R"(vector = StringVector.new
|
522
|
+
vector << "abc"
|
523
|
+
vector << "def"
|
524
|
+
vector << "ghi"
|
525
|
+
vector.to_a)";
|
526
|
+
|
527
|
+
Array array = m.module_eval(code);
|
528
|
+
ASSERT_EQUAL(3u, array.size());
|
529
|
+
|
530
|
+
ASSERT_EQUAL("abc", detail::From_Ruby<std::string>().convert(array[0].value()));
|
531
|
+
ASSERT_EQUAL("def", detail::From_Ruby<std::string>().convert(array[1].value()));
|
532
|
+
ASSERT_EQUAL("ghi", detail::From_Ruby<std::string>().convert(array[2].value()));
|
533
|
+
}
|
534
|
+
|
521
535
|
namespace
|
522
536
|
{
|
523
537
|
std::vector<int> ints;
|
@@ -553,7 +567,7 @@ TESTCASE(ArrayToVector)
|
|
553
567
|
Module m = define_module("Testing");
|
554
568
|
|
555
569
|
std::string code = "array_to_vector([7, 9, 1_000_000], [49.0, 78.0, 999.0], %w[one two three])";
|
556
|
-
m.
|
570
|
+
m.module_eval(code);
|
557
571
|
|
558
572
|
ASSERT_EQUAL(3, ints.size());
|
559
573
|
ASSERT_EQUAL(7, ints[0]);
|
@@ -578,7 +592,7 @@ TESTCASE(ArrayToVectorRefs)
|
|
578
592
|
Module m = define_module("Testing");
|
579
593
|
|
580
594
|
std::string code = "array_to_vector_refs([8, 10, 1_000_001], [50.0, 79.0, 1_000.0], %w[eleven twelve thirteen])";
|
581
|
-
m.
|
595
|
+
m.module_eval(code);
|
582
596
|
|
583
597
|
ASSERT_EQUAL(3, ints.size());
|
584
598
|
ASSERT_EQUAL(8, ints[0]);
|
@@ -603,7 +617,7 @@ TESTCASE(ArrayToVectorPointers)
|
|
603
617
|
Module m = define_module("Testing");
|
604
618
|
|
605
619
|
std::string code = "array_to_vector_pointers([9, 11, 1_000_002], [51.0, 80.0, 1_001.0], %w[fourteen fifteen sixteen])";
|
606
|
-
m.
|
620
|
+
m.module_eval(code);
|
607
621
|
|
608
622
|
ASSERT_EQUAL(3, ints.size());
|
609
623
|
ASSERT_EQUAL(9, ints[0]);
|
@@ -631,7 +645,7 @@ TESTCASE(ArrayToVectorWrongTypes)
|
|
631
645
|
|
632
646
|
ASSERT_EXCEPTION_CHECK(
|
633
647
|
Exception,
|
634
|
-
m.
|
648
|
+
m.module_eval(code),
|
635
649
|
ASSERT_EQUAL("wrong argument type Float (expected String)", ex.what())
|
636
650
|
);
|
637
651
|
}
|
@@ -646,7 +660,152 @@ TESTCASE(ArrayToVectorMixedTypes)
|
|
646
660
|
|
647
661
|
ASSERT_EXCEPTION_CHECK(
|
648
662
|
Exception,
|
649
|
-
m.
|
663
|
+
m.module_eval(code),
|
650
664
|
ASSERT_EQUAL("no implicit conversion of String into Integer", ex.what())
|
651
665
|
);
|
652
666
|
}
|
667
|
+
|
668
|
+
namespace
|
669
|
+
{
|
670
|
+
class Factory
|
671
|
+
{
|
672
|
+
public:
|
673
|
+
std::vector<std::string>* returnPointer()
|
674
|
+
{
|
675
|
+
return &this->instance_;
|
676
|
+
}
|
677
|
+
|
678
|
+
std::vector<std::string>& returnReference()
|
679
|
+
{
|
680
|
+
return this->instance_;
|
681
|
+
}
|
682
|
+
|
683
|
+
std::vector<std::string> returnValue()
|
684
|
+
{
|
685
|
+
return this->instance_;
|
686
|
+
}
|
687
|
+
|
688
|
+
public:
|
689
|
+
static inline std::vector<std::string> instance_{ "one", "two", "three" };
|
690
|
+
};
|
691
|
+
|
692
|
+
std::ostream& operator<<(std::ostream& stream, const std::vector<std::string>& vector)
|
693
|
+
{
|
694
|
+
stream << "Vector";
|
695
|
+
return stream;
|
696
|
+
}
|
697
|
+
}
|
698
|
+
|
699
|
+
void createFactoryClass()
|
700
|
+
{
|
701
|
+
define_class<Factory>("Factory").
|
702
|
+
define_constructor(Constructor<Factory>()).
|
703
|
+
define_method("pointer", &Factory::returnPointer).
|
704
|
+
define_method("reference", &Factory::returnReference).
|
705
|
+
define_method("value", &Factory::returnValue);
|
706
|
+
}
|
707
|
+
|
708
|
+
TESTCASE(Returns)
|
709
|
+
{
|
710
|
+
createFactoryClass();
|
711
|
+
Module m = define_module("TestingModule");
|
712
|
+
Object factory = m.module_eval("Factory.new");
|
713
|
+
|
714
|
+
std::vector<std::string> expected{ "one", "two", "three" };
|
715
|
+
|
716
|
+
Data_Object<std::vector<std::string>> vec1 = factory.call("pointer");
|
717
|
+
ASSERT_EQUAL(expected, *vec1);
|
718
|
+
|
719
|
+
Data_Object<std::vector<std::string>> vec2 = factory.call("reference");
|
720
|
+
ASSERT_EQUAL(expected, *vec2);
|
721
|
+
|
722
|
+
Data_Object<std::vector<std::string>> vec3 = factory.call("value");
|
723
|
+
ASSERT_EQUAL(expected, *vec3);
|
724
|
+
}
|
725
|
+
|
726
|
+
TESTCASE(Iterate)
|
727
|
+
{
|
728
|
+
Module m = define_module("Testing");
|
729
|
+
Class c = define_vector<std::vector<double>>("DoubleVector");
|
730
|
+
|
731
|
+
std::string code = R"(vector = DoubleVector.new
|
732
|
+
vector << 5.0 << 6.0 << 7.0
|
733
|
+
updated = vector.map do |value|
|
734
|
+
value * 2.0
|
735
|
+
end)";
|
736
|
+
|
737
|
+
Array result = m.module_eval(code);
|
738
|
+
ASSERT_EQUAL(3, result.size());
|
739
|
+
ASSERT_EQUAL(10.0, detail::From_Ruby<double>().convert(result[0].value()));
|
740
|
+
ASSERT_EQUAL(12.0, detail::From_Ruby<double>().convert(result[1].value()));
|
741
|
+
ASSERT_EQUAL(14.0, detail::From_Ruby<double>().convert(result[2].value()));
|
742
|
+
}
|
743
|
+
|
744
|
+
TESTCASE(ToEnumPointer)
|
745
|
+
{
|
746
|
+
createFactoryClass();
|
747
|
+
Module m = define_module("TestingModule");
|
748
|
+
|
749
|
+
std::string code = R"(factory = Factory.new
|
750
|
+
vector = factory.pointer
|
751
|
+
updated = vector.each.map do |value|
|
752
|
+
value + "_updated"
|
753
|
+
end)";
|
754
|
+
|
755
|
+
Array result = m.module_eval(code);
|
756
|
+
|
757
|
+
ASSERT_EQUAL(3, result.size());
|
758
|
+
ASSERT_EQUAL("one_updated", detail::From_Ruby<std::string>().convert(result[0].value()));
|
759
|
+
ASSERT_EQUAL("two_updated", detail::From_Ruby<std::string>().convert(result[1].value()));
|
760
|
+
ASSERT_EQUAL("three_updated", detail::From_Ruby<std::string>().convert(result[2].value()));
|
761
|
+
}
|
762
|
+
|
763
|
+
TESTCASE(ToEnumReference)
|
764
|
+
{
|
765
|
+
createFactoryClass();
|
766
|
+
Module m = define_module("TestingModule");
|
767
|
+
|
768
|
+
std::string code = R"(factory = Factory.new
|
769
|
+
vector = factory.reference
|
770
|
+
updated = vector.each.map do |value|
|
771
|
+
value + "_updated"
|
772
|
+
end)";
|
773
|
+
|
774
|
+
Array result = m.module_eval(code);
|
775
|
+
|
776
|
+
ASSERT_EQUAL(3, result.size());
|
777
|
+
ASSERT_EQUAL("one_updated", detail::From_Ruby<std::string>().convert(result[0].value()));
|
778
|
+
ASSERT_EQUAL("two_updated", detail::From_Ruby<std::string>().convert(result[1].value()));
|
779
|
+
ASSERT_EQUAL("three_updated", detail::From_Ruby<std::string>().convert(result[2].value()));
|
780
|
+
}
|
781
|
+
|
782
|
+
TESTCASE(ToEnumValue)
|
783
|
+
{
|
784
|
+
createFactoryClass();
|
785
|
+
Module m = define_module("TestingModule");
|
786
|
+
|
787
|
+
std::string code = R"(factory = Factory.new
|
788
|
+
vector = factory.value
|
789
|
+
updated = vector.each.map do |value|
|
790
|
+
value + "_updated"
|
791
|
+
end)";
|
792
|
+
|
793
|
+
Array result = m.module_eval(code);
|
794
|
+
|
795
|
+
ASSERT_EQUAL(3, result.size());
|
796
|
+
ASSERT_EQUAL("one_updated", detail::From_Ruby<std::string>().convert(result[0].value()));
|
797
|
+
ASSERT_EQUAL("two_updated", detail::From_Ruby<std::string>().convert(result[1].value()));
|
798
|
+
ASSERT_EQUAL("three_updated", detail::From_Ruby<std::string>().convert(result[2].value()));
|
799
|
+
}
|
800
|
+
|
801
|
+
TESTCASE(ToEnumSize)
|
802
|
+
{
|
803
|
+
createFactoryClass();
|
804
|
+
Module m = define_module("TestingModule");
|
805
|
+
Object factory = m.module_eval("Factory.new");
|
806
|
+
Object vector = factory.call("pointer");
|
807
|
+
Object enumerable = vector.call("each");
|
808
|
+
Object result = enumerable.call("size");
|
809
|
+
|
810
|
+
ASSERT_EQUAL(3, detail::From_Ruby<int>().convert(result));
|
811
|
+
}
|