rice 4.3.2 → 4.5.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 (151) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -25
  3. data/README.md +7 -2
  4. data/Rakefile +7 -1
  5. data/include/rice/rice.hpp +7321 -4470
  6. data/include/rice/stl.hpp +769 -222
  7. data/lib/mkmf-rice.rb +37 -95
  8. data/rice/Address_Registration_Guard.hpp +72 -3
  9. data/rice/Arg.hpp +19 -5
  10. data/rice/Arg.ipp +24 -0
  11. data/rice/Callback.hpp +21 -0
  12. data/rice/Callback.ipp +13 -0
  13. data/rice/Constructor.hpp +4 -27
  14. data/rice/Constructor.ipp +79 -0
  15. data/rice/Data_Object.hpp +74 -3
  16. data/rice/Data_Object.ipp +324 -32
  17. data/rice/Data_Type.hpp +215 -3
  18. data/rice/Data_Type.ipp +125 -64
  19. data/rice/Director.hpp +0 -2
  20. data/rice/Enum.hpp +4 -6
  21. data/rice/Enum.ipp +101 -57
  22. data/rice/Exception.hpp +62 -2
  23. data/rice/Exception.ipp +7 -12
  24. data/rice/JumpException.hpp +44 -0
  25. data/rice/JumpException.ipp +48 -0
  26. data/rice/MemoryView.hpp +11 -0
  27. data/rice/MemoryView.ipp +43 -0
  28. data/rice/Return.hpp +6 -26
  29. data/rice/Return.ipp +10 -16
  30. data/rice/detail/DefaultHandler.hpp +12 -0
  31. data/rice/detail/DefaultHandler.ipp +8 -0
  32. data/rice/detail/HandlerRegistry.hpp +5 -35
  33. data/rice/detail/HandlerRegistry.ipp +7 -11
  34. data/rice/detail/InstanceRegistry.hpp +1 -4
  35. data/rice/detail/MethodInfo.hpp +15 -5
  36. data/rice/detail/MethodInfo.ipp +78 -6
  37. data/rice/detail/Native.hpp +32 -0
  38. data/rice/detail/Native.ipp +129 -0
  39. data/rice/detail/NativeAttributeGet.hpp +51 -0
  40. data/rice/detail/NativeAttributeGet.ipp +51 -0
  41. data/rice/detail/NativeAttributeSet.hpp +43 -0
  42. data/rice/detail/NativeAttributeSet.ipp +82 -0
  43. data/rice/detail/NativeCallbackFFI.hpp +55 -0
  44. data/rice/detail/NativeCallbackFFI.ipp +151 -0
  45. data/rice/detail/NativeCallbackSimple.hpp +30 -0
  46. data/rice/detail/NativeCallbackSimple.ipp +29 -0
  47. data/rice/detail/NativeFunction.hpp +20 -21
  48. data/rice/detail/NativeFunction.ipp +199 -64
  49. data/rice/detail/NativeIterator.hpp +8 -11
  50. data/rice/detail/NativeIterator.ipp +27 -31
  51. data/rice/detail/NativeRegistry.hpp +24 -17
  52. data/rice/detail/NativeRegistry.ipp +23 -56
  53. data/rice/detail/Proc.hpp +4 -0
  54. data/rice/detail/Proc.ipp +85 -0
  55. data/rice/detail/Registries.hpp +0 -7
  56. data/rice/detail/Registries.ipp +0 -18
  57. data/rice/detail/RubyFunction.hpp +0 -3
  58. data/rice/detail/RubyFunction.ipp +4 -8
  59. data/rice/detail/RubyType.hpp +19 -0
  60. data/rice/detail/RubyType.ipp +187 -0
  61. data/rice/detail/TupleIterator.hpp +14 -0
  62. data/rice/detail/Type.hpp +5 -6
  63. data/rice/detail/Type.ipp +150 -33
  64. data/rice/detail/TypeRegistry.hpp +15 -7
  65. data/rice/detail/TypeRegistry.ipp +105 -12
  66. data/rice/detail/Wrapper.hpp +6 -5
  67. data/rice/detail/Wrapper.ipp +45 -23
  68. data/rice/detail/cpp_protect.hpp +5 -6
  69. data/rice/detail/default_allocation_func.ipp +0 -2
  70. data/rice/detail/from_ruby.hpp +37 -3
  71. data/rice/detail/from_ruby.ipp +911 -454
  72. data/rice/detail/ruby.hpp +18 -0
  73. data/rice/detail/to_ruby.hpp +41 -3
  74. data/rice/detail/to_ruby.ipp +437 -113
  75. data/rice/global_function.hpp +0 -4
  76. data/rice/global_function.ipp +1 -2
  77. data/rice/rice.hpp +105 -22
  78. data/rice/ruby_mark.hpp +4 -3
  79. data/rice/stl.hpp +4 -0
  80. data/test/embed_ruby.cpp +4 -1
  81. data/test/extconf.rb +2 -0
  82. data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
  83. data/test/test_Address_Registration_Guard.cpp +5 -0
  84. data/test/test_Array.cpp +12 -1
  85. data/test/test_Attribute.cpp +103 -21
  86. data/test/test_Builtin_Object.cpp +5 -0
  87. data/test/test_Callback.cpp +231 -0
  88. data/test/test_Class.cpp +5 -31
  89. data/test/test_Constructor.cpp +69 -6
  90. data/test/test_Data_Object.cpp +9 -4
  91. data/test/test_Data_Type.cpp +428 -64
  92. data/test/test_Director.cpp +10 -5
  93. data/test/test_Enum.cpp +152 -40
  94. data/test/test_Exception.cpp +235 -0
  95. data/test/test_File.cpp +70 -0
  96. data/test/test_From_Ruby.cpp +542 -0
  97. data/test/test_Hash.cpp +5 -0
  98. data/test/test_Identifier.cpp +5 -0
  99. data/test/test_Inheritance.cpp +6 -1
  100. data/test/test_Iterator.cpp +5 -0
  101. data/test/test_JumpException.cpp +22 -0
  102. data/test/test_Keep_Alive.cpp +6 -1
  103. data/test/test_Keep_Alive_No_Wrapper.cpp +5 -0
  104. data/test/test_Memory_Management.cpp +5 -0
  105. data/test/test_Module.cpp +118 -64
  106. data/test/test_Native_Registry.cpp +2 -33
  107. data/test/test_Object.cpp +5 -0
  108. data/test/test_Overloads.cpp +631 -0
  109. data/test/test_Ownership.cpp +67 -4
  110. data/test/test_Proc.cpp +45 -0
  111. data/test/test_Self.cpp +5 -0
  112. data/test/test_Stl_Exception.cpp +109 -0
  113. data/test/test_Stl_Map.cpp +22 -8
  114. data/test/test_Stl_Optional.cpp +5 -0
  115. data/test/test_Stl_Pair.cpp +7 -2
  116. data/test/test_Stl_Reference_Wrapper.cpp +5 -0
  117. data/test/test_Stl_SmartPointer.cpp +210 -5
  118. data/test/test_Stl_String.cpp +5 -0
  119. data/test/test_Stl_String_View.cpp +5 -0
  120. data/test/test_Stl_Type.cpp +147 -0
  121. data/test/test_Stl_Unordered_Map.cpp +18 -7
  122. data/test/test_Stl_Variant.cpp +5 -0
  123. data/test/test_Stl_Vector.cpp +130 -8
  124. data/test/test_String.cpp +5 -0
  125. data/test/test_Struct.cpp +5 -0
  126. data/test/test_Symbol.cpp +5 -0
  127. data/test/test_Template.cpp +192 -0
  128. data/test/test_To_Ruby.cpp +152 -0
  129. data/test/test_Tracking.cpp +1 -0
  130. data/test/test_Type.cpp +100 -0
  131. data/test/test_global_functions.cpp +53 -6
  132. data/test/unittest.cpp +8 -0
  133. metadata +37 -20
  134. data/lib/version.rb +0 -3
  135. data/rice/Address_Registration_Guard_defn.hpp +0 -79
  136. data/rice/Data_Object_defn.hpp +0 -84
  137. data/rice/Data_Type_defn.hpp +0 -190
  138. data/rice/Exception_defn.hpp +0 -68
  139. data/rice/HandlerRegistration.hpp +0 -15
  140. data/rice/Identifier.hpp +0 -50
  141. data/rice/Identifier.ipp +0 -29
  142. data/rice/detail/ExceptionHandler.hpp +0 -8
  143. data/rice/detail/ExceptionHandler.ipp +0 -28
  144. data/rice/detail/ExceptionHandler_defn.hpp +0 -77
  145. data/rice/detail/Jump_Tag.hpp +0 -21
  146. data/rice/detail/NativeAttribute.hpp +0 -64
  147. data/rice/detail/NativeAttribute.ipp +0 -112
  148. data/rice/detail/from_ruby_defn.hpp +0 -38
  149. data/rice/detail/to_ruby_defn.hpp +0 -48
  150. data/test/test_Jump_Tag.cpp +0 -17
  151. data/test/test_To_From_Ruby.cpp +0 -399
