rice 2.1.3 → 4.0.2

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 (246) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +121 -0
  3. data/CONTRIBUTORS.md +19 -0
  4. data/COPYING +2 -2
  5. data/Gemfile +3 -0
  6. data/README.md +45 -1028
  7. data/Rakefile +95 -12
  8. data/include/rice/rice.hpp +7766 -0
  9. data/include/rice/stl.hpp +1113 -0
  10. data/lib/mkmf-rice.rb +127 -0
  11. data/lib/version.rb +3 -0
  12. data/rice/Address_Registration_Guard.ipp +75 -32
  13. data/rice/Address_Registration_Guard_defn.hpp +60 -56
  14. data/rice/Arg.hpp +80 -4
  15. data/rice/Arg.ipp +51 -0
  16. data/rice/Constructor.hpp +30 -376
  17. data/rice/Data_Object.ipp +234 -107
  18. data/rice/Data_Object_defn.hpp +77 -117
  19. data/rice/Data_Type.hpp +1 -2
  20. data/rice/Data_Type.ipp +251 -295
  21. data/rice/Data_Type_defn.hpp +175 -243
  22. data/rice/Director.hpp +14 -9
  23. data/rice/Enum.hpp +54 -104
  24. data/rice/Enum.ipp +104 -230
  25. data/rice/Exception.hpp +2 -8
  26. data/rice/Exception.ipp +65 -0
  27. data/rice/Exception_defn.hpp +46 -47
  28. data/rice/Identifier.hpp +28 -28
  29. data/rice/Identifier.ipp +23 -27
  30. data/rice/Return.hpp +39 -0
  31. data/rice/Return.ipp +33 -0
  32. data/rice/detail/Exception_Handler.ipp +22 -62
  33. data/rice/detail/Exception_Handler_defn.hpp +76 -91
  34. data/rice/detail/Iterator.hpp +18 -88
  35. data/rice/detail/Iterator.ipp +47 -0
  36. data/rice/detail/Jump_Tag.hpp +21 -0
  37. data/rice/detail/MethodInfo.hpp +44 -0
  38. data/rice/detail/MethodInfo.ipp +78 -0
  39. data/rice/detail/NativeAttribute.hpp +53 -0
  40. data/rice/detail/NativeAttribute.ipp +83 -0
  41. data/rice/detail/NativeFunction.hpp +69 -0
  42. data/rice/detail/NativeFunction.ipp +248 -0
  43. data/rice/detail/RubyFunction.hpp +39 -0
  44. data/rice/detail/RubyFunction.ipp +92 -0
  45. data/rice/detail/Type.hpp +29 -0
  46. data/rice/detail/Type.ipp +138 -0
  47. data/rice/detail/TypeRegistry.hpp +50 -0
  48. data/rice/detail/TypeRegistry.ipp +106 -0
  49. data/rice/detail/Wrapper.hpp +51 -0
  50. data/rice/detail/Wrapper.ipp +151 -0
  51. data/rice/detail/default_allocation_func.hpp +8 -19
  52. data/rice/detail/default_allocation_func.ipp +9 -8
  53. data/rice/detail/from_ruby.hpp +2 -37
  54. data/rice/detail/from_ruby.ipp +1020 -46
  55. data/rice/detail/from_ruby_defn.hpp +38 -0
  56. data/rice/detail/function_traits.hpp +124 -0
  57. data/rice/detail/method_data.hpp +23 -15
  58. data/rice/detail/method_data.ipp +53 -0
  59. data/rice/detail/rice_traits.hpp +116 -0
  60. data/rice/detail/ruby.hpp +9 -50
  61. data/rice/detail/to_ruby.hpp +3 -17
  62. data/rice/detail/to_ruby.ipp +409 -31
  63. data/rice/detail/to_ruby_defn.hpp +48 -0
  64. data/rice/forward_declares.ipp +82 -0
  65. data/rice/global_function.hpp +16 -20
  66. data/rice/global_function.ipp +8 -17
  67. data/rice/rice.hpp +59 -0
  68. data/rice/ruby_mark.hpp +5 -3
  69. data/rice/ruby_try_catch.hpp +4 -4
  70. data/rice/stl.hpp +11 -0
  71. data/sample/callbacks/extconf.rb +6 -0
  72. data/sample/callbacks/sample_callbacks.cpp +35 -0
  73. data/sample/callbacks/test.rb +28 -0
  74. data/sample/enum/extconf.rb +3 -0
  75. data/sample/enum/sample_enum.cpp +3 -17
  76. data/sample/enum/test.rb +2 -2
  77. data/sample/inheritance/animals.cpp +8 -24
  78. data/sample/inheritance/extconf.rb +3 -0
  79. data/sample/inheritance/test.rb +1 -1
  80. data/sample/map/extconf.rb +3 -0
  81. data/sample/map/map.cpp +10 -18
  82. data/sample/map/test.rb +1 -1
  83. data/test/embed_ruby.cpp +34 -0
  84. data/test/embed_ruby.hpp +4 -0
  85. data/test/ext/t1/extconf.rb +3 -0
  86. data/test/ext/t1/t1.cpp +1 -3
  87. data/test/ext/t2/extconf.rb +3 -0
  88. data/test/ext/t2/t2.cpp +1 -1
  89. data/test/extconf.rb +23 -0
  90. data/test/ruby/test_callbacks_sample.rb +28 -0
  91. data/test/ruby/test_multiple_extensions.rb +18 -0
  92. data/test/ruby/test_multiple_extensions_same_class.rb +14 -0
  93. data/test/ruby/test_multiple_extensions_with_inheritance.rb +20 -0
  94. data/test/test_Address_Registration_Guard.cpp +25 -11
  95. data/test/test_Array.cpp +131 -74
  96. data/test/test_Attribute.cpp +147 -0
  97. data/test/test_Builtin_Object.cpp +36 -15
  98. data/test/test_Class.cpp +151 -276
  99. data/test/test_Constructor.cpp +10 -9
  100. data/test/test_Data_Object.cpp +135 -193
  101. data/test/test_Data_Type.cpp +323 -252
  102. data/test/test_Director.cpp +56 -42
  103. data/test/test_Enum.cpp +230 -104
  104. data/test/test_Exception.cpp +7 -7
  105. data/test/test_Hash.cpp +33 -31
  106. data/test/test_Identifier.cpp +6 -6
  107. data/test/test_Inheritance.cpp +221 -0
  108. data/test/test_Iterator.cpp +161 -0
  109. data/test/test_Jump_Tag.cpp +1 -1
  110. data/test/test_Keep_Alive.cpp +161 -0
  111. data/test/test_Memory_Management.cpp +4 -5
  112. data/test/test_Module.cpp +169 -111
  113. data/test/test_Object.cpp +51 -19
  114. data/test/test_Ownership.cpp +275 -0
  115. data/test/test_Self.cpp +205 -0
  116. data/test/test_Stl_Optional.cpp +90 -0
  117. data/test/test_Stl_Pair.cpp +144 -0
  118. data/test/test_Stl_SmartPointer.cpp +200 -0
  119. data/test/test_Stl_String.cpp +74 -0
  120. data/test/test_Stl_Vector.cpp +652 -0
  121. data/test/test_String.cpp +3 -3
  122. data/test/test_Struct.cpp +31 -40
  123. data/test/test_Symbol.cpp +3 -3
  124. data/test/test_To_From_Ruby.cpp +283 -218
  125. data/test/test_global_functions.cpp +41 -20
  126. data/test/unittest.cpp +34 -8
  127. data/test/unittest.hpp +0 -4
  128. metadata +121 -136
  129. data/Doxyfile +0 -2268
  130. data/Makefile.am +0 -26
  131. data/Makefile.in +0 -923
  132. data/README.mingw +0 -8
  133. data/aclocal.m4 +0 -1088
  134. data/bootstrap +0 -8
  135. data/check_stdcxx_11.ac +0 -103
  136. data/config.guess +0 -1421
  137. data/config.sub +0 -1807
  138. data/configure +0 -7367
  139. data/configure.ac +0 -55
  140. data/depcomp +0 -791
  141. data/doxygen.ac +0 -314
  142. data/doxygen.am +0 -186
  143. data/extconf.rb +0 -69
  144. data/install-sh +0 -501
  145. data/missing +0 -215
  146. data/post-autoconf.rb +0 -22
  147. data/post-automake.rb +0 -28
  148. data/rice/Address_Registration_Guard.cpp +0 -22
  149. data/rice/Arg_impl.hpp +0 -129
  150. data/rice/Arg_operators.cpp +0 -21
  151. data/rice/Arg_operators.hpp +0 -19
  152. data/rice/Array.hpp +0 -214
  153. data/rice/Array.ipp +0 -256
  154. data/rice/Builtin_Object.hpp +0 -8
  155. data/rice/Builtin_Object.ipp +0 -50
  156. data/rice/Builtin_Object_defn.hpp +0 -50
  157. data/rice/Class.cpp +0 -57
  158. data/rice/Class.hpp +0 -8
  159. data/rice/Class.ipp +0 -6
  160. data/rice/Class_defn.hpp +0 -83
  161. data/rice/Data_Type.cpp +0 -54
  162. data/rice/Data_Type_fwd.hpp +0 -12
  163. data/rice/Director.cpp +0 -13
  164. data/rice/Exception.cpp +0 -59
  165. data/rice/Exception_Base.hpp +0 -8
  166. data/rice/Exception_Base.ipp +0 -13
  167. data/rice/Exception_Base_defn.hpp +0 -27
  168. data/rice/Hash.hpp +0 -227
  169. data/rice/Hash.ipp +0 -329
  170. data/rice/Identifier.cpp +0 -8
  171. data/rice/Jump_Tag.hpp +0 -24
  172. data/rice/Makefile.am +0 -125
  173. data/rice/Makefile.in +0 -888
  174. data/rice/Module.cpp +0 -84
  175. data/rice/Module.hpp +0 -8
  176. data/rice/Module.ipp +0 -6
  177. data/rice/Module_defn.hpp +0 -88
  178. data/rice/Module_impl.hpp +0 -281
  179. data/rice/Module_impl.ipp +0 -345
  180. data/rice/Object.cpp +0 -169
  181. data/rice/Object.hpp +0 -8
  182. data/rice/Object.ipp +0 -19
  183. data/rice/Object_defn.hpp +0 -191
  184. data/rice/Require_Guard.hpp +0 -21
  185. data/rice/String.cpp +0 -94
  186. data/rice/String.hpp +0 -91
  187. data/rice/Struct.cpp +0 -117
  188. data/rice/Struct.hpp +0 -162
  189. data/rice/Struct.ipp +0 -26
  190. data/rice/Symbol.cpp +0 -25
  191. data/rice/Symbol.hpp +0 -66
  192. data/rice/Symbol.ipp +0 -44
  193. data/rice/config.hpp +0 -47
  194. data/rice/config.hpp.in +0 -46
  195. data/rice/detail/Arguments.hpp +0 -118
  196. data/rice/detail/Auto_Function_Wrapper.hpp +0 -898
  197. data/rice/detail/Auto_Function_Wrapper.ipp +0 -3694
  198. data/rice/detail/Auto_Member_Function_Wrapper.hpp +0 -897
  199. data/rice/detail/Auto_Member_Function_Wrapper.ipp +0 -2774
  200. data/rice/detail/Caster.hpp +0 -103
  201. data/rice/detail/Not_Copyable.hpp +0 -25
  202. data/rice/detail/Wrapped_Function.hpp +0 -33
  203. data/rice/detail/cfp.hpp +0 -24
  204. data/rice/detail/cfp.ipp +0 -51
  205. data/rice/detail/check_ruby_type.cpp +0 -27
  206. data/rice/detail/check_ruby_type.hpp +0 -23
  207. data/rice/detail/creation_funcs.hpp +0 -37
  208. data/rice/detail/creation_funcs.ipp +0 -36
  209. data/rice/detail/define_method_and_auto_wrap.hpp +0 -31
  210. data/rice/detail/define_method_and_auto_wrap.ipp +0 -30
  211. data/rice/detail/demangle.cpp +0 -56
  212. data/rice/detail/demangle.hpp +0 -19
  213. data/rice/detail/env.hpp +0 -11
  214. data/rice/detail/method_data.cpp +0 -86
  215. data/rice/detail/node.hpp +0 -13
  216. data/rice/detail/object_call.hpp +0 -69
  217. data/rice/detail/object_call.ipp +0 -131
  218. data/rice/detail/protect.cpp +0 -29
  219. data/rice/detail/protect.hpp +0 -34
  220. data/rice/detail/ruby_version_code.hpp +0 -6
  221. data/rice/detail/ruby_version_code.hpp.in +0 -6
  222. data/rice/detail/st.hpp +0 -22
  223. data/rice/detail/traits.hpp +0 -43
  224. data/rice/detail/win32.hpp +0 -16
  225. data/rice/detail/wrap_function.hpp +0 -341
  226. data/rice/detail/wrap_function.ipp +0 -514
  227. data/rice/protect.hpp +0 -92
  228. data/rice/protect.ipp +0 -1134
  229. data/rice/rubypp.rb +0 -97
  230. data/rice/to_from_ruby.hpp +0 -8
  231. data/rice/to_from_ruby.ipp +0 -294
  232. data/rice/to_from_ruby_defn.hpp +0 -70
  233. data/ruby.ac +0 -135
  234. data/ruby/Makefile.am +0 -1
  235. data/ruby/Makefile.in +0 -628
  236. data/ruby/lib/Makefile.am +0 -3
  237. data/ruby/lib/Makefile.in +0 -506
  238. data/ruby/lib/mkmf-rice.rb.in +0 -217
  239. data/ruby/lib/version.rb +0 -3
  240. data/sample/Makefile.am +0 -47
  241. data/sample/Makefile.in +0 -489
  242. data/test/Makefile.am +0 -72
  243. data/test/Makefile.in +0 -1213
  244. data/test/ext/Makefile.am +0 -41
  245. data/test/ext/Makefile.in +0 -483
  246. data/test/test_rice.rb +0 -41
