rice 4.3.2 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -25
  3. data/README.md +7 -2
  4. data/Rakefile +7 -1
  5. data/include/rice/rice.hpp +7321 -4470
  6. data/include/rice/stl.hpp +769 -222
  7. data/lib/mkmf-rice.rb +37 -95
  8. data/rice/Address_Registration_Guard.hpp +72 -3
  9. data/rice/Arg.hpp +19 -5
  10. data/rice/Arg.ipp +24 -0
  11. data/rice/Callback.hpp +21 -0
  12. data/rice/Callback.ipp +13 -0
  13. data/rice/Constructor.hpp +4 -27
  14. data/rice/Constructor.ipp +79 -0
  15. data/rice/Data_Object.hpp +74 -3
  16. data/rice/Data_Object.ipp +324 -32
  17. data/rice/Data_Type.hpp +215 -3
  18. data/rice/Data_Type.ipp +125 -64
  19. data/rice/Director.hpp +0 -2
  20. data/rice/Enum.hpp +4 -6
  21. data/rice/Enum.ipp +101 -57
  22. data/rice/Exception.hpp +62 -2
  23. data/rice/Exception.ipp +7 -12
  24. data/rice/JumpException.hpp +44 -0
  25. data/rice/JumpException.ipp +48 -0
  26. data/rice/MemoryView.hpp +11 -0
  27. data/rice/MemoryView.ipp +43 -0
  28. data/rice/Return.hpp +6 -26
  29. data/rice/Return.ipp +10 -16
  30. data/rice/detail/DefaultHandler.hpp +12 -0
  31. data/rice/detail/DefaultHandler.ipp +8 -0
  32. data/rice/detail/HandlerRegistry.hpp +5 -35
  33. data/rice/detail/HandlerRegistry.ipp +7 -11
  34. data/rice/detail/InstanceRegistry.hpp +1 -4
  35. data/rice/detail/MethodInfo.hpp +15 -5
  36. data/rice/detail/MethodInfo.ipp +78 -6
  37. data/rice/detail/Native.hpp +32 -0
  38. data/rice/detail/Native.ipp +129 -0
  39. data/rice/detail/NativeAttributeGet.hpp +51 -0
  40. data/rice/detail/NativeAttributeGet.ipp +51 -0
  41. data/rice/detail/NativeAttributeSet.hpp +43 -0
  42. data/rice/detail/NativeAttributeSet.ipp +82 -0
  43. data/rice/detail/NativeCallbackFFI.hpp +55 -0
  44. data/rice/detail/NativeCallbackFFI.ipp +151 -0
  45. data/rice/detail/NativeCallbackSimple.hpp +30 -0
  46. data/rice/detail/NativeCallbackSimple.ipp +29 -0
  47. data/rice/detail/NativeFunction.hpp +20 -21
  48. data/rice/detail/NativeFunction.ipp +199 -64
  49. data/rice/detail/NativeIterator.hpp +8 -11
  50. data/rice/detail/NativeIterator.ipp +27 -31
  51. data/rice/detail/NativeRegistry.hpp +24 -17
  52. data/rice/detail/NativeRegistry.ipp +23 -56
  53. data/rice/detail/Proc.hpp +4 -0
  54. data/rice/detail/Proc.ipp +85 -0
  55. data/rice/detail/Registries.hpp +0 -7
  56. data/rice/detail/Registries.ipp +0 -18
  57. data/rice/detail/RubyFunction.hpp +0 -3
  58. data/rice/detail/RubyFunction.ipp +4 -8
  59. data/rice/detail/RubyType.hpp +19 -0
  60. data/rice/detail/RubyType.ipp +187 -0
  61. data/rice/detail/TupleIterator.hpp +14 -0
  62. data/rice/detail/Type.hpp +5 -6
  63. data/rice/detail/Type.ipp +150 -33
  64. data/rice/detail/TypeRegistry.hpp +15 -7
  65. data/rice/detail/TypeRegistry.ipp +105 -12
  66. data/rice/detail/Wrapper.hpp +6 -5
  67. data/rice/detail/Wrapper.ipp +45 -23
  68. data/rice/detail/cpp_protect.hpp +5 -6
  69. data/rice/detail/default_allocation_func.ipp +0 -2
  70. data/rice/detail/from_ruby.hpp +37 -3
  71. data/rice/detail/from_ruby.ipp +911 -454
  72. data/rice/detail/ruby.hpp +18 -0
  73. data/rice/detail/to_ruby.hpp +41 -3
  74. data/rice/detail/to_ruby.ipp +437 -113
  75. data/rice/global_function.hpp +0 -4
  76. data/rice/global_function.ipp +1 -2
  77. data/rice/rice.hpp +105 -22
  78. data/rice/ruby_mark.hpp +4 -3
  79. data/rice/stl.hpp +4 -0
  80. data/test/embed_ruby.cpp +4 -1
  81. data/test/extconf.rb +2 -0
  82. data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
  83. data/test/test_Address_Registration_Guard.cpp +5 -0
  84. data/test/test_Array.cpp +12 -1
  85. data/test/test_Attribute.cpp +103 -21
  86. data/test/test_Builtin_Object.cpp +5 -0
  87. data/test/test_Callback.cpp +231 -0
  88. data/test/test_Class.cpp +5 -31
  89. data/test/test_Constructor.cpp +69 -6
  90. data/test/test_Data_Object.cpp +9 -4
  91. data/test/test_Data_Type.cpp +428 -64
  92. data/test/test_Director.cpp +10 -5
  93. data/test/test_Enum.cpp +152 -40
  94. data/test/test_Exception.cpp +235 -0
  95. data/test/test_File.cpp +70 -0
  96. data/test/test_From_Ruby.cpp +542 -0
  97. data/test/test_Hash.cpp +5 -0
  98. data/test/test_Identifier.cpp +5 -0
  99. data/test/test_Inheritance.cpp +6 -1
  100. data/test/test_Iterator.cpp +5 -0
  101. data/test/test_JumpException.cpp +22 -0
  102. data/test/test_Keep_Alive.cpp +6 -1
  103. data/test/test_Keep_Alive_No_Wrapper.cpp +5 -0
  104. data/test/test_Memory_Management.cpp +5 -0
  105. data/test/test_Module.cpp +118 -64
  106. data/test/test_Native_Registry.cpp +2 -33
  107. data/test/test_Object.cpp +5 -0
  108. data/test/test_Overloads.cpp +631 -0
  109. data/test/test_Ownership.cpp +67 -4
  110. data/test/test_Proc.cpp +45 -0
  111. data/test/test_Self.cpp +5 -0
  112. data/test/test_Stl_Exception.cpp +109 -0
  113. data/test/test_Stl_Map.cpp +22 -8
  114. data/test/test_Stl_Optional.cpp +5 -0
  115. data/test/test_Stl_Pair.cpp +7 -2
  116. data/test/test_Stl_Reference_Wrapper.cpp +5 -0
  117. data/test/test_Stl_SmartPointer.cpp +210 -5
  118. data/test/test_Stl_String.cpp +5 -0
  119. data/test/test_Stl_String_View.cpp +5 -0
  120. data/test/test_Stl_Type.cpp +147 -0
  121. data/test/test_Stl_Unordered_Map.cpp +18 -7
  122. data/test/test_Stl_Variant.cpp +5 -0
  123. data/test/test_Stl_Vector.cpp +130 -8
  124. data/test/test_String.cpp +5 -0
  125. data/test/test_Struct.cpp +5 -0
  126. data/test/test_Symbol.cpp +5 -0
  127. data/test/test_Template.cpp +192 -0
  128. data/test/test_To_Ruby.cpp +152 -0
  129. data/test/test_Tracking.cpp +1 -0
  130. data/test/test_Type.cpp +100 -0
  131. data/test/test_global_functions.cpp +53 -6
  132. data/test/unittest.cpp +8 -0
  133. metadata +37 -20
  134. data/lib/version.rb +0 -3
  135. data/rice/Address_Registration_Guard_defn.hpp +0 -79
  136. data/rice/Data_Object_defn.hpp +0 -84
  137. data/rice/Data_Type_defn.hpp +0 -190
  138. data/rice/Exception_defn.hpp +0 -68
  139. data/rice/HandlerRegistration.hpp +0 -15
  140. data/rice/Identifier.hpp +0 -50
  141. data/rice/Identifier.ipp +0 -29
  142. data/rice/detail/ExceptionHandler.hpp +0 -8
  143. data/rice/detail/ExceptionHandler.ipp +0 -28
  144. data/rice/detail/ExceptionHandler_defn.hpp +0 -77
  145. data/rice/detail/Jump_Tag.hpp +0 -21
  146. data/rice/detail/NativeAttribute.hpp +0 -64
  147. data/rice/detail/NativeAttribute.ipp +0 -112
  148. data/rice/detail/from_ruby_defn.hpp +0 -38
  149. data/rice/detail/to_ruby_defn.hpp +0 -48
  150. data/test/test_Jump_Tag.cpp +0 -17
  151. data/test/test_To_From_Ruby.cpp +0 -399
@@ -1,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
+ }