rice 4.3.3 → 4.6.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 (237) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -26
  3. data/CMakeLists.txt +31 -0
  4. data/CMakePresets.json +75 -0
  5. data/COPYING +3 -2
  6. data/FindRuby.cmake +437 -0
  7. data/README.md +7 -2
  8. data/Rakefile +12 -5
  9. data/include/rice/rice.hpp +9522 -4426
  10. data/include/rice/stl.hpp +2831 -1198
  11. data/lib/make_rice_headers.rb +79 -0
  12. data/lib/mkmf-rice.rb +40 -94
  13. data/lib/rice/version.rb +3 -0
  14. data/lib/rice.rb +1 -0
  15. data/lib/rubygems/builder.rb +11 -0
  16. data/lib/rubygems/cmake_builder.rb +113 -0
  17. data/lib/rubygems_plugin.rb +9 -0
  18. data/rice/Address_Registration_Guard.hpp +72 -3
  19. data/rice/Arg.hpp +26 -6
  20. data/rice/Arg.ipp +35 -2
  21. data/rice/Buffer.hpp +123 -0
  22. data/rice/Buffer.ipp +599 -0
  23. data/rice/Callback.hpp +21 -0
  24. data/rice/Callback.ipp +13 -0
  25. data/rice/Constructor.hpp +4 -27
  26. data/rice/Constructor.ipp +79 -0
  27. data/rice/Data_Object.hpp +73 -3
  28. data/rice/Data_Object.ipp +388 -96
  29. data/rice/Data_Type.hpp +214 -3
  30. data/rice/Data_Type.ipp +144 -67
  31. data/rice/Director.hpp +0 -2
  32. data/rice/Enum.hpp +4 -7
  33. data/rice/Enum.ipp +102 -55
  34. data/rice/Exception.hpp +62 -2
  35. data/rice/Exception.ipp +7 -12
  36. data/rice/Init.hpp +8 -0
  37. data/rice/Init.ipp +8 -0
  38. data/rice/JumpException.hpp +44 -0
  39. data/rice/JumpException.ipp +48 -0
  40. data/rice/MemoryView.hpp +11 -0
  41. data/rice/MemoryView.ipp +3 -0
  42. data/rice/Return.hpp +7 -27
  43. data/rice/Return.ipp +13 -13
  44. data/rice/cpp_api/Array.hpp +209 -0
  45. data/rice/cpp_api/Array.ipp +304 -0
  46. data/rice/cpp_api/Builtin_Object.hpp +31 -0
  47. data/rice/cpp_api/Builtin_Object.ipp +37 -0
  48. data/rice/cpp_api/Class.hpp +70 -0
  49. data/rice/cpp_api/Class.ipp +97 -0
  50. data/rice/cpp_api/Encoding.hpp +32 -0
  51. data/rice/cpp_api/Encoding.ipp +59 -0
  52. data/rice/cpp_api/Hash.hpp +194 -0
  53. data/rice/cpp_api/Hash.ipp +257 -0
  54. data/rice/{Identifier.hpp → cpp_api/Identifier.hpp} +2 -6
  55. data/rice/{Identifier.ipp → cpp_api/Identifier.ipp} +4 -2
  56. data/rice/cpp_api/Module.hpp +72 -0
  57. data/rice/cpp_api/Module.ipp +101 -0
  58. data/rice/cpp_api/Object.hpp +272 -0
  59. data/rice/cpp_api/Object.ipp +235 -0
  60. data/rice/cpp_api/String.hpp +74 -0
  61. data/rice/cpp_api/String.ipp +120 -0
  62. data/rice/cpp_api/Struct.hpp +113 -0
  63. data/rice/cpp_api/Struct.ipp +92 -0
  64. data/rice/cpp_api/Symbol.hpp +46 -0
  65. data/rice/cpp_api/Symbol.ipp +93 -0
  66. data/rice/cpp_api/shared_methods.hpp +134 -0
  67. data/rice/detail/DefaultHandler.hpp +12 -0
  68. data/rice/detail/DefaultHandler.ipp +8 -0
  69. data/rice/detail/HandlerRegistry.hpp +5 -35
  70. data/rice/detail/HandlerRegistry.ipp +7 -11
  71. data/rice/detail/InstanceRegistry.hpp +1 -4
  72. data/rice/detail/MethodInfo.hpp +12 -10
  73. data/rice/detail/MethodInfo.ipp +26 -21
  74. data/rice/detail/Native.hpp +33 -0
  75. data/rice/detail/Native.ipp +157 -0
  76. data/rice/detail/NativeAttributeGet.hpp +52 -0
  77. data/rice/detail/NativeAttributeGet.ipp +57 -0
  78. data/rice/detail/NativeAttributeSet.hpp +44 -0
  79. data/rice/detail/NativeAttributeSet.ipp +88 -0
  80. data/rice/detail/NativeCallbackFFI.hpp +55 -0
  81. data/rice/detail/NativeCallbackFFI.ipp +151 -0
  82. data/rice/detail/NativeCallbackSimple.hpp +30 -0
  83. data/rice/detail/NativeCallbackSimple.ipp +29 -0
  84. data/rice/detail/NativeFunction.hpp +33 -23
  85. data/rice/detail/NativeFunction.ipp +309 -70
  86. data/rice/detail/NativeIterator.hpp +9 -11
  87. data/rice/detail/NativeIterator.ipp +33 -31
  88. data/rice/detail/NativeRegistry.hpp +24 -15
  89. data/rice/detail/NativeRegistry.ipp +23 -48
  90. data/rice/detail/Proc.hpp +4 -0
  91. data/rice/detail/Proc.ipp +85 -0
  92. data/rice/detail/Registries.hpp +0 -7
  93. data/rice/detail/Registries.ipp +0 -18
  94. data/rice/detail/RubyFunction.hpp +0 -3
  95. data/rice/detail/RubyFunction.ipp +4 -8
  96. data/rice/detail/RubyType.hpp +16 -0
  97. data/rice/detail/RubyType.ipp +232 -0
  98. data/rice/detail/Type.hpp +7 -6
  99. data/rice/detail/Type.ipp +192 -45
  100. data/rice/detail/TypeRegistry.hpp +15 -7
  101. data/rice/detail/TypeRegistry.ipp +105 -12
  102. data/rice/detail/Wrapper.hpp +68 -32
  103. data/rice/detail/Wrapper.ipp +121 -109
  104. data/rice/detail/cpp_protect.hpp +5 -6
  105. data/rice/detail/default_allocation_func.ipp +0 -2
  106. data/rice/detail/from_ruby.hpp +38 -3
  107. data/rice/detail/from_ruby.ipp +1321 -492
  108. data/rice/detail/ruby.hpp +18 -0
  109. data/rice/detail/to_ruby.hpp +41 -3
  110. data/rice/detail/to_ruby.ipp +1424 -194
  111. data/rice/global_function.hpp +0 -4
  112. data/rice/global_function.ipp +0 -1
  113. data/rice/libc/file.hpp +11 -0
  114. data/rice/libc/file.ipp +32 -0
  115. data/rice/rice.hpp +116 -26
  116. data/rice/ruby_mark.hpp +4 -3
  117. data/rice/stl/complex.hpp +6 -0
  118. data/rice/stl/complex.ipp +93 -0
  119. data/rice/stl/exception.hpp +11 -0
  120. data/rice/stl/exception.ipp +29 -0
  121. data/rice/stl/exception_ptr.hpp +6 -0
  122. data/rice/stl/exception_ptr.ipp +27 -0
  123. data/rice/stl/map.hpp +12 -0
  124. data/rice/stl/map.ipp +469 -0
  125. data/rice/stl/monostate.hpp +6 -0
  126. data/rice/stl/monostate.ipp +80 -0
  127. data/rice/stl/multimap.hpp +14 -0
  128. data/rice/stl/multimap.ipp +448 -0
  129. data/rice/stl/optional.hpp +6 -0
  130. data/rice/stl/optional.ipp +118 -0
  131. data/rice/stl/pair.hpp +13 -0
  132. data/rice/stl/pair.ipp +155 -0
  133. data/rice/stl/reference_wrapper.hpp +6 -0
  134. data/rice/stl/reference_wrapper.ipp +41 -0
  135. data/rice/stl/set.hpp +12 -0
  136. data/rice/stl/set.ipp +495 -0
  137. data/rice/stl/shared_ptr.hpp +28 -0
  138. data/rice/stl/shared_ptr.ipp +224 -0
  139. data/rice/stl/string.hpp +6 -0
  140. data/rice/stl/string.ipp +158 -0
  141. data/rice/stl/string_view.hpp +6 -0
  142. data/rice/stl/string_view.ipp +65 -0
  143. data/rice/stl/tuple.hpp +6 -0
  144. data/rice/stl/tuple.ipp +128 -0
  145. data/rice/stl/type_index.hpp +6 -0
  146. data/rice/stl/type_index.ipp +30 -0
  147. data/rice/stl/type_info.hpp +6 -0
  148. data/rice/stl/type_info.ipp +29 -0
  149. data/rice/stl/unique_ptr.hpp +22 -0
  150. data/rice/stl/unique_ptr.ipp +139 -0
  151. data/rice/stl/unordered_map.hpp +12 -0
  152. data/rice/stl/unordered_map.ipp +469 -0
  153. data/rice/stl/variant.hpp +6 -0
  154. data/rice/stl/variant.ipp +242 -0
  155. data/rice/stl/vector.hpp +12 -0
  156. data/rice/stl/vector.ipp +590 -0
  157. data/rice/stl.hpp +11 -3
  158. data/rice/traits/attribute_traits.hpp +26 -0
  159. data/rice/traits/function_traits.hpp +95 -0
  160. data/rice/traits/method_traits.hpp +47 -0
  161. data/rice/traits/rice_traits.hpp +160 -0
  162. data/rice.gemspec +85 -0
  163. data/test/embed_ruby.cpp +7 -1
  164. data/test/extconf.rb +2 -0
  165. data/test/test_Address_Registration_Guard.cpp +5 -0
  166. data/test/test_Array.cpp +18 -4
  167. data/test/test_Attribute.cpp +136 -21
  168. data/test/test_Buffer.cpp +285 -0
  169. data/test/test_Builtin_Object.cpp +5 -0
  170. data/test/test_Callback.cpp +230 -0
  171. data/test/test_Class.cpp +5 -31
  172. data/test/test_Constructor.cpp +69 -6
  173. data/test/test_Data_Object.cpp +97 -38
  174. data/test/test_Data_Type.cpp +470 -65
  175. data/test/test_Director.cpp +17 -8
  176. data/test/test_Enum.cpp +155 -40
  177. data/test/test_Exception.cpp +235 -0
  178. data/test/test_File.cpp +70 -0
  179. data/test/test_From_Ruby.cpp +609 -0
  180. data/test/test_Hash.cpp +5 -0
  181. data/test/test_Identifier.cpp +5 -0
  182. data/test/test_Inheritance.cpp +6 -1
  183. data/test/test_Iterator.cpp +6 -1
  184. data/test/test_Jump_Exception.cpp +23 -0
  185. data/test/test_Keep_Alive.cpp +13 -19
  186. data/test/test_Keep_Alive_No_Wrapper.cpp +5 -1
  187. data/test/test_Memory_Management.cpp +5 -0
  188. data/test/test_Module.cpp +128 -67
  189. data/test/test_Native_Registry.cpp +2 -34
  190. data/test/test_Object.cpp +5 -0
  191. data/test/test_Overloads.cpp +806 -0
  192. data/test/test_Ownership.cpp +160 -54
  193. data/test/test_Proc.cpp +44 -0
  194. data/test/test_Self.cpp +9 -4
  195. data/test/test_Stl_Exception.cpp +109 -0
  196. data/test/test_Stl_Map.cpp +54 -42
  197. data/test/test_Stl_Multimap.cpp +693 -0
  198. data/test/test_Stl_Optional.cpp +5 -0
  199. data/test/test_Stl_Pair.cpp +14 -9
  200. data/test/test_Stl_Reference_Wrapper.cpp +9 -2
  201. data/test/test_Stl_Set.cpp +790 -0
  202. data/test/test_Stl_SharedPtr.cpp +458 -0
  203. data/test/test_Stl_String.cpp +5 -0
  204. data/test/test_Stl_String_View.cpp +5 -0
  205. data/test/test_Stl_Tuple.cpp +116 -0
  206. data/test/test_Stl_Type.cpp +147 -0
  207. data/test/test_Stl_UniquePtr.cpp +202 -0
  208. data/test/test_Stl_Unordered_Map.cpp +43 -38
  209. data/test/test_Stl_Variant.cpp +217 -84
  210. data/test/test_Stl_Vector.cpp +306 -58
  211. data/test/test_String.cpp +5 -0
  212. data/test/test_Struct.cpp +5 -0
  213. data/test/test_Symbol.cpp +5 -0
  214. data/test/test_Template.cpp +192 -0
  215. data/test/test_To_Ruby.cpp +524 -0
  216. data/test/test_Tracking.cpp +1 -0
  217. data/test/test_Type.cpp +171 -0
  218. data/test/test_global_functions.cpp +67 -7
  219. data/test/unittest.cpp +8 -0
  220. metadata +127 -26
  221. data/lib/version.rb +0 -3
  222. data/rice/Address_Registration_Guard_defn.hpp +0 -79
  223. data/rice/Data_Object_defn.hpp +0 -84
  224. data/rice/Data_Type_defn.hpp +0 -190
  225. data/rice/Exception_defn.hpp +0 -68
  226. data/rice/HandlerRegistration.hpp +0 -15
  227. data/rice/detail/ExceptionHandler.hpp +0 -8
  228. data/rice/detail/ExceptionHandler.ipp +0 -28
  229. data/rice/detail/ExceptionHandler_defn.hpp +0 -77
  230. data/rice/detail/Jump_Tag.hpp +0 -21
  231. data/rice/detail/NativeAttribute.hpp +0 -64
  232. data/rice/detail/NativeAttribute.ipp +0 -112
  233. data/rice/detail/from_ruby_defn.hpp +0 -38
  234. data/rice/detail/to_ruby_defn.hpp +0 -48
  235. data/test/test_Jump_Tag.cpp +0 -17
  236. data/test/test_Stl_SmartPointer.cpp +0 -283
  237. data/test/test_To_From_Ruby.cpp +0 -399
