rice2 2.2.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 (190) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +23 -0
  3. data/Doxyfile +2268 -0
  4. data/Makefile.am +26 -0
  5. data/Makefile.in +929 -0
  6. data/README.md +1054 -0
  7. data/README.mingw +8 -0
  8. data/Rakefile +24 -0
  9. data/aclocal.m4 +1090 -0
  10. data/bootstrap +8 -0
  11. data/config.guess +1667 -0
  12. data/config.sub +1793 -0
  13. data/configure +8209 -0
  14. data/configure.ac +55 -0
  15. data/depcomp +791 -0
  16. data/doxygen.ac +314 -0
  17. data/doxygen.am +186 -0
  18. data/extconf.rb +66 -0
  19. data/install-sh +529 -0
  20. data/missing +215 -0
  21. data/post-autoconf.rb +22 -0
  22. data/post-automake.rb +28 -0
  23. data/rice/Address_Registration_Guard.cpp +22 -0
  24. data/rice/Address_Registration_Guard.hpp +7 -0
  25. data/rice/Address_Registration_Guard.ipp +37 -0
  26. data/rice/Address_Registration_Guard_defn.hpp +75 -0
  27. data/rice/Arg.hpp +8 -0
  28. data/rice/Arg_impl.hpp +129 -0
  29. data/rice/Arg_operators.cpp +21 -0
  30. data/rice/Arg_operators.hpp +19 -0
  31. data/rice/Array.hpp +214 -0
  32. data/rice/Array.ipp +256 -0
  33. data/rice/Builtin_Object.hpp +8 -0
  34. data/rice/Builtin_Object.ipp +50 -0
  35. data/rice/Builtin_Object_defn.hpp +50 -0
  36. data/rice/Class.cpp +57 -0
  37. data/rice/Class.hpp +8 -0
  38. data/rice/Class.ipp +6 -0
  39. data/rice/Class_defn.hpp +83 -0
  40. data/rice/Constructor.hpp +47 -0
  41. data/rice/Data_Object.hpp +8 -0
  42. data/rice/Data_Object.ipp +133 -0
  43. data/rice/Data_Object_defn.hpp +138 -0
  44. data/rice/Data_Type.cpp +54 -0
  45. data/rice/Data_Type.hpp +8 -0
  46. data/rice/Data_Type.ipp +365 -0
  47. data/rice/Data_Type_defn.hpp +261 -0
  48. data/rice/Data_Type_fwd.hpp +12 -0
  49. data/rice/Director.cpp +13 -0
  50. data/rice/Director.hpp +39 -0
  51. data/rice/Enum.hpp +117 -0
  52. data/rice/Enum.ipp +246 -0
  53. data/rice/Exception.cpp +59 -0
  54. data/rice/Exception.hpp +13 -0
  55. data/rice/Exception_Base.hpp +8 -0
  56. data/rice/Exception_Base.ipp +13 -0
  57. data/rice/Exception_Base_defn.hpp +27 -0
  58. data/rice/Exception_defn.hpp +69 -0
  59. data/rice/Hash.hpp +227 -0
  60. data/rice/Hash.ipp +329 -0
  61. data/rice/Identifier.cpp +8 -0
  62. data/rice/Identifier.hpp +50 -0
  63. data/rice/Identifier.ipp +33 -0
  64. data/rice/Jump_Tag.hpp +24 -0
  65. data/rice/Makefile.am +122 -0
  66. data/rice/Makefile.in +885 -0
  67. data/rice/Module.cpp +84 -0
  68. data/rice/Module.hpp +8 -0
  69. data/rice/Module.ipp +6 -0
  70. data/rice/Module_defn.hpp +88 -0
  71. data/rice/Module_impl.hpp +281 -0
  72. data/rice/Module_impl.ipp +345 -0
  73. data/rice/Object.cpp +169 -0
  74. data/rice/Object.hpp +8 -0
  75. data/rice/Object.ipp +33 -0
  76. data/rice/Object_defn.hpp +214 -0
  77. data/rice/Require_Guard.hpp +21 -0
  78. data/rice/String.cpp +94 -0
  79. data/rice/String.hpp +91 -0
  80. data/rice/Struct.cpp +117 -0
  81. data/rice/Struct.hpp +162 -0
  82. data/rice/Struct.ipp +26 -0
  83. data/rice/Symbol.cpp +25 -0
  84. data/rice/Symbol.hpp +66 -0
  85. data/rice/Symbol.ipp +44 -0
  86. data/rice/config.hpp +47 -0
  87. data/rice/config.hpp.in +46 -0
  88. data/rice/detail/Arguments.hpp +118 -0
  89. data/rice/detail/Auto_Function_Wrapper.hpp +898 -0
  90. data/rice/detail/Auto_Function_Wrapper.ipp +3694 -0
  91. data/rice/detail/Auto_Member_Function_Wrapper.hpp +897 -0
  92. data/rice/detail/Auto_Member_Function_Wrapper.ipp +2774 -0
  93. data/rice/detail/Caster.hpp +103 -0
  94. data/rice/detail/Exception_Handler.hpp +8 -0
  95. data/rice/detail/Exception_Handler.ipp +68 -0
  96. data/rice/detail/Exception_Handler_defn.hpp +96 -0
  97. data/rice/detail/Iterator.hpp +93 -0
  98. data/rice/detail/Not_Copyable.hpp +25 -0
  99. data/rice/detail/Wrapped_Function.hpp +33 -0
  100. data/rice/detail/cfp.hpp +24 -0
  101. data/rice/detail/cfp.ipp +51 -0
  102. data/rice/detail/check_ruby_type.cpp +27 -0
  103. data/rice/detail/check_ruby_type.hpp +23 -0
  104. data/rice/detail/creation_funcs.hpp +37 -0
  105. data/rice/detail/creation_funcs.ipp +36 -0
  106. data/rice/detail/default_allocation_func.hpp +23 -0
  107. data/rice/detail/default_allocation_func.ipp +11 -0
  108. data/rice/detail/define_method_and_auto_wrap.hpp +31 -0
  109. data/rice/detail/define_method_and_auto_wrap.ipp +30 -0
  110. data/rice/detail/demangle.cpp +56 -0
  111. data/rice/detail/demangle.hpp +19 -0
  112. data/rice/detail/env.hpp +11 -0
  113. data/rice/detail/from_ruby.hpp +43 -0
  114. data/rice/detail/from_ruby.ipp +60 -0
  115. data/rice/detail/method_data.cpp +92 -0
  116. data/rice/detail/method_data.hpp +21 -0
  117. data/rice/detail/node.hpp +13 -0
  118. data/rice/detail/protect.cpp +29 -0
  119. data/rice/detail/protect.hpp +34 -0
  120. data/rice/detail/ruby.hpp +74 -0
  121. data/rice/detail/ruby_version_code.hpp +6 -0
  122. data/rice/detail/ruby_version_code.hpp.in +6 -0
  123. data/rice/detail/st.hpp +22 -0
  124. data/rice/detail/to_ruby.hpp +22 -0
  125. data/rice/detail/to_ruby.ipp +36 -0
  126. data/rice/detail/traits.hpp +43 -0
  127. data/rice/detail/win32.hpp +16 -0
  128. data/rice/detail/wrap_function.hpp +66 -0
  129. data/rice/global_function.hpp +33 -0
  130. data/rice/global_function.ipp +22 -0
  131. data/rice/protect.hpp +38 -0
  132. data/rice/protect.ipp +1134 -0
  133. data/rice/ruby_mark.hpp +13 -0
  134. data/rice/ruby_try_catch.hpp +86 -0
  135. data/rice/rubypp.rb +97 -0
  136. data/rice/to_from_ruby.hpp +8 -0
  137. data/rice/to_from_ruby.ipp +418 -0
  138. data/rice/to_from_ruby_defn.hpp +70 -0
  139. data/ruby.ac +135 -0
  140. data/ruby/Makefile.am +1 -0
  141. data/ruby/Makefile.in +628 -0
  142. data/ruby/lib/Makefile.am +3 -0
  143. data/ruby/lib/Makefile.in +506 -0
  144. data/ruby/lib/mkmf-rice.rb.in +217 -0
  145. data/ruby/lib/version.rb +3 -0
  146. data/sample/Makefile.am +47 -0
  147. data/sample/Makefile.in +489 -0
  148. data/sample/enum/extconf.rb +3 -0
  149. data/sample/enum/sample_enum.cpp +54 -0
  150. data/sample/enum/test.rb +8 -0
  151. data/sample/inheritance/animals.cpp +98 -0
  152. data/sample/inheritance/extconf.rb +3 -0
  153. data/sample/inheritance/test.rb +7 -0
  154. data/sample/map/extconf.rb +3 -0
  155. data/sample/map/map.cpp +81 -0
  156. data/sample/map/test.rb +7 -0
  157. data/test/Makefile.am +72 -0
  158. data/test/Makefile.in +1213 -0
  159. data/test/ext/Makefile.am +41 -0
  160. data/test/ext/Makefile.in +483 -0
  161. data/test/ext/t1/Foo.hpp +10 -0
  162. data/test/ext/t1/extconf.rb +2 -0
  163. data/test/ext/t1/t1.cpp +15 -0
  164. data/test/ext/t2/extconf.rb +2 -0
  165. data/test/ext/t2/t2.cpp +11 -0
  166. data/test/test_Address_Registration_Guard.cpp +43 -0
  167. data/test/test_Array.cpp +248 -0
  168. data/test/test_Builtin_Object.cpp +71 -0
  169. data/test/test_Class.cpp +496 -0
  170. data/test/test_Constructor.cpp +128 -0
  171. data/test/test_Data_Object.cpp +275 -0
  172. data/test/test_Data_Type.cpp +348 -0
  173. data/test/test_Director.cpp +308 -0
  174. data/test/test_Enum.cpp +215 -0
  175. data/test/test_Exception.cpp +47 -0
  176. data/test/test_Hash.cpp +212 -0
  177. data/test/test_Identifier.cpp +70 -0
  178. data/test/test_Jump_Tag.cpp +17 -0
  179. data/test/test_Memory_Management.cpp +50 -0
  180. data/test/test_Module.cpp +497 -0
  181. data/test/test_Object.cpp +159 -0
  182. data/test/test_String.cpp +107 -0
  183. data/test/test_Struct.cpp +205 -0
  184. data/test/test_Symbol.cpp +63 -0
  185. data/test/test_To_From_Ruby.cpp +428 -0
  186. data/test/test_global_functions.cpp +114 -0
  187. data/test/test_rice.rb +41 -0
  188. data/test/unittest.cpp +136 -0
  189. data/test/unittest.hpp +294 -0
  190. metadata +297 -0
