rice 4.3.3 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +63 -26
  3. data/README.md +7 -2
  4. data/Rakefile +7 -1
  5. data/include/rice/rice.hpp +7291 -4430
  6. data/include/rice/stl.hpp +769 -222
  7. data/lib/mkmf-rice.rb +37 -95
  8. data/rice/Address_Registration_Guard.hpp +72 -3
  9. data/rice/Arg.hpp +19 -5
  10. data/rice/Arg.ipp +24 -0
  11. data/rice/Callback.hpp +21 -0
  12. data/rice/Callback.ipp +13 -0
  13. data/rice/Constructor.hpp +4 -27
  14. data/rice/Constructor.ipp +79 -0
  15. data/rice/Data_Object.hpp +74 -3
  16. data/rice/Data_Object.ipp +324 -32
  17. data/rice/Data_Type.hpp +215 -3
  18. data/rice/Data_Type.ipp +125 -64
  19. data/rice/Director.hpp +0 -2
  20. data/rice/Enum.hpp +4 -6
  21. data/rice/Enum.ipp +101 -57
  22. data/rice/Exception.hpp +62 -2
  23. data/rice/Exception.ipp +7 -12
  24. data/rice/JumpException.hpp +44 -0
  25. data/rice/JumpException.ipp +48 -0
  26. data/rice/MemoryView.hpp +11 -0
  27. data/rice/MemoryView.ipp +43 -0
  28. data/rice/Return.hpp +6 -26
  29. data/rice/Return.ipp +10 -16
  30. data/rice/detail/DefaultHandler.hpp +12 -0
  31. data/rice/detail/DefaultHandler.ipp +8 -0
  32. data/rice/detail/HandlerRegistry.hpp +5 -35
  33. data/rice/detail/HandlerRegistry.ipp +7 -11
  34. data/rice/detail/InstanceRegistry.hpp +1 -4
  35. data/rice/detail/MethodInfo.hpp +15 -5
  36. data/rice/detail/MethodInfo.ipp +78 -6
  37. data/rice/detail/Native.hpp +32 -0
  38. data/rice/detail/Native.ipp +129 -0
  39. data/rice/detail/NativeAttributeGet.hpp +51 -0
  40. data/rice/detail/NativeAttributeGet.ipp +51 -0
  41. data/rice/detail/NativeAttributeSet.hpp +43 -0
  42. data/rice/detail/NativeAttributeSet.ipp +82 -0
  43. data/rice/detail/NativeCallbackFFI.hpp +55 -0
  44. data/rice/detail/NativeCallbackFFI.ipp +151 -0
  45. data/rice/detail/NativeCallbackSimple.hpp +30 -0
  46. data/rice/detail/NativeCallbackSimple.ipp +29 -0
  47. data/rice/detail/NativeFunction.hpp +20 -21
  48. data/rice/detail/NativeFunction.ipp +199 -64
  49. data/rice/detail/NativeIterator.hpp +8 -11
  50. data/rice/detail/NativeIterator.ipp +27 -31
  51. data/rice/detail/NativeRegistry.hpp +24 -15
  52. data/rice/detail/NativeRegistry.ipp +23 -48
  53. data/rice/detail/Proc.hpp +4 -0
  54. data/rice/detail/Proc.ipp +85 -0
  55. data/rice/detail/Registries.hpp +0 -7
  56. data/rice/detail/Registries.ipp +0 -18
  57. data/rice/detail/RubyFunction.hpp +0 -3
  58. data/rice/detail/RubyFunction.ipp +4 -8
  59. data/rice/detail/RubyType.hpp +19 -0
  60. data/rice/detail/RubyType.ipp +187 -0
  61. data/rice/detail/TupleIterator.hpp +14 -0
  62. data/rice/detail/Type.hpp +5 -6
  63. data/rice/detail/Type.ipp +150 -33
  64. data/rice/detail/TypeRegistry.hpp +15 -7
  65. data/rice/detail/TypeRegistry.ipp +105 -12
  66. data/rice/detail/Wrapper.hpp +6 -5
  67. data/rice/detail/Wrapper.ipp +45 -23
  68. data/rice/detail/cpp_protect.hpp +5 -6
  69. data/rice/detail/default_allocation_func.ipp +0 -2
  70. data/rice/detail/from_ruby.hpp +37 -3
  71. data/rice/detail/from_ruby.ipp +911 -454
  72. data/rice/detail/ruby.hpp +18 -0
  73. data/rice/detail/to_ruby.hpp +41 -3
  74. data/rice/detail/to_ruby.ipp +437 -113
  75. data/rice/global_function.hpp +0 -4
  76. data/rice/global_function.ipp +1 -2
  77. data/rice/rice.hpp +105 -22
  78. data/rice/ruby_mark.hpp +4 -3
  79. data/rice/stl.hpp +4 -0
  80. data/test/embed_ruby.cpp +4 -1
  81. data/test/extconf.rb +2 -0
  82. data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
  83. data/test/test_Address_Registration_Guard.cpp +5 -0
  84. data/test/test_Array.cpp +12 -1
  85. data/test/test_Attribute.cpp +103 -21
  86. data/test/test_Builtin_Object.cpp +5 -0
  87. data/test/test_Callback.cpp +231 -0
  88. data/test/test_Class.cpp +5 -31
  89. data/test/test_Constructor.cpp +69 -6
  90. data/test/test_Data_Object.cpp +9 -4
  91. data/test/test_Data_Type.cpp +428 -64
  92. data/test/test_Director.cpp +10 -5
  93. data/test/test_Enum.cpp +152 -40
  94. data/test/test_Exception.cpp +235 -0
  95. data/test/test_File.cpp +70 -0
  96. data/test/test_From_Ruby.cpp +542 -0
  97. data/test/test_Hash.cpp +5 -0
  98. data/test/test_Identifier.cpp +5 -0
  99. data/test/test_Inheritance.cpp +6 -1
  100. data/test/test_Iterator.cpp +5 -0
  101. data/test/test_JumpException.cpp +22 -0
  102. data/test/test_Keep_Alive.cpp +6 -1
  103. data/test/test_Keep_Alive_No_Wrapper.cpp +5 -0
  104. data/test/test_Memory_Management.cpp +5 -0
  105. data/test/test_Module.cpp +118 -64
  106. data/test/test_Native_Registry.cpp +2 -33
  107. data/test/test_Object.cpp +5 -0
  108. data/test/test_Overloads.cpp +631 -0
  109. data/test/test_Ownership.cpp +67 -4
  110. data/test/test_Proc.cpp +45 -0
  111. data/test/test_Self.cpp +5 -0
  112. data/test/test_Stl_Exception.cpp +109 -0
  113. data/test/test_Stl_Map.cpp +22 -8
  114. data/test/test_Stl_Optional.cpp +5 -0
  115. data/test/test_Stl_Pair.cpp +7 -2
  116. data/test/test_Stl_Reference_Wrapper.cpp +5 -0
  117. data/test/test_Stl_SmartPointer.cpp +210 -5
  118. data/test/test_Stl_String.cpp +5 -0
  119. data/test/test_Stl_String_View.cpp +5 -0
  120. data/test/test_Stl_Type.cpp +147 -0
  121. data/test/test_Stl_Unordered_Map.cpp +18 -7
  122. data/test/test_Stl_Variant.cpp +5 -0
  123. data/test/test_Stl_Vector.cpp +130 -8
  124. data/test/test_String.cpp +5 -0
  125. data/test/test_Struct.cpp +5 -0
  126. data/test/test_Symbol.cpp +5 -0
  127. data/test/test_Template.cpp +192 -0
  128. data/test/test_To_Ruby.cpp +152 -0
  129. data/test/test_Tracking.cpp +1 -0
  130. data/test/test_Type.cpp +100 -0
  131. data/test/test_global_functions.cpp +53 -6
  132. data/test/unittest.cpp +8 -0
  133. metadata +37 -20
  134. data/lib/version.rb +0 -3
  135. data/rice/Address_Registration_Guard_defn.hpp +0 -79
  136. data/rice/Data_Object_defn.hpp +0 -84
  137. data/rice/Data_Type_defn.hpp +0 -190
  138. data/rice/Exception_defn.hpp +0 -68
  139. data/rice/HandlerRegistration.hpp +0 -15
  140. data/rice/Identifier.hpp +0 -50
  141. data/rice/Identifier.ipp +0 -29
  142. data/rice/detail/ExceptionHandler.hpp +0 -8
  143. data/rice/detail/ExceptionHandler.ipp +0 -28
  144. data/rice/detail/ExceptionHandler_defn.hpp +0 -77
  145. data/rice/detail/Jump_Tag.hpp +0 -21
  146. data/rice/detail/NativeAttribute.hpp +0 -64
  147. data/rice/detail/NativeAttribute.ipp +0 -112
  148. data/rice/detail/from_ruby_defn.hpp +0 -38
  149. data/rice/detail/to_ruby_defn.hpp +0 -48
  150. data/test/test_Jump_Tag.cpp +0 -17
  151. data/test/test_To_From_Ruby.cpp +0 -399