@@ -14,14 +14,12 @@ SETUP(Data_Type)
14
14
  embed_ruby();
15
15
  }
16
16
 
17
- /**
18
- * The tests here are for the feature of taking an instance
19
- * of a Ruby-subclass of a Rice wrapped class and passing
20
- * that instance back into the Rice wrapper. While that
21
- * might be confusing, the test code is pretty straight foward
22
- * to see what we're talking about.
23
- */
24
-
17
+ TEARDOWN(Data_Type)
18
+ {
19
+ Rice::detail::Registries::instance.types.clearUnverifiedTypes();
20
+ rb_gc_start();
21
+ }
22
+ /*
25
23
  namespace
26
24
  {
27
25
  class MyClass
@@ -110,6 +108,59 @@ TESTCASE(methods_with_member_pointers)
110
108
  ASSERT_EQUAL("multiple_args(81, 1, 7.000000, a string, a char)", detail::From_Ruby<std::string>().convert(result.value()));
111
109
  }
112
110
 
111
+ namespace
112
+ {
113
+ class MyClassOriginal
114
+ {
115
+
116
+ };
117
+
118
+ namespace InnerNamespace
119
+ {
120
+ class MyClassOriginal
121
+ {
122
+ };
123
+ }
124
+ }
125
+
126
+ TESTCASE(define_class_twice)
127
+ {
128
+ Module module(rb_cObject);
129
+
130
+ Class c1 = define_class<MyClassOriginal>("MyClassOriginal");
131
+ bool result = module.const_defined("MyClassOriginal");
132
+ ASSERT(result);
133
+ String name = c1.name();
134
+ ASSERT_EQUAL("MyClassOriginal", name.str());
135
+
136
+ Class c2 = define_class<MyClassOriginal>("MyClassDuplicate");
137
+ result = c2.is_equal(c1);
138
+ ASSERT(result);
139
+
140
+ result = module.const_defined("MyClassDuplicate");
141
+ name = c2.name();
142
+ ASSERT_EQUAL("MyClassOriginal", name.str());
143
+ }
144
+
145
+ TESTCASE(define_class_twice_under)
146
+ {
147
+ Module inner = define_module("InnerNamespace");
148
+
149
+ Class c1 = define_class_under<InnerNamespace::MyClassOriginal>(inner, "MyClassOriginal");
150
+ bool result = inner.const_defined("MyClassOriginal");
151
+ ASSERT(result);
152
+ String name = c1.name();
153
+ ASSERT_EQUAL("InnerNamespace::MyClassOriginal", name.str());
154
+
155
+ Class c2 = define_class_under<InnerNamespace::MyClassOriginal>(inner, "MyClassDuplicate");
156
+ result = c2.is_equal(c1);
157
+ ASSERT(result);
158
+
159
+ result = inner.const_defined("MyClassDuplicate");
160
+ name = c2.name();
161
+ ASSERT_EQUAL("InnerNamespace::MyClassOriginal", name.str());
162
+ }
163
+
113
164
  TESTCASE(incorrect_number_of_args)
114
165
  {
115
166
  Class c =
@@ -366,6 +417,57 @@ TESTCASE(define_singleton_method_returning_reference)
366
417
  ASSERT_EQUAL(result, String("foo"));
367
418
  }
368
419
 
420
+ namespace
421
+ {
422
+ class RValue
423
+ {
424
+ public:
425
+ RValue() {}
426
+
427
+ RValue(RValue&& other) = default;
428
+
429
+ // Move assignment operator.
430
+ RValue& operator=(RValue&& other) noexcept
431
+ {
432
+ return *this;
433
+ }
434
+
435
+ bool takesRValue(RValue&& rvalue)
436
+ {
437
+ return true;
438
+ }
439
+ };
440
+ }
441
+
442
+ TESTCASE(rvalue_parameter)
443
+ {
444
+ Class c = define_class<RValue>("RValue")
445
+ .define_constructor(Constructor<RValue>())
446
+ .define_method("takes_r_value", &RValue::takesRValue);
447
+
448
+ Module m(anonymous_module());
449
+ std::string code = R"(rvalue = RValue.new
450
+ rvalue.takes_r_value(rvalue))";
451
+
452
+ Object result = m.module_eval(code);
453
+ ASSERT_EQUAL(Qtrue, result.value());
454
+ }
455
+
456
+ TESTCASE(move_assignment)
457
+ {
458
+ Class c = define_class<RValue>("RValue")
459
+ .define_constructor(Constructor<RValue>())
460
+ .define_method<RValue&(RValue::*)(RValue && other) noexcept>("=", &RValue::operator=);
461
+
462
+ Module m(anonymous_module());
463
+ std::string code = R"(object1 = RValue.new
464
+ object2 = RValue.new
465
+ object1 = object2)";
466
+
467
+ Object result = m.module_eval(code);
468
+ ASSERT_EQUAL(c, result.class_of());
469
+ }
470
+
369
471
  namespace
370
472
  {
371
473
  struct MyStruct
@@ -401,115 +503,377 @@ TESTCASE(null_ptrs)
401
503
 
402
504
  namespace
403
505
  {
404
- class SomeClass
506
+ class Helper
507
+ {
508
+ public:
509
+
510
+ Helper(int value) : value_(value)
511
+ {
512
+ }
513
+
514
+ int value()
515
+ {
516
+ return this->value_;
517
+ }
518
+
519
+ private:
520
+ int value_;
521
+ };
522
+
523
+ class MyClass2
405
524
  {
525
+ public:
526
+ Helper* passThrough(Helper* helper)
527
+ {
528
+ return helper;
529
+ }
530
+
531
+ const Helper* passThroughConst(const Helper* helper)
532
+ {
533
+ return helper;
534
+ }
535
+
536
+ Helper* passThrough(void* helper)
537
+ {
538
+ return static_cast<Helper*>(helper);
539
+ }
540
+
541
+ void* returnVoidHelper()
542
+ {
543
+ if (!this->helper_)
544
+ this->helper_ = new Helper(4);
545
+
546
+ return static_cast<void*>(this->helper_);
547
+ }
548
+
549
+ bool checkVoidHelper(void* helper)
550
+ {
551
+ return helper == this->helper_;
552
+ }
553
+
554
+ private:
555
+ Helper* helper_ = nullptr;
406
556
  };
557
+ } // namespace
558
+
559
+ TESTCASE(pointers)
560
+ {
561
+ Class voidClass = define_class<void>("Void");
562
+
563
+ Class helperClass = define_class<Helper>("Helper")
564
+ .define_constructor(Constructor<Helper, int>())
565
+ .define_method("value", &Helper::value);
566
+
567
+ Class myClass = define_class<MyClass2>("MyClass2")
568
+ .define_constructor(Constructor<MyClass2>())
569
+ .define_method<Helper*(MyClass2::*)(Helper*)>("pass_through", &MyClass2::passThrough)
570
+ .define_method<const Helper*(MyClass2::*)(const Helper*)>("pass_through_const", &MyClass2::passThroughConst)
571
+ .define_method<Helper*(MyClass2::*)(void*)>("pass_through_void", &MyClass2::passThrough)
572
+ .define_method<void*(MyClass2::*)()>("return_void_helper", &MyClass2::returnVoidHelper)
573
+ .define_method<bool(MyClass2::*)(void*)>("check_void_helper", &MyClass2::checkVoidHelper);
574
+
575
+ Object helper = helperClass.call("new", 5);
576
+ Object object = myClass.call("new");
407
577
 
408
- void undefinedArg(SomeClass& someClass)
578
+ Object result = object.call("pass_through", nullptr);
579
+ ASSERT_EQUAL(Qnil, result.value());
580
+
581
+ result = object.call("pass_through", helper);
582
+ Object value = result.call("value");
583
+ ASSERT_EQUAL(5, detail::From_Ruby<int>().convert(value));
584
+
585
+ result = object.call("pass_through_const", helper);
586
+ value = result.call("value");
587
+ ASSERT_EQUAL(5, detail::From_Ruby<int>().convert(value));
588
+
589
+ result = object.call("pass_through_void", nullptr);
590
+ ASSERT_EQUAL(Qnil, result.value());
591
+
592
+ result = object.call("pass_through_void", helper);
593
+ value = result.call("value");
594
+ ASSERT_EQUAL(5, detail::From_Ruby<int>().convert(value));
595
+
596
+ helper = object.call("return_void_helper");
597
+ result = object.call("check_void_helper", helper);
598
+ ASSERT_EQUAL(Qtrue, result.value());
599
+ }
600
+
601
+ namespace
602
+ {
603
+ class BigObject
604
+ {
605
+ public:
606
+ BigObject(int value): value(value)
607
+ {
608
+ }
609
+
610
+ public:
611
+ int value;
612
+ };
613
+
614
+ class Processor
615
+ {
616
+ public:
617
+ BigObject** createBigObjects(size_t size)
618
+ {
619
+ BigObject** result = new BigObject*[size];
620
+
621
+ for (int i = 0; i < size; ++i)
622
+ {
623
+ result[i] = new BigObject(i + 5);
624
+ }
625
+ return result;
626
+ }
627
+
628
+ int sumBigObjects(BigObject** bigObjects, size_t size)
629
+ {
630
+ int result = 0;
631
+
632
+ for (int i = 0; i < size; i++)
633
+ {
634
+ result += bigObjects[i]->value;
635
+ }
636
+ return result;
637
+ }
638
+
639
+ int sumBigObjectsConst(const BigObject** bigObjects, size_t size)
640
+ {
641
+ int result = 0;
642
+
643
+ for (int i = 0; i < size; i++)
644
+ {
645
+ result += bigObjects[i]->value;
646
+ }
647
+ return result;
648
+ }
649
+
650
+ private:
651
+ BigObject** bigObjects_ = nullptr;
652
+ };
653
+
654
+ }
655
+
656
+ TESTCASE(pointerToPointer)
657
+ {
658
+ Class BigObjectClass = define_class<BigObject>("BigObject")
659
+ .define_attr("value", &BigObject::value);
660
+
661
+ Class ProcessorClass = define_class<Processor>("ProcessorClass")
662
+ .define_constructor(Constructor<Processor>())
663
+ .define_method("create", &Processor::createBigObjects)
664
+ .define_method("sum", &Processor::sumBigObjects)
665
+ .define_method("sum_const", &Processor::sumBigObjectsConst);
666
+
667
+ size_t size = 2;
668
+ Data_Object<Processor> processor = ProcessorClass.call("new");
669
+ Data_Object<BigObject> bigObjects = processor.call("create", size);
670
+
671
+ Object result = processor.call("sum", bigObjects, size);
672
+ ASSERT_EQUAL(11, detail::From_Ruby<int>().convert(result));
673
+
674
+ result = processor.call("sum_const", bigObjects, size);
675
+ ASSERT_EQUAL(11, detail::From_Ruby<int>().convert(result));
676
+ }
677
+
678
+ namespace
679
+ {
680
+ class UnknownClass
681
+ {
682
+ };
683
+
684
+ void undefinedArg(UnknownClass unknownClass)
685
+ {
686
+ }
687
+
688
+ void undefinedArg(UnknownClass& unknownClass)
689
+ {
690
+ }
691
+
692
+ void undefinedArg(UnknownClass* unknownClass)
409
693
  {
410
694
  }
411
695
 
412
- SomeClass undefinedReturn()
696
+ UnknownClass undefinedReturn()
413
697
  {
414
- return SomeClass();
698
+ return UnknownClass();
415
699
  }
416
700
  }
417
701
 
418
702
  TESTCASE(not_defined)
419
703
  {
704
+ Module m = define_module("TestingDataTypeNotDefined");
705
+
420
706
  #ifdef _MSC_VER
421
- const char* message = "Type is not defined with Rice: class `anonymous namespace'::SomeClass";
707
+ const char* message = "The following types are not registered with Rice:\n class `anonymous namespace'::UnknownClass\n";
422
708
  #else
423
- const char* message = "Type is not defined with Rice: (anonymous namespace)::SomeClass";
709
+ const char* message = "The following types are not registered with Rice:\n (anonymous namespace)::UnknownClass\n";
424
710
  #endif
425
-
426
- ASSERT_EXCEPTION_CHECK(
711
+
712
+ m.define_module_function("undefined_return", &undefinedReturn);
713
+
714
+ ASSERT_EXCEPTION_CHECK(
427
715
  std::invalid_argument,
428
- define_global_function("undefined_arg", &undefinedArg),
716
+ Rice::detail::Registries::instance.types.validateTypes(),
429
717
  ASSERT_EQUAL(message, ex.what())
430
718
  );
431
719
 
720
+ #ifdef _MSC_VER
721
+ message = "Type is not registered with Rice: class `anonymous namespace'::UnknownClass";
722
+ #else
723
+ message = "Type is not registered with Rice: (anonymous namespace)::UnknownClass";
724
+ #endif
725
+
432
726
  ASSERT_EXCEPTION_CHECK(
433
- std::invalid_argument,
434
- define_global_function("undefined_return", &undefinedReturn),
727
+ Rice::Exception,
728
+ m.call("undefined_return"),
729
+ ASSERT_EQUAL(message, ex.what())
730
+ );
731
+
732
+ #ifdef _MSC_VER
733
+ message = "Type is not defined with Rice: class `anonymous namespace'::UnknownClass";
734
+ #else
735
+ message = "Type is not defined with Rice: (anonymous namespace)::UnknownClass";
736
+ #endif
737
+
738
+ m.define_module_function<void(*)(UnknownClass)>("undefined_arg_value", &undefinedArg);
739
+
740
+ ASSERT_EXCEPTION_CHECK(
741
+ Rice::Exception,
742
+ m.call("undefined_arg_value", nullptr),
435
743
  ASSERT_EQUAL(message, ex.what())
436
744
  );
437
- }
438
745
 
746
+ m.define_module_function<void(*)(UnknownClass)>("undefined_arg_reference", &undefinedArg);
747
+
748
+ ASSERT_EXCEPTION_CHECK(
749
+ Rice::Exception,
750
+ m.call("undefined_arg_reference", nullptr),
751
+ ASSERT_EQUAL(message, ex.what())
752
+ );
753
+
754
+ m.define_module_function<void(*)(UnknownClass*)>("undefined_arg_pointer", &undefinedArg);
755
+
756
+ // This actually works because we pass a nullptr
757
+ m.call("undefined_arg_pointer", nullptr);
758
+ }
759
+ */
439
760
  namespace
