rice 1.2.0 → 1.3.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 (65) hide show
  1. data/Doxyfile +1 -1
  2. data/Makefile.in +130 -52
  3. data/README +45 -79
  4. data/Rakefile +1 -36
  5. data/aclocal.m4 +133 -61
  6. data/config.guess +43 -8
  7. data/config.sub +41 -13
  8. data/configure +1370 -1898
  9. data/configure.ac +2 -2
  10. data/doxygen.ac +1 -1
  11. data/extconf.rb +3 -1
  12. data/rice/Arg_impl.hpp +2 -2
  13. data/rice/Data_Type.cpp +34 -1
  14. data/rice/Data_Type.ipp +14 -5
  15. data/rice/Data_Type_defn.hpp +28 -1
  16. data/rice/Director.cpp +0 -6
  17. data/rice/Director.hpp +0 -8
  18. data/rice/Hash.hpp +1 -1
  19. data/rice/Makefile.am +2 -12
  20. data/rice/Makefile.in +111 -88
  21. data/rice/Object.cpp +8 -1
  22. data/rice/Object.ipp +1 -1
  23. data/rice/Object_defn.hpp +8 -0
  24. data/rice/config.hpp +3 -0
  25. data/rice/config.hpp.in +3 -0
  26. data/rice/detail/Auto_Function_Wrapper.ipp +1025 -512
  27. data/rice/detail/Auto_Member_Function_Wrapper.ipp +545 -272
  28. data/rice/detail/cfp.hpp +24 -0
  29. data/rice/detail/cfp.ipp +51 -0
  30. data/rice/detail/method_data.cpp +107 -336
  31. data/rice/detail/node.hpp +13 -13
  32. data/rice/detail/ruby.hpp +4 -0
  33. data/rice/detail/rubysig.hpp +19 -19
  34. data/rice/detail/traits.hpp +43 -0
  35. data/rice/generate_code.rb +37 -16
  36. data/rice/protect.hpp +1 -1
  37. data/rice/protect.ipp +448 -192
  38. data/rice/to_from_ruby.ipp +4 -12
  39. data/rice/to_from_ruby_defn.hpp +2 -2
  40. data/ruby/Makefile.in +99 -32
  41. data/ruby/lib/Makefile.in +61 -21
  42. data/ruby/lib/mkmf-rice.rb.in +9 -2
  43. data/ruby/lib/version.rb +1 -1
  44. data/sample/Makefile.in +33 -10
  45. data/test/Makefile.am +27 -0
  46. data/test/Makefile.in +270 -59
  47. data/test/ext/Makefile.am +43 -0
  48. data/test/ext/Makefile.in +399 -0
  49. data/test/ext/t1/Foo.hpp +10 -0
  50. data/test/ext/t1/extconf.rb +2 -0
  51. data/test/ext/t1/t1.cpp +15 -0
  52. data/test/ext/t2/extconf.rb +2 -0
  53. data/test/ext/t2/t2.cpp +11 -0
  54. data/test/test_Allocation_Strategies.cpp +1 -1
  55. data/test/test_Class.cpp +79 -0
  56. data/test/test_Data_Type.cpp +2 -2
  57. data/test/test_Director.cpp +114 -38
  58. data/test/test_Module.cpp +27 -2
  59. data/test/test_To_From_Ruby.cpp +4 -4
  60. data/test/test_rice.rb +9 -1
  61. metadata +23 -8
  62. data/rice/detail/method_data.cpp.rpp +0 -301
  63. data/rice/detail/mininode.cpp.rpp +0 -62
  64. data/rice/detail/mininode.hpp.rpp +0 -119
  65. data/rice/detail/remove_const.hpp +0 -21