data/test/test_Object.cpp CHANGED
@@ -1,8 +1,6 @@
1
1
  #include "unittest.hpp"
2
- #include "rice/Object.hpp"
3
- #include "rice/Class.hpp"
4
- #include "rice/String.hpp"
5
- #include "rice/Array.hpp"
2
+ #include "embed_ruby.hpp"
3
+ #include <rice/rice.hpp>
6
4
 
7
5
  using namespace Rice;
8
6
 
@@ -10,7 +8,7 @@ TESTSUITE(Object);
10
8
 
11
9
  SETUP(Object)
12
10
  {
13
- ruby_init();
11
+ embed_ruby();
14
12
  }
15
13
 
16
14
  TESTCASE(default_construct)
@@ -27,9 +25,34 @@ TESTCASE(construct_with_value)
27
25
 
28
26
  TESTCASE(copy_construct)
29
27
  {
30
- Object o(INT2NUM(42));
31
- Object o2(o);
32
- ASSERT_EQUAL(INT2NUM(42), o2.value());
28
+ Object o1(INT2NUM(42));
29
+ Object o2(o1);
30
+ ASSERT_EQUAL(o2.value(), o1.value());
31
+ }
32
+
33
+ TESTCASE(copy_assign)
34
+ {
35
+ Object o1(INT2NUM(42));
36
+ Object o2(INT2NUM(43));
37
+ o2 = o1;
38
+ ASSERT_EQUAL(o2.value(), o1.value());
39
+ }
40
+
41
+ TESTCASE(move_construct)
42
+ {
43
+ Object o1(INT2NUM(42));
44
+ Object o2(std::move(o1));
45
+ ASSERT_EQUAL(o2.value(), INT2NUM(42));
46
+ ASSERT_EQUAL(o1.value(), Qnil);
47
+ }
48
+
49
+ TESTCASE(move_assign)
50
+ {
51
+ Object o1(INT2NUM(42));
52
+ Object o2(INT2NUM(43));
53
+ o2 = std::move(o1);
54
+ ASSERT_EQUAL(o2.value(), INT2NUM(42));
55
+ ASSERT_EQUAL(o1.value(), Qnil);
33
56
  }