440
761
  {
441
- class Container
762
+ class Range
442
763
  {
443
764
  public:
444
- size_t capacity()
765
+ Range(int x, int y) : x(x), y(y)
445
766
  {
446
- return this->capacity_;
447
767
  }
448
768
 
449
- void capacity(size_t value)
769
+ Range(const Range& other) = default;
770
+
771
+ int x;
772
+ int y;
773
+ };
774
+
775
+ int sumRangesArray(int size, Range ranges[])
776
+ {
777
+ int result = 0;
778
+ for (int i = 0; i < size; i++)
450
779
  {
451
- this->capacity_ = value;
780
+ const Range& range = ranges[i];
781
+ result += range.x + range.y;
452
782
  }
453
783
 
454
- private:
455
- size_t capacity_;
456
- };
784
+ return result;
785
+ }
786
+
787
+ int sumRanges(int size, const Range* ranges)
788
+ {
789
+ int result = 0;
790
+ for (int i = 0; i < size; i++)
791
+ {
792
+ const Range& range = ranges[i];
793
+ result += range.x + range.y;
794
+ }
795
+
796
+ return result;
797
+ }
798
+
799
+ int sumRanges(int size, const Range** ranges)
800
+ {
801
+ int result = 0;
802
+ for (int i = 0; i < size; i++)
803
+ {
804
+ const Range* range = ranges[i];
805
+ result += range->x + range->y;
806
+ }
807
+
808
+ return result;
809
+ }
457
810
  }