@@ -0,0 +1,2 @@
1
+ require 'mkmf-rice'
2
+ create_makefile('t1')
@@ -0,0 +1,15 @@
1
+ #include "Foo.hpp"
2
+
3
+ #include "rice/Data_Type.hpp"
4
+ #include "rice/Constructor.hpp"
5
+
6
+ using namespace Rice;
7
+
8
+ extern "C"
9
+ void Init_t1()
10
+ {
11
+ define_class<Foo>("Foo")
12
+ .define_constructor(Constructor<Foo>())
13
+ .define_method("foo", &Foo::foo);
14
+ }
15
+
@@ -0,0 +1,2 @@
1
+ require 'mkmf-rice'
2
+ create_makefile('t2')
@@ -0,0 +1,11 @@
1
+ #include "../t1/Foo.hpp"
2
+ #include "rice/Data_Type.hpp"
3
+
4
+ using namespace Rice;
5
+
6
+ extern "C"
7
+ void Init_t2()
8
+ {
9
+ volatile Data_Type<Foo> foo;
10
+ }
11
+
@@ -67,7 +67,7 @@ TESTCASE(xmalloc_allocation_strategy_allocate)
67
67
 
68
68
  TESTCASE(xmalloc_allocation_strategy_free)
69
69
  {
70
- Foo * t = new Foo;
70
+ Foo * t = Xmalloc_Allocation_Strategy<Foo>::allocate();
71
71
  ASSERT(constructor_called);
72
72
  ASSERT(!destructor_called);
73
73
  Xmalloc_Allocation_Strategy<Foo>::free(t);
@@ -396,3 +396,82 @@ TESTCASE(subclassing)
396
396
  m.instance_eval("class NewClass < Testing::BaseClass; end;");
397
397
  m.instance_eval("n = NewClass.new");
398
398
  }
399
+
400
+ namespace
401
+ {
402
+ int defaults_method_one_arg1;
403
+ int defaults_method_one_arg2;
404
+ bool defaults_method_one_arg3 = false;
405
+
406
+ class DefaultArgs
407
+ {
408
+ public:
409
+ void defaults_method_one(int arg1, int arg2 = 3, bool arg3 = true)
410
+ {
411
+ defaults_method_one_arg1 = arg1;
412
+ defaults_method_one_arg2 = arg2;
413
+ defaults_method_one_arg3 = arg3;
414
+ }
415
+ };
416
+ }
417
+
418
+ TESTCASE(define_method_default_arguments)
419
+ {
420
+ Class c = define_class<DefaultArgs>("DefaultArgs")
421
+ .define_constructor(Constructor<DefaultArgs>())
422
+ .define_method("with_defaults",
423
+ &DefaultArgs::defaults_method_one,
424
+ (Arg("arg1"), Arg("arg2") = 3, Arg("arg3") = true));
425
+
426
+ Object o = c.call("new");
427
+ o.call("with_defaults", 2);
428
+
429
+ ASSERT_EQUAL(2, defaults_method_one_arg1);
430
+ ASSERT_EQUAL(3, defaults_method_one_arg2);
431
+ ASSERT(defaults_method_one_arg3);
432
+
433
+ o.call("with_defaults", 11, 10);
434
+
435
+ ASSERT_EQUAL(11, defaults_method_one_arg1);
436
+ ASSERT_EQUAL(10, defaults_method_one_arg2);
437
+ ASSERT(defaults_method_one_arg3);
438
+
439
+ o.call("with_defaults", 22, 33, false);
440
+
441
+ ASSERT_EQUAL(22, defaults_method_one_arg1);
442
+ ASSERT_EQUAL(33, defaults_method_one_arg2);
443
+ ASSERT(!defaults_method_one_arg3);
444
+ }
445
+
446
+ /*
447
+ namespace {
448
+ float with_reference_defaults_x;
449
+ std::string with_reference_defaults_str;
450
+
451
+ class DefaultArgsRefs
452
+ {
453
+ public:
454
+ void with_reference_defaults(float x, std::string const& str = std::string("testing"))
455
+ {
456
+ with_reference_defaults_x = x;
457
+ with_reference_defaults_str = str;
458
+ }
459
+ };
460
+
461
+ }
462
+
463
+ TESTCASE(define_method_works_with_reference_const_default_values)
464
+ {
465
+ Class c = define_class<DefaultArgsRefs>("DefaultArgsRefs")
466
+ .define_constructor(Constructor<DefaultArgsRefs>())
467
+ .define_method("bar",
468
+ &DefaultArgsRefs::with_reference_defaults,
469
+ (Arg("x"), Arg("str") = std::string("testing")));
470
+
471
+ Object o = c.call("new");
472
+ o.call("bar", 3);
473
+
474
+ ASSERT_EQUAL(3, with_reference_defaults_x);
475
+ ASSERT_EQUAL("testing", with_reference_defaults_str);
476
+ }
477
+ */
@@ -44,7 +44,7 @@ namespace {
44
44
  }
