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,230 @@
1
+ #include <functional>
2
+
3
+ #include "unittest.hpp"
4
+ #include "embed_ruby.hpp"
5
+ #include <rice/rice.hpp>
6
+
7
+ using namespace Rice;
8
+
9
+ TESTSUITE(Callback);
10
+
11
+ SETUP(Callback)
12
+ {
13
+ embed_ruby();
14
+ }
15
+
16
+ TEARDOWN(Callback)
17
+ {
18
+ rb_gc_start();
19
+ }
20
+
21
+ namespace
22
+ {
23
+ using Callback_T = char*(*)(int, double, bool, char*);
24
+ Callback_T globalCallback;
25
+
26
+ void registerCallback(Callback_T callback)
27
+ {
28
+ globalCallback = callback;
29
+ }
30
+
31
+ char* triggerCallback(int anInt, double aDouble, bool aBool, char* aString)
32
+ {
33
+ if (globalCallback)
34
+ {
35
+ return globalCallback(anInt, aDouble, aBool, aString);
36
+ }
37
+ throw std::runtime_error("Callback has not been registered");
38
+ }
39
+ }
40
+
41
+ TESTCASE(LambdaCallBack)
42
+ {
43
+ Module m = define_module("TestingLambda");
44
+ m.define_module_function("register_callback", registerCallback).
45
+ define_module_function("trigger_callback", triggerCallback);
46
+
47
+ ASSERT_EQUAL(globalCallback, nullptr);
48
+
49
+ std::string code = R"(callback = lambda do |an_int, a_double, a_bool, a_string|
50
+ values = [an_int, a_double, a_bool, a_string]
51
+ values.map {|value| value.to_s}.join(" - ")
52
+ end
53
+ register_callback(callback))";
54
+
55
+
56
+ m.module_eval(code);
57
+ ASSERT((globalCallback != nullptr));
58
+
59
+ String result = m.call("trigger_callback", 1, 2, true, "hello");
60
+ ASSERT_EQUAL("1 - 2.0 - true - hello", result.c_str());
61
+ }
62
+
63
+ TESTCASE(BlockCallBack)
64
+ {
65
+ Module m = define_module("TestingBlock");
66
+ m.define_module_function("register_callback", registerCallback).
67
+ define_module_function("trigger_callback", triggerCallback);
68
+
69
+ std::string code = R"(register_callback do |an_int, a_double, a_bool, a_string|
70
+ values = [an_int, a_double, a_bool, a_string]
71
+ values.map {|value| value.to_s}.join(" - ")
72
+ end)";
73
+
74
+ m.module_eval(code);
75
+
76
+ String result = m.call("trigger_callback", 4, 5.5, false, "Hello block");
77
+ ASSERT_EQUAL("4 - 5.5 - false - Hello block", result.c_str());
78
+ }
79
+
80
+ TESTCASE(ProcCallBack)
81
+ {
82
+ Module m = define_module("TestingProc");
83
+ m.define_module_function("register_callback", registerCallback).
84
+ define_module_function("trigger_callback", triggerCallback);
85
+
86
+ std::string code = R"(callback = Proc.new do |an_int, a_double, a_bool, a_string|
87
+ values = [an_int, a_double, a_bool, a_string]
88
+ values.map {|value| value.to_s}.join(" - ")
89
+ end
90
+ register_callback(callback))";
91
+
92
+ m.module_eval(code);
93
+
94
+ String result = m.call("trigger_callback", 8, 4.4, true, "Hello proc");
95
+ ASSERT_EQUAL("8 - 4.4 - true - Hello proc", result.c_str());
96
+ }
97
+
98
+ TESTCASE(MethodCallBack)
99
+ {
100
+ Module m = define_module("TestingMethod");
101
+ m.define_module_function("register_callback", registerCallback).
102
+ define_module_function("trigger_callback", triggerCallback);
103
+
104
+ std::string code = R"(def self.callback(an_int, a_double, a_bool, a_string)
105
+ values = [an_int, a_double, a_bool, a_string]
106
+ values.map {|value| value.to_s}.join(" - ")
107
+ end
108
+ register_callback(method(:callback).to_proc))";
109
+
110
+ m.module_eval(code);
111
+
112
+ String result = m.call("trigger_callback", 11.1, 22.9, true, "Hello method");
113
+ ASSERT_EQUAL("11 - 22.9 - true - Hello method", result.c_str());
114
+ }
115
+
116
+ namespace
117
+ {
118
+ int functionArg(int i, int(*f)(int))
119
+ {
120
+ return f(i);
121
+ }
122
+ }
123
+
124
+ TESTCASE(FunctionArg)
125
+ {
126
+ Module m = define_module("TestingFunctionArg");
127
+ m.define_module_function("function_arg", functionArg);
128
+
129
+ std::string code = R"(function_arg(4) do |i|
130
+ i * i
131
+ end)";
132
+
133
+ Object result = m.module_eval(code);
134
+ ASSERT_EQUAL(16, detail::From_Ruby<int>().convert(result));
135
+ }
136
+
137
+ namespace
138
+ {
139
+ using Callback_T2 = char*(*)();
140
+ std::vector<Callback_T2> callbacks;
141
+
142
+ void registerTwoCallbacks(Callback_T2 callback1, Callback_T2 callback2)
143
+ {
144
+ callbacks.push_back(callback1);
145
+ callbacks.push_back(callback2);
146
+ }
147
+
148
+ char* triggerCallback(int callBackIndex)
149
+ {
150
+ Callback_T2 callback = callbacks[callBackIndex];
151
+ return callback();
152
+ }
153
+ }
154
+
155
+ #ifdef HAVE_LIBFFI
156
+ TESTCASE(MultipleCallbacks)
157
+ {
158
+ Module m = define_module("TestingMultipleCallbacks");
159
+ m.define_module_function<void(*)(Callback_T2, Callback_T2)>("register_callback", registerTwoCallbacks).
160
+ define_module_function<char*(*)(int)>("trigger_callback", triggerCallback);
161
+
162
+ std::string code = R"(proc1 = Proc.new do
163
+ "Proc 1"
164
+ end
165
+
166
+ proc2 = Proc.new do
167
+ "Proc 2"
168
+ end
169
+
170
+ register_callback(proc1, proc2))";
171
+
172
+ m.module_eval(code);
173
+
174
+ String result = m.call("trigger_callback", 0);
175
+ ASSERT_EQUAL("Proc 1", result.c_str());
176
+
177
+ result = m.call("trigger_callback", 1);
178
+ ASSERT_EQUAL("Proc 2", result.c_str());
179
+ }
180
+ #endif
181
+
182
+ namespace
183
+ {
184
+ using Callback_T3 = char*(*)(void* userData);
185
+ Callback_T3 globalCallback3;
186
+ void* globalUserData = nullptr;
187
+
188
+ void registerCallback3(Callback_T3 callback, void* userData)
189
+ {
190
+ globalCallback3 = callback;
191
+ globalUserData = userData;
192
+ }
193
+
194
+ char* triggerCallback3()
195
+ {
196
+ if (globalCallback3)
197
+ {
198
+ return globalCallback3(globalUserData);
199
+ }
200
+ throw std::runtime_error("Callback has not been registered");
201
+ }
202
+ }
203
+
204
+ TESTCASE(UserData)
205
+ {
206
+ Module m = define_module("TestingUserData");
207
+ m.define_module_function("register_callback", registerCallback3, Arg("callback"), Arg("user_data").setOpaque()).
208
+ define_module_function("trigger_callback", triggerCallback3);
209
+
210
+ define_callback<Callback_T3>(Arg("user_data").setOpaque());
211
+
212
+ std::string code = R"(class UserDataClass
213
+ end
214
+
215
+ user_data_1 = UserDataClass.new
216
+
217
+ callback = Proc.new do |user_data_2|
218
+ unless user_data_1.equal?(user_data_2)
219
+ raise("Unexpected user data object")
220
+ end
221
+ user_data_2.class.name
222
+ end
223
+
224
+ register_callback(callback, user_data_1))";
225
+
226
+ m.module_eval(code);
227
+
228
+ String result = m.call("trigger_callback");
229
+ ASSERT_EQUAL("TestingUserData::UserDataClass", result.c_str());
230
+ }
data/test/test_Class.cpp CHANGED
@@ -11,6 +11,11 @@ SETUP(Class)
11
11
  embed_ruby();
