rice 4.8.0 → 4.9.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.
@@ -29,6 +29,8 @@ namespace
29
29
 
30
30
  public:
31
31
  int flag = 0;
32
+ std::string name = "default";
33
+ int threshold = 0;
32
34
 
33
35
  public:
34
36
  MyClass()
@@ -57,6 +59,17 @@ namespace
57
59
  }
58
60
  };
59
61
 
62
+ class MyClassInherited : public MyClass
63
+ {
64
+ public:
65
+ int extra = 0;
66
+
67
+ void setExtra(int value)
68
+ {
69
+ this->extra = value;
70
+ }
71
+ };
72
+
60
73
  class Factory
61
74
  {
62
75
  public:
@@ -87,6 +100,11 @@ namespace
87
100
  return instance_;
88
101
  }
89
102
 
103
+ std::shared_ptr<MyClassInherited> share_inherited()
104
+ {
105
+ return std::make_shared<MyClassInherited>();
106
+ }
107
+
90
108
  public:
91
109
  static inline std::shared_ptr<MyClass> instance_;
92
110
  };
@@ -138,12 +156,20 @@ SETUP(SharedPtr)
138
156
 
139
157
  define_class<MyClass>("MyClass").
140
158
  define_constructor(Constructor<MyClass>()).
141
- define_method("set_flag", &MyClass::setFlag);
159
+ define_method("set_flag", &MyClass::setFlag).
160
+ define_attr("name", &MyClass::name, Rice::AttrAccess::Read).
161
+ define_attr("threshold", &MyClass::threshold);
162
+
163
+ define_class<MyClassInherited, MyClass>("MyClassInherited").
164
+ define_constructor(Constructor<MyClassInherited>()).
165
+ define_method("set_extra", &MyClassInherited::setExtra).
166
+ define_attr("extra", &MyClassInherited::extra);
142
167
 
143
168
  define_class<Factory>("Factory").
144
169
  define_constructor(Constructor<Factory>()).
145
170
  define_method("share", &Factory::share).
146
- define_method("share_ref", &Factory::share_ref);
171
+ define_method("share_ref", &Factory::share_ref).
172
+ define_method("share_inherited", &Factory::share_inherited);
147
173
 
148
174
  define_class<Sink>("Sink").
149
175
  define_constructor(Constructor<Sink>()).
@@ -173,8 +199,8 @@ TEARDOWN(SharedPtr)
173
199
 
174
200
  TESTCASE(ShareOwnership)
175
201
  {
176
- MyClass::reset();
177
202
  Factory::reset();
203
+ MyClass::reset();
178
204
 
179
205
  Module m = define_module("TestingModule");
180
206
 
@@ -182,9 +208,9 @@ TESTCASE(ShareOwnership)
182
208
  std::string code = R"(ary = Array.new
183
209
  factory = Factory.new
184
210
  10.times do |i|
185
- ptr = factory.share
186
- ptr.get.set_flag(i)
187
- ary << ptr
211
+ my_class = factory.share
212
+ my_class.set_flag(i)
213
+ ary << my_class
188
214
  end)";
189
215
 
190
216
  ASSERT_EQUAL(0, Factory::instance_.use_count());
@@ -203,43 +229,44 @@ TESTCASE(ShareOwnership)
203
229
 
204
230
  TESTCASE(ShareOwnership2)
205
231
  {
206
- MyClass::reset();
207
232
  Factory::reset();
233
+ MyClass::reset();
208
234
 
209
235
  Module m = define_module("TestingModule");
210
236
 
211
237
  // Create ruby objects that point to the same instance of MyClass
212
238
  std::string code = R"(factory = Factory.new
213
239
  10.times do |i|
214
- ptr = factory.share
215
- ptr.get.set_flag(i)
240
+ my_class = factory.share
241
+ my_class.set_flag(i)
216
242
  end)";
217
243
 
218
- Factory factory;
219
- std::shared_ptr<MyClass> myClass = factory.share();
220
- ASSERT_EQUAL(2, Factory::instance_.use_count());
221
-
222
- // Call some ruby code
223
- Data_Object<Factory> wrapper(factory);
224
- ASSERT_EQUAL(2, Factory::instance_.use_count());
225
- wrapper.instance_eval("share_ref.get.set_flag(1)");
244
+ ASSERT_EQUAL(0, Factory::instance_.use_count());
245
+ m.module_eval(code);
226
246
 
227
- ASSERT_EQUAL(2, Factory::instance_.use_count());
247
+ ASSERT_EQUAL(11, Factory::instance_.use_count());
228
248
  rb_gc_start();