@@ -1,4 +1,4 @@
1
- #include <complex>
1
+ #include <complex>
2
2
 
3
3
  #include "unittest.hpp"
4
4
  #include "embed_ruby.hpp"
@@ -14,9 +14,13 @@ SETUP(Vector)
14
14
  embed_ruby();
15
15
  }
16
16
 
17
- namespace
17
+ TEARDOWN(Vector)
18
18
  {
19
+ rb_gc_start();
20
+ }
19
21
 
22
+ namespace
23
+ {
20
24
  class MyClass
21
25
  {
22
26
  public:
@@ -136,6 +140,42 @@ TESTCASE(Indexing)
136
140
  ASSERT_EQUAL(2, detail::From_Ruby<int32_t>().convert(result));
137
141
  }
138
142
 
143
+ TESTCASE(Slice)
144
+ {
145
+ Module m = define_module("Testing");
146
+
147
+ Class c = define_vector<std::vector<std::int32_t>>("IntVector");
148
+ Object vec = c.call("new");
149
+ vec.call("push", 7);
150
+ vec.call("push", 8);
151
+ vec.call("push", 9);
152
+ vec.call("push", 10);
153
+ vec.call("push", 11);
154
+ vec.call("push", 12);
155
+
156
+ Array result = vec.call("[]", 3, 1);
157
+ std::vector<std::int32_t> slice = result.to_vector<int32_t>();
158
+ ASSERT_EQUAL(1, slice.size());
159
+ ASSERT_EQUAL(10, slice[0]);
160
+
161
+ result = vec.call("[]", 3, 2);
162
+ slice = result.to_vector<int32_t>();
163
+ ASSERT_EQUAL(2, slice.size());
164
+ ASSERT_EQUAL(10, slice[0]);
165
+ ASSERT_EQUAL(11, slice[1]);
166
+
167
+ result = vec.call("[]", 4, 10);
168
+ slice = result.to_vector<int32_t>();
169
+ ASSERT_EQUAL(2, slice.size());
170
+ ASSERT_EQUAL(11, slice[0]);
171
+ ASSERT_EQUAL(12, slice[1]);
172
+
173
+ result = vec.call("[]", -1, 2);
174
+ slice = result.to_vector<int32_t>();
175
+ ASSERT_EQUAL(1, slice.size());
176
+ ASSERT_EQUAL(12, slice[0]);
177
+ }
178
+
139
179
  TESTCASE(Sizing)
140
180
  {
141
181
  Module m = define_module("Testing");
@@ -385,6 +425,49 @@ TESTCASE(Comparable)
385
425
  ASSERT_EQUAL(1, detail::From_Ruby<size_t>().convert(result.value()));
386
426
  }
387
427
 
428
+ namespace
429
+ {
430
+ class ComparableButNotBool
431
+ {
432
+ public:
433
+ ComparableButNotBool(uint32_t value) : value_(value)
434
+ {
435
+ };
436
+
437
+ std::string operator==(const ComparableButNotBool& other)
438
+ {
439
+ return "not a boolean";
440
+ }
441
+
442
+ uint32_t value_;
443
+ };
444
+ }
445
+
446
+ TESTCASE(ComparableButNotBool)
447
+ {
448
+ define_class<ComparableButNotBool>("IsComparableButNotBool").
449
+ define_constructor(Constructor<ComparableButNotBool, uint32_t>());
450
+
451
+ Class c = define_vector<std::vector<ComparableButNotBool>>("ComparableButNotBoolVector");
452
+
453
+ Object vec = c.call("new");
454
+ vec.call("push", ComparableButNotBool(1));
455
+ vec.call("push", ComparableButNotBool(2));
456
+ vec.call("push", ComparableButNotBool(3));
457
+
458
+ Object result = vec.call("delete", ComparableButNotBool(1));
459
+ ASSERT_EQUAL(Qnil, result.value());
460
+
461
+ result = vec.call("length");
462
+ ASSERT_EQUAL(3u, detail::From_Ruby<size_t>().convert(result));
463
+
464
+ result = vec.call("include?", ComparableButNotBool(2));
465
+ ASSERT_EQUAL(Qfalse, result.value());
466
+
467
+ result = vec.call("index", ComparableButNotBool(3));
468
+ ASSERT_EQUAL(Qnil, result.value());
469
+ }
470
+
388
471
  TESTCASE(DefaultConstructable)
389
472
  {
390
473
  define_class<Comparable>("IsComparable").
@@ -443,7 +526,7 @@ TESTCASE(AutoRegisterReturn)
443
526
 
444
527
  Module m = define_module("Testing");
445
528
  Object vec = m.module_eval("return_complex_vector");
446
- ASSERT_EQUAL("Rice::Std::Vector__complex__double___allocator__complex__double______", vec.class_name().str());
529
+ ASSERT_EQUAL(u8"Rice::Std::Vector≺complex≺double≻≻", vec.class_name().str());
447
530
 
448
531
  std::string code = R"(vector = return_complex_vector
449
532
  complex = vector.last
@@ -469,16 +552,16 @@ TESTCASE(AutoRegisterParameter)
469
552
  {
470
553
  define_global_function("pass_complex_vector", &passComplexVector);
471
554
 
472
- std::string code = R"(vector = Rice::Std::Vector__complex__double___allocator__complex__double______.new
473
- vector << Complex(4.0, 4.0)
474
- vector << Complex(5.0, 5.0)
475
- pass_complex_vector(vector))";
555
+ std::string code = u8R"(vector = Rice::Std::Vector≺complex≺double≻≻.new
556
+ vector << Complex(4.0, 4.0)
557
+ vector << Complex(5.0, 5.0)
558
+ pass_complex_vector(vector))";
476
559
 
477
560
  Module m = define_module("Testing");
478
561
  Object vec = m.module_eval(code);
479
562
 
480
563
  Object result = vec.call("size");
481
- ASSERT_EQUAL("Rice::Std::Vector__complex__double___allocator__complex__double______", vec.class_name().str());
564
+ ASSERT_EQUAL(u8"Rice::Std::Vector≺complex≺double≻≻", vec.class_name().str());
482
565
  ASSERT_EQUAL(2, detail::From_Ruby<int32_t>().convert(result));
483
566
 
484
567
  std::vector<std::complex<double>> complexes = detail::From_Ruby<std::vector<std::complex<double>>>().convert(vec);
@@ -869,3 +952,42 @@ TESTCASE(MyClass2PointerVector)
869
952
  MyClass2* pMyClass = (*result)[0];
870
953
  ASSERT_EQUAL("Hello MyClass2", pMyClass->name);
871
954
  }