12
12
  }
13
13
 
14
+ TEARDOWN(Class)
15
+ {
16
+ rb_gc_start();
17
+ }
18
+
14
19
  TESTCASE(construct)
15
20
  {
16
21
  Class c(rb_cObject);
@@ -125,37 +130,6 @@ TESTCASE(module_function)
125
130
  );
126
131
  }
127
132
 
128
- namespace
129
- {
130
- class Silly_Exception
131
- : public std::exception
132
- {
133
- };
134
-
135
- void handle_silly_exception(Silly_Exception const & ex)
136
- {
137
- throw Exception(rb_eRuntimeError, "SILLY");
138
- }
139
-
140
- void throw_silly_exception()
141
- {
142
- throw Silly_Exception();
143
- }
144
- }
145
-
146
- TESTCASE(add_handler)
147
- {
148
- register_handler<Silly_Exception>(handle_silly_exception);
149
-
150
- Class c(rb_cObject);
151
- c.define_function("foo", throw_silly_exception);
152
-
153
- Object exc = detail::protect(rb_eval_string, "begin; foo; rescue Exception; $!; end");
154
- ASSERT_EQUAL(rb_eRuntimeError, CLASS_OF(exc));
155
- Exception ex(exc);
156
- ASSERT_EQUAL("SILLY", ex.what());
157
- }
158
-
159
133
  TESTCASE(define_class)
