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,790 @@
1
+ #include <complex>
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(Set);
11
+
12
+ SETUP(Set)
13
+ {
14
+ embed_ruby();
15
+ }
16
+
17
+ TEARDOWN(Set)
18
+ {
19
+ rb_gc_start();
20
+ }
21
+
22
+ namespace
23
+ {
24
+ class MySetClass
25
+ {
26
+ public:
27
+ std::set<std::string> stringSet()
28
+ {
29
+ std::set<std::string> result{ "One", "Two", "Three" };
30
+ return result;
31
+ }
32
+ };
33
+ }
34
+
35
+ TESTCASE(Size)
36
+ {
37
+ Module m = define_module("Testing");
38
+ define_set<std::string>("StringSet");
39
+
40
+ std::string code = R"(s = Std::StringSet.new
41
+ s.size)";
42
+
43
+ Object result = m.instance_eval(code);
44
+ ASSERT_EQUAL(0, detail::From_Ruby<int32_t>().convert(result));
45
+
46
+ code = R"(s = Std::StringSet.new
47
+ s << "one" << "two"
48
+ s.size)";
49
+
50
+ result = m.instance_eval(code);
51
+ ASSERT_EQUAL(2, detail::From_Ruby<int32_t>().convert(result));
52
+
53
+ code = R"(s = Std::StringSet.new
54
+ s << "one" << "two"
55
+ s.clear
56
+ s.size)";
57
+
58
+ result = m.instance_eval(code);
59
+ ASSERT_EQUAL(0, detail::From_Ruby<int32_t>().convert(result));
60
+ }
61
+
62
+ TESTCASE(Add)
63
+ {
64
+ Module m = define_module("Testing");
65
+ define_set<std::string>("StringSet");
66
+
67
+ std::string code = R"(set = Std::StringSet.new
68
+ set << "one" << "two" << "two" << "three"
69
+ set)";
70
+
71
+ Object set = m.instance_eval(code);
72
+ Object size = set.call("size");
73
+ ASSERT_EQUAL(3, detail::From_Ruby<int32_t>().convert(size));
74
+
75
+ String string = set.call("to_s");
76
+ ASSERT_EQUAL("<Set≺string≻:{one, three, two}>", string.c_str());
77
+
78
+ set.call("insert", "four");
79
+
80
+ size = set.call("size");
81
+ ASSERT_EQUAL(4, detail::From_Ruby<int32_t>().convert(size));
82
+ }
83
+
84
+ TESTCASE(WrongType)
85
+ {
86
+ Module m = define_module("Testing");
87
+ Class c = define_set<std::string>("StringSet");
88
+
89
+ std::string code = R"(set = Std::StringSet.new
90
+ set << 1
91
+ set)";
92
+
93
+ ASSERT_EXCEPTION_CHECK(
94
+ Exception,
95
+ m.module_eval(code),
96
+ ASSERT_EQUAL("wrong argument type Integer (expected String)", ex.what()));
97
+ }
98
+
99
+ TESTCASE(Empty)
100
+ {
101
+ Module m = define_module("Testing");
102
+
103
+ Class c = define_set<std::int32_t>("IntSet");
104
+
105
+ std::string code = R"(set = Std::StringSet.new
106
+ set.size)";
107
+
108
+ Object size = m.instance_eval(code);
109
+ ASSERT_EQUAL(0, detail::From_Ruby<int32_t>().convert(size));
110
+
111
+ code = R"(set = Std::StringSet.new
112
+ set.empty?)";
113
+ Object result = m.instance_eval(code);
114
+ ASSERT_EQUAL(Qtrue, result.value());
115
+ }
116
+
117
+ TESTCASE(ToString)
118
+ {
119
+ Module m = define_module("Testing");
120
+ define_set<std::string>("StringSet");
121
+
122
+ std::string code = R"(set = Std::StringSet.new
123
+ set.insert("one")
124
+ set << "two" << "two" << "three"
125
+ set.to_s)";
126
+
127
+ String string = m.instance_eval(code);
128
+ ASSERT_EQUAL("<Set≺string≻:{one, three, two}>", string.c_str());
129
+ }
130
+
131
+ TESTCASE(Include)
132
+ {
133
+ Module m = define_module("Testing");
134
+ define_set<std::string>("StringSet");
135
+
136
+ std::string code = R"(set = Std::StringSet.new
137
+ set << "one" << "two" << "two" << "three"
138
+ set.include?("two"))";
139
+
140
+ Object result = m.instance_eval(code);
141
+ ASSERT_EQUAL(Qtrue, result.value());
142
+ }
143
+
144
+ TESTCASE(Modify)
145
+ {
146
+ Module m = define_module("Testing");
147
+
148
+ Class c = define_set<int>("Int64Set");
149
+ Object set = c.call("new");
150
+
151
+ Object result = set.call("insert", 11);
152
+ ASSERT(result.is_equal(set));
153
+
154
+ result = set.call("insert", 22);
155
+ ASSERT(result.is_equal(set));
156
+
157
+ result = set.call("size");
158
+ ASSERT_EQUAL(2, detail::From_Ruby<int>().convert(result));
159
+
160
+ result = set.call("insert", 33);
161
+ ASSERT(result.is_equal(set));
162
+
163
+ String string = set.call("to_s");
164
+ ASSERT_EQUAL("<Set≺int≻:{11, 22, 33}>", string.c_str());
165
+
166
+ set.call("delete", 11);
167
+ string = set.call("to_s");
168
+ ASSERT_EQUAL("<Set≺int≻:{22, 33}>", string.c_str());
169
+ }
170
+
171
+ TESTCASE(Clone)
172
+ {
173
+ Module m = define_module("Testing");
174
+ Class c = define_set<double>("DoubleSet");
175
+
176
+ std::string code = R"(set = Std::DoubleSet.new
177
+ set << 11.1 << 22.2)";
178
+
179
+ Object set = m.instance_eval(code);
180
+ Object copy = set.call("clone");
181
+
182
+ Object size = set.call("size");
183
+ Object copySize = copy.call("size");
184
+ ASSERT_EQUAL(detail::From_Ruby<int32_t>().convert(size), detail::From_Ruby<int32_t>().convert(copySize));
185
+
186
+ String string = set.call("to_s");
187
+ String copyString = copy.call("to_s");
188
+ ASSERT_EQUAL(string.c_str(), copyString.c_str());
189
+ }
190
+
191
+ namespace
192
+ {
193
+ class NotPrintable
194
+ {
195
+ public:
196
+ NotPrintable(uint32_t value) : value_(value)
197
+ {
198
+ };
199
+
200
+ uint32_t value_;
201
+ };
202
+
203
+ bool operator< (const NotPrintable& lhs, const NotPrintable& rhs)
204
+ {
205
+ return lhs.value_ < rhs.value_;
206
+ }
207
+ }
208
+
209
+ TESTCASE(NotPrintable)
210
+ {
211
+ define_class<NotPrintable>("NotPrintable").
212
+ define_constructor(Constructor<NotPrintable, uint32_t>());
213
+
214
+ Class c = define_set<NotPrintable>("NotPrintableSet");
215
+
216
+ Object set = c.call("new");
217
+ set.call("insert", NotPrintable(1));
218
+ set.call("insert", NotPrintable(2));
219
+ set.call("insert", NotPrintable(3));
220
+
221
+ Object result = set.call("to_s");
222
+ ASSERT_EQUAL("[Not printable]", detail::From_Ruby<std::string>().convert(result));
223
+ }
224
+
225
+ namespace
226
+ {
227
+ std::set<float> returnFloatSet()
228
+ {
229
+ std::set<float> result;
230
+ result.insert(1.1f);
231
+ result.insert(2.2f);
232
+ result.insert(3.3f);
233
+ return result;
234
+ }
235
+
236
+ std::set<float> passFloatSet(std::set<float>& set)
237
+ {
238
+ return set;
239
+ }
240
+ }
241
+
242
+ TESTCASE(AutoRegisterReturn)
243
+ {
244
+ define_global_function("return_float_set", &returnFloatSet);
245
+
246
+ Module m = define_module("Testing");
247
+ Object set = m.module_eval("return_float_set");
248
+ ASSERT_EQUAL("Std::Set≺float≻", set.class_name().str());
249
+
250
+ std::string code = R"(set = return_float_set
251
+ set.size == 3)";
252
+
253
+ Object result = m.module_eval(code);
254
+ ASSERT_EQUAL(Qtrue, result.value());
255
+
256
+ // Now register this same set
257
+ define_set<float>("FloatSet");
258
+ code = R"(set = Std::FloatSet.new)";
259
+ result = m.module_eval(code);
260
+ ASSERT(result.is_instance_of(set.class_of()));
261
+
262
+ // Now register it again in the module
263
+ define_set<float>("FloatSet2");
264
+ code = R"(set = Std::FloatSet2.new)";
265
+ result = m.module_eval(code);
266
+ ASSERT(result.is_instance_of(set.class_of()));
267
+ }
268
+
269
+ TESTCASE(AutoRegisterParameter)
270
+ {
271
+ define_global_function("pass_float_set", &passFloatSet);
272
+
273
+ std::string code = R"(set = Std::Set≺float≻.new
274
+ set << 4.0
275
+ set << 5.0
276
+ pass_float_set(set))";
277
+
278
+ Module m = define_module("Testing");
279
+ Object set = m.module_eval(code);
280
+
281
+ Object result = set.call("size");
282
+ ASSERT_EQUAL("Std::Set≺float≻", set.class_name().str());
283
+ ASSERT_EQUAL(2, detail::From_Ruby<int32_t>().convert(result));
284
+ }
285
+
286
+ namespace
287
+ {
288
+ std::set<std::string> defaultSet(std::set<std::string> strings = {"one", "two", "three"})
289
+ {
290
+ return strings;
291
+ }
292
+ }
293
+
294
+ TESTCASE(DefaultValue)
295
+ {
296
+ define_set<std::string>("StringSet");
297
+ define_global_function("default_set", &defaultSet, Arg("strings") = std::set<std::string> { "one", "two", "three" });
298
+
299
+ Module m = define_module("Testing");
300
+ Object result = m.module_eval("default_set");
301
+ std::set<std::string> actual = detail::From_Ruby<std::set<std::string>>().convert(result);
302
+
303
+ std::set<std::string> expected{ "one", "two", "three" };
304
+
305
+ ASSERT_EQUAL(expected.size(), actual.size());
306
+ ASSERT_EQUAL(expected, actual);
307
+ }
308
+
309
+ TESTCASE(Equal)
310
+ {
311
+ Module m = define_module("Testing");
312
+ Class c = define_set<int>("IntSet");
313
+
314
+ std::string code = R"(set1 = Std::IntSet.new
315
+ set1 << 4 << 5 << 6
316
+
317
+ set2 = Std::IntSet.new
318
+ set2 << 4 << 5 << 6
319
+
320
+ set1 == set2)";
321
+
322
+ Object result = m.instance_eval(code);
323
+ ASSERT_EQUAL(Qtrue, result.value());
324
+
325
+ define_class<NotPrintable>("NotPrintable").
326
+ define_constructor(Constructor<NotPrintable, uint32_t>());
327
+
328
+ define_set<NotPrintable>("NotPrintableSet");
329
+
330
+ code = R"(set1 = Std::NotPrintableSet.new
331
+ set2 = Std::NotPrintableSet.new
332
+ set1 == set2)";
333
+
334
+ result = m.instance_eval(code);
335
+ ASSERT_EQUAL(Qfalse, result.value());
336
+ }
337
+
338
+ TESTCASE(ToArray)
339
+ {
340
+ Module m = define_module("Testing");
341
+
342
+ Class c = define_set<std::string>("StringSet").
343
+ define_constructor(Constructor<std::set<std::string>>());
344
+
345
+ std::string code = R"(set = Std::StringSet.new
346
+ set << "abc"
347
+ set << "def"
348
+ set << "ghi"
349
+ set.to_a)";
350
+
351
+ Array array = m.module_eval(code);
352
+ ASSERT_EQUAL(3u, array.size());
353
+
354
+ ASSERT_EQUAL("abc", detail::From_Ruby<std::string>().convert(array[0].value()));
355
+ ASSERT_EQUAL("def", detail::From_Ruby<std::string>().convert(array[1].value()));
356
+ ASSERT_EQUAL("ghi", detail::From_Ruby<std::string>().convert(array[2].value()));
357
+ }
358
+
359
+ namespace
360
+ {
361
+ std::set<int> ints;
362
+ std::set<float> floats;
363
+ std::set<std::string> strings;
364
+
365
+ void setToSet(std::set<int> aInts, std::set<float> aFloats, std::set<std::string> aStrings)
366
+ {
367
+ ints = aInts;
368
+ floats = aFloats;
369
+ strings = aStrings;
370
+ }
371
+
372
+ void setToSetRefs(std::set<int>& aInts, std::set<float>& aFloats, std::set<std::string>& aStrings)
373
+ {
374
+ ints = aInts;
375
+ floats = aFloats;
376
+ strings = aStrings;
377
+ }
378
+
379
+ void setToSetPointers(std::set<int>* aInts, std::set<float>* aFloats, std::set<std::string>* aStrings)
380
+ {
381
+ ints = *aInts;
382
+ floats = *aFloats;
383
+ strings = *aStrings;
384
+ }
385
+ }
386
+
387
+ TESTCASE(ToSet)
388
+ {
389
+ define_global_function("set_to_set", &setToSet);
390
+
391
+ Module m = define_module("Testing");
392
+
393
+ std::string code = R"(require 'set'
394
+ set_to_set(Set[7, 9, 1_000_000],
395
+ Set[49.0, 78.0, 999.0],
396
+ Set["one", "two", "three"]))";
397
+ m.module_eval(code);
398
+
399
+ std::set<int> expectedInts{ 7, 9, 1000000 };
400
+ ASSERT_EQUAL(expectedInts, ints);
401
+
402
+ std::set<float> expectedFloats{ 49.0, 78.0, 999.0 };
403
+ ASSERT_EQUAL(expectedFloats, floats);
404
+
405
+ std::set<std::string> expectedStrings{ "one", "two", "three" };
406
+ ASSERT_EQUAL(expectedStrings, strings);
407
+ }
408
+
409
+ TESTCASE(ToSetRefs)
410
+ {
411
+ define_global_function("set_to_set_refs", &setToSetRefs);
412
+
413
+ Module m = define_module("Testing");
414
+
415
+ std::string code = R"(require 'set'
416
+ set_to_set_refs(Set[8, 10, 1_000_001],
417
+ Set[50.0, 79.0, 1_000.0],
418
+ Set["eleven", "twelve", "thirteen"]))";
419
+ m.module_eval(code);
420
+
421
+ std::set<int> expectedInts{ 8, 10, 1000001 };
422
+ ASSERT_EQUAL(expectedInts, ints);
423
+
424
+ std::set<float> expectedFloats{ 50.0, 79.0, 1000.0 };
425
+ ASSERT_EQUAL(expectedFloats, floats);
426
+
427
+ std::set<std::string> expectedStrings{ "eleven", "twelve", "thirteen" };
428
+ ASSERT_EQUAL(expectedStrings, strings);
429
+ }
430
+
431
+ TESTCASE(ToSetPointers)
432
+ {
433
+ define_global_function("set_to_set_pointers", &setToSetPointers);
434
+
435
+ Module m = define_module("Testing");
436
+
437
+ std::string code = R"(require 'set'
438
+ set_to_set_pointers(Set[9, 11, 1_000_002],
439
+ Set[51.0, 80.0, 1_001.0],
440
+ Set["fourteen", "fifteen", "sixteen"]))";
441
+ m.module_eval(code);
442
+
443
+ std::set<int> expectedInts{ 9, 11, 1000002 };
444
+ ASSERT_EQUAL(expectedInts, ints);
445
+
446
+ std::set<float> expectedFloats{ 51.0, 80.0, 1001.0 };
447
+ ASSERT_EQUAL(expectedFloats, floats);
448
+
449
+ std::set<std::string> expectedStrings{ "fourteen", "fifteen", "sixteen" };
450
+ ASSERT_EQUAL(expectedStrings, strings);
451
+ }
452
+
453
+ TESTCASE(ToSetWrongTypes)
454
+ {
455
+ define_global_function("set_to_set", &setToSet);
456
+
457
+ Module m = define_module("Testing");
458
+
459
+ std::string code = R"(require 'set'
460
+ set_to_set(Set[7, 9, 1_000_000],
461
+ Set[49.0, 78.0, 999.0],
462
+ Set[50.0, 79.0, 1000.0]))";
463
+
464
+ ASSERT_EXCEPTION_CHECK(
465
+ Exception,
466
+ m.module_eval(code),
467
+ ASSERT_EQUAL("wrong argument type Float (expected String)", ex.what())
468
+ );
469
+ }
470
+
471
+ TESTCASE(ToSetMixedTypes)
472
+ {
473
+ define_global_function("set_to_set", &setToSet);
474
+
475
+ Module m = define_module("Testing");
476
+
477
+ std::string code = R"(set_to_set(Set[7, 'nine', true], Set[49.0, 78.0, 999.0], Set["one", "two", "three"]))";
478
+
479
+ ASSERT_EXCEPTION_CHECK(
480
+ Exception,
481
+ m.module_eval(code),
482
+ ASSERT_EQUAL("no implicit conversion of String into Integer", ex.what())
483
+ );
484
+ }
485
+
486
+ namespace
487
+ {
488
+ class Factory
489
+ {
490
+ public:
491
+ std::set<std::string>* returnPointer()
492
+ {
493
+ return &this->instance_;
494
+ }
495
+
496
+ std::set<std::string>& returnReference()
497
+ {
498
+ return this->instance_;
499
+ }
500
+
501
+ std::set<std::string> returnValue()
502
+ {
503
+ return this->instance_;
504
+ }
505
+
506
+ public:
507
+ static inline std::set<std::string> instance_{ "one", "two", "three" };
508
+ };
509
+
510
+ std::ostream& operator<<(std::ostream& stream, const std::set<std::string>& set)
511
+ {
512
+ stream << "Set";
513
+ return stream;
514
+ }
515
+
516
+ void createFactoryClass()
517
+ {
518
+ define_class<Factory>("Factory").
519
+ define_constructor(Constructor<Factory>()).
520
+ define_method("pointer", &Factory::returnPointer).
521
+ define_method("reference", &Factory::returnReference).
522
+ define_method("value", &Factory::returnValue);
523
+ }
524
+ }
525
+
526
+ TESTCASE(Returns)
527
+ {
528
+ createFactoryClass();
529
+ Module m = define_module("TestingModule");
530
+ Object factory = m.module_eval("Factory.new");
531
+
532
+ std::set<std::string> expected{ "one", "two", "three" };
533
+
534
+ Data_Object<std::set<std::string>> set1 = factory.call("pointer");
535
+ ASSERT_EQUAL(expected, *set1);
536
+
537
+ Data_Object<std::set<std::string>> set2 = factory.call("reference");
538
+ ASSERT_EQUAL(expected, *set2);
539
+
540
+ Data_Object<std::set<std::string>> set3 = factory.call("value");
541
+ ASSERT_EQUAL(expected, *set3);
542
+ }
543
+
544
+ TESTCASE(Iterate)
545
+ {
546
+ Module m = define_module("Testing");
547
+ Class c = define_set<double>("DoubleSet");
548
+
549
+ std::string code = R"(set = Std::DoubleSet.new
550
+ set << 5.0 << 6.0 << 7.0
551
+ set.map do |value|
552
+ value * 2.0
553
+ end)";
554
+
555
+ Array result = m.module_eval(code);
556
+ ASSERT_EQUAL(3, result.size());
557
+ ASSERT_EQUAL(10.0, detail::From_Ruby<double>().convert(result[0].value()));
558
+ ASSERT_EQUAL(12.0, detail::From_Ruby<double>().convert(result[1].value()));
559
+ ASSERT_EQUAL(14.0, detail::From_Ruby<double>().convert(result[2].value()));
560
+ }
561
+
562
+ TESTCASE(ToEnumPointer)
563
+ {
564
+ createFactoryClass();
565
+ Module m = define_module("TestingModule");
566
+
567
+ std::string code = R"(factory = Factory.new
568
+ set = factory.pointer
569
+ updated = set.each.map do |value|
570
+ value + "_updated"
571
+ end)";
572
+
573
+ Array result = m.module_eval(code);
574
+
575
+ ASSERT_EQUAL(3, result.size());
576
+ ASSERT_EQUAL("one_updated", detail::From_Ruby<std::string>().convert(result[0].value()));
577
+ ASSERT_EQUAL("three_updated", detail::From_Ruby<std::string>().convert(result[1].value()));
578
+ ASSERT_EQUAL("two_updated", detail::From_Ruby<std::string>().convert(result[2].value()));
579
+ }
580
+
581
+ TESTCASE(ToEnumReference)
582
+ {
583
+ createFactoryClass();
584
+ Module m = define_module("TestingModule");
585
+
586
+ std::string code = R"(factory = Factory.new
587
+ set = factory.reference
588
+ updated = set.each.map do |value|
589
+ value + "_updated"
590
+ end)";
591
+
592
+ Array result = m.module_eval(code);
593
+
594
+ ASSERT_EQUAL(3, result.size());
595
+ ASSERT_EQUAL("one_updated", detail::From_Ruby<std::string>().convert(result[0].value()));
596
+ ASSERT_EQUAL("three_updated", detail::From_Ruby<std::string>().convert(result[1].value()));
597
+ ASSERT_EQUAL("two_updated", detail::From_Ruby<std::string>().convert(result[2].value()));
598
+ }
599
+
600
+ TESTCASE(ToEnumValue)
601
+ {
602
+ createFactoryClass();
603
+ Module m = define_module("TestingModule");
604
+
605
+ std::string code = R"(factory = Factory.new
606
+ set = factory.value
607
+ updated = set.each.map do |value|
608
+ value + "_updated"
609
+ end)";
610
+
611
+ Array result = m.module_eval(code);
612
+
613
+ ASSERT_EQUAL(3, result.size());
614
+ ASSERT_EQUAL("one_updated", detail::From_Ruby<std::string>().convert(result[0].value()));
615
+ ASSERT_EQUAL("three_updated", detail::From_Ruby<std::string>().convert(result[1].value()));
616
+ ASSERT_EQUAL("two_updated", detail::From_Ruby<std::string>().convert(result[2].value()));
617
+ }
618
+
619
+ TESTCASE(ToEnumSize)
620
+ {
621
+ createFactoryClass();
622
+ Module m = define_module("TestingModule");
623
+ Object factory = m.module_eval("Factory.new");
624
+ Object set = factory.call("pointer");
625
+ Object enumerable = set.call("each");
626
+ Object result = enumerable.call("size");
627
+
628
+ ASSERT_EQUAL(3, detail::From_Ruby<int>().convert(result));
629
+ }
630
+
631
+ namespace
632
+ {
633
+ std::set<std::string*> setOfStringPointers()
634
+ {
635
+ std::set<std::string*> result;
636
+ std::string* pString = new std::string("Hello");
637
+ result.insert(pString);
638
+ return result;
639
+ }
640
+ }
641
+
642
+ TESTCASE(StringPointerSet)
643
+ {
644
+ define_global_function("set_of_string_pointers", &setOfStringPointers);
645
+
646
+ Module m(rb_mKernel);
647
+ Data_Object<std::set<std::string*>> set = m.call("set_of_string_pointers");
648
+ ASSERT_EQUAL(1, set->size());
649
+
650
+ std::string expected = "Hello";
651
+ const std::string* actual = *set->begin();
652
+ ASSERT_EQUAL(expected, *actual);
653
+ }
654
+
655
+ namespace
656
+ {
657
+ class MyClass2
658
+ {
659
+ public:
660
+ MyClass2(std::string name): name(name)
661
+ {
662
+ }
663
+ std::string name;
664
+ };
665
+
666
+ std::set<MyClass2*> setOfMyClass2Pointers()
667
+ {
668
+ std::set<MyClass2*> result;
669
+ MyClass2* pMyClass = new MyClass2("Hello MyClass2");
670
+ result.insert(pMyClass);
671
+ return result;
672
+ }
673
+ }
674
+
675
+ TESTCASE(MyClass2PointerSet)
676
+ {
677
+ Class c = define_class<MyClass2>("MyClass2").
678
+ define_constructor(Constructor<MyClass2, std::string>()).
679
+ define_attr("name", &MyClass2::name, AttrAccess::Read);
680
+
681
+ define_global_function("set_of_myclass2_pointers", &setOfMyClass2Pointers);
682
+
683
+ Module m(rb_mKernel);
684
+ Data_Object<std::set<MyClass2*>> result = m.call("set_of_myclass2_pointers");
685
+ ASSERT_EQUAL(1, result->size());
686
+
687
+ MyClass2* pMyClass = *result->begin();
688
+ ASSERT_EQUAL("Hello MyClass2", pMyClass->name);
689
+ }
690
+
691
+ TESTCASE(Intersect)
692
+ {
693
+ Module m = define_module("Testing");
694
+ define_set<std::string>("StringSet");
695
+
696
+ std::string code = R"(set1 = Std::StringSet.new
697
+ set1 << "one" << "two" << "two" << "three"
698
+
699
+ set2 = Std::StringSet.new
700
+ set2 << "three" << "four"
701
+
702
+ set1 & set2)";
703
+
704
+ Object set = m.instance_eval(code);
705
+ Object size = set.call("size");
706
+ ASSERT_EQUAL(1, detail::From_Ruby<int32_t>().convert(size));
707
+
708
+ String string = set.call("to_s");
709
+ ASSERT_EQUAL("<Set≺string≻:{three}>", string.c_str());
710
+ }
711
+
712
+ TESTCASE(Union)
713
+ {
714
+ Module m = define_module("Testing");
715
+ define_set<std::string>("StringSet");
716
+
717
+ std::string code = R"(set1 = Std::StringSet.new
718
+ set1 << "one" << "two" << "two" << "three"
719
+
720
+ set2 = Std::StringSet.new
721
+ set2 << "three" << "four"
722
+
723
+ set1 | set2)";
724
+
725
+ Object set = m.instance_eval(code);
726
+ Object size = set.call("size");
727
+ ASSERT_EQUAL(4, detail::From_Ruby<int32_t>().convert(size));
728
+
729
+ String string = set.call("to_s");
730
+ ASSERT_EQUAL("<Set≺string≻:{four, one, three, two}>", string.c_str());
731
+ }
732
+
733
+ TESTCASE(Difference)
734
+ {
735
+ Module m = define_module("Testing");
736
+ define_set<std::string>("StringSet");
737
+
738
+ std::string code = R"(set1 = Std::StringSet.new
739
+ set1 << "one" << "two" << "two" << "three"
740
+
741
+ set2 = Std::StringSet.new
742
+ set2 << "three" << "four"
743
+
744
+ set1 - set2)";
745
+
746
+ Object set = m.instance_eval(code);
747
+ Object size = set.call("size");
748
+ ASSERT_EQUAL(2, detail::From_Ruby<int32_t>().convert(size));
749
+
750
+ String string = set.call("to_s");
751
+ ASSERT_EQUAL("<Set≺string≻:{one, two}>", string.c_str());
752
+ }
753
+
754
+ TESTCASE(Exclusive)
755
+ {
756
+ Module m = define_module("Testing");
757
+ define_set<std::string>("StringSet");
758
+
759
+ std::string code = R"(set1 = Std::StringSet.new
760
+ set1 << "one" << "two" << "three"
761
+
762
+ set2 = Std::StringSet.new
763
+ set2 << "three" << "four"
764
+
765
+ set1 ^ set2)";
766
+
767
+ Object set = m.instance_eval(code);
768
+ Object size = set.call("size");
769
+ ASSERT_EQUAL(3, detail::From_Ruby<int32_t>().convert(size));
770
+
771
+ String string = set.call("to_s");
772
+ ASSERT_EQUAL("<Set≺string≻:{four, one, two}>", string.c_str());
773
+ }
774
+
775
+ TESTCASE(Superset)
776
+ {
777
+ Module m = define_module("Testing");
778
+ define_set<std::string>("StringSet");
779
+
780
+ std::string code = R"(set1 = Std::StringSet.new
781
+ set1 << "one" << "two" << "three"
782
+
783
+ set2 = Std::StringSet.new
784
+ set2 << "three"
785
+
786
+ set1 > set2)";
787
+
788
+ Object result = m.instance_eval(code);
789
+ ASSERT_EQUAL(Qtrue, result.value());
790
+ }