955
+
956
+ TESTCASE(BoolVector)
957
+ {
958
+ Class boolVecClass = define_vector<std::vector<bool>>("BoolVector");
959
+
960
+ Object vec = boolVecClass.call("new");
961
+ vec.call("resize", 3, true);
962
+
963
+ Object result = vec.call("size");
964
+ ASSERT_EQUAL(3, detail::From_Ruby<int32_t>().convert(result));
965
+ result = vec.call("first");
966
+ ASSERT_EQUAL(Qtrue, result.value());
967
+
968
+ Object enumerable = vec.call("each");
969
+ Object arr = enumerable.call("to_a");
970
+ Object size = arr.call("size");
971
+ ASSERT_EQUAL(3, detail::From_Ruby<int32_t>().convert(size));
972
+
973
+ result = vec.call("[]", 0);
974
+ ASSERT_EQUAL(Qtrue, result.value());
975
+
976
+ result = vec.call("[]=", 1, false);
977
+ ASSERT_EQUAL(Qfalse, result.value());
978
+
979
+ std::string code = R"(array = self.each.to_a
980
+ array == [true, false, true])";
981
+
982
+ result = vec.instance_eval(code);
983
+ ASSERT_EQUAL(Qtrue, result.value());
984
+
985
+ result = vec.call("delete", 1);
986
+ ASSERT_EQUAL(Qtrue, result.value());
987
+ result = vec.call("size");
988
+ ASSERT_EQUAL(2, detail::From_Ruby<int32_t>().convert(result));
989
+
990
+ vec.call("clear");
991
+ result = vec.call("size");
992
+ ASSERT_EQUAL(0, detail::From_Ruby<int32_t>().convert(result));
993
+ }
data/test/test_String.cpp CHANGED
@@ -11,6 +11,11 @@ SETUP(String)
11
11
  embed_ruby();