458
811
 
459
- TESTCASE(OverloadsWithTemplateParameter)
812
+ TESTCASE(array_of_ranges)
460
813
  {
461
- Class c = define_class<Container>("Container")
462
- .define_constructor(Constructor<Container>())
463
- .define_method<size_t(Container::*)()>("capacity", &Container::capacity)
464
- .define_method<void(Container::*)(size_t)>("capacity=", &Container::capacity);
814
+ Module m = define_module("ArrayOfRanges");
465
815
 
466
-
467
- Module m = define_module("Testing");
816
+ Class c = define_class_under<Range>(m, "Range")
817
+ .define_constructor(Constructor<Range, int, int>())
818
+ .define_attr("x", &Range::x)
819
+ .define_attr("y", &Range::y);
820
+
821
+ m.define_module_function("sum_ranges", sumRangesArray);
468
822
 
469
- std::string code = R"(container = Container.new
470
- container.capacity = 5
471
- container.capacity)";
823
+ std::string code = R"(range1 = Range.new(1, 2)
824
+ range2 = Range.new(3, 4)
825
+ range3 = Range.new(5, 6)
826
+
827
+ ranges = [range1, range2, range3]
828
+
829
+ sum_ranges(ranges.count, ranges))";
472
830
 
473
831
  Object result = m.module_eval(code);