229
- ASSERT_EQUAL(2, Factory::instance_.use_count());
249
+ ASSERT_EQUAL(1, Factory::instance_.use_count());
250
+
251
+ ASSERT_EQUAL(1, MyClass::constructorCalls);
252
+ ASSERT_EQUAL(0, MyClass::copyConstructorCalls);
253
+ ASSERT_EQUAL(0, MyClass::moveConstructorCalls);
254
+ ASSERT_EQUAL(0, MyClass::destructorCalls);
255
+ ASSERT_EQUAL(9, Factory::instance_->flag);
256
+
230
257
  }
231
258
 
232
259
  TESTCASE(PtrParameter)
233
260
  {
234
- MyClass::reset();
235
261
  Factory::reset();
262
+ MyClass::reset();
236
263
 
237
264
  Module m = define_module("TestingModule");
238
265
 
239
266
  std::string code = R"(factory = Factory.new
240
- ptr = factory.share
241
- ptr.get.set_flag(8)
242
- extract_flag_shared_ptr(ptr))";
267
+ my_class = factory.share
268
+ my_class.set_flag(8)
269
+ extract_flag_shared_ptr(my_class))";
243
270
 
244
271
  Object result = m.module_eval(code);
245
272
  ASSERT_EQUAL(8, detail::From_Ruby<int>().convert(result));
@@ -247,15 +274,15 @@ TESTCASE(PtrParameter)
247
274
 
248
275
  TESTCASE(RefParameter)
249
276
  {
250
- MyClass::reset();
251
277
  Factory::reset();
278
+ MyClass::reset();
252
279
 
253
280
  Module m = define_module("TestingModule");
254
281
 
255
282
  std::string code = R"(factory = Factory.new
256
- ptr = factory.share
257
- ptr.get.set_flag(9)
258
- extract_flag_shared_ptr_ref(ptr))";
283
+ my_class = factory.share
284
+ my_class.set_flag(9)
285
+ extract_flag_shared_ptr_ref(my_class))";
259
286
 
260
287
  Object result = m.module_eval(code);
261
288
  ASSERT_EQUAL(9, detail::From_Ruby<int>().convert(result));
@@ -263,14 +290,14 @@ TESTCASE(RefParameter)
263
290
 
264
291
  TESTCASE(DefaultParameter)
265
292
  {
266
- MyClass::reset();
267
293
  Factory::reset();
294
+ MyClass::reset();
268
295
 
269
296
  Module m = define_module("TestingModule");
270
297
 
271
298
  std::string code = R"(factory = Factory.new
272
- ptr = factory.share
273
- ptr.get.set_flag(7)
299
+ my_class = factory.share
300
+ my_class.set_flag(7)
274
301
  extract_flag_shared_ptr_with_default())";
275
302
 
276
303
  Object result = m.module_eval(code);
@@ -280,14 +307,14 @@ TESTCASE(DefaultParameter)
280
307
 
281
308
  TESTCASE(RefDefaultParameter)
282
309
  {
283
- MyClass::reset();
284
310
  Factory::reset();
311
+ MyClass::reset();
285
312
 
286
313
  Module m = define_module("TestingModule");
287
314
 
288
315
  std::string code = R"(factory = Factory.new
289
- ptr = factory.share
290
- ptr.get.set_flag(7)
316
+ my_class = factory.share
317
+ my_class.set_flag(7)
291
318
  extract_flag_shared_ptr_ref_with_default())";
292
319
 
293
320
  Object result = m.module_eval(code);
@@ -299,13 +326,13 @@ TESTCASE(RefDefaultParameter)
299
326
  ASSERT_EQUAL(1, MyClass::constructorCalls);
300
327
  ASSERT_EQUAL(0, MyClass::copyConstructorCalls);
301
328
  ASSERT_EQUAL(0, MyClass::moveConstructorCalls);
302
- ASSERT_EQUAL(1, MyClass::destructorCalls);
329
+ ASSERT_EQUAL(0, MyClass::destructorCalls);
303
330
  }
304
331
 
305
332
  TESTCASE(RoundTrip)
306
333
  {
307
- MyClass::reset();
308
334
  Factory::reset();
335
+ MyClass::reset();
309
336
 
310
337
  Module m = define_module("TestingModule");
311
338
 
@@ -322,26 +349,26 @@ TESTCASE(RoundTrip)
322
349
  ASSERT_EQUAL(1, MyClass::constructorCalls);
323
350
  ASSERT_EQUAL(0, MyClass::copyConstructorCalls);
324
351
  ASSERT_EQUAL(0, MyClass::moveConstructorCalls);
325
- ASSERT_EQUAL(1, MyClass::destructorCalls);
352
+ ASSERT_EQUAL(0, MyClass::destructorCalls);
326
353
  }