12
12
  }
13
13
 
14
+ TEARDOWN(String)
15
+ {
16
+ rb_gc_start();
17
+ }
18
+
14
19
  TESTCASE(default_construct)
15
20
  {
16
21
  String s;
data/test/test_Struct.cpp CHANGED
@@ -24,6 +24,11 @@ SETUP(Struct)
24
24
  embed_ruby();
25
25
  }
26
26
 
27
+ TEARDOWN(Struct)
28
+ {
29
+ rb_gc_start();
30
+ }
31
+
27
32
  TESTCASE(default_construct)
28
33
  {
29
34
  Struct s;
data/test/test_Symbol.cpp CHANGED
@@ -11,6 +11,11 @@ SETUP(Symbol)
11
11
  embed_ruby();
12
12
  }
13
13
 
14
+ TEARDOWN(Symbol)
15
+ {
16
+ rb_gc_start();
17
+ }
18
+
14
19
  TESTCASE(construct_from_symbol)
15
20
  {
16
21
  VALUE v = ID2SYM(rb_intern("foo"));
@@ -0,0 +1,192 @@
1
+ #include <assert.h>
2
+
3
+ #include "unittest.hpp"
4
+ #include "embed_ruby.hpp"
5
+ #include <rice/rice.hpp>
6
+ #include <rice/stl.hpp>
7
+
8
+ using namespace Rice;
9
+
10
+ TESTSUITE(Template);
11
+
12
+ SETUP(Template)
13
+ {
14
+ embed_ruby();
15
+ }
16
+
17
+ TEARDOWN(Template)
18
+ {
19
+ rb_gc_start();
20
+ }
21
+
22
+ namespace
23
+ {
24
+ template<typename T>
25
+ class MyVector
26
+ {
27
+ public:
28
+ MyVector() = default;
29
+
30
+ void add(T& element)
31
+ {
32
+ this->vector_.push_back(element);
33
+ this->empty = false;
34
+ }
35
+
36
+ size_t size()
37
+ {
38
+ return this->vector_.size();
39
+ }
40
+
41
+ bool empty = true;
42
+ private:
43
+ std::vector<T> vector_;
44
+ };
45
+ }
46
+
47
+ template<typename Data_Type_T, typename T>
48
+ void MyVector_builder(Data_Type_T& klass)
49
+ {
50
+ klass.define_constructor(Constructor<MyVector<T>>())
51
+ .define_method("add", &MyVector<T>::add)
52
+ .define_method("size", &MyVector<T>::size)
53
+ .define_attr("empty", &MyVector<T>::empty, Rice::AttrAccess::Read);
54
+ }
55
+
56
+ TESTCASE(my_vector)
57
+ {
58
+ Class C1 = define_class<MyVector<int>>("MyVecInt").
59
+ define(&MyVector_builder<Data_Type<MyVector<int>>, int>);
60
+
61
+ Object o1 = C1.create();
62
+ Object result1 = o1.instance_eval("empty");
63
+ ASSERT_EQUAL(Qtrue, result1.value());
64
+
65
+ result1 = o1.instance_eval("size");
66
+ ASSERT_EQUAL(0, detail::From_Ruby<int>().convert(result1.value()));
67
+
68
+ o1.call("add", 5);
69
+ result1 = o1.instance_eval("empty");
70
+ ASSERT_EQUAL(Qfalse, o1.instance_eval("empty").value());
71
+
72
+ result1 = o1.instance_eval("size");
73
+ ASSERT_EQUAL(1, detail::From_Ruby<int>().convert(result1.value()));
74
+
75
+ Class C2 = define_class<MyVector< std::string>>("MyVecInt").
76
+ define(&MyVector_builder<Data_Type<MyVector<std::string>>, std::string>);
77
+
78
+ Object o2 = C2.create();
79
+ Object result2 = o2.instance_eval("empty");
80
+ ASSERT_EQUAL(Qtrue, result2.value());
81
+
82
+ result2 = o2.instance_eval("size");
83
+ ASSERT_EQUAL(0, detail::From_Ruby<int>().convert(result2.value()));
84
+
85
+ o2.call("add", "five");
86
+ result2 = o2.instance_eval("empty");
87
+ ASSERT_EQUAL(Qfalse, result2.value());
88
+
89
+ result2 = o2.instance_eval("size");
90
+ ASSERT_EQUAL(1, detail::From_Ruby<int>().convert(result2.value()));
91
+ }
92
+
93
+ namespace
94
+ {
95
+ template<typename T, int Rows, int Columns>
96
+ class Matrix
97
+ {
98
+ public:
99
+ int rows() const
100
+ {
101
+ return Rows;
102
+ }
103
+
104
+ int cols() const
105
+ {
106
+ return Columns;
107
+ }
108
+ };
109
+
110
+ template<typename T, int N>
111
+ class Scalar : public Matrix<T, N, 1>
112
+ {
113
+ public:
114
+ int size() const
115
+ {
116
+ return N;
117
+ }
118
+ };
119
+ }
120
+
121
+ template<typename Data_Type_T, typename T, int Rows, int Columns>
122
+ void Matrix_builder(Data_Type_T& klass)
123
+ {
124
+ klass.define_constructor(Constructor<Matrix<T, Rows, Columns>>())
125
+ .define_method("rows", &Matrix<T, Rows, Columns>::rows)
126
+ .define_method("cols", &Matrix<T, Rows, Columns>::cols);
127
+ }
128
+
129
+ template<typename Data_Type_T, typename T, int N>
130
+ void Scalar_builder(Data_Type_T& klass)
131
+ {
132
+ klass.define_constructor(Constructor<Scalar<T, N>>())
133
+ .define_method("size", &Scalar<T, N>::size);
134
+ }
135
+
136
+ TESTCASE(matrix)
137
+ {
138
+ Class C = define_class<Matrix<float, 5, 4>>("Matrixf54").
139
+ define(&Matrix_builder<Data_Type<Matrix<float, 5, 4>>, float, 5, 4>);
140
+
141
+ Object o = C.create();
142
+
143
+ Object result = o.instance_eval("cols");
144
+ ASSERT_EQUAL(4, detail::From_Ruby<int>().convert(result.value()));
145
+ }
146
+
147
+ TESTCASE(duplicate_template)
148
+ {
149
+ Class C1 = define_class<Matrix<float, 6, 4>>("MatrixFirst").
150
+ define(&Matrix_builder<Data_Type<Matrix<float, 6, 4>>, float, 6, 4>);
151
+
152
+ String name = C1.name();
153
+ ASSERT_EQUAL("MatrixFirst", name.str());
154
+
155
+ Object aClass1 = Object(rb_cObject).instance_eval("MatrixFirst");
156
+ bool result = aClass1.is_equal(C1);
157
+ ASSERT(result);
158
+
159
+ Class C2 = define_class<Matrix<float, 6, 4>>("MatrixSecond").
160
+ define(&Matrix_builder<Data_Type<Matrix<float, 6, 4>>, float, 6, 4>);
161
+
162
+ // The first definition name is the one that wins!
163
+ name = C2.name();
164
+ ASSERT_EQUAL("MatrixFirst", name.str());
165
+
166
+ Object aClass2 = Object(rb_cObject).instance_eval("MatrixSecond");
167
+ result = aClass2.is_equal(C2);
168
+ ASSERT(result);
169
+
170
+ result = C1.is_equal(C2);
171
+ ASSERT(result);
172
+ }
173
+
174
+ TESTCASE(template_inheritance)
175
+ {
176
+ Class MatrixClass = define_class<Matrix<float, 5, 1>>("Matrixf51").
177
+ define(&Matrix_builder<Data_Type<Matrix<float, 5, 1>>, float, 5, 1>);
178
+
179
+ Class ScalarClass = define_class<Scalar<float, 5>, Matrix<float, 5, 1>>("Scalarf5").
180
+ define(&Scalar_builder<Data_Type<Scalar<float, 5>>, float, 5>);
181
+
182
+ Object o = ScalarClass.create();
183
+
184
+ Object result = o.instance_eval("size");
185
+ ASSERT_EQUAL(5, detail::From_Ruby<int>().convert(result.value()));
186
+
187
+ result = o.instance_eval("rows");
188
+ ASSERT_EQUAL(5, detail::From_Ruby<int>().convert(result.value()));
189
+
190
+ result = o.instance_eval("cols");
191
+ ASSERT_EQUAL(1, detail::From_Ruby<int>().convert(result.value()));
192
+ }
@@ -0,0 +1,152 @@
1
+ #include "unittest.hpp"
2
+ #include "embed_ruby.hpp"
3
+ #include <rice/rice.hpp>
4
+
5
+ #include <limits>
6
+ #include <cmath>
7
+
8
+ using namespace Rice;
9
+
10
+ TESTSUITE(ToRuby);
11
+
12
+ SETUP(ToRuby)
13
+ {
14
+ embed_ruby();
15
+ }
16
+
17
+ TEARDOWN(ToRuby)
18
+ {
19
+ rb_gc_start();
20
+ }
21
+
22
+ TESTCASE(object_to_ruby)
23
+ {
24
+ Object o(rb_str_new2("foo"));
25
+ ASSERT_EQUAL(o.value(), detail::to_ruby(o));
26
+ }
27
+
28
+ TESTCASE(short_to_ruby)
29
+ {
30
+ ASSERT_EQUAL(INT2NUM(0), detail::to_ruby((short)0));
31
+ ASSERT_EQUAL(INT2NUM(-1), detail::to_ruby((short)-1));
32
+ ASSERT_EQUAL(INT2NUM(1), detail::to_ruby((short)1));
33
+ ASSERT_EQUAL(INT2NUM(std::numeric_limits<short>::min()),
34
+ detail::to_ruby(std::numeric_limits<short>::min()));
35
+ ASSERT_EQUAL(INT2NUM(std::numeric_limits<short>::max()),
36
+ detail::to_ruby(std::numeric_limits<short>::max()));
37
+ }
38
+
39
+ TESTCASE(int_to_ruby)
40
+ {
41
+ ASSERT(rb_equal(INT2NUM(0), detail::to_ruby((int)0)));
42
+ ASSERT(rb_equal(INT2NUM(-1), detail::to_ruby((int)-1)));
43
+ ASSERT(rb_equal(INT2NUM(1), detail::to_ruby((int)1)));
44
+ ASSERT(rb_equal(INT2NUM(std::numeric_limits<int>::min()), detail::to_ruby(std::numeric_limits<int>::min())));
45
+ ASSERT(rb_equal(INT2NUM(std::numeric_limits<int>::max()), detail::to_ruby(std::numeric_limits<int>::max())));
46
+ }
47
+
48
+ TESTCASE(long_to_ruby)
49
+ {
50
+ ASSERT(rb_equal(LONG2NUM(0), detail::to_ruby((long)0)));
51
+ ASSERT(rb_equal(LONG2NUM(-1), detail::to_ruby((long)-1)));
52
+ ASSERT(rb_equal(LONG2NUM(1), detail::to_ruby((long)1)));
53
+ ASSERT(rb_equal(LONG2NUM(FIXNUM_MAX), detail::to_ruby(FIXNUM_MAX)));
54
+ ASSERT(rb_equal(LONG2NUM(FIXNUM_MIN), detail::to_ruby(FIXNUM_MIN)));
55
+ ASSERT(rb_equal(LONG2NUM(std::numeric_limits<long>::min()), detail::to_ruby(std::numeric_limits<long>::min())));
56
+ ASSERT(rb_equal(LONG2NUM(std::numeric_limits<long>::max()), detail::to_ruby(std::numeric_limits<long>::max())));
57
+ }
58
+
59
+ TESTCASE(long_long_to_ruby)
60
+ {
61
+ ASSERT(rb_equal(LL2NUM(0), detail::to_ruby((long long)0)));
62
+ ASSERT(rb_equal(LL2NUM(-1), detail::to_ruby((long long)-1)));
63
+ ASSERT(rb_equal(LL2NUM(1), detail::to_ruby((long long)1)));
64
+ ASSERT(rb_equal(LL2NUM(std::numeric_limits<long long>::min()), detail::to_ruby(std::numeric_limits<long long>::min())));
65
+ ASSERT(rb_equal(LL2NUM(std::numeric_limits<long long>::max()), detail::to_ruby(std::numeric_limits<long long>::max())));
66
+ }
67
+
68
+ TESTCASE(unsigned_short_to_ruby)
69
+ {
70
+ ASSERT(rb_equal(UINT2NUM(0), detail::to_ruby((unsigned short)0)));
71
+ ASSERT(rb_equal(UINT2NUM(1), detail::to_ruby((unsigned short)1)));
72
+ ASSERT(rb_equal(UINT2NUM(std::numeric_limits<unsigned short>::min()), detail::to_ruby(std::numeric_limits<unsigned short>::min())));
73
+ ASSERT(rb_equal(UINT2NUM(std::numeric_limits<unsigned short>::max()), detail::to_ruby(std::numeric_limits<unsigned short>::max())));
74
+ }
75
+
76
+ TESTCASE(unsigned_int_to_ruby)
77
+ {
78
+ ASSERT(rb_equal(UINT2NUM(0), detail::to_ruby((unsigned int)0)));
79
+ ASSERT(rb_equal(UINT2NUM(1), detail::to_ruby((unsigned int)1)));
80
+ ASSERT(rb_equal(UINT2NUM(std::numeric_limits<unsigned int>::min()), detail::to_ruby(std::numeric_limits<unsigned int>::min())));
81
+ ASSERT(rb_equal(UINT2NUM(std::numeric_limits<unsigned int>::max()), detail::to_ruby(std::numeric_limits<unsigned int>::max())));
82
+ }
83
+
84
+ TESTCASE(unsigned_long_to_ruby)
85
+ {
86
+ ASSERT(rb_equal(ULONG2NUM(0), detail::to_ruby((unsigned long)0)));
87
+ ASSERT(rb_equal(ULONG2NUM(1), detail::to_ruby((unsigned long)1)));
88
+ ASSERT(rb_equal(ULONG2NUM(FIXNUM_MAX), detail::to_ruby(FIXNUM_MAX)));
89
+ ASSERT(rb_equal(ULONG2NUM(std::numeric_limits<unsigned long>::min()), detail::to_ruby(std::numeric_limits<unsigned long>::min())));
90
+ ASSERT(rb_equal(ULONG2NUM(std::numeric_limits<unsigned long>::max()), detail::to_ruby(std::numeric_limits<unsigned long>::max())));
91
+ }
92
+
93
+ TESTCASE(unsigned_long_long_to_ruby)
94
+ {
95
+ ASSERT(rb_equal(ULL2NUM(0), detail::to_ruby((unsigned long long)0)));
96
+ ASSERT(rb_equal(ULL2NUM(1), detail::to_ruby((unsigned long long)1)));
97
+ ASSERT(rb_equal(ULL2NUM(std::numeric_limits<unsigned long long>::min()), detail::to_ruby(std::numeric_limits<unsigned long long>::min())));
98
+ ASSERT(rb_equal(ULL2NUM(std::numeric_limits<unsigned long long>::max()), detail::to_ruby(std::numeric_limits<unsigned long long>::max())));
99
+ }
100
+
101
+ TESTCASE(bool_to_ruby)
102
+ {
103
+ ASSERT(rb_equal(Qfalse, detail::to_ruby(false)));
104
+ ASSERT(rb_equal(Qtrue, detail::to_ruby(true)));
105
+ }
106
+
107
+ TESTCASE(float_to_ruby)
108
+ {
109
+ ASSERT(rb_equal(rb_float_new(0.0f), detail::to_ruby(0.0f)));
110
+ ASSERT(rb_equal(rb_float_new(-1.0f), detail::to_ruby(-1.0f)));
111
+ ASSERT(rb_equal(rb_float_new(1.0f), detail::to_ruby(1.0f)));
112
+ ASSERT(rb_equal(rb_float_new(0.5f), detail::to_ruby(0.5f)));
113
+ ASSERT(rb_equal(rb_float_new(std::numeric_limits<float>::min()), detail::to_ruby(std::numeric_limits<float>::min())));
114
+ ASSERT(rb_equal(rb_float_new(std::numeric_limits<float>::max()), detail::to_ruby(std::numeric_limits<float>::max())));
115
+ ASSERT(Object(detail::to_ruby(std::numeric_limits<float>::quiet_NaN())).call("nan?"));
116
+ ASSERT(Object(detail::to_ruby(std::numeric_limits<float>::signaling_NaN())).call("nan?"));
117
+ ASSERT_EQUAL(rb_float_new(std::numeric_limits<float>::epsilon()),
118
+ detail::to_ruby(std::numeric_limits<float>::epsilon()));
119
+ }
120
+
121
+ TESTCASE(double_to_ruby)
122
+ {
123
+ ASSERT(rb_equal(rb_float_new(0.0f), detail::to_ruby(0.0f)));
124
+ ASSERT(rb_equal(rb_float_new(-1.0f), detail::to_ruby(-1.0f)));
125
+ ASSERT(rb_equal(rb_float_new(1.0f), detail::to_ruby(1.0f)));
126
+ ASSERT(rb_equal(rb_float_new(0.5f), detail::to_ruby(0.5f)));
127
+ ASSERT(rb_equal(rb_float_new(std::numeric_limits<double>::min()), detail::to_ruby(std::numeric_limits<double>::min())));
128
+ ASSERT(rb_equal(rb_float_new(std::numeric_limits<double>::max()), detail::to_ruby(std::numeric_limits<double>::max())));
129
+ ASSERT(Object(detail::to_ruby(std::numeric_limits<double>::quiet_NaN())).call("nan?"));
130
+ ASSERT(Object(detail::to_ruby(std::numeric_limits<double>::signaling_NaN())).call("nan?"));
131
+ ASSERT(rb_equal(rb_float_new(std::numeric_limits<double>::epsilon()), detail::to_ruby(std::numeric_limits<double>::epsilon())));
132
+ }
133
+
134
+ TESTCASE(char_ptr_to_ruby)
135
+ {
136
+ detail::To_Ruby<char*> toRuby;
137
+ ASSERT(rb_equal(String("").value(), toRuby.convert("")));
138
+ ASSERT(rb_equal(String("A string").value(), toRuby.convert("A string")));
139
+ ASSERT(rb_equal(Qnil, toRuby.convert(nullptr)));
140
+ }
141
+
142
+ TESTCASE(char_const_ptr_to_ruby)
143
+ {
144
+ ASSERT(rb_equal(String("").value(), detail::to_ruby((char const *)"")));
145
+ ASSERT(rb_equal(String("foo").value(), detail::to_ruby((char const *)"foo")));
146
+ ASSERT(rb_equal(String("foo").value(), detail::to_ruby("foo")));
147
+ }
148
+
149
+ TESTCASE(char_const_array_to_ruby_symbol)
150
+ {
151
+ ASSERT(rb_equal(Symbol("foo").value(), detail::to_ruby(":foo")));
152
+ }
@@ -87,6 +87,7 @@ SETUP(Tracking)
87
87
  TEARDOWN(Tracking)
88
88
  {
89
89
  detail::Registries::instance.instances.isEnabled = true;
90
+ rb_gc_start();
90
91
  }
91
92
 
92
93
  TESTCASE(TransferPointer)
@@ -0,0 +1,100 @@
1
+ #include "unittest.hpp"
2
+ #include "embed_ruby.hpp"
3
+
4
+ #include <rice/rice.hpp>
5
+
6
+ #include <complex>
7
+
8
+ using namespace Rice;
9
+
10
+ TESTSUITE(Type);
11
+
12
+ namespace Outer
13
+ {
14
+ namespace Inner
15
+ {
16
+ using Vec1 = std::vector<std::complex<float>>;
17
+ using Vec2 = std::vector<unsigned char*>;
18
+ using Map1 = std::map<std::string, std::vector<std::complex<float>>>;
19
+ using UnorderedMap1 = std::unordered_map<std::string, std::complex<float>>;
20
+
21
+ class SomeClass
22
+ {
23
+ };
24
+
25
+ using Vec3 = std::vector<SomeClass>;
26
+ }
27
+ }
28
+
29
+ SETUP(Type)
30
+ {
31
+ embed_ruby();
32
+ }
33
+
34
+ TEARDOWN(Type)
35
+ {
36
+ rb_gc_start();
37
+ }
38
+
39
+ TESTCASE(FindGroup)
40
+ {
41
+ std::string name = "class std::vector<class cv::Vec<unsigned char, 2>, class std::allocator<class cv::Vec<unsigned char, 2> > >";
42
+
43
+ std::string group = detail::findGroup(name, 0);
44
+ ASSERT_EQUAL("<class cv::Vec<unsigned char, 2>, class std::allocator<class cv::Vec<unsigned char, 2> > >", group.c_str());
45
+
46
+ group = detail::findGroup(name, 18);
47
+ ASSERT_EQUAL("<unsigned char, 2>", group.c_str());
48
+
49
+ group = detail::findGroup(name, 49);
50
+ ASSERT_EQUAL("<class cv::Vec<unsigned char, 2> >", group.c_str());
51
+
52
+ ASSERT_EXCEPTION_CHECK(
53
+ std::runtime_error,
54
+ detail::findGroup(name, 48),
55
+ ASSERT_EQUAL("Unbalanced Group", ex.what())
56
+ );
57
+ }
58
+
59
+ TESTCASE(MakeClassName)
60
+ {
61
+ std::string typeName = detail::typeName(typeid(Outer::Inner::Vec1));
62
+ std::string className = detail::makeClassName(typeName);
63
+ ASSERT_EQUAL(u8"Vector≺complex≺float≻≻", className.c_str());
64
+
65
+ typeName = detail::typeName(typeid(Outer::Inner::Vec2));
66
+ className = detail::makeClassName(typeName);
67
+ ASSERT_EQUAL(u8"Vector≺unsigned char*≻", className.c_str());
68
+
69
+ typeName = detail::typeName(typeid(Outer::Inner::Vec3));
70
+ className = detail::makeClassName(typeName);
71
+ ASSERT_EQUAL(u8"Vector≺Outer꞉꞉Inner꞉꞉SomeClass≻", className.c_str());
72
+
73
+ typeName = detail::typeName(typeid(Outer::Inner::Map1));
74
+ className = detail::makeClassName(typeName);
75
+ ASSERT_EQUAL(u8"Map≺string≺char≻‚ vector≺complex≺float≻≻≻", className.c_str());
76
+
77
+ typeName = detail::typeName(typeid(Outer::Inner::UnorderedMap1));
78
+ className = detail::makeClassName(typeName);
79
+ ASSERT_EQUAL(u8"UnorderedMap≺string≺char≻‚ complex≺float≻≻", className.c_str());
80
+ }
81
+
82
+ TESTCASE(MakeRubyClass)
83
+ {
84
+ std::string typeName = detail::typeName(typeid(Outer::Inner::Vec1));
85
+ std::string rubyClassName = detail::makeClassName(typeName);
86
+
87
+ Module module = define_module("Testing");
88
+
89
+ Identifier id(rubyClassName);
90
+ define_class_under<Outer::Inner::Vec1>(module, id);
91
+
92
+ std::string code = R"(Testing.constants.grep(/Vector/).sort)";
93
+
94
+ Array result = module.module_eval(code);
95
+ ASSERT_EQUAL(1, result.size());
96
+
97
+ // FIXME - fails compilation on GCC
98
+ // Symbol element = result[0];
99
+ // ASSERT_EQUAL(u8"Vector≺complex≺float≻≻", element.c_str());
100
+ }