474
- ASSERT_EQUAL(5, detail::From_Ruby<int>().convert(result.value()));
832
+ ASSERT_EQUAL(21, detail::From_Ruby<int>().convert(result));
475
833
  }
476
834
 
477
- TESTCASE(OverloadsWithUsing)
835
+ TESTCASE(pointer_of_ranges)
478
836
  {
479
- using Getter_T = size_t(Container::*)();
480
- using Setter_T = void(Container::*)(size_t);
837
+ Module m = define_module("PointerOfRanges");
481
838
 
482
- Class c = define_class<Container>("Container")
483
- .define_constructor(Constructor<Container>())
484
- .define_method("capacity", (Getter_T)&Container::capacity)
485
- .define_method("capacity=", (Setter_T)&Container::capacity);
839
+ Class c = define_class_under<Range>(m, "Range")
840
+ .define_constructor(Constructor<Range, int, int>())
841
+ .define_attr("x", &Range::x)
842
+ .define_attr("y", &Range::y);
486
843
 
487
- Module m = define_module("Testing");
844
+ m.define_module_function<int(*)(int, const Range*)>("sum_ranges", sumRanges);
488
845
 
489
- std::string code = R"(container = Container.new
490
- container.capacity = 6
491
- container.capacity)";
846
+ std::string code = R"(range1 = Range.new(1, 2)
847
+ range2 = Range.new(3, 4)
848
+ range3 = Range.new(5, 6)
849
+
850
+ ranges = [range1, range2, range3]
851
+
852
+ sum_ranges(ranges.count, ranges))";
492
853
 