327
354
 
328
355
  TESTCASE(Update)
329
356
  {
330
- MyClass::reset();
331
357
  Factory::reset();
358
+ MyClass::reset();
332
359
 
333
360
  Module m = define_module("TestingModule");
334
361
 
335
362
  // Create ruby objects that point to the same instance of MyClass
336
363
  std::string code = R"(factory = Factory.new
337
- ptr1 = factory.share
338
- ptr1.get.set_flag(7)
364
+ my_class1 = factory.share
365
+ my_class1.set_flag(7)
339
366
 
340
- myclass = MyClass.new
341
- myclass.set_flag(14)
367
+ my_class2 = MyClass.new
368
+ my_class2.set_flag(14)
342
369
 
343
370
  sink = Sink.new
344
- sink.update_pointer(ptr1, myclass))";
371
+ sink.update_pointer(my_class1, my_class2))";
345
372
 
346
373
  Object result = m.instance_eval(code);
347
374
  ASSERT_EQUAL(14, detail::From_Ruby<long>().convert(result.value()));
@@ -370,8 +397,8 @@ TESTCASE(KlassSharedPtr)
370
397
 
371
398
  TESTCASE(Void)
372
399
  {
373
- MyClass::reset();
374
400
  Factory::reset();
401
+ MyClass::reset();
375
402
 
376
403
  Module m = define_module("TestingModule");
377
404
 
@@ -482,13 +509,101 @@ TESTCASE(UpdatePointerToInt)
482
509
  TESTCASE(ReadPointerToInt)
483
510
  {
484
511
  Module m = define_module("ReadPointerToInt").
485
- define_module_function("create_pointer", &createPointer);
512
+ define_module_function("create_pointer", &createPointer);
486
513
 
487
514
  std::string code = R"(ptr = create_pointer(50)
488
515
  ptr.get.buffer.to_ary(1))";
489
516
 
490
517
  Array array = m.instance_eval(code);
491
518
  std::vector<int> actual = array.to_vector<int>();
492
- std::vector<int> expected { 50 };
519
+ std::vector<int> expected{ 50 };
493
520
  ASSERT_EQUAL(expected, actual);
521
+ }
522
+
523
+ TESTCASE(AttributeForwarding)
524
+ {
525
+ Factory::reset();
526
+ MyClass::reset();
527
+
528
+ Module m = define_module("TestingModule");
529
+
530
+ // Test read-only attribute
531
+ std::string code = R"(factory = Factory.new
532
+ ptr = factory.share
533
+ ptr.name)";
534
+
535
+ Object result = m.module_eval(code);
536
+ ASSERT_EQUAL("default", detail::From_Ruby<std::string>().convert(result));
537
+
538
+ // Test read/write attribute - read
539
+ code = R"(factory = Factory.new
540
+ ptr = factory.share
541
+ ptr.threshold)";
542
+
543
+ result = m.module_eval(code);
544
+ ASSERT_EQUAL(0, detail::From_Ruby<int>().convert(result));
545
+
546
+ // Test read/write attribute - write and read back
547
+ code = R"(factory = Factory.new
548
+ ptr = factory.share
549
+ ptr.threshold = 42
550
+ ptr.threshold)";
551
+
552
+ result = m.module_eval(code);
553
+ ASSERT_EQUAL(42, detail::From_Ruby<int>().convert(result));
554
+ }
555
+
556
+ TESTCASE(InheritedForwarding)
557
+ {
558
+ Factory::reset();
559
+ MyClass::reset();
560
+
561
+ Module m = define_module("TestingModule");
562
+
563
+ // Test inherited method from MyClass via forwarding
564
+ std::string code = R"(factory = Factory.new
565
+ $ptr = factory.share_inherited
566
+ $ptr.set_flag(99))";
567
+
568
+ m.module_eval(code);
569
+
570
+ // Verify via C++ that set_flag worked
571
+ std::shared_ptr<MyClassInherited>* ptr = detail::From_Ruby<std::shared_ptr<MyClassInherited>*>().convert(
572
+ m.module_eval("$ptr"));
573
+ ASSERT_EQUAL(99, (*ptr)->flag);
574
+
575
+ // Test inherited read-only attribute from MyClass
576
+ code = R"(factory = Factory.new
577
+ ptr = factory.share_inherited
578
+ ptr.name)";
579
+
580
+ Object result = m.module_eval(code);
581
+ ASSERT_EQUAL("default", detail::From_Ruby<std::string>().convert(result));
582
+
583
+ // Test inherited read/write attribute from MyClass
584
+ code = R"(factory = Factory.new
585
+ ptr = factory.share_inherited
586
+ ptr.threshold = 77
587
+ ptr.threshold)";
588
+
589
+ result = m.module_eval(code);
590
+ ASSERT_EQUAL(77, detail::From_Ruby<int>().convert(result));
591
+
592
+ // Test own method on MyClassInherited via forwarding
593
+ code = R"(factory = Factory.new
594
+ ptr = factory.share_inherited
595
+ ptr.set_extra(123)
596
+ ptr.extra)";
597
+
598
+ result = m.module_eval(code);
599
+ ASSERT_EQUAL(123, detail::From_Ruby<int>().convert(result));
600
+
601
+ // Test own attribute on MyClassInherited via forwarding
602
+ code = R"(factory = Factory.new
603
+ ptr = factory.share_inherited
604
+ ptr.extra = 456
605
+ ptr.extra)";
606
+
607
+ result = m.module_eval(code);
608
+ ASSERT_EQUAL(456, detail::From_Ruby<int>().convert(result));
494
609
  }