@@ -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,524 @@
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
+ using namespace std::string_literals;
10
+
11
+ TESTSUITE(ToRuby);
12
+
13
+ SETUP(ToRuby)
14
+ {
15
+ embed_ruby();
16
+ define_fundamental_buffer_types();
17
+ }
18
+
19
+ TEARDOWN(ToRuby)
20
+ {
21
+ rb_gc_start();
22
+ }
23
+
24
+ TESTCASE(object_to_ruby)
25
+ {
26
+ Object o(rb_str_new2("foo"));
27
+ ASSERT_EQUAL(o.value(), detail::to_ruby(o));
28
+ }
29
+
30
+ TESTCASE(short_to_ruby)
31
+ {
32
+ ASSERT_EQUAL(INT2NUM(0), detail::to_ruby((short)0));
33
+ ASSERT_EQUAL(INT2NUM(-1), detail::to_ruby((short)-1));
34
+ ASSERT_EQUAL(INT2NUM(1), detail::to_ruby((short)1));
35
+ ASSERT_EQUAL(INT2NUM(std::numeric_limits<short>::min()),
36
+ detail::to_ruby(std::numeric_limits<short>::min()));
37
+ ASSERT_EQUAL(INT2NUM(std::numeric_limits<short>::max()),
38
+ detail::to_ruby(std::numeric_limits<short>::max()));
39
+ }
40
+
41
+ TESTCASE(int_to_ruby)
42
+ {
43
+ ASSERT(rb_equal(INT2NUM(0), detail::to_ruby((int)0)));
44
+ ASSERT(rb_equal(INT2NUM(-1), detail::to_ruby((int)-1)));
45
+ ASSERT(rb_equal(INT2NUM(1), detail::to_ruby((int)1)));
46
+ ASSERT(rb_equal(INT2NUM(std::numeric_limits<int>::min()), detail::to_ruby(std::numeric_limits<int>::min())));
47
+ ASSERT(rb_equal(INT2NUM(std::numeric_limits<int>::max()), detail::to_ruby(std::numeric_limits<int>::max())));
48
+ }
49
+
50
+ TESTCASE(long_to_ruby)
51
+ {
52
+ ASSERT(rb_equal(LONG2NUM(0), detail::to_ruby((long)0)));
53
+ ASSERT(rb_equal(LONG2NUM(-1), detail::to_ruby((long)-1)));
54
+ ASSERT(rb_equal(LONG2NUM(1), detail::to_ruby((long)1)));
55
+ ASSERT(rb_equal(LONG2NUM(FIXNUM_MAX), detail::to_ruby(FIXNUM_MAX)));
56
+ ASSERT(rb_equal(LONG2NUM(FIXNUM_MIN), detail::to_ruby(FIXNUM_MIN)));
57
+ ASSERT(rb_equal(LONG2NUM(std::numeric_limits<long>::min()), detail::to_ruby(std::numeric_limits<long>::min())));
58
+ ASSERT(rb_equal(LONG2NUM(std::numeric_limits<long>::max()), detail::to_ruby(std::numeric_limits<long>::max())));
59
+ }
60
+
61
+ TESTCASE(long_long_to_ruby)
62
+ {
63
+ ASSERT(rb_equal(LL2NUM(0), detail::to_ruby((long long)0)));
64
+ ASSERT(rb_equal(LL2NUM(-1), detail::to_ruby((long long)-1)));
65
+ ASSERT(rb_equal(LL2NUM(1), detail::to_ruby((long long)1)));
66
+ ASSERT(rb_equal(LL2NUM(std::numeric_limits<long long>::min()), detail::to_ruby(std::numeric_limits<long long>::min())));
67
+ ASSERT(rb_equal(LL2NUM(std::numeric_limits<long long>::max()), detail::to_ruby(std::numeric_limits<long long>::max())));
68
+ }
69
+
70
+ TESTCASE(unsigned_short_to_ruby)
71
+ {
72
+ ASSERT(rb_equal(UINT2NUM(0), detail::to_ruby((unsigned short)0)));
73
+ ASSERT(rb_equal(UINT2NUM(1), detail::to_ruby((unsigned short)1)));
74
+ ASSERT(rb_equal(UINT2NUM(std::numeric_limits<unsigned short>::min()), detail::to_ruby(std::numeric_limits<unsigned short>::min())));
75
+ ASSERT(rb_equal(UINT2NUM(std::numeric_limits<unsigned short>::max()), detail::to_ruby(std::numeric_limits<unsigned short>::max())));
76
+ }
77
+
78
+ TESTCASE(unsigned_int_to_ruby)
79
+ {
80
+ ASSERT(rb_equal(UINT2NUM(0), detail::to_ruby((unsigned int)0)));
81
+ ASSERT(rb_equal(UINT2NUM(1), detail::to_ruby((unsigned int)1)));
82
+ ASSERT(rb_equal(UINT2NUM(std::numeric_limits<unsigned int>::min()), detail::to_ruby(std::numeric_limits<unsigned int>::min())));
83
+ ASSERT(rb_equal(UINT2NUM(std::numeric_limits<unsigned int>::max()), detail::to_ruby(std::numeric_limits<unsigned int>::max())));
84
+ }
85
+
86
+ TESTCASE(unsigned_long_to_ruby)
87
+ {
88
+ ASSERT(rb_equal(ULONG2NUM(0), detail::to_ruby((unsigned long)0)));
89
+ ASSERT(rb_equal(ULONG2NUM(1), detail::to_ruby((unsigned long)1)));
90
+ ASSERT(rb_equal(ULONG2NUM(FIXNUM_MAX), detail::to_ruby(FIXNUM_MAX)));
91
+ ASSERT(rb_equal(ULONG2NUM(std::numeric_limits<unsigned long>::min()), detail::to_ruby(std::numeric_limits<unsigned long>::min())));
92
+ ASSERT(rb_equal(ULONG2NUM(std::numeric_limits<unsigned long>::max()), detail::to_ruby(std::numeric_limits<unsigned long>::max())));
93
+ }
94
+
95
+ TESTCASE(unsigned_long_long_to_ruby)
96
+ {
97
+ ASSERT(rb_equal(ULL2NUM(0), detail::to_ruby((unsigned long long)0)));
98
+ ASSERT(rb_equal(ULL2NUM(1), detail::to_ruby((unsigned long long)1)));
99
+ ASSERT(rb_equal(ULL2NUM(std::numeric_limits<unsigned long long>::min()), detail::to_ruby(std::numeric_limits<unsigned long long>::min())));
100
+ ASSERT(rb_equal(ULL2NUM(std::numeric_limits<unsigned long long>::max()), detail::to_ruby(std::numeric_limits<unsigned long long>::max())));
101
+ }
102
+
103
+ TESTCASE(bool_to_ruby)
104
+ {
105
+ ASSERT(rb_equal(Qfalse, detail::to_ruby(false)));
106
+ ASSERT(rb_equal(Qtrue, detail::to_ruby(true)));
107
+ }
108
+
109
+ TESTCASE(float_to_ruby)
110
+ {
111
+ ASSERT(rb_equal(rb_float_new(0.0f), detail::to_ruby(0.0f)));
112
+ ASSERT(rb_equal(rb_float_new(-1.0f), detail::to_ruby(-1.0f)));
113
+ ASSERT(rb_equal(rb_float_new(1.0f), detail::to_ruby(1.0f)));
114
+ ASSERT(rb_equal(rb_float_new(0.5f), detail::to_ruby(0.5f)));
115
+ ASSERT(rb_equal(rb_float_new(std::numeric_limits<float>::min()), detail::to_ruby(std::numeric_limits<float>::min())));
116
+ ASSERT(rb_equal(rb_float_new(std::numeric_limits<float>::max()), detail::to_ruby(std::numeric_limits<float>::max())));
117
+ ASSERT(Object(detail::to_ruby(std::numeric_limits<float>::quiet_NaN())).call("nan?"));
118
+ ASSERT(Object(detail::to_ruby(std::numeric_limits<float>::signaling_NaN())).call("nan?"));
119
+ ASSERT_EQUAL(rb_float_new(std::numeric_limits<float>::epsilon()),
120
+ detail::to_ruby(std::numeric_limits<float>::epsilon()));
121
+ }
122
+
123
+ TESTCASE(double_to_ruby)
124
+ {
125
+ ASSERT(rb_equal(rb_float_new(0.0f), detail::to_ruby(0.0f)));
126
+ ASSERT(rb_equal(rb_float_new(-1.0f), detail::to_ruby(-1.0f)));
127
+ ASSERT(rb_equal(rb_float_new(1.0f), detail::to_ruby(1.0f)));
128
+ ASSERT(rb_equal(rb_float_new(0.5f), detail::to_ruby(0.5f)));
129
+ ASSERT(rb_equal(rb_float_new(std::numeric_limits<double>::min()), detail::to_ruby(std::numeric_limits<double>::min())));
130
+ ASSERT(rb_equal(rb_float_new(std::numeric_limits<double>::max()), detail::to_ruby(std::numeric_limits<double>::max())));
131
+ ASSERT(Object(detail::to_ruby(std::numeric_limits<double>::quiet_NaN())).call("nan?"));
132
+ ASSERT(Object(detail::to_ruby(std::numeric_limits<double>::signaling_NaN())).call("nan?"));
133
+ ASSERT(rb_equal(rb_float_new(std::numeric_limits<double>::epsilon()), detail::to_ruby(std::numeric_limits<double>::epsilon())));
134
+ }
135
+
136
+ TESTCASE(char_ptr_to_ruby)
137
+ {
138
+ detail::To_Ruby<char*> toRuby;
139
+ ASSERT(rb_equal(String("").value(), toRuby.convert("")));
140
+ ASSERT(rb_equal(String("A string").value(), toRuby.convert("A string")));
141
+ ASSERT(rb_equal(Qnil, toRuby.convert(nullptr)));
142
+ }
143
+
144
+ TESTCASE(char_const_ptr_to_ruby)
145
+ {
146
+ ASSERT(rb_equal(String("").value(), detail::to_ruby((char const *)"")));
147
+ ASSERT(rb_equal(String("foo").value(), detail::to_ruby((char const *)"foo")));
148
+ ASSERT(rb_equal(String("foo").value(), detail::to_ruby("foo")));
149
+ }
150
+
151
+ TESTCASE(char_const_array_to_ruby_symbol)
152
+ {
153
+ ASSERT(rb_equal(Symbol("foo").value(), detail::to_ruby(":foo")));
154
+ }
155
+
156
+ namespace
157
+ {
158
+ template<typename T>
159
+ class Matrix2
160
+ {
161
+ public:
162
+ T* ptr()
163
+ {
164
+ return this->data;
165
+ }
166
+
167
+ T data[5] = { 1,2,3,4,5 };
168
+ };
169
+
170
+ using Matrix2UnsignedChar = Matrix2<unsigned char>;
171
+ using Matrix2Char = Matrix2<char>;
172
+ using Matrix2UnsignedShort = Matrix2<unsigned short>;
173
+ using Matrix2Short = Matrix2<short>;
174
+ using Matrix2UnsignedInt = Matrix2<unsigned int>;
175
+ using Matrix2Int = Matrix2<int>;
176
+ using Matrix2Float = Matrix2<float>;
177
+ using Matrix2Double = Matrix2<double>;
178
+
179
+ template<typename T>
180
+ class Matrix3
181
+ {
182
+ public:
183
+ T** ptr()
184
+ {
185
+ return this->data;
186
+ }
187
+
188
+ private:
189
+ T one = 1;
190
+ T two = 2;
191
+ T three = 3;
192
+ T four = 4;
193
+ T five = 5;
194
+
195
+ public:
196
+ T* data[5] = { &one, &two, &three, &four, &five };
197
+
198
+ };
199
+
200
+ using Matrix3UnsignedChar = Matrix3<unsigned char>;
201
+ }
202
+
203
+ TESTCASE(unsigned_char_ptr_buffer)
204
+ {
205
+ Module m = define_module("ToRubyPtr");
206
+
207
+ Class c = define_class_under<Matrix2UnsignedChar>(m, "Matrix2UnsignedChar")
208
+ .define_constructor(Constructor<Matrix2UnsignedChar>())
209
+ .define_method("ptr", &Matrix2UnsignedChar::ptr)
210
+ .define_attr("data", &Matrix2UnsignedChar::data, Rice::AttrAccess::Read);
211
+
212
+ std::string code = R"(matrix = Matrix2UnsignedChar.new
213
+ buffer = matrix.ptr
214
+ buffer.bytes(5))";
215
+ String buffer = m.module_eval(code);
216
+ ASSERT_EQUAL("\x1\x2\x3\x4\x5", buffer.str());
217
+
218
+ code = R"(matrix = Matrix2UnsignedChar.new
219
+ buffer = matrix.ptr
220
+ buffer.bytes(0))";
221
+ buffer = m.module_eval(code);
222
+ ASSERT_EQUAL("", buffer.str());
223
+
224
+ code = R"(matrix = Matrix2UnsignedChar.new
225
+ buffer = matrix.data
226
+ buffer.bytes)";
227
+
228
+ buffer = m.module_eval(code);
229
+ ASSERT_EQUAL("\x1\x2\x3\x4\x5", buffer.str());
230
+ }
231
+
232
+ TESTCASE(unsigned_char_ptr_array)
233
+ {
234
+ Module m = define_module("ToRubyPtr");
235
+
236
+ Class c = define_class_under<Matrix2UnsignedChar>(m, "Matrix2UnsignedChar")
237
+ .define_constructor(Constructor<Matrix2UnsignedChar>())
238
+ .define_method("ptr", &Matrix2UnsignedChar::ptr);
239
+
240
+ std::string code = R"(matrix = Matrix2UnsignedChar.new
241
+ buffer = matrix.ptr
242
+ buffer.to_ary(5))";
243
+
244
+ std::vector<unsigned char> expected = std::vector<unsigned char>{ 1,2,3,4,5 };
245
+ Array array = m.module_eval(code);
246
+ std::vector<unsigned char> actual = array.to_vector<unsigned char>();
247
+ ASSERT_EQUAL(expected, actual);
248
+
249
+ code = R"(matrix = Matrix2UnsignedChar.new
250
+ buffer = matrix.ptr
251
+ buffer.to_ary(1))";
252
+
253
+ expected = std::vector<unsigned char>{ 1 };
254
+ array = m.module_eval(code);
255
+ actual = array.to_vector<unsigned char>();
256
+ ASSERT_EQUAL(expected, actual);
257
+ }
258
+
259
+ TESTCASE(unsigned_char_ptr_ptr_buffer)
260
+ {
261
+ Module m = define_module("ToRubyPtr");
262
+
263
+ Class c = define_class_under<Matrix3UnsignedChar>(m, "Matrix3UnsignedChar")
264
+ .define_constructor(Constructor<Matrix3UnsignedChar>())
265
+ .define_method("ptr", &Matrix3UnsignedChar::ptr)
266
+ .define_attr("data", &Matrix3UnsignedChar::data, Rice::AttrAccess::Read);
267
+
268
+ std::string code = R"(matrix = Matrix3UnsignedChar.new
269
+ buffer = matrix.ptr
270
+ buffer2 = buffer.to_ary(1).first
271
+ buffer2.to_ary(5))";
272
+ Array array = m.module_eval(code);
273
+ ASSERT_EQUAL(5, array.size());
274
+
275
+ std::vector<unsigned char> expected{ 1, 2, 3, 4, 5 };
276
+ std::vector<unsigned char> actual = array.to_vector<unsigned char>();
277
+ ASSERT_EQUAL(expected, actual);
278
+ }
279
+
280
+ TESTCASE(unsigned_char_ptr_ptr_array)
281
+ {
282
+ Module m = define_module("ToRubyPtr");
283
+
284
+ Class c = define_class_under<Matrix3UnsignedChar>(m, "Matrix3UnsignedChar")
285
+ .define_constructor(Constructor<Matrix3UnsignedChar>())
286
+ .define_method("ptr", &Matrix3UnsignedChar::ptr);
287
+
288
+ std::string code = R"(matrix = Matrix3UnsignedChar.new
289
+ buffer = matrix.ptr
290
+ buffer.to_ary(5))";
291
+
292
+ Array pointers = m.module_eval(code);
293
+ ASSERT_EQUAL(5, pointers.size());
294
+
295
+ for (int i = 0; i < pointers.size(); i++)
296
+ {
297
+ Object buffer = pointers[i];
298
+ Array array = buffer.call("to_ary", 1);
299
+
300
+ std::vector<unsigned char> expected = std::vector<unsigned char>{ (unsigned char)(i + 1) };
301
+ std::vector<unsigned char> actual = array.to_vector<unsigned char>();
302
+ ASSERT_EQUAL(expected, actual);
303
+ }
304
+ }
305
+
306
+ TESTCASE(short_ptr_buffer)
307
+ {
308
+ Module m = define_module("ToRubyPtr");
309
+
310
+ Class c = define_class_under<Matrix2Short>(m, "Matrix2Short")
311
+ .define_constructor(Constructor<Matrix2Short>())
312
+ .define_method("ptr", &Matrix2Short::ptr);
313
+
314
+ std::string code = R"(matrix = Matrix2Short.new
315
+ buffer = matrix.ptr
316
+ buffer.bytes(5))";
317
+
318
+ std::string expected = "\x1\0\x2\0\x3\0\x4\0\x5\0"s;
319
+ String buffer = m.module_eval(code);
320
+ ASSERT_EQUAL(expected, buffer.str());
321
+
322
+ code = R"(matrix = Matrix2Short.new
323
+ buffer = matrix.ptr
324
+ buffer.bytes(0))";
325
+ expected = ""s;
326
+ buffer = m.module_eval(code);
327
+ ASSERT_EQUAL(expected, buffer.str());
328
+ }
329
+
330
+ TESTCASE(short_ptr_array)
331
+ {
332
+ Module m = define_module("ToRubyPtr");
333
+
334
+ Class c = define_class_under<Matrix2Short>(m, "Matrix2Short")
335
+ .define_constructor(Constructor<Matrix2Short>())
336
+ .define_method("ptr", &Matrix2Short::ptr);
337
+
338
+ std::string code = R"(matrix = Matrix2Short.new
339
+ buffer = matrix.ptr
340
+ buffer.to_ary(5))";
341
+
342
+ std::vector<short> expected = std::vector<short>{1,2,3,4,5};
343
+ Array array = m.module_eval(code);
344
+ std::vector<short> actual = array.to_vector<short>();
345
+ ASSERT_EQUAL(expected, actual);
346
+ }
347
+
348
+ TESTCASE(unsigned_short_ptr_buffer)
349
+ {
350
+ Module m = define_module("ToRubyPtr");
351
+
352
+ Class c = define_class_under<Matrix2UnsignedShort>(m, "Matrix2UnsignedShort")
353
+ .define_constructor(Constructor<Matrix2UnsignedShort>())
354
+ .define_method("ptr", &Matrix2UnsignedShort::ptr);
355
+
356
+ std::string code = R"(matrix = Matrix2UnsignedShort.new
357
+ buffer = matrix.ptr
358
+ buffer.bytes(5))";
359
+
360
+ std::string expected = "\x1\0\x2\0\x3\0\x4\0\x5\0"s;
361
+ String buffer = m.module_eval(code);
362
+ ASSERT_EQUAL(expected, buffer.str());
363
+
364
+ code = R"(matrix = Matrix2UnsignedShort.new
365
+ buffer = matrix.ptr
366
+ buffer.bytes(0))";
367
+ expected = ""s;
368
+ buffer = m.module_eval(code);
369
+ ASSERT_EQUAL(expected, buffer.str());
370
+ }
371
+
372
+ TESTCASE(unsigned_short_ptr_array)
373
+ {
374
+ Module m = define_module("ToRubyPtr");
375
+
376
+ Class c = define_class_under<Matrix2UnsignedShort>(m, "Matrix2UnsignedShort")
377
+ .define_constructor(Constructor<Matrix2UnsignedShort>())
378
+ .define_method("ptr", &Matrix2UnsignedShort::ptr);
379
+
380
+ std::string code = R"(matrix = Matrix2UnsignedShort.new
381
+ buffer = matrix.ptr
382
+ buffer.to_ary(5))";
383
+
384
+ std::vector<unsigned short> expected = std::vector<unsigned short>{ 1,2,3,4,5 };
385
+ Array array = m.module_eval(code);
386
+ std::vector<unsigned short> actual = array.to_vector<unsigned short>();
387
+ ASSERT_EQUAL(expected, actual);
388
+ }
389
+
390
+ TESTCASE(int_ptr_buffer)
391
+ {
392
+ Module m = define_module("ToRubyPtr");
393
+
394
+ Class c = define_class_under<Matrix2Int>(m, "Matrix2Int")
395
+ .define_constructor(Constructor<Matrix2Int>())
396
+ .define_method("ptr", &Matrix2Int::ptr);
397
+
398
+ std::string code = R"(matrix = Matrix2Int.new
399
+ buffer = matrix.ptr
400
+ buffer.bytes(5))";
401
+
402
+ std::string expected = "\x1\0\0\0\x2\0\0\0\x3\0\0\0\x4\0\0\0\x5\0\0\0"s;
403
+ String buffer = m.module_eval(code);
404
+ ASSERT_EQUAL(expected, buffer.str());
405
+
406
+ code = R"(matrix = Matrix2Int.new
407
+ buffer = matrix.ptr
408
+ buffer.bytes(0))";
409
+ expected = ""s;
410
+ buffer = m.module_eval(code);
411
+ ASSERT_EQUAL(expected, buffer.str());
412
+ }
413
+
414
+ TESTCASE(int_ptr_array)
415
+ {
416
+ Module m = define_module("ToRubyPtr");
417
+
418
+ Class c = define_class_under<Matrix2Int>(m, "Matrix2Int")
419
+ .define_constructor(Constructor<Matrix2Int>())
420
+ .define_method("ptr", &Matrix2Int::ptr);
421
+
422
+ std::string code = R"(matrix = Matrix2Int.new
423
+ buffer = matrix.ptr
424
+ buffer.to_ary(5))";
425
+
426
+ std::vector<int> expected = std::vector<int>{ 1,2,3,4,5 };
427
+ Array array = m.module_eval(code);
428
+ std::vector<int> actual = array.to_vector<int>();
429
+ ASSERT_EQUAL(expected, actual);
430
+ }
431
+
432
+ TESTCASE(float_ptr_buffer)
433
+ {
434
+ Module m = define_module("ToRubyPtr");
435
+
436
+ Class c = define_class_under<Matrix2Float>(m, "Matrix2Float")
437
+ .define_constructor(Constructor<Matrix2Float>())
438
+ .define_method("ptr", &Matrix2Float::ptr);
439
+
440
+ std::string code = R"(matrix = Matrix2Float.new
441
+ buffer = matrix.ptr
442
+ buffer.bytes(5))";
443
+
444
+ std::string expected = "\0\0\x80\x3f\0\0\0\x40\0\0\x40\x40\0\0\x80\x40\0\0\xa0\x40"s;
445
+ String buffer = m.module_eval(code);
446
+ ASSERT_EQUAL(expected, buffer.str());
447
+
448
+ code = R"(matrix = Matrix2Float.new
449
+ buffer = matrix.ptr
450
+ buffer.bytes(0))";
451
+ expected = ""s;
452
+ buffer = m.module_eval(code);
453
+ ASSERT_EQUAL(expected, buffer.str());
454
+ }
455
+
456
+ TESTCASE(float_ptr_array)
457
+ {
458
+ Module m = define_module("ToRubyPtr");
459
+
460
+ Class c = define_class_under<Matrix2Float>(m, "Matrix2Float")
461
+ .define_constructor(Constructor<Matrix2Float>())
462
+ .define_method("ptr", &Matrix2Float::ptr);
463
+
464
+ std::string code = R"(matrix = Matrix2Float.new
465
+ buffer = matrix.ptr
466
+ buffer.to_ary(5))";
467
+
468
+ std::vector<float> expected = std::vector<float>{ 1.0,2.0,3.0,4.0,5.0 };
469
+ Array array = m.module_eval(code);
470
+ std::vector<float> actual = array.to_vector<float>();
471
+ ASSERT_EQUAL(expected, actual);
472
+ }
473
+
474
+ TESTCASE(double_ptr_buffer)
475
+ {
476
+ Module m = define_module("ToRubyPtr");
477
+
478
+ Class c = define_class_under<Matrix2Double>(m, "Matrix2Double")
479
+ .define_constructor(Constructor<Matrix2Double>())
480
+ .define_method("ptr", &Matrix2Double::ptr);
481
+
482
+ std::string code = R"(matrix = Matrix2Double.new
483
+ buffer = matrix.ptr
484
+ buffer.bytes(5))";
485
+
486
+ std::string expected = "\0\0\0\0\0\0\xf0\x3f\0\0\0\0\0\0\0\x40\0\0\0\0\0\0\x08\x40\0\0\0\0\0\0\x10\x40\0\0\0\0\0\0\x14\x40"s;
487
+ String buffer = m.module_eval(code);
488
+ const char* ptr = RSTRING_PTR(buffer.value());
489
+ ASSERT_EQUAL(expected, buffer.str());
490
+
491
+ code = R"(matrix = Matrix2Double.new
492
+ buffer = matrix.ptr
493
+ buffer.bytes(0))";
494
+ expected = ""s;
495
+ buffer = m.module_eval(code);
496
+ ASSERT_EQUAL(expected, buffer.str());
497
+ }
498
+
499
+ TESTCASE(double_ptr_array)
500
+ {
501
+ Module m = define_module("ToRubyPtr");
502
+
503
+ Class c = define_class_under<Matrix2Double>(m, "Matrix2Double")
504
+ .define_constructor(Constructor<Matrix2Double>())
505
+ .define_method("ptr", &Matrix2Double::ptr);
506
+
507
+ std::string code = R"(matrix = Matrix2Double.new
508
+ buffer = matrix.ptr
509
+ buffer.to_ary(5))";
510
+
511
+ std::vector<double> expected = std::vector<double>{ 1.0,2.0,3.0,4.0,5.0 };
512
+ Array array = m.module_eval(code);
513
+ std::vector<double> actual = array.to_vector<double>();
514
+ ASSERT_EQUAL(expected, actual);
515
+
516
+ code = R"(matrix = Matrix2Double.new
517
+ buffer = matrix.ptr
518
+ buffer.to_ary(0))";
519
+
520
+ expected = std::vector<double>{ };
521
+ array = m.module_eval(code);
522
+ actual = array.to_vector<double>();
523
+ ASSERT_EQUAL(expected, actual);
524
+ }