@@ -0,0 +1,128 @@
1
+ #include "unittest.hpp"
2
+ #include "rice/Constructor.hpp"
3
+ #include "rice/Data_Type.hpp"
4
+
5
+ #include "rice/detail/env.hpp"
6
+
7
+ #include <iostream>
8
+ using namespace std;
9
+
10
+ using namespace Rice;
11
+
12
+ TESTSUITE(Constructor);
13
+
14
+ namespace
15
+ {
16
+ class Default_Constructible
17
+ {
18
+ public:
19
+ Default_Constructible()
20
+ {
21
+ }
22
+ };
23
+ }
24
+
25
+ TESTCASE(default_constructor)
26
+ {
27
+ Data_Type<Default_Constructible> rb_cDefault_Constructible(
28
+ anonymous_class());
29
+ rb_cDefault_Constructible
30
+ .define_constructor(Constructor<Default_Constructible>());
31
+ Object o = rb_cDefault_Constructible.call("new");
32
+ ASSERT_EQUAL(rb_cDefault_Constructible, o.class_of());
33
+ }
34
+
35
+
36
+ namespace
37
+ {
38
+ class Non_Default_Constructible
39
+ {
40
+ public:
41
+ Non_Default_Constructible(int i)
42
+ : i_(i)
43
+ {
44
+ }
45
+
46
+ int i() const
47
+ {
48
+ return i_;
49
+ }
50
+
51
+ private:
52
+ int i_;
53
+ };
54
+ }
55
+
56
+ TESTCASE(non_default_constructor)
57
+ {
58
+ Data_Type<Non_Default_Constructible> rb_cNon_Default_Constructible(
59
+ anonymous_class());
60
+ rb_cNon_Default_Constructible
61
+ .define_constructor(Constructor<Non_Default_Constructible, int>());
62
+ Data_Object<Non_Default_Constructible> o =
63
+ rb_cNon_Default_Constructible.call("new", 42);
64
+ ASSERT_EQUAL(rb_cNon_Default_Constructible, o.class_of());
65
+ ASSERT_EQUAL(42, o->i());
66
+ }
67
+
68
+ namespace
69
+ {
70
+ int withArgsX;
71
+ float withArgsY;
72
+ bool withArgsYes;
73
+
74
+ class WithDefaultArgs
75
+ {
76
+ public:
77
+ WithDefaultArgs(int x, float y = 2.0, bool yes = false)
78
+ {
79
+ withArgsX = x;
80
+ withArgsY = y;
81
+ withArgsYes = yes;
82
+ }
83
+ };
84
+
85
+ int withArgX;
86
+ class WithOneArg
87
+ {
88
+ public:
89
+ WithOneArg(int x = 14) {
90
+ withArgX = x;
91
+ }
92
+ };
93
+ }
94
+
95
+ TESTCASE(constructor_supports_default_arguments)
96
+ {
97
+ Class klass = define_class<WithDefaultArgs>("WithDefaultArgs").
98
+ define_constructor(Constructor<WithDefaultArgs, int, float, bool>(),
99
+ ( Arg("x"), Arg("y") = (float)2.0, Arg("yes") = (bool)false ));
100
+
101
+ klass.call("new", 4);
102
+ ASSERT_EQUAL(4, withArgsX);
103
+ ASSERT_EQUAL(2.0, withArgsY);
104
+ ASSERT_EQUAL(false, withArgsYes);
105
+
106
+ klass.call("new", 5, 3.0);
107
+ ASSERT_EQUAL(5, withArgsX);
108
+ ASSERT_EQUAL(3.0, withArgsY);
109
+ ASSERT_EQUAL(false, withArgsYes);
110
+
111
+ klass.call("new", 7, 12.0, true);
112
+ ASSERT_EQUAL(7, withArgsX);
113
+ ASSERT_EQUAL(12.0, withArgsY);
114
+ ASSERT_EQUAL(true, withArgsYes);
115
+ }
116
+
117
+ TESTCASE(constructor_supports_single_default_argument)
118
+ {
119
+ Class klass = define_class<WithOneArg>("WithOneArg").
120
+ define_constructor(Constructor<WithOneArg, int>(),
121
+ ( Arg("x") = 14 ));
122
+
123
+ klass.call("new");
124
+ ASSERT_EQUAL(14, withArgX);
125
+
126
+ klass.call("new", 6);
127
+ ASSERT_EQUAL(6, withArgX);
128
+ }
@@ -0,0 +1,275 @@
1
+ #include "unittest.hpp"
2
+ #include "rice/Data_Object.hpp"
3
+ #include "rice/Data_Type.hpp"
4
+ #include "rice/Exception.hpp"
5
+
6
+ using namespace Rice;
7
+
8
+ TESTSUITE(Data_Object);
9
+
10
+ namespace
11
+ {
12
+ struct Foo { Foo() : x_(42) { } int x_; };
13
+
14
+ bool test_ruby_mark__marked = false;
15
+ }
16
+
17
+ template<>
18
+ void ruby_mark(Foo * foo)
19
+ {
20
+ test_ruby_mark__marked = true;
21
+ }
22
+
23
+ SETUP(Data_Object)
24
+ {
25
+ ruby_init();
26
+
27
+ if(!Data_Type<Foo>::is_bound())
28
+ {
29
+ Class object(rb_cObject);
30
+ if(object.const_defined("Foo"))
31
+ {
32
+ object.remove_const("Foo");
33
+ }
34
+
35
+ define_class<Foo>("Foo");
36
+ }
37
+ }
38
+
39
+ TESTCASE(construct_from_pointer_with_defaults)
40
+ {
41
+ Data_Type<Foo> rb_cFoo;
42
+ Foo * foo = new Foo;
43
+ Data_Object<Foo> wrapped_foo(foo);
44
+ ASSERT_EQUAL(foo, wrapped_foo.get());
45
+ ASSERT_EQUAL(Data_Type<Foo>::klass(), wrapped_foo.class_of());
46
+ typedef void (*Mark_Func)(void *);
47
+ typedef void (*Mark_Func_Foo)(Foo *);
48
+ Mark_Func expected_mark_func =
49
+ Mark_Func(Mark_Func_Foo(ruby_mark<Foo>));
50
+ ASSERT_EQUAL(
51
+ expected_mark_func,
52
+ RDATA(wrapped_foo.value())->dmark);
53
+ ASSERT_EQUAL(
54
+ RUBY_DATA_FUNC(Default_Free_Function<Foo>::free),
55
+ RUBY_DATA_FUNC(RDATA(wrapped_foo.value())->dfree));
56
+ ASSERT_EQUAL(foo, DATA_PTR(wrapped_foo.value()));
57
+ }
58
+
59
+ TESTCASE(construct_from_pointer_and_klass)
60
+ {
61
+ Data_Type<Foo> rb_cFoo;
62
+ Foo * foo = new Foo;
63
+ Data_Object<Foo> wrapped_foo(foo, Data_Type<Foo>::klass());
64
+ ASSERT_EQUAL(foo, wrapped_foo.get());
65
+ ASSERT_EQUAL(Data_Type<Foo>::klass(), wrapped_foo.class_of());
66
+ typedef void (*Mark_Func)(void *);
67
+ typedef void (*Mark_Func_Foo)(Foo *);
68
+ Mark_Func expected_mark_func =
69
+ Mark_Func(Mark_Func_Foo(ruby_mark<Foo>));
70
+ ASSERT_EQUAL(
71
+ expected_mark_func,
72
+ RDATA(wrapped_foo.value())->dmark);
73
+ ASSERT_EQUAL(
74
+ RUBY_DATA_FUNC(Default_Free_Function<Foo>::free),
75
+ RUBY_DATA_FUNC(RDATA(wrapped_foo.value())->dfree));
76
+ ASSERT_EQUAL(foo, DATA_PTR(wrapped_foo.value()));
77
+ }
78
+
79
+ TESTCASE(construct_from_pointer_and_alternate_klass)
80
+ {
81
+ Data_Type<Foo> rb_cFoo;
82
+ Foo * foo = new Foo;
83
+ Data_Object<Foo> wrapped_foo(foo, rb_cObject);
84
+ ASSERT_EQUAL(foo, wrapped_foo.get());
85
+ ASSERT_EQUAL(rb_cObject, CLASS_OF(wrapped_foo.value()));
86
+ typedef void (*Mark_Func)(void *);
87
+ typedef void (*Mark_Func_Foo)(Foo *);
88
+ Mark_Func expected_mark_func =
89
+ Mark_Func(Mark_Func_Foo(ruby_mark<Foo>));
90
+ ASSERT_EQUAL(
91
+ expected_mark_func,
92
+ RDATA(wrapped_foo.value())->dmark);
93
+ ASSERT_EQUAL(
94
+ RUBY_DATA_FUNC(Default_Free_Function<Foo>::free),
95
+ RUBY_DATA_FUNC(RDATA(wrapped_foo.value())->dfree));
96
+ ASSERT_EQUAL(foo, DATA_PTR(wrapped_foo.value()));
97
+ }
98
+
99
+ namespace
100
+ {
101
+ void dummy_mark(Foo *)
102
+ {
103
+ }
104
+ }
105
+
106
+ TESTCASE(construct_from_pointer_and_klass_and_mark_function)
107
+ {
108
+ Data_Type<Foo> rb_cFoo;
109
+ Foo * foo = new Foo;
110
+ Data_Object<Foo> wrapped_foo(foo, rb_cFoo, dummy_mark);
111
+ ASSERT_EQUAL(foo, wrapped_foo.get());
112
+ ASSERT_EQUAL(Data_Type<Foo>::klass(), wrapped_foo.class_of());
113
+ ASSERT_EQUAL((void *)dummy_mark, RDATA(wrapped_foo.value())->dmark);
114
+ ASSERT_EQUAL(
115
+ RUBY_DATA_FUNC(Default_Free_Function<Foo>::free),
116
+ RUBY_DATA_FUNC(RDATA(wrapped_foo.value())->dfree));
117
+ ASSERT_EQUAL(foo, DATA_PTR(wrapped_foo.value()));
118
+ }
119
+
120
+ namespace
121
+ {
122
+ void my_free(Foo * f)
123
+ {
124
+ delete f;
125
+ }
126
+ }
127
+
128
+ TESTCASE(construct_from_pointer_and_klass_and_mark_and_free)
129
+ {
130
+ Data_Type<Foo> rb_cFoo;
131
+ Foo * foo = new Foo;
132
+ Data_Object<Foo> wrapped_foo(foo, rb_cFoo, dummy_mark, my_free);
133
+ ASSERT_EQUAL(foo, wrapped_foo.get());
134
+ ASSERT_EQUAL(Data_Type<Foo>::klass(), wrapped_foo.class_of());
135
+ ASSERT_EQUAL((void *)dummy_mark, RDATA(wrapped_foo.value())->dmark);
136
+ ASSERT_EQUAL(
137
+ RUBY_DATA_FUNC(my_free),
138
+ RUBY_DATA_FUNC(RDATA(wrapped_foo.value())->dfree));
139
+ ASSERT_EQUAL(foo, DATA_PTR(wrapped_foo.value()));
140
+ }
141
+
142
+ TESTCASE(construct_from_ruby_object)
143
+ {
144
+ Foo * foo = new Foo;
145
+ VALUE wrapped_foo = Data_Wrap_Struct(Data_Type<Foo>::klass(), 0, Default_Free_Function<Foo>::free, foo);
146
+ Data_Object<Foo> data_object_foo(wrapped_foo);
147
+ ASSERT_EQUAL(foo, data_object_foo.get());
148
+ ASSERT_EQUAL(Data_Type<Foo>::klass(), data_object_foo.class_of());
149
+ ASSERT_EQUAL(RDATA(wrapped_foo), RDATA(data_object_foo.value()));
150
+ ASSERT_EQUAL(RUBY_DATA_FUNC(0), RDATA(data_object_foo.value())->dmark);
151
+ ASSERT_EQUAL(
152
+ RUBY_DATA_FUNC(Default_Free_Function<Foo>::free),
153
+ RUBY_DATA_FUNC(RDATA(data_object_foo.value())->dfree));
154
+ ASSERT_EQUAL(foo, DATA_PTR(data_object_foo.value()));
155
+ }
156
+
157
+ TESTCASE(construct_from_ruby_object_and_class)
158
+ {
159
+ Data_Type<Foo> rb_cFoo;
160
+ Foo * foo = new Foo;
161
+ VALUE wrapped_foo = Data_Wrap_Struct(Data_Type<Foo>::klass(), 0, Default_Free_Function<Foo>::free, foo);
162
+ Data_Object<Foo> data_object_foo(wrapped_foo, rb_cFoo);
163
+ ASSERT_EQUAL(foo, data_object_foo.get());
164
+ ASSERT_EQUAL(Data_Type<Foo>::klass(), data_object_foo.class_of());
165
+ ASSERT_EQUAL(RDATA(wrapped_foo), RDATA(data_object_foo.value()));
166
+ ASSERT_EQUAL(RUBY_DATA_FUNC(0), RDATA(data_object_foo.value())->dmark);
167
+ ASSERT_EQUAL(
168
+ RUBY_DATA_FUNC(Default_Free_Function<Foo>::free),
169
+ RUBY_DATA_FUNC(RDATA(data_object_foo.value())->dfree));
170
+ ASSERT_EQUAL(foo, DATA_PTR(data_object_foo.value()));
171
+ }
172
+
173
+ TESTCASE(construct_from_ruby_object_and_wrong_class)
174
+ {
175
+ Foo * foo = new Foo;
176
+ Data_Type<Foo> rb_cFoo;
177
+ VALUE wrapped_foo = Data_Wrap_Struct(rb_cObject, 0, Default_Free_Function<Foo>::free, foo);
178
+ ASSERT_EXCEPTION_CHECK(
179
+ Exception,
180
+ Data_Object<Foo> data_object_foo(wrapped_foo, rb_cFoo),
181
+ ASSERT_EQUAL(
182
+ Object(rb_eTypeError),
183
+ Object(CLASS_OF(ex.value()))
184
+ )
185
+ );
186
+ }
187
+
188
+ TESTCASE(copy_construct)
189
+ {
190
+ Data_Type<Foo> rb_cFoo;
191
+ Foo * foo = new Foo;
192
+ VALUE wrapped_foo = Data_Wrap_Struct(Data_Type<Foo>::klass(), 0, Default_Free_Function<Foo>::free, foo);
193
+ Data_Object<Foo> orig_data_object_foo(wrapped_foo, rb_cFoo);
194
+ Data_Object<Foo> data_object_foo(orig_data_object_foo);
195
+ ASSERT_EQUAL(foo, data_object_foo.get());
196
+ ASSERT_EQUAL(Data_Type<Foo>::klass(), data_object_foo.class_of());
197
+ ASSERT_EQUAL(RDATA(wrapped_foo), RDATA(data_object_foo.value()));
198
+ ASSERT_EQUAL(RUBY_DATA_FUNC(0), RDATA(data_object_foo.value())->dmark);
199
+ ASSERT_EQUAL(
200
+ RUBY_DATA_FUNC(Default_Free_Function<Foo>::free),
201
+ RUBY_DATA_FUNC(RDATA(data_object_foo.value())->dfree));
202
+ ASSERT_EQUAL(foo, DATA_PTR(data_object_foo.value()));
203
+ }
204
+
205
+ TESTCASE(dereference)
206
+ {
207
+ Data_Type<Foo> rb_cFoo;
208
+ Foo * foo = new Foo;
209
+ Data_Object<Foo> wrapped_foo(foo);
210
+ ASSERT_EQUAL(foo, &*wrapped_foo);
211
+ }
212
+
213
+ TESTCASE(arrow)
214
+ {
215
+ Data_Type<Foo> rb_cFoo;
216
+ Foo * foo = new Foo;
217
+ Data_Object<Foo> wrapped_foo(foo);
218
+ ASSERT_EQUAL(42, foo->x_);
219
+ }
220
+
221
+ TESTCASE(get)
222
+ {
223
+ Data_Type<Foo> rb_cFoo;
224
+ Foo * foo = new Foo;
225
+ Data_Object<Foo> wrapped_foo(foo);
226
+ ASSERT_EQUAL(foo, wrapped_foo.get());
227
+ }
228
+
229
+ // TODO: swap
230
+
231
+ TESTCASE(to_ruby)
232
+ {
233
+ Data_Type<Foo> rb_cFoo;
234
+ Foo * foo = new Foo;
235
+ Data_Object<Foo> wrapped_foo(foo);
236
+ ASSERT_EQUAL(wrapped_foo.value(), to_ruby(wrapped_foo).value());
237
+ }
238
+
239
+ TESTCASE(from_ruby)
240
+ {
241
+ Data_Type<Foo> rb_cFoo;
242
+ Foo * foo = new Foo;
243
+ Data_Object<Foo> wrapped_foo(foo);
244
+ ASSERT_EQUAL(foo, from_ruby<Foo *>(wrapped_foo));
245
+ }
246
+
247
+ TESTCASE(from_ruby_const_ref)
248
+ {
249
+ Data_Type<Foo> rb_cFoo;
250
+ Foo * foo = new Foo;
251
+ Data_Object<Foo> wrapped_foo(foo);
252
+ ASSERT_EQUAL(foo->x_, from_ruby<Foo const &>(wrapped_foo).x_);
253
+ }
254
+
255
+ TESTCASE(from_ruby_copy)
256
+ {
257
+ Data_Type<Foo> rb_cFoo;
258
+ Foo * foo = new Foo;
259
+ Data_Object<Foo> wrapped_foo(foo);
260
+ ASSERT_EQUAL(foo->x_, from_ruby<Foo>(wrapped_foo).x_);
261
+ }
262
+
263
+ TESTCASE(ruby_mark)
264
+ {
265
+ Data_Type<Foo> rb_cFoo;
266
+ Foo * foo = new Foo;
267
+ Data_Object<Foo> wrapped_foo(foo);
268
+
269
+ test_ruby_mark__marked = false;
270
+
271
+ rb_gc_start();
272
+
273
+ ASSERT_EQUAL(true, test_ruby_mark__marked);
274
+ }
275
+
@@ -0,0 +1,348 @@
1
+ #include "unittest.hpp"
2
+ #include "rice/Data_Type.hpp"
3
+ #include "rice/Exception.hpp"
4
+ #include "rice/Constructor.hpp"
5
+ #include "rice/global_function.hpp"
6
+
7
+ using namespace Rice;
8
+
9
+ TESTSUITE(Data_Type);
10
+
11
+ /**
12
+ * The tests here are for the feature of taking an instance
13
+ * of a Ruby-subclass of a Rice wrapped class and passing
14
+ * that instance back into the Rice wrapper. While that
15
+ * might be confusing, the test code is pretty straight foward
16
+ * to see what we're talking about.
17
+ */
18
+
19
+ namespace {
20
+
21
+ /**
22
+ * The class we will subclass in Ruby
23
+ */
24
+ class Listener {
25
+ public:
26
+ Listener() { }
27
+
28
+ virtual ~Listener() { }
29
+
30
+ virtual int getValue() { return 4; }
31
+ };
32
+
33
+ /**
34
+ * This class will recieve a new Listener instance
35
+ * from Ruby
36
+ */
37
+ class ListenerHandler {
38
+
39
+ public:
40
+
41
+ ListenerHandler() { }
42
+
43
+ void addListener(Listener* newList) {
44
+ mListeners.push_back(newList);
45
+ }
46
+
47
+ int process() {
48
+ std::vector<Listener*>::iterator i = mListeners.begin();
49
+ int accum = 0;
50
+ for(; i != mListeners.end(); i++) {
51
+ accum += (*i)->getValue();
52
+ }
53
+
54
+ return accum;
55
+ }
56
+
57
+ size_t listenerCount() { return mListeners.size(); }
58
+
59
+ private:
60
+ std::vector<Listener*> mListeners;
61
+ };
62
+ }
63
+
64
+ SETUP(Data_Type)
65
+ {
66
+ ruby_init();
67
+
68
+ define_class<Listener>("Listener")
69
+ .define_constructor(Constructor<Listener>())
70
+ .define_method("get_value", &Listener::getValue);
71
+
72
+ define_class<ListenerHandler>("ListenerHandler")
73
+ .define_constructor(Constructor<ListenerHandler>())
74
+ .define_method("add_listener", &ListenerHandler::addListener)
75
+ .define_method("process", &ListenerHandler::process)
76
+ .define_method("listener_count", &ListenerHandler::listenerCount);
77
+
78
+ }
79
+
80
+ TESTCASE(can_send_ruby_instance_back_into_rice)
81
+ {
82
+ Module m = define_module("TestingModule");
83
+ Object handler = m.instance_eval("@handler = ListenerHandler.new");
84
+
85
+ ASSERT_EQUAL(INT2NUM(0), handler.call("listener_count").value());
86
+
87
+ m.instance_eval("class MyListener < Listener; end;");
88
+ m.instance_eval("@handler.add_listener(MyListener.new)");
89
+
90
+ ASSERT_EQUAL(INT2NUM(1), handler.call("listener_count").value());
91
+ ASSERT_EQUAL(INT2NUM(4), handler.call("process").value());
92
+
93
+ m.instance_eval("@handler.add_listener(Listener.new)");
94
+
95
+ ASSERT_EQUAL(INT2NUM(2), handler.call("listener_count").value());
96
+ ASSERT_EQUAL(INT2NUM(8), handler.call("process").value());
97
+ }
98
+
99
+ /**
100
+ * The following test SEGFAULTs right now
101
+ */
102
+ /*
103
+ TESTCASE(no_super_in_constructor_still_works)
104
+ {
105
+ Module m = define_module("TestingModule");
106
+ Object handler = m.instance_eval("@handler = ListenerHandler.new");
107
+
108
+ ASSERT_EQUAL(INT2NUM(0), handler.call("listener_count").value());
109
+
110
+ // Because of this, there's a constructor but no super call
111
+ m.instance_eval("class MyListener < Listener; def initialize; @val = 10; end; end;");
112
+ m.instance_eval("@handler.add_listener(MyListener.new)");
113
+
114
+ ASSERT_EQUAL(INT2NUM(1), handler.call("listener_count").value());
115
+ ASSERT_EQUAL(INT2NUM(4), handler.call("process").value());
116
+
117
+ m.instance_eval("@handler.add_listener(MyListener.new)");
118
+
119
+ ASSERT_EQUAL(INT2NUM(2), handler.call("listener_count").value());
120
+ ASSERT_EQUAL(INT2NUM(8), handler.call("process").value());
121
+ }
122
+ */
123
+
124
+ /**
125
+ * Implicit Casting across unrelated types
126
+ *
127
+ * Two ways of defining if types are implicitly castable
128
+ *
129
+ * 1) operator
130
+ * 2) constructor
131
+ */
132
+
133
+ /**
134
+ * Examples here taken from Ogre's Math library.
135
+ * This uses the constructor method of casting types.
136
+ */
137
+ namespace
138
+ {
139
+ const int degree2Radians = (3.14 / 180.0);
140
+ const int radian2Degrees = (180.0 / 3.14);
141
+
142
+ class Radian;
143
+
144
+ class Degree
145
+ {
146
+ public:
147
+ explicit Degree(float d) : val_(d) {}
148
+ Degree(const Radian& r);
149
+
150
+ float valueDegrees() const { return val_; }
151
+ float valueRadians() const { return val_ * degree2Radians; }
152
+
153
+ private:
154
+ float val_;
155
+ };
156
+
157
+ class Radian
158
+ {
159
+ public:
160
+ explicit Radian(float r) : val_(r) {}
161
+ Radian(const Degree& d) : val_(d.valueRadians()) {}
162
+
163
+ float valueRadians() const { return val_; }
164
+ float valueDegrees() const { return val_ * radian2Degrees; }
165
+
166
+ private:
167
+ float val_;
168
+ };
169
+
170
+ // Due to circular dependencies, need to define some
171
+ // methods down here
172
+ Degree::Degree(const Radian& r)
173
+ {
174
+ val_ = r.valueDegrees();
175
+ }
176
+
177
+ /**
178
+ * And now some methods that work w/ the above two classes
179
+ */
180
+ bool isAcute(Degree degree) {
181
+ return degree.valueDegrees() < 90;
182
+ }
183
+
184
+ bool isObtuse(Radian radian) {
185
+ return radian.valueDegrees() > 90 && radian.valueDegrees() <= 180;
186
+ }
187
+
188
+ bool isRight(Degree* degree) {
189
+ return degree->valueDegrees() == 90;
190
+ }
191
+ }
192
+
193
+ TESTCASE(can_define_implicit_type_conversions_across_wrapped_types)
194
+ {
195
+ define_class<Degree>("Degree")
196
+ .define_constructor(Constructor<Degree, float>());
197
+
198
+ define_class<Radian>("Radian")
199
+ .define_constructor(Constructor<Radian, float>());
200
+
201
+ define_implicit_cast<Degree, Radian>();
202
+ define_implicit_cast<Radian, Degree>();
203
+
204
+ define_global_function("is_acute", &isAcute);
205
+ define_global_function("is_obtuse", &isObtuse);
206
+ define_global_function("is_right", &isRight);
207
+
208
+ Module m = define_module("TestingModule");
209
+ Object result;
210
+
211
+ // ACUTE
212
+ result = m.instance_eval("is_acute(Degree.new(75))");
213
+ ASSERT(from_ruby<bool>(result.value()));
214
+
215
+ result = m.instance_eval("is_acute(Radian.new(2.0))");
216
+ ASSERT(!from_ruby<bool>(result.value()));
217
+
218
+ // OBTUSE
219
+ result = m.instance_eval("is_obtuse(Degree.new(75))");
220
+ ASSERT(!from_ruby<bool>(result.value()));
221
+
222
+ result = m.instance_eval("is_obtuse(Radian.new(2.0))");
223
+ ASSERT(from_ruby<bool>(result.value()));
224
+
225
+ // RIGHT
226
+ result = m.instance_eval("is_right(Degree.new(90))");
227
+ ASSERT(from_ruby<bool>(result.value()));
228
+
229
+ result = m.instance_eval("is_right(Radian.new(2.0))");
230
+ ASSERT(!from_ruby<bool>(result.value()));
231
+ }
232
+
233
+ namespace {
234
+ class Explicit
235
+ {
236
+ public:
237
+ Explicit(float v) {
238
+ value = v;
239
+ }
240
+
241
+ Explicit(const Degree &d) {
242
+ value = d.valueDegrees();
243
+ }
244
+
245
+ float getValue() { return value; }
246
+
247
+ private:
248
+ float value;
249
+ };
250
+
251
+ float getExplicitValue(Explicit* v) {
252
+ return v->getValue();
253
+ }
254
+ }
255
+
256
+ TESTCASE(supports_multiple_implicit_conversions_for_a_type)
257
+ {
258
+ define_class<Degree>("Degree")
259
+ .define_constructor(Constructor<Degree, float>());
260
+
261
+ define_class<Radian>("Radian")
262
+ .define_constructor(Constructor<Radian, float>());
263
+
264
+ define_class<Explicit>("Explicit")
265
+ .define_constructor(Constructor<Explicit, float>());
266
+
267
+ define_global_function("is_obtuse", &isObtuse);
268
+ define_global_function("explicit_value", &getExplicitValue);
269
+
270
+ define_implicit_cast<Radian, Degree>();
271
+ define_implicit_cast<Degree, Radian>();
272
+ define_implicit_cast<Degree, Explicit>();
273
+
274
+ Module m = define_module("TestingModule");
275
+ Object result;
276
+
277
+ result = m.instance_eval("is_obtuse(Degree.new(75))");
278
+ ASSERT(!from_ruby<bool>(result.value()));
279
+
280
+ result = m.instance_eval("explicit_value(Degree.new(75))");
281
+ ASSERT_EQUAL(75.0, from_ruby<float>(result.value()));
282
+ }
283
+
284
+ /**
285
+ * Sample taken and modified from boost::python::implicit:
286
+ * http://www.boost.org/doc/libs/1_41_0/libs/python/doc/v2/implicit.html
287
+ *
288
+ * This is the operator version of casting and shows that this works for
289
+ * base types as well as defined types
290
+ */
291
+ /*
292
+ namespace {
293
+ struct Real
294
+ {
295
+ Real(int x)
296
+ : v(x)
297
+ {}
298
+
299
+ operator int() const
300
+ {
301
+ return v;
302
+ }
303
+
304
+ int v;
305
+ };
306
+
307
+ int realValue(Real const& x)
308
+ {
309
+ return x.v;
310
+ }
311
+
312
+ Real makeReal(int n)
313
+ {
314
+ return Real(n);
315
+ }
316
+ }
317
+
318
+ TESTCASE(can_define_implicit_type_conversions_to_base_types)
319
+ {
320
+ define_class<Real>("Real")
321
+ .define_constructor(Constructor<Real, int>());
322
+
323
+ // Define the conversion rules
324
+ define_implicit_cast<Real, int>();
325
+ define_implicit_cast<int, Real>();
326
+
327
+ define_global_function("real_value", &realValue);
328
+ define_global_function("make_real", &makeReal);
329
+
330
+ Module m = define_module("TestingModule");
331
+
332
+ // As Real object
333
+ Object result = m.instance_eval("real_value( Real.new(4) )");
334
+ ASSERT_EQUAL(4, from_ruby<int>(result.value()));
335
+
336
+ // As fixnum (int)
337
+ result = m.instance_eval("real_value(4)");
338
+ ASSERT_EQUAL(4, from_ruby<int>(result.value()));
339
+
340
+ // As Real object
341
+ result = m.instance_eval("r = make_real( Real.new(6) ); real_value(r)");
342
+ ASSERT_EQUAL(6, from_ruby<int>(result.value()));
343
+
344
+ // As fixnum (int)
345
+ result = m.instance_eval("r = make_real(6); real_value(r)");
346
+ ASSERT_EQUAL(6, from_ruby<int>(result.value()));
347
+ }
348
+ */