@@ -1,4 +1,4 @@
1
- #include "unittest.hpp"
1
+ #include "unittest.hpp"
2
2
  #include "embed_ruby.hpp"
3
3
  #include <rice/rice.hpp>
4
4
  #include <rice/stl.hpp>
@@ -55,6 +55,11 @@ namespace
55
55
  {
56
56
  this->flag = value;
57
57
  }
58
+
59
+ int getFlag()
60
+ {
61
+ return this->flag;
62
+ }
58
63
  };
59
64
 
60
65
  class Factory
@@ -97,7 +102,8 @@ SETUP(UniquePtr)
97
102
 
98
103
  define_class<MyClass>("MyClass").
99
104
  define_constructor(Constructor<MyClass>()).
100
- define_method("set_flag", &MyClass::setFlag);
105
+ define_method("set_flag", &MyClass::setFlag).
106
+ define_method("get_flag", &MyClass::getFlag);
101
107
 
102
108
  define_class<Factory>("Factory").
103
109
  define_constructor(Constructor<Factory>()).
@@ -203,8 +209,47 @@ TESTCASE(Update)
203
209
 
204
210
  TESTCASE(Klass)
205
211
  {
212
+ define_unique_ptr<MyClass>();
206
213
  detail::TypeMapper<std::unique_ptr<MyClass>> typeMapper;
207
- Object expected = Object(rb_cObject).const_get("MyClass");
214
+ Module aModule("Std");
215
+ Object expected = aModule.const_get("UniquePtr≺AnonymousNamespace꞉꞉MyClass≻");
208
216
  VALUE actual = typeMapper.rubyKlass();
209
217
  ASSERT_EQUAL(expected.value(), actual);
218
+ }
219
+
220
+ TESTCASE(Empty)
221
+ {
222
+ Module m = define_module("TestingModule");
223
+
224
+ std::string code = R"(factory = Factory.new
225
+ unique_ptr = factory.transfer
226
+ unique_ptr.empty?)";
227
+
228
+ Object result = m.module_eval(code);
229
+ ASSERT_EQUAL(Qfalse, result.value());
230
+ }
231
+
232
+ TESTCASE(Release)
233
+ {
234
+ MyClass::reset();
235
+
236
+ Module m = define_module("TestingModule");
237
+
238
+ std::string code = R"(factory = Factory.new
239
+ $unique_ptr = factory.transfer
240
+ $unique_ptr.release)";
241
+
242
+ Object result = m.module_eval(code);
243
+ ASSERT_EQUAL("MyClass", result.class_name().str());
244
+
245
+ code = R"($unique_ptr.empty?)";
246
+ result = m.module_eval(code);
247
+ ASSERT_EQUAL(Qtrue, result.value());
248
+
249
+ code = R"($unique_ptr.set_flag(8))";
250
+
251
+ ASSERT_EXCEPTION_CHECK(
252
+ Exception,
253
+ m.module_eval(code),
254
+ ASSERT(std::string(ex.what()).find("undefined method") == 0));
210
255
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rice
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.8.0
4
+ version: 4.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Brannan
@@ -157,6 +157,8 @@ files:
157
157
  - rice/cpp_api/shared_methods.hpp
158
158
  - rice/detail/DefaultHandler.hpp
159
159
  - rice/detail/DefaultHandler.ipp
160
+ - rice/detail/Forwards.hpp
161
+ - rice/detail/Forwards.ipp
160
162
  - rice/detail/HandlerRegistry.hpp
161
163
  - rice/detail/HandlerRegistry.ipp
162
164
  - rice/detail/InstanceRegistry.hpp