45
45
 
46
46
  int process() {
47
- vector<Listener*>::iterator i = mListeners.begin();
47
+ std::vector<Listener*>::iterator i = mListeners.begin();
48
48
  int accum = 0;
49
49
  for(; i != mListeners.end(); i++) {
50
50
  accum += (*i)->getValue();
@@ -56,7 +56,7 @@ namespace {
56
56
  int listenerCount() { return mListeners.size(); }
57
57
 
58
58
  private:
59
- vector<Listener*> mListeners;
59
+ std::vector<Listener*> mListeners;
60
60
  };
61
61
  }
62
62
 
@@ -65,20 +65,20 @@ namespace {
65
65
  public:
66
66
  WorkerDirector(Object self) : Director(self) { }
67
67
 
68
- int process(int num) {
69
- if(callIsFromRuby("process")) {
70
- raisePureVirtual();
71
- } else {
72
- return from_ruby<int>( getSelf().call("process", num) );
73
- }
68
+ virtual int process(int num) {
69
+ return from_ruby<int>( getSelf().call("process", num) );
74
70
  }
75
71
 
76
- int doSomething(int num) {
77
- if(callIsFromRuby("do_something")) {
78
- return this->Worker::doSomething(num);
79
- } else {
80
- return from_ruby<int>( getSelf().call("do_something", num) );
81
- }
72
+ int default_process(int num) {
73
+ raisePureVirtual();
74
+ }
75
+
76
+ virtual int doSomething(int num) {
77
+ return from_ruby<int>( getSelf().call("do_something", num) );
78
+ }
79
+
80
+ int default_doSomething(int num) {
81
+ return Worker::doSomething(num);
82
82
  }
83
83
  };
84
84
  };
@@ -86,15 +86,12 @@ namespace {
86
86
  SETUP(Director)
87
87
  {
88
88
  ruby_init();
89
-
90
- // Always need to tell Rice about the base class so that
91
- // casting works correctly
92
- define_class<Worker>("__Worker__");
93
89
  }
94
90
 
95
91
  TESTCASE(exposes_worker_as_instantiatable_class)
96
92
  {
97
- define_class<WorkerDirector, Worker>("Worker")
93
+ define_class<Worker>("Worker")
94
+ .define_director<WorkerDirector>()
98
95
  .define_constructor(Constructor<WorkerDirector, Object>())
99
96
  .define_method("get_number", &Worker::getNumber);
100
97
 
@@ -106,10 +103,11 @@ TESTCASE(exposes_worker_as_instantiatable_class)
106
103
 
107
104
  TESTCASE(can_call_virtual_methods_on_base_class)
108
105
  {
109
- define_class<WorkerDirector, Worker>("Worker")
106
+ define_class<Worker>("Worker")
107
+ .define_director<WorkerDirector>()
110
108
  .define_constructor(Constructor<WorkerDirector, Object>())
111
109
  .define_method("get_number", &Worker::getNumber)
112
- .define_method("do_something", &WorkerDirector::doSomething);
110
+ .define_method("do_something", &WorkerDirector::default_doSomething);
113
111
 
114
112
  Module m = define_module("Testing");
115
113
 
@@ -120,9 +118,10 @@ TESTCASE(can_call_virtual_methods_on_base_class)
120
118
 
121
119
  TESTCASE(super_calls_pass_execution_up_the_inheritance_chain)
122
120
  {
123
- define_class<WorkerDirector, Worker>("Worker")
121
+ define_class<Worker>("Worker")
122
+ .define_director<WorkerDirector>()
124
123
  .define_constructor(Constructor<WorkerDirector, Object>())
125
- .define_method("do_something", &WorkerDirector::doSomething);
124
+ .define_method("do_something", &WorkerDirector::default_doSomething);
126
125
 
127
126
  Module m = define_module("Testing");
128
127
  m.instance_eval("class RubyWorker < Worker; def do_something(num); super * num; end; end");
@@ -134,9 +133,10 @@ TESTCASE(super_calls_pass_execution_up_the_inheritance_chain)
134
133
 
135
134
  TESTCASE(super_calls_on_pure_virtual_raise_error)
136
135
  {
137
- define_class<WorkerDirector, Worker>("Worker")
136
+ define_class<Worker>("Worker")
137
+ .define_director<WorkerDirector>()
138
138
  .define_constructor(Constructor<WorkerDirector, Object>())
139
- .define_method("process", &WorkerDirector::process);
139
+ .define_method("process", &WorkerDirector::default_process);
140
140
 
141
141
  Module m = define_module("Testing");
142
142
  m.instance_eval("class RubyWorker < Worker; def process(num); super; end; end");
@@ -158,21 +158,22 @@ TESTCASE(polymorphic_calls_head_down_the_call_chain)
158
158
  .define_method("add_worker", &Handler::addWorker)
159
159
  .define_method("process_workers", &Handler::processWorkers);
160
160
 
161
- define_class<WorkerDirector, Worker>("Worker")
161
+ define_class<Worker>("Worker")
162
+ .define_director<WorkerDirector>()
162
163
  .define_constructor(Constructor<WorkerDirector, Object>())
163
- .define_method("process", &WorkerDirector::process);
164
+ .define_method("process", &WorkerDirector::default_process);
164
165
 
165
166
  Module m = define_module("Testing");
166
167
 
167
168
  m.instance_eval(
168
169
  "class EchoWorker < Worker; def process(num); num + 2; end; end;"
169
170
  "class DoubleWorker < Worker; def process(num); num * 2; end; end;"
170
- "handler = Handler.new;"
171
- "handler.add_worker(EchoWorker.new);"
172
- "handler.add_worker(DoubleWorker.new);"
171
+ "$handler = Handler.new;"
172
+ "$handler.add_worker(EchoWorker.new);"
173
+ "$handler.add_worker(DoubleWorker.new);"
173
174
  );
174
175
 
175
- Object result = m.instance_eval("handler.process_workers(5)");
176
+ Object result = m.instance_eval("$handler.process_workers(5)");
176
177
 
177
178
  // Hit's EchoWorker, so 5 + 2, then passes that to DoubleWorker, so 7 * 2 = 14
178
179
  ASSERT_EQUAL(14, from_ruby<int>(result.value()));
@@ -195,23 +196,42 @@ namespace {
195
196
  CallsSelfDirector(Object self) : Director(self) { }
196
197
 
197
198
  virtual int doItImpl(int in) {
198
- if(!callIsFromRuby("do_it_impl")) {
199
- return 0;
200
- } else {
201
- return from_ruby<int>( getSelf().call("do_it_impl", in) );
202
- }
199
+ return from_ruby<int>( getSelf().call("do_it_impl", in) );
200
+ }
201
+
202
+ int default_doItImpl(int in) {
203
+ raisePureVirtual();
203
204
  }
204
205
  };
205
206
 
207
+ struct MyCallsSelf : CallsSelf {
208
+ MyCallsSelf() { }
209
+
210
+ int doItImpl(int in) { return in * 12; }
211
+ };
212
+
213
+ // Abstract type return types handled properly
214
+ CallsSelf* getCallsSelf() {
215
+ return new MyCallsSelf();
216
+ }
217
+
218
+ // Abstract type Argument types handled properly
219
+ int doItOnPointer(CallsSelf* obj, int in) {
220
+ return obj->doIt(in);
221
+ }
222
+
223
+ int doItOnReference(CallsSelf& obj, int in) {
224
+ return obj.doIt(in);
225
+ }
226
+
206
227
  }
207
228
 
208
229
  TESTCASE(mix_of_polymorphic_calls_and_inheritance_dont_cause_infinite_loops)
209
230
  {
210
- define_class<CallsSelf>("__CallsSelf__");
211
-
212
- define_class<CallsSelfDirector, CallsSelf>("CallsSelf")
231
+ define_class<CallsSelf>("CallsSelf")
232
+ .define_director<CallsSelfDirector>()
213
233
  .define_constructor(Constructor<CallsSelfDirector, Rice::Object>())
214
- .define_method("do_it_impl", &CallsSelfDirector::doItImpl)
234
+ .define_method("do_it_impl", &CallsSelfDirector::default_doItImpl)
215
235
  .define_method("do_it", &CallsSelf::doIt);
216
236
 
217
237
  Module m = define_module("Testing");
@@ -223,3 +243,59 @@ TESTCASE(mix_of_polymorphic_calls_and_inheritance_dont_cause_infinite_loops)
223
243
 
224
244
  ASSERT_EQUAL(100, from_ruby<int>(result.value()));
225
245
  }
246
+
247
+ TESTCASE(director_class_super_classes_get_type_bound)
248
+ {
249
+ Module m = define_module("Testing");
250
+ m.define_module_function("get_calls_self", &getCallsSelf);
251
+
252
+ define_class<CallsSelf>("CallsSelf")
253
+ .define_director<CallsSelfDirector>()
254
+ .define_constructor(Constructor<CallsSelfDirector, Rice::Object>())
255
+ .define_method("do_it_impl", &CallsSelfDirector::default_doItImpl)
256
+ .define_method("do_it", &CallsSelf::doIt);
257
+
258
+ Object result = m.instance_eval("cs = Testing::get_calls_self; cs.do_it(3);");
259
+ ASSERT_EQUAL(36, from_ruby<int>(result.value()));
260
+ }
261
+
262
+ TESTCASE(director_allows_abstract_types_used_as_parameters_pointers)
263
+ {
264
+ Module m = define_module("Testing");
265
+ m.define_module_function("do_it_on_pointer", &doItOnPointer);
266
+
267
+ define_class<CallsSelf>("CallsSelf")
268
+ .define_director<CallsSelfDirector>()
269
+ .define_constructor(Constructor<CallsSelfDirector, Rice::Object>())
270
+ .define_method("do_it_impl", &CallsSelfDirector::default_doItImpl)
271
+ .define_method("do_it", &CallsSelf::doIt);
272
+
273
+ Object result = m.instance_eval(
274
+ "class MySelf < CallsSelf; def do_it_impl(num); num * 10; end; end;"
275
+ "c = MySelf.new;"
276
+ "Testing::do_it_on_pointer(c, 5)"
277
+ );
278
+
279
+ ASSERT_EQUAL(50, from_ruby<int>(result.value()));
280
+ }
281
+ /*
282
+ TESTCASE(director_allows_abstract_types_used_as_parameters_reference)
283
+ {
284
+ Module m = define_module("Testing");
285
+ m.define_module_function("do_it_on_ref", &doItOnReference);
286
+
287
+ define_class<CallsSelf>("CallsSelf")
288
+ .define_director<CallsSelfDirector>()
289
+ .define_constructor(Constructor<CallsSelfDirector, Rice::Object>())
290
+ .define_method("do_it_impl", &CallsSelfDirector::default_doItImpl)
291
+ .define_method("do_it", &CallsSelf::doIt);
292
+
293
+ Object result = m.instance_eval(
294
+ "class MySelf < CallsSelf; def do_it_impl(num); num * 10; end; end;"
295
+ "c = MySelf.new;"
296
+ "Testing::do_it_on_ref(c, 3)"
297
+ );
298
+
299
+ ASSERT_EQUAL(30, from_ruby<int>(result.value()));
300
+ }
301
+ */
@@ -179,12 +179,12 @@ Foo * from_ruby<Foo *>(Object x)
179
179
  TESTCASE(define_singleton_method_int_foo)
180
180
  {
181
181
  Module m(anonymous_module());
182
- m.define_singleton_method("foo", define_method_int_foo_helper);
182
+ m.define_singleton_method("int_and_foo", define_method_int_foo_helper);
183
183
  define_method_int_result = 0;
184
184
  Foo * foo = new Foo;
185
185
  foo->x = 1024;
186
186
  VALUE f = Data_Wrap_Struct(rb_cObject, 0, Default_Allocation_Strategy<Foo>::free, foo);
187
- m.call("foo", 42, Object(f));
187
+ m.call("int_and_foo", 42, Object(f));
188
188
  ASSERT_EQUAL(42, define_method_int_foo_result_i);
189
189
  ASSERT_EQUAL(foo, define_method_int_foo_result_x);
190
190
  }
@@ -426,3 +426,28 @@ TESTCASE(define_method_works_with_reference_arguments)
426
426
  ASSERT_EQUAL("test", with_defaults_and_references_x);
427
427
  ASSERT(!with_defaults_and_references_doIt);
428
428
  }
429
+
430
+ /*
431
+ namespace {
432
+ float with_reference_defaults_x;
433
+ std::string with_reference_defaults_str;
434
+
435
+ void with_reference_defaults(float x, std::string const& str = std::string("testing"))
436
+ {
437
+ with_reference_defaults_x = x;
438
+ with_reference_defaults_str = str;
439
+ }
440
+ }
441
+
442
+ TESTCASE(define_method_works_with_reference_const_default_values)
443
+ {
444
+ Module m(anonymous_module());
445
+ m.define_module_function("bar", &with_reference_defaults,
446
+ (Arg("x"), Arg("str") = std::string("testing")));
447
+
448
+ m.call("bar", 3);
449
+
450
+ ASSERT_EQUAL(3, with_reference_defaults_x);
451
+ ASSERT_EQUAL("testing", with_reference_defaults_str);
452
+ }
453
+ */
@@ -188,9 +188,9 @@ TESTCASE(float_from_ruby)
188
188
  std::numeric_limits<float>::max(),
189
189
  from_ruby<float>(rb_float_new(std::numeric_limits<float>::max())));
190
190
  ASSERT(
191
- isnan(from_ruby<float>(rb_float_new(std::numeric_limits<float>::quiet_NaN()))));
191
+ std::isnan(from_ruby<float>(rb_float_new(std::numeric_limits<float>::quiet_NaN()))));
192
192
  ASSERT(
193
- isnan(from_ruby<float>(rb_float_new(std::numeric_limits<float>::signaling_NaN()))));
193
+ std::isnan(from_ruby<float>(rb_float_new(std::numeric_limits<float>::signaling_NaN()))));
194
194
  ASSERT_EQUAL(
195
195
  std::numeric_limits<float>::epsilon(),
196
196
  from_ruby<float>(rb_float_new(std::numeric_limits<float>::epsilon())));
@@ -229,9 +229,9 @@ TESTCASE(double_from_ruby)
229
229
  std::numeric_limits<double>::max(),
230
230
  from_ruby<double>(rb_float_new(std::numeric_limits<double>::max())));
231
231
  ASSERT(
232
- isnan(from_ruby<double>(rb_float_new(std::numeric_limits<double>::quiet_NaN()))));
232
+ std::isnan(from_ruby<double>(rb_float_new(std::numeric_limits<double>::quiet_NaN()))));
233
233
  ASSERT(
234
- isnan(from_ruby<double>(rb_float_new(std::numeric_limits<double>::signaling_NaN()))));
234
+ std::isnan(from_ruby<double>(rb_float_new(std::numeric_limits<double>::signaling_NaN()))));
235
235
  ASSERT_EQUAL(
236
236
  std::numeric_limits<double>::epsilon(),
237
237
  from_ruby<double>(rb_float_new(std::numeric_limits<double>::epsilon())));
@@ -16,10 +16,18 @@ class RiceTest < Test::Unit::TestCase
16
16
  run_external_test("./vm_unittest#{EXEEXT}")
17
17
  end
18
18
 
19
- def test_vm_unittest
19
+ def test_multiple_extensions
20
20
  run_external_test("#{RUBY} test_multiple_extensions.rb")
21
21
  end
22
22
 
23
+ def test_multiple_extensions_with_inheritance
24
+ run_external_test("#{RUBY} test_multiple_extensions_with_inheritance.rb")
25
+ end
26
+
27
+ def test_multiple_extensions_same_class
28
+ run_external_test("#{RUBY} test_multiple_extensions_same_class.rb")
29
+ end
30
+
23
31
  def run_external_test(executable)
24
32
  if VERBOSE then
25
33
  system(executable)