34
57
 
35
58
  TESTCASE(test)
@@ -63,7 +86,7 @@ TESTCASE(is_nil)
63
86
 
64
87
  TESTCASE(implicit_conversion_to_value)
65
88
  {
66
- // g++ 3.3.3 can't handle constructor-style inside the assert, which
89
+ // Compilers (g++, msvc) can't handle constructor-style inside the assert, which
67
90
  // is why we use cast-style here.
68
91
  ASSERT_EQUAL(Qtrue, (VALUE)Object(Qtrue));
69
92
  ASSERT_EQUAL(INT2NUM(42), (VALUE)Object(INT2NUM(42)));
@@ -121,20 +144,11 @@ TESTCASE(is_frozen)
121
144
  ASSERT(o.is_frozen());
122
145
  }
123
146
 
124
- TESTCASE(swap)
125
- {
126
- Object o1(INT2NUM(42));
127
- Object o2(rb_ary_new());
128
- o1.swap(o2);
129
- ASSERT_EQUAL(to_ruby(42), o2);
130
- ASSERT_EQUAL(Class(rb_cArray), o1.class_of());
131
- }
132
-
133
147
  TESTCASE(instance_eval)
134
148
  {
135
149
  Object o(Class(rb_cObject).call("new"));
136
150
  o.iv_set("@foo", 42);
137
- ASSERT_EQUAL(to_ruby(42), o.instance_eval("@foo"));
151
+ ASSERT_EQUAL(detail::to_ruby(42), o.instance_eval("@foo").value());
138
152
  }