160
134
  {
161
135
  Class object(rb_cObject);
@@ -7,6 +7,16 @@ using namespace Rice;
7
7
 
8
8
  TESTSUITE(Constructor);
9
9
 
10
+ SETUP(Constructor)
11
+ {
12
+ embed_ruby();
13
+ }
14
+
15
+ TEARDOWN(Constructor)
16
+ {
17
+ rb_gc_start();
18
+ }
19
+
10
20
  namespace
11
21
  {
12
22
  class Default_Constructible
@@ -18,11 +28,6 @@ namespace
18
28
  };
19
29
  }
20
30
 
21
- SETUP(Array)
22
- {
23
- embed_ruby();
24
- }
25
-
26
31
  TESTCASE(default_constructor)
27
32
  {
28
33
  Data_Type<Default_Constructible> rb_cDefault_Constructible(anonymous_class());
@@ -31,7 +36,6 @@ TESTCASE(default_constructor)
31
36
  ASSERT_EQUAL(rb_cDefault_Constructible, o.class_of());
32
37
  }
33
38
 
34
-
35
39
  namespace
36
40
  {
37
41
  class Non_Default_Constructible
@@ -125,3 +129,62 @@ TESTCASE(constructor_supports_single_default_argument)
125
129
  klass.call("new", 6);
126
130
  ASSERT_EQUAL(6, withArgX);
127
131
  }