493
854
  Object result = m.module_eval(code);
494
- ASSERT_EQUAL(6, detail::From_Ruby<int>().convert(result.value()));
855
+ ASSERT_EQUAL(21, detail::From_Ruby<int>().convert(result));
495
856
  }
496
857
 
497
- TESTCASE(OverloadsWithTypedef)
858
+ TESTCASE(pointer_of_pointer_ranges)
498
859
  {
499
- typedef size_t(Container::* Getter_T)();
500
- typedef void (Container::* Setter_T)(size_t);
860
+ Module m = define_module("PointerOfPointersOfRanges");
501
861
 
502
- Class c = define_class<Container>("Container")
503
- .define_constructor(Constructor<Container>())
504
- .define_method("capacity", (Getter_T)&Container::capacity)
505
- .define_method("capacity=", (Setter_T)&Container::capacity);
862
+ Class c = define_class_under<Range>(m, "Range")
863
+ .define_constructor(Constructor<Range, int, int>())
864
+ .define_attr("x", &Range::x)
865
+ .define_attr("y", &Range::y);
506
866
 
507
- Module m = define_module("Testing");
867
+ m.define_module_function<int(*)(int, const Range**)>("sum_ranges", sumRanges);
508
868
 
509
- std::string code = R"(container = Container.new
510
- container.capacity = 7
511
- container.capacity)";
869
+ std::string code = R"(range1 = Range.new(1, 2)
870
+ range2 = Range.new(3, 4)
871
+ range3 = Range.new(5, 6)
872
+
873
+ ranges = [range1, range2, range3]
874
+
875
+ sum_ranges(ranges.count, ranges))";
512
876
 
513
877
  Object result = m.module_eval(code);
514
- ASSERT_EQUAL(7, detail::From_Ruby<int>().convert(result.value()));
515
- }
878
+ ASSERT_EQUAL(21, detail::From_Ruby<int>().convert(result));
879
+ }
@@ -8,6 +8,16 @@ using namespace Rice;
8
8
 
9
9
  TESTSUITE(Director);
10
10
 
11
+ SETUP(Director)
12
+ {
13
+ embed_ruby();
14
+ }
15
+
16
+ TEARDOWN(Director)
17
+ {
18
+ rb_gc_start();
19
+ }
20
+
11
21
  namespace {
12
22
  /**
13
23
  * Abstract base class
@@ -93,11 +103,6 @@ namespace {
93
103
  };
94
104
  };
95
105
 
96
- SETUP(Director)
97
- {
98
- embed_ruby();
99
- }
100
-
101
106
  TESTCASE(exposes_worker_as_instantiatable_class)
102
107
  {
103
108
  define_class<Worker>("Worker")