139
153
 
140
154
  TESTCASE(rb_type)
@@ -146,3 +160,21 @@ TESTCASE(rb_type)
146
160
  ASSERT_EQUAL(T_UNDEF, Object(Qundef).rb_type());
147
161
  }
148
162
 
163
+ TESTCASE(call_no_arguments)
164
+ {
165
+ Object three = Object(detail::to_ruby(3)).call("to_s");
166
+ ASSERT_EQUAL(String("3"), three);
167
+ }
168
+
169
+ TESTCASE(call_return_rice_object)
170
+ {
171
+ Object three = Object(detail::to_ruby(1)).call("+", 2);
172
+ ASSERT_EQUAL(Object(detail::to_ruby(3)), three);
173
+ }
174
+
175
+ /*TESTCASE(test_mark)
176
+ {
177
+ Object o(INT2NUM(42));
178
+ rb_gc_start();
179
+ ASSERT_EQUAL(42, detail::From_Ruby<int>::convert(o.value()));
180
+ }*/
@@ -0,0 +1,275 @@
1
+ #include "unittest.hpp"
2
+ #include "embed_ruby.hpp"
3
+ #include <rice/rice.hpp>
4
+
5
+ #include <memory>
6
+
7
+ using namespace Rice;
8
+
9
+ TESTSUITE(Ownership);
10
+
11
+ namespace
12
+ {
13
+ class MyClass
14
+ {
15
+ public:
16
+ static inline uint32_t constructorCalls = 0;
17
+ static inline uint32_t copyConstructorCalls = 0;
18
+ static inline uint32_t moveConstructorCalls = 0;
19
+ static inline uint32_t destructorCalls = 0;
20
+ static inline uint32_t methodCalls = 0;
21
+
22
+ static void reset()
23
+ {
24
+ constructorCalls = 0;
25
+ copyConstructorCalls = 0;
26
+ moveConstructorCalls = 0;
27
+ destructorCalls = 0;
28
+ methodCalls = 0;
29
+ }
30
+
31
+ public:
32
+ int flag = 0;
33
+
34
+ public:
35
+ MyClass()
36
+ {
37
+ constructorCalls++;
38
+ }
39
+
40
+ ~MyClass()
41
+ {
42
+ destructorCalls++;
43
+ }
44
+
45
+ MyClass(const MyClass& other): flag(other.flag)
46
+ {
47
+ copyConstructorCalls++;
48
+ }
49
+
50
+ MyClass(MyClass&& other) : flag(other.flag)
51
+ {
52
+ moveConstructorCalls++;
53
+ }
54
+
55
+ int32_t process()
56
+ {
57
+ methodCalls++;
58
+ return methodCalls;
59
+ }
60
+
61
+ void setFlag(int value)
62
+ {
63
+ this->flag = value;
64
+ }
65
+ };
66
+
67
+ class Factory
68
+ {
69
+ public:
70
+ static void reset()
71
+ {
72
+ delete Factory::instance_;
73
+ Factory::instance_ = nullptr;
74
+ }
75
+
76
+ public:
77
+ MyClass* transferPointer()
78
+ {
79
+ return new MyClass();
80
+ }
81
+
82
+ MyClass* keepPointer()
83
+ {
84
+ return this->instance();
85
+ }
86
+
87
+ MyClass& keepReference()
88
+ {
89
+ return *this->instance();
90
+ }
91
+
92
+ MyClass value()
93
+ {
94
+ return MyClass();
95
+ }
96
+
97
+ MyClass moveValue()
98
+ {
99
+ return std::move(MyClass());
100
+ }
101
+
102
+ MyClass* instance()
103
+ {
104
+ if (!instance_)
105
+ {
106
+ instance_ = new MyClass();
107
+ }
108
+ return instance_;
109
+ }
110
+
111
+ public:
112
+ static inline MyClass* instance_ = nullptr;
113
+ };
114
+ }
115
+
116
+ SETUP(Ownership)
117
+ {
118
+ embed_ruby();
119
+
120
+ define_class<MyClass>("MyClass").
121
+ define_method("process", &MyClass::process).
122
+ define_method("set_flag", &MyClass::setFlag);
123
+
124
+ define_class<Factory>("Factory").
125
+ define_constructor(Constructor<Factory>()).
126
+ define_method("value", &Factory::value).
127
+ define_method("move_value", &Factory::moveValue).
128
+ define_method("transfer_pointer", &Factory::transferPointer, Return().takeOwnership()).
129
+ define_method("keep_pointer", &Factory::keepPointer).
130
+ define_method("copy_reference", &Factory::keepReference, Return().takeOwnership()).
131
+ define_method("keep_reference", &Factory::keepReference);
132
+ }
133
+
134
+ TESTCASE(TransferPointer)
135
+ {
136
+ Factory::reset();
137
+ MyClass::reset();
138
+
139
+ Module m = define_module("TestingModule");
140
+
141
+ std::string code = R"(factory = Factory.new
142
+ 10.times do |i|
143
+ my_class = factory.transfer_pointer
144
+ my_class.set_flag(i)
145
+ my_class = nil
146
+ end)";
147
+
148
+ m.instance_eval(code);
149
+ rb_gc_start();
150
+
151
+ ASSERT_EQUAL(10, MyClass::constructorCalls);
152
+ ASSERT_EQUAL(0, MyClass::copyConstructorCalls);
153
+ ASSERT_EQUAL(0, MyClass::moveConstructorCalls);
154
+ ASSERT_EQUAL(10, MyClass::destructorCalls);
155
+ ASSERT(!Factory::instance_);
156
+ }
157
+
158
+ TESTCASE(KeepPointer)
159
+ {
160
+ Factory::reset();
161
+ MyClass::reset();
162
+
163
+ Module m = define_module("TestingModule");
164
+
165
+ // Create ruby objects that point to the same instance of MyClass
166
+ std::string code = R"(factory = Factory.new
167
+ 10.times do |i|
168
+ my_class = factory.keep_pointer
169
+ my_class.set_flag(i)
170
+ end)";
171
+
172
+ m.instance_eval(code);
173
+ rb_gc_start();
174
+
175
+ ASSERT_EQUAL(1, MyClass::constructorCalls);
176
+ ASSERT_EQUAL(0, MyClass::copyConstructorCalls);
177
+ ASSERT_EQUAL(0, MyClass::moveConstructorCalls);
178
+ ASSERT_EQUAL(0, MyClass::destructorCalls);
179
+ ASSERT_EQUAL(9, Factory::instance_->flag);
180
+ }
181
+
182
+ TESTCASE(KeepReference)
183
+ {
184
+ Factory::reset();
185
+ MyClass::reset();
186
+
187
+ Module m = define_module("TestingModule");
188
+
189
+ // Create ruby objects that point to the same instance of MyClass
190
+ std::string code = R"(factory = Factory.new
191
+ 10.times do |i|
192
+ my_class = factory.keep_reference
193
+ my_class.set_flag(i)
194
+ end)";
195
+
196
+ m.instance_eval(code);
197
+ rb_gc_start();
198
+
199
+ ASSERT_EQUAL(1, MyClass::constructorCalls);
200
+ ASSERT_EQUAL(0, MyClass::copyConstructorCalls);
201
+ ASSERT_EQUAL(0, MyClass::moveConstructorCalls);
202
+ ASSERT_EQUAL(0, MyClass::destructorCalls);
203
+ ASSERT_EQUAL(9, Factory::instance_->flag);
204
+ }
205
+
206
+ TESTCASE(CopyReference)
207
+ {
208
+ Factory::reset();
209
+ MyClass::reset();
210
+
211
+ Module m = define_module("TestingModule");
212
+
213
+ // Create ruby objects that point to the same instance of MyClass
214
+ std::string code = R"(factory = Factory.new
215
+ 10.times do |i|
216
+ my_class = factory.copy_reference
217
+ my_class.set_flag(i)
218
+ end)";
219
+
220
+ m.instance_eval(code);
221
+ rb_gc_start();
222
+
223
+ ASSERT_EQUAL(1, MyClass::constructorCalls);
224
+ ASSERT_EQUAL(0, MyClass::copyConstructorCalls);
225
+ ASSERT_EQUAL(10, MyClass::moveConstructorCalls);
226
+ ASSERT_EQUAL(10, MyClass::destructorCalls);
227
+ ASSERT_EQUAL(0, Factory::instance_->flag);
228
+ }
229
+
230
+ /*TESTCASE(TransferValue)
231
+ {
232
+ Factory::reset();
233
+ MyClass::reset();
234
+
235
+ Module m = define_module("TestingModule");
236
+
237
+ std::string code = R"(factory = Factory.new
238
+ 10.times do |i|
239
+ my_class = factory.value
240
+ my_class.set_flag(i)
241
+ end)";
242
+
243
+ m.instance_eval(code);
244
+ rb_gc_start();
245
+
246
+ ASSERT_EQUAL(10, MyClass::constructorCalls);
247
+ ASSERT_EQUAL(0, MyClass::copyConstructorCalls);
248
+ ASSERT_EQUAL(10, MyClass::moveConstructorCalls);
249
+ ASSERT_EQUAL(20, MyClass::destructorCalls);
250
+ ASSERT(!Factory::instance_);
251
+ }
252
+
253
+ TESTCASE(MoveValue)
254
+ {
255
+ Factory::reset();
256
+ MyClass::reset();
257
+
258
+ Module m = define_module("TestingModule");
259
+
260
+ std::string code = R"(factory = Factory.new
261
+ 10.times do |i|
262
+ my_class = factory.move_value
263
+ my_class.set_flag(i)
264
+ end)";
265
+
266
+ m.instance_eval(code);
267
+ rb_gc_start();
268
+
269
+ ASSERT_EQUAL(10, MyClass::constructorCalls);
270
+ ASSERT_EQUAL(0, MyClass::copyConstructorCalls);
271
+ ASSERT_EQUAL(20, MyClass::moveConstructorCalls);
272
+ ASSERT_EQUAL(30, MyClass::destructorCalls);
273
+ ASSERT(!Factory::instance_);
274
+ }
275
+ */
@@ -0,0 +1,205 @@
1
+ #include "unittest.hpp"
2
+ #include "embed_ruby.hpp"
3
+ #include <rice/rice.hpp>
4
+
5
+ #include <memory>
6
+
7
+ using namespace Rice;
8
+
9
+ TESTSUITE(Self);
10
+
11
+ namespace
12
+ {
13
+ class SelfClass
14
+ {
15
+ public:
16
+ static inline uint32_t constructorCalls = 0;
17
+ static inline uint32_t copyConstructorCalls = 0;
18
+ static inline uint32_t moveConstructorCalls = 0;
19
+ static inline uint32_t destructorCalls = 0;
20
+ static inline uint32_t methodCalls = 0;
21
+
22
+ static void reset()
23
+ {
24
+ constructorCalls = 0;
25
+ copyConstructorCalls = 0;
26
+ moveConstructorCalls = 0;
27
+ destructorCalls = 0;
28
+ methodCalls = 0;
29
+ }
30
+
31
+ public:
32
+ SelfClass()
33
+ {
34
+ constructorCalls++;
35
+ }
36
+
37
+ ~SelfClass()
38
+ {
39
+ destructorCalls++;
40
+ }
41
+
42
+ SelfClass(const SelfClass& other)
43
+ {
44
+ copyConstructorCalls++;
45
+ }
46
+
47
+ SelfClass(SelfClass&& other)
48
+ {
49
+ moveConstructorCalls++;
50
+ }
51
+
52
+ SelfClass* selfPointer()
53
+ {
54
+ return this;
55
+ }
56
+
57
+ SelfClass& selfReference()
58
+ {
59
+ return *this;
60
+ }
61
+
62
+ SelfClass selfValue()
63
+ {
64
+ return *this;
65
+ }
66
+ };
67
+ }
68
+
69
+ SETUP(Self)
70
+ {
71
+ embed_ruby();
72
+
73
+ define_class<SelfClass>("SelfClass").
74
+ define_constructor(Constructor<SelfClass>()).
75
+ define_method("self_reference", &SelfClass::selfReference).
76
+ define_method("self_pointer", &SelfClass::selfPointer).
77
+ define_method("self_value", &SelfClass::selfValue).
78
+ define_method("self_reference_lambda", [](SelfClass& self) -> SelfClass&
79
+ {
80
+ return self;
81
+ }).
82
+ define_method("self_pointer_lambda", [](SelfClass& self)
83
+ {
84
+ return &self;
85
+ }).
86
+ define_method("self_value_lambda", [](SelfClass& self)
87
+ {
88
+ return self;
89
+ });
90
+ }
91
+
92
+ TESTCASE(SelfPointer)
93
+ {
94
+ SelfClass::reset();
95
+
96
+ Module m = define_module("TestingModule");
97
+ Object selfClass1 = m.instance_eval("SelfClass.new");
98
+ Object selfClass2 = selfClass1.call("self_pointer");
99
+ ASSERT(selfClass2.is_equal(selfClass1));
100
+
101
+ SelfClass* pointer1 = detail::From_Ruby<SelfClass*>().convert(selfClass1);
102
+ SelfClass* pointer2 = detail::From_Ruby<SelfClass*>().convert(selfClass2);
103
+ ASSERT((pointer1 == pointer2));
104
+
105
+ ASSERT_EQUAL(1, SelfClass::constructorCalls);
106
+ ASSERT_EQUAL(0, SelfClass::copyConstructorCalls);
107
+ ASSERT_EQUAL(0, SelfClass::moveConstructorCalls);
108
+ ASSERT_EQUAL(0, SelfClass::destructorCalls);
109
+ }
110
+
111
+ TESTCASE(SelfReference)
112
+ {
113
+ SelfClass::reset();
114
+
115
+ Module m = define_module("TestingModule");
116
+ Object selfClass1 = m.instance_eval("SelfClass.new");
117
+ Object selfClass2 = selfClass1.call("self_reference");
118
+ ASSERT(selfClass2.is_equal(selfClass1));
119
+
120
+ SelfClass* pointer1 = detail::From_Ruby<SelfClass*>().convert(selfClass1);
121
+ SelfClass* pointer2 = detail::From_Ruby<SelfClass*>().convert(selfClass2);
122
+ ASSERT((pointer1 == pointer2));
123
+
124
+ ASSERT_EQUAL(1, SelfClass::constructorCalls);
125
+ ASSERT_EQUAL(0, SelfClass::copyConstructorCalls);
126
+ ASSERT_EQUAL(0, SelfClass::moveConstructorCalls);
127
+ ASSERT_EQUAL(0, SelfClass::destructorCalls);
128
+ }
129
+
130
+ TESTCASE(SelfValue)
131
+ {
132
+ SelfClass::reset();
133
+
134
+ Module m = define_module("TestingModule");
135
+ Object selfClass1 = m.instance_eval("SelfClass.new");
136
+ Object selfClass2 = selfClass1.call("self_value");
137
+ ASSERT(!selfClass2.is_equal(selfClass1));
138
+
139
+ SelfClass* pointer1 = detail::From_Ruby<SelfClass*>().convert(selfClass1);
140
+ SelfClass* pointer2 = detail::From_Ruby<SelfClass*>().convert(selfClass2);
141
+ ASSERT((pointer1 != pointer2));
142
+
143
+ ASSERT_EQUAL(1, SelfClass::constructorCalls);
144
+ ASSERT_EQUAL(1, SelfClass::copyConstructorCalls);
145
+ ASSERT_EQUAL(1, SelfClass::moveConstructorCalls);
146
+ ASSERT_EQUAL(1, SelfClass::destructorCalls);
147
+ }
148
+
149
+ TESTCASE(SelfPointerLambda)
150
+ {
151
+ SelfClass::reset();
152
+
153
+ Module m = define_module("TestingModule");
154
+ Object selfClass1 = m.instance_eval("SelfClass.new");
155
+ Object selfClass2 = selfClass1.call("self_pointer_lambda");
156
+ ASSERT(selfClass2.is_equal(selfClass1));
157
+
158
+ SelfClass* pointer1 = detail::From_Ruby<SelfClass*>().convert(selfClass1);
159
+ SelfClass* pointer2 = detail::From_Ruby<SelfClass*>().convert(selfClass2);
160
+ ASSERT((pointer1 == pointer2));
161
+
162
+ ASSERT_EQUAL(1, SelfClass::constructorCalls);
163
+ ASSERT_EQUAL(0, SelfClass::copyConstructorCalls);
164
+ ASSERT_EQUAL(0, SelfClass::moveConstructorCalls);
165
+ // TODO: re-enable this. It fails regularly on Ubuntu + Ruby 2.7, and nothing else.
166
+ // ASSERT_EQUAL(0, SelfClass::destructorCalls);
167
+ }
168
+
169
+ TESTCASE(SelfReferenceLambda)
170
+ {
171
+ SelfClass::reset();
172
+
173
+ Module m = define_module("TestingModule");
174
+ Object selfClass1 = m.instance_eval("SelfClass.new");
175
+ Object selfClass2 = selfClass1.call("self_reference_lambda");
176
+ ASSERT(selfClass2.is_equal(selfClass1));
177
+
178
+ SelfClass* pointer1 = detail::From_Ruby<SelfClass*>().convert(selfClass1);
179
+ SelfClass* pointer2 = detail::From_Ruby<SelfClass*>().convert(selfClass2);
180
+ ASSERT((pointer1 == pointer2));
181
+
182
+ ASSERT_EQUAL(1, SelfClass::constructorCalls);
183
+ ASSERT_EQUAL(0, SelfClass::copyConstructorCalls);
184
+ ASSERT_EQUAL(0, SelfClass::moveConstructorCalls);
185
+ ASSERT_EQUAL(0, SelfClass::destructorCalls);
186
+ }
187
+
188
+ TESTCASE(SelfValueLambda)
189
+ {
190
+ SelfClass::reset();
191
+
192
+ Module m = define_module("TestingModule");
193
+ Object selfClass1 = m.instance_eval("SelfClass.new");
194
+ Object selfClass2 = selfClass1.call("self_value_lambda");
195
+ ASSERT(!selfClass2.is_equal(selfClass1));
196
+
197
+ SelfClass* pointer1 = detail::From_Ruby<SelfClass*>().convert(selfClass1);
198
+ SelfClass* pointer2 = detail::From_Ruby<SelfClass*>().convert(selfClass2);
199
+ ASSERT((pointer1 != pointer2));
200
+
201
+ ASSERT_EQUAL(1, SelfClass::constructorCalls);
202
+ ASSERT_EQUAL(1, SelfClass::copyConstructorCalls);
203
+ ASSERT_EQUAL(1, SelfClass::moveConstructorCalls);
204
+ ASSERT_EQUAL(1, SelfClass::destructorCalls);
205
+ }