132
+
133
+ namespace
134
+ {
135
+ class MyClass
136
+ {
137
+ public:
138
+ MyClass() = default;
139
+ MyClass(const MyClass& other) = default;
140
+ MyClass(MyClass&& other) = default;
141
+ int value;
142
+ };
143
+ }
144
+
145
+ TESTCASE(constructor_clone)
146
+ {
147
+ Class c = define_class<MyClass>("MyClass")
148
+ .define_constructor(Constructor<MyClass>())
149
+ .define_constructor(Constructor<MyClass, const MyClass&>())
150
+ .define_attr("value", &MyClass::value);
151
+
152
+ // Default constructor
153
+ Object o1 = c.call("new");
154
+ o1.call("value=", 7);
155
+ ASSERT_EQUAL(c, o1.class_of());
156
+
157
+ // Clone
158
+ Object o2 = o1.call("clone");
159
+ Object value = o2.call("value");
160
+ ASSERT_EQUAL(c, o2.class_of());
161
+ ASSERT_EQUAL(7, detail::From_Ruby<int>().convert(value));
162
+ }
163
+
164
+ TESTCASE(constructor_dup)
165
+ {
166
+ Class c = define_class<MyClass>("MyClass").
167
+ define_constructor(Constructor<MyClass>()).
168
+ define_constructor(Constructor<MyClass, const MyClass&>()).
169
+ define_attr("value", &MyClass::value);
170
+
171
+ // Default constructor
172
+ Object o1 = c.call("new");
173
+ o1.call("value=", 7);
174
+ ASSERT_EQUAL(c, o1.class_of());
175
+
176
+ // Clone
177
+ Object o2 = o1.call("dup");
178
+ Object value = o2.call("value");
179
+ ASSERT_EQUAL(c, o2.class_of());
180
+ ASSERT_EQUAL(7, detail::From_Ruby<int>().convert(value));
181
+ }
182
+
183
+ TESTCASE(constructor_move)
184
+ {
185
+ Data_Type<MyClass> c = define_class<MyClass>("MyClass").
186
+ define_constructor(Constructor<MyClass>());
187
+
188
+ // This intentionally will not compile due to a static_assert
189
+ //c.define_constructor(Constructor<MyClass, MyClass&&>());
190
+ }
@@ -1,5 +1,3 @@
1
- #include <ruby/version.h>
2
-
3
1
  #include "unittest.hpp"
4
2
  #include "embed_ruby.hpp"
5
3
  #include <rice/rice.hpp>
@@ -15,7 +13,7 @@ namespace
15
13
 
16
14
  struct MyDataType
17
15
  {
18
- MyDataType() : x(42)
16
+ MyDataType(int value) : x(value)
19
17
  {
20
18
  }
21
19
 
@@ -27,6 +25,17 @@ namespace
27
25
  int x;
28
26
  };
29
27
 
28
+ static MyDataType myDataTypes[] = { 1,2,3 };
29
+ MyDataType* dataTypes()
30
+ {
31
+ return myDataTypes;
32
+ }
33
+
34
+ int dataTypesCount()
35
+ {
36
+ return sizeof(myDataTypes)/sizeof(MyDataType);
37
+ }
38
+
30
39
  struct Bar
31
40
  {
32
41
  };
@@ -48,7 +57,7 @@ SETUP(Data_Object)
48
57
  if (!Data_Type<MyDataType>::is_bound())
49
58
  {
50
59
  Class object(rb_cObject);
51
- if(object.const_defined("MyDataType"))
60
+ if (object.const_defined("MyDataType"))
52
61
  {
53
62
  object.remove_const("MyDataType");
54
63
  }
@@ -58,30 +67,35 @@ SETUP(Data_Object)
58
67
  }
59
68
  }
60
69
 
61
- TESTCASE(construct_from_pointer)
70
+ TEARDOWN(Data_Object)
71
+ {
72
+ rb_gc_start();
73
+ }
74
+
75
+ TESTCASE(data_object_construct_from_pointer)
62
76
  {
63
- MyDataType* myDataType = new MyDataType;
77
+ MyDataType* myDataType = new MyDataType(42);
64
78
  Data_Object<MyDataType> wrapped_foo(myDataType);
65
79
  ASSERT_EQUAL(myDataType, wrapped_foo.get());
66
80
  ASSERT_EQUAL(Data_Type<MyDataType>::klass(), wrapped_foo.class_of());
67
- ASSERT_EQUAL(myDataType, detail::unwrap<MyDataType>(wrapped_foo, Data_Type<MyDataType>::ruby_data_type()));
81
+ ASSERT_EQUAL(myDataType, detail::unwrap<MyDataType>(wrapped_foo, Data_Type<MyDataType>::ruby_data_type(), false));
68
82
  }
69
83
 
70
- TESTCASE(construct_from_ruby_object)
84
+ TESTCASE(data_object_construct_from_ruby_object)
71
85
  {
72
- MyDataType * myDataType = new MyDataType;
86
+ MyDataType * myDataType = new MyDataType(42);
73
87
  VALUE wrapped_foo = detail::wrap(Data_Type<MyDataType>::klass(), Data_Type<MyDataType>::ruby_data_type(), myDataType, true);
74
88
 
75
89
  Data_Object<MyDataType> data_object_foo(wrapped_foo);
76
90
  ASSERT_EQUAL(myDataType, data_object_foo.get());
77
91
  ASSERT_EQUAL(Data_Type<MyDataType>::klass(), data_object_foo.class_of());
78
92
  ASSERT_EQUAL(RTYPEDDATA(wrapped_foo), RTYPEDDATA(data_object_foo.value()));
79
- ASSERT_EQUAL(myDataType, detail::unwrap<MyDataType>(wrapped_foo, Data_Type<MyDataType>::ruby_data_type()));
93
+ ASSERT_EQUAL(myDataType, detail::unwrap<MyDataType>(wrapped_foo, Data_Type<MyDataType>::ruby_data_type(), false));
80
94
  }
81
95
 
82
- TESTCASE(construct_from_ruby_object_and_wrong_class)
96
+ TESTCASE(data_object_construct_from_ruby_object_and_wrong_class)
83
97
  {
84
- MyDataType * myDataType = new MyDataType;
98
+ MyDataType * myDataType = new MyDataType(42);
85
99
  VALUE wrapped_foo = detail::wrap(Data_Type<MyDataType>::klass(), Data_Type<MyDataType>::ruby_data_type(), myDataType, true);
86
100
 
87
101
  ASSERT_EXCEPTION_CHECK(
@@ -95,9 +109,9 @@ TESTCASE(construct_from_ruby_object_and_wrong_class)
95
109
  ASSERT_EQUAL("Wrong argument type. Expected: Bar. Received: MyDataType.", ex.what()));
96
110
  }
97
111
 
98
- TESTCASE(copy_construct)
112
+ TESTCASE(data_object_copy_construct)
99
113
  {
100
- MyDataType * myDataType = new MyDataType;
114
+ MyDataType * myDataType = new MyDataType(42);
101
115
  VALUE wrapped_foo = detail::wrap(Data_Type<MyDataType>::klass(), Data_Type<MyDataType>::ruby_data_type(), myDataType, true);
102
116
  Data_Object<MyDataType> orig_data_object_foo(wrapped_foo);
103
117
  Data_Object<MyDataType> data_object_foo(orig_data_object_foo);
@@ -105,12 +119,12 @@ TESTCASE(copy_construct)
105
119
  ASSERT_EQUAL(myDataType, data_object_foo.get());
106
120
  ASSERT_EQUAL(Data_Type<MyDataType>::klass(), data_object_foo.class_of());
107
121
  ASSERT_EQUAL(RTYPEDDATA(wrapped_foo), RTYPEDDATA(data_object_foo.value()));
108
- ASSERT_EQUAL(myDataType, detail::unwrap<MyDataType>(wrapped_foo, Data_Type<MyDataType>::ruby_data_type()));
122
+ ASSERT_EQUAL(myDataType, detail::unwrap<MyDataType>(wrapped_foo, Data_Type<MyDataType>::ruby_data_type(), false));
109
123
  }
110
124
 
111
- TESTCASE(move_construct)
125
+ TESTCASE(data_object_move_construct)
112
126
  {
113
- MyDataType* myDataType = new MyDataType;
127
+ MyDataType* myDataType = new MyDataType(42);
114
128
 
115
129
  Data_Object<MyDataType> wrapper1(myDataType);
116
130
  Data_Object<MyDataType> wrapper2(std::move(wrapper1));
@@ -119,12 +133,12 @@ TESTCASE(move_construct)
119
133
  ASSERT((wrapper1.get() == nullptr));
120
134
  }
121
135
 
122
- TESTCASE(move_assign)
136
+ TESTCASE(data_object_move_assign)
123
137
  {
124
- MyDataType* foo1 = new MyDataType;
138
+ MyDataType* foo1 = new MyDataType(42);
125
139
  Data_Object<MyDataType> wrapper1(foo1);
126
140
 
127
- MyDataType* foo2 = new MyDataType;
141
+ MyDataType* foo2 = new MyDataType(42);
128
142
  Data_Object<MyDataType> wrapper2(foo2);
129
143
 
130
144
  wrapper2 = std::move(wrapper1);
@@ -133,74 +147,119 @@ TESTCASE(move_assign)
133
147
  ASSERT((wrapper1.get() == nullptr));
134
148
  }
135
149
 
136
- TESTCASE(dereference)
150
+ TESTCASE(data_object_dereference)
137
151
  {
138
152
  Data_Type<MyDataType> rb_cFoo;
139
- MyDataType * myDataType = new MyDataType;
153
+ MyDataType * myDataType = new MyDataType(42);
140
154
  Data_Object<MyDataType> wrapped_foo(myDataType);
141
155
  ASSERT_EQUAL(myDataType, &*wrapped_foo);
142
156
  }
143
157
 
144
- TESTCASE(arrow)
158
+ TESTCASE(data_object_arrow)
145
159
  {
146
160
  Data_Type<MyDataType> rb_cFoo;
147
- MyDataType * myDataType = new MyDataType;
161
+ MyDataType * myDataType = new MyDataType(42);
148
162
  Data_Object<MyDataType> wrapped_foo(myDataType);
149
163
  ASSERT_EQUAL(42, myDataType->x);
150
164
  }
151
165
 
152
- TESTCASE(get)
166
+ TESTCASE(data_object_get)
153
167
  {
154
168
  Data_Type<MyDataType> rb_cFoo;
155
- MyDataType * myDataType = new MyDataType;
169
+ MyDataType * myDataType = new MyDataType(42);
156
170
  Data_Object<MyDataType> wrapped_foo(myDataType);
157
171
  ASSERT_EQUAL(myDataType, wrapped_foo.get());
158
172
  }
159
173
 
160
- TESTCASE(to_ruby)
174
+ TESTCASE(data_object_to_ruby)
161
175
  {
162
176
  Data_Type<MyDataType> rb_cFoo;
163
- MyDataType * myDataType = new MyDataType;
177
+ MyDataType * myDataType = new MyDataType(42);
164
178
  Data_Object<MyDataType> wrapped_foo(myDataType);
165
179
  ASSERT_EQUAL(String("MyDataType"), wrapped_foo.class_name());
166
180
  }
167
181
 
168
- TESTCASE(from_ruby)
182
+ TESTCASE(data_object_from_ruby)
169
183
  {
170
184
  Data_Type<MyDataType> rb_cFoo;
171
- MyDataType* myDataType = new MyDataType();
185
+ MyDataType* myDataType = new MyDataType(42);
172
186
  Data_Object<MyDataType> wrapped_foo(myDataType);
173
187
  ASSERT_EQUAL(myDataType, wrapped_foo.get());
174
188
  }
175
189
 
176
- TESTCASE(from_ruby_const_ref)
190
+ TESTCASE(data_object_from_ruby_const_ref)
177
191
  {
178
192
  Data_Type<MyDataType> rb_cFoo;
179
- MyDataType * myDataType = new MyDataType;
193
+ MyDataType * myDataType = new MyDataType(42);
180
194
  Data_Object<MyDataType> wrapped_foo(myDataType);
181
195
  ASSERT_EQUAL(myDataType->x, detail::From_Ruby<MyDataType const &>().convert(wrapped_foo).x);
182
196
  }
183
197
 
184
- TESTCASE(from_ruby_copy)
198
+ TESTCASE(data_object_from_ruby_copy)
185
199
  {
186
200
  Data_Type<MyDataType> rb_cFoo;
187
- MyDataType * myDataType = new MyDataType;
201
+ MyDataType * myDataType = new MyDataType(42);
188
202
  Data_Object<MyDataType> wrapped_foo(myDataType);
189
203
  ASSERT_EQUAL(myDataType->x, detail::From_Ruby<MyDataType>().convert(wrapped_foo).x);
190
204
  }
191
205
 
192
- TESTCASE(ruby_custom_mark)
206
+ TESTCASE(data_object_return_array)
207
+ {
208
+ define_buffer<MyDataType>();
209
+
210
+ Module m = define_module("DataObjectTest").
211
+ define_module_function("data_types", &dataTypes, Return().setArray()).
212
+ define_module_function("data_types_count", &dataTypesCount);
213
+
214
+ std::string code = R"(buffer = data_types
215
+ count = data_types_count
216
+ buffer.to_ary(count))";
217
+
218
+ Array dataTypes = m.module_eval(code);
219
+ ASSERT_EQUAL(3, dataTypes.size());
220
+
221
+ std::vector<MyDataType> vector = dataTypes.to_vector<MyDataType>();
222
+ ASSERT_EQUAL(1, vector[0].x);
223
+ ASSERT_EQUAL(2, vector[1].x);
224
+ ASSERT_EQUAL(3, vector[2].x);
225
+ }
226
+
227
+ TESTCASE(data_object_update_buffer)
228
+ {
229
+ define_buffer<MyDataType>();
230
+
231
+ Class c = define_class<MyDataType>("MyDataType")
232
+ .define_constructor(Constructor<MyDataType, int>());
233
+
234
+ Module m = define_module("DataObjectTest").
235
+ define_module_function("data_types", &dataTypes, Return().setArray()).
236
+ define_module_function("data_types_count", &dataTypesCount);
237
+
238
+ std::string code = R"(buffer = data_types
239
+ my_data_type = MyDataType.new(100)
240
+ buffer.size = 3
241
+ buffer[2] = my_data_type
242
+ buffer)";
243
+
244
+ Object result = m.module_eval(code);
245
+ Data_Object<Buffer<MyDataType>> dataObject(result);
246
+ Buffer<MyDataType>* buffer = dataObject.get();
247
+ MyDataType myDataType = buffer->get(2);
248
+ ASSERT_EQUAL(100, myDataType.x);
249
+ }
250
+
251
+ TESTCASE(data_object_ruby_custom_mark)
193
252
  {
194
253
  test_ruby_mark_called = false;
195
254
 
196
- MyDataType* myDataType = new MyDataType;
255
+ MyDataType* myDataType = new MyDataType(42);
197
256
  Data_Object<MyDataType> wrapped_foo(myDataType);
198
257
  rb_gc_start();
199
258
 
200
259
  ASSERT_EQUAL(true, test_ruby_mark_called);
201
260
  }
202
261
 
203
- TESTCASE(ruby_custom_free)
262
+ TESTCASE(data_object_ruby_custom_free)
204
263
  {
205
264
  test_ruby_mark_called = false;
206
265
  test_destructor_called = false;
@@ -208,7 +267,7 @@ TESTCASE(ruby_custom_free)
208
267
  {
209
268
  // Put this code in a block so wrapped_foo is destroyed at the end of it.
210
269
  // That will set its value field to Qnil allowing myDataType to be freed
211
- MyDataType* myDataType = new MyDataType;
270
+ MyDataType* myDataType = new MyDataType(42);
212
271
  Data_Object<MyDataType> wrapped_foo(myDataType, true);
213
272
 
214
273
  // Force a mark