rice 4.0.4 → 4.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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -0
  3. data/CONTRIBUTORS.md +2 -0
  4. data/Rakefile +1 -1
  5. data/include/rice/rice.hpp +2851 -1955
  6. data/include/rice/stl.hpp +1654 -287
  7. data/lib/mkmf-rice.rb +5 -2
  8. data/lib/version.rb +1 -1
  9. data/rice/Arg.hpp +6 -6
  10. data/rice/Arg.ipp +8 -9
  11. data/rice/Constructor.hpp +2 -2
  12. data/rice/Data_Object.ipp +69 -15
  13. data/rice/Data_Object_defn.hpp +1 -15
  14. data/rice/Data_Type.ipp +56 -86
  15. data/rice/Data_Type_defn.hpp +14 -17
  16. data/rice/Director.hpp +0 -1
  17. data/rice/Enum.ipp +31 -22
  18. data/rice/Exception.ipp +2 -3
  19. data/rice/Exception_defn.hpp +5 -5
  20. data/rice/HandlerRegistration.hpp +15 -0
  21. data/rice/Return.hpp +5 -4
  22. data/rice/Return.ipp +8 -3
  23. data/rice/detail/ExceptionHandler.hpp +8 -0
  24. data/rice/detail/ExceptionHandler.ipp +28 -0
  25. data/rice/detail/{Exception_Handler_defn.hpp → ExceptionHandler_defn.hpp} +17 -21
  26. data/rice/detail/HandlerRegistry.hpp +51 -0
  27. data/rice/detail/HandlerRegistry.ipp +20 -0
  28. data/rice/detail/InstanceRegistry.hpp +34 -0
  29. data/rice/detail/InstanceRegistry.ipp +50 -0
  30. data/rice/detail/MethodInfo.ipp +1 -1
  31. data/rice/detail/NativeAttribute.hpp +26 -15
  32. data/rice/detail/NativeAttribute.ipp +76 -47
  33. data/rice/detail/NativeFunction.hpp +64 -14
  34. data/rice/detail/NativeFunction.ipp +138 -86
  35. data/rice/detail/NativeIterator.hpp +49 -0
  36. data/rice/detail/NativeIterator.ipp +102 -0
  37. data/rice/detail/NativeRegistry.hpp +31 -0
  38. data/rice/detail/{method_data.ipp → NativeRegistry.ipp} +20 -16
  39. data/rice/detail/Registries.hpp +26 -0
  40. data/rice/detail/Registries.ipp +23 -0
  41. data/rice/detail/RubyFunction.hpp +6 -11
  42. data/rice/detail/RubyFunction.ipp +10 -22
  43. data/rice/detail/Type.hpp +1 -1
  44. data/rice/detail/Type.ipp +2 -2
  45. data/rice/detail/TypeRegistry.hpp +8 -11
  46. data/rice/detail/TypeRegistry.ipp +3 -28
  47. data/rice/detail/Wrapper.hpp +0 -2
  48. data/rice/detail/Wrapper.ipp +74 -24
  49. data/rice/detail/cpp_protect.hpp +93 -0
  50. data/rice/detail/default_allocation_func.ipp +1 -1
  51. data/rice/detail/from_ruby.ipp +206 -2
  52. data/rice/detail/to_ruby.ipp +39 -5
  53. data/rice/detail/to_ruby_defn.hpp +1 -1
  54. data/rice/forward_declares.ipp +6 -0
  55. data/rice/global_function.hpp +0 -4
  56. data/rice/global_function.ipp +0 -6
  57. data/rice/rice.hpp +29 -24
  58. data/rice/stl.hpp +6 -1
  59. data/sample/callbacks/extconf.rb +0 -1
  60. data/sample/enum/extconf.rb +0 -1
  61. data/sample/inheritance/extconf.rb +0 -1
  62. data/sample/map/extconf.rb +0 -1
  63. data/test/embed_ruby.cpp +6 -15
  64. data/test/ext/t1/extconf.rb +0 -1
  65. data/test/ext/t2/extconf.rb +0 -1
  66. data/test/extconf.rb +0 -1
  67. data/test/test_Array.cpp +20 -24
  68. data/test/test_Attribute.cpp +6 -6
  69. data/test/test_Class.cpp +8 -47
  70. data/test/test_Constructor.cpp +0 -2
  71. data/test/test_Data_Object.cpp +25 -11
  72. data/test/test_Data_Type.cpp +124 -28
  73. data/test/test_Director.cpp +12 -13
  74. data/test/test_Enum.cpp +65 -26
  75. data/test/test_Inheritance.cpp +9 -9
  76. data/test/test_Iterator.cpp +134 -5
  77. data/test/test_Keep_Alive.cpp +7 -7
  78. data/test/test_Keep_Alive_No_Wrapper.cpp +80 -0
  79. data/test/test_Memory_Management.cpp +1 -1
  80. data/test/test_Module.cpp +25 -62
  81. data/test/test_Object.cpp +75 -3
  82. data/test/test_Ownership.cpp +12 -13
  83. data/test/test_Self.cpp +12 -13
  84. data/test/test_Stl_Map.cpp +696 -0
  85. data/test/test_Stl_Optional.cpp +3 -3
  86. data/test/test_Stl_Pair.cpp +38 -2
  87. data/test/test_Stl_Reference_Wrapper.cpp +102 -0
  88. data/test/test_Stl_SmartPointer.cpp +49 -9
  89. data/test/test_Stl_String.cpp +5 -2
  90. data/test/test_Stl_Unordered_Map.cpp +697 -0
  91. data/test/test_Stl_Variant.cpp +346 -0
  92. data/test/test_Stl_Vector.cpp +200 -41
  93. data/test/test_Struct.cpp +3 -3
  94. data/test/test_To_From_Ruby.cpp +8 -2
  95. data/test/test_Tracking.cpp +239 -0
  96. data/test/unittest.hpp +21 -4
  97. metadata +24 -13
  98. data/rice/detail/Exception_Handler.hpp +0 -8
  99. data/rice/detail/Exception_Handler.ipp +0 -28
  100. data/rice/detail/Iterator.hpp +0 -23
  101. data/rice/detail/Iterator.ipp +0 -47
  102. data/rice/detail/function_traits.hpp +0 -124
  103. data/rice/detail/method_data.hpp +0 -29
  104. data/rice/detail/rice_traits.hpp +0 -116
  105. data/rice/ruby_try_catch.hpp +0 -86
@@ -53,7 +53,7 @@ SETUP(Optional)
53
53
  TESTCASE(OptionalReturn)
54
54
  {
55
55
  Module m = define_module("Testing");
56
- Object myClass = m.instance_eval("MyClass.new");
56
+ Object myClass = m.module_eval("MyClass.new");
57
57
 
58
58
  Object result = myClass.call("optional_return", true);
59
59
  ASSERT_EQUAL("Here is a value", detail::From_Ruby<std::string>().convert(result));
@@ -65,7 +65,7 @@ TESTCASE(OptionalReturn)
65
65
  TESTCASE(OptionalArgument)
66
66
  {
67
67
  Module m = define_module("Testing");
68
- Object myClass = m.instance_eval("MyClass.new");
68
+ Object myClass = m.module_eval("MyClass.new");
69
69
 
70
70
  Object result = myClass.call("optional_argument", 77);
71
71
  ASSERT_EQUAL(77, detail::From_Ruby<int32_t>().convert(result));
@@ -77,7 +77,7 @@ TESTCASE(OptionalArgument)
77
77
  TESTCASE(OptionalAttribute)
78
78
  {
79
79
  Module m = define_module("Testing");
80
- Object myClass = m.instance_eval("MyClass.new");
80
+ Object myClass = m.module_eval("MyClass.new");
81
81
 
82
82
  Object result = myClass.call("optional_attr");
83
83
  ASSERT_EQUAL(Qnil, result.value());
@@ -41,6 +41,32 @@ TESTCASE(CreatePair)
41
41
  ASSERT_EQUAL("A second value", detail::From_Ruby<std::string>().convert(result));
42
42
  }
43
43
 
44
+ TESTCASE(CreatePairConst)
45
+ {
46
+ Module m = define_module("Testing");
47
+
48
+ Class c = define_pair<std::pair<const std::string, const std::string>>("ConstStringPair");
49
+ Object pair = c.call("new", "pair1", "pair2");
50
+
51
+ Object result = pair.call("first");
52
+ ASSERT_EQUAL("pair1", detail::From_Ruby<std::string>().convert(result));
53
+
54
+ result = pair.call("second");
55
+ ASSERT_EQUAL("pair2", detail::From_Ruby<std::string>().convert(result));
56
+
57
+ ASSERT_EXCEPTION_CHECK(
58
+ Exception,
59
+ pair.call("first=", "A second value"),
60
+ ASSERT_EQUAL("Cannot set pair.first since it is a constant", ex.what())
61
+ );
62
+
63
+ ASSERT_EXCEPTION_CHECK(
64
+ Exception,
65
+ pair.call("second=", "A second value"),
66
+ ASSERT_EQUAL("Cannot set pair.second since it is a constant", ex.what())
67
+ );
68
+ }
69
+
44
70
  namespace
45
71
  {
46
72
  class SomeClass
@@ -63,7 +89,6 @@ namespace
63
89
 
64
90
  // This test passes everywhere except for Ruby 2.7 on Windows
65
91
  // and I don't know why. Throws a "bad any_cast" from MethodData::data
66
- #ifndef _WIN32
67
92
  TESTCASE(AutoRegister)
68
93
  {
69
94
  Module m = define_module("Testing");
@@ -98,8 +123,19 @@ TESTCASE(AutoRegister)
98
123
 
99
124
  result = newPair.call("second");
100
125
  ASSERT_EQUAL(3.2, detail::From_Ruby<double>().convert(result));
126
+
127
+ // Now register the pair again
128
+ define_pair<std::pair<std::string, double>>("SomePair");
129
+ std::string code = R"(pair = SomePair.new('string', 2.0))";
130
+ result = m.module_eval(code);
131
+ ASSERT(result.is_instance_of(pair.class_of()));
132
+
133
+ // And again in the module
134
+ define_pair_under<std::pair<std::string, double>>(m, "SomePair2");
135
+ code = R"(pair = Testing::SomePair2.new('string', 3.0))";
136
+ result = m.module_eval(code);
137
+ ASSERT(result.is_instance_of(pair.class_of()));
101
138
  }
102
- #endif
103
139
 
104
140
  namespace
105
141
  {
@@ -0,0 +1,102 @@
1
+ #include "unittest.hpp"
2
+ #include "embed_ruby.hpp"
3
+ #include <rice/rice.hpp>
4
+ #include <rice/stl.hpp>
5
+
6
+ #include <functional>
7
+
8
+ using namespace Rice;
9
+
10
+ TESTSUITE(ReferenceWrapper);
11
+
12
+ namespace
13
+ {
14
+ class MyClass
15
+ {
16
+ public:
17
+ int reference_wrapper_argument(std::reference_wrapper<int32_t> ref)
18
+ {
19
+ return ref.get();
20
+ }
21
+
22
+ std::reference_wrapper<std::string> reference_wrapper_return()
23
+ {
24
+ return reference_wrapper_;
25
+ }
26
+
27
+ std::string say_hello()
28
+ {
29
+ return "My ref wrapper class";
30
+ }
31
+
32
+ std::string string_ = "A ref wrapped string";
33
+ std::reference_wrapper<std::string> reference_wrapper_ = std::ref(string_);
34
+ };
35
+
36
+ std::reference_wrapper<MyClass> roundtrip_class(std::reference_wrapper<MyClass> instance)
37
+ {
38
+ return instance;
39
+ }
40
+
41
+ std::variant<std::reference_wrapper<MyClass>> roundtrip_class_in_variant(std::variant<std::reference_wrapper<MyClass>> instance)
42
+ {
43
+ return instance;
44
+ }
45
+ }
46
+
47
+ void makeReferenceWrapperClass()
48
+ {
49
+ define_class<MyClass>("MyClass").
50
+ define_constructor(Constructor<MyClass>()).
51
+ define_method("reference_wrapper_argument", &MyClass::reference_wrapper_argument).
52
+ define_method("reference_wrapper_return", &MyClass::reference_wrapper_return);
53
+
54
+ define_global_function("roundtrip_class", &roundtrip_class);
55
+ define_global_function("roundtrip_class_in_variant", &roundtrip_class_in_variant);
56
+ }
57
+
58
+ SETUP(ReferenceWrapper)
59
+ {
60
+ embed_ruby();
61
+ makeReferenceWrapperClass();
62
+ }
63
+
64
+ TESTCASE(Return)
65
+ {
66
+ Module m = define_module("Testing");
67
+ Object myClass = m.module_eval("MyClass.new");
68
+
69
+ Object result = myClass.call("reference_wrapper_return");
70
+ ASSERT_EQUAL("A ref wrapped string", detail::From_Ruby<std::string>().convert(result));
71
+ }
72
+
73
+ TESTCASE(Argument)
74
+ {
75
+ Module m = define_module("Testing");
76
+ Object myClass = m.module_eval("MyClass.new");
77
+
78
+ Object result = myClass.call("reference_wrapper_argument", 77);
79
+ ASSERT_EQUAL(77, detail::From_Ruby<int32_t>().convert(result));
80
+ }
81
+
82
+ TESTCASE(RoundTrip)
83
+ {
84
+ Module m = define_module("Testing");
85
+ Object myClass = m.module_eval("MyClass.new");
86
+
87
+ Object result = myClass.call("roundtrip_class", myClass);
88
+ Data_Object<MyClass> finish(result);
89
+
90
+ ASSERT_EQUAL(Data_Object<MyClass>::from_ruby(myClass), Data_Object<MyClass>::from_ruby(result));
91
+ }
92
+
93
+ TESTCASE(RoundTripInVariant)
94
+ {
95
+ Module m = define_module("Testing");
96
+ Object myClass = m.module_eval("MyClass.new");
97
+
98
+ Object result = myClass.call("roundtrip_class_in_variant", myClass);
99
+ Data_Object<MyClass> finish(result);
100
+
101
+ ASSERT_EQUAL(Data_Object<MyClass>::from_ruby(myClass), Data_Object<MyClass>::from_ruby(result));
102
+ }
@@ -109,6 +109,11 @@ SETUP(SmartPointer)
109
109
  define_global_function("extract_flag_unique_ptr_ref", &extractFlagUniquePtrRef);
110
110
  define_global_function("extract_flag_shared_ptr", &extractFlagSharedPtr);
111
111
  define_global_function("extract_flag_shared_ptr_ref", &extractFlagSharedPtrRef);
112
+
113
+ define_global_function("extract_flag_shared_ptr_with_default", &extractFlagSharedPtr,
114
+ Arg("myClass") = std::make_shared<MyClass>());
115
+ define_global_function("extract_flag_shared_ptr_ref_with_default", &extractFlagSharedPtrRef,
116
+ Arg("myClass") = std::make_shared<MyClass>());
112
117
  }
113
118
 
114
119
  TESTCASE(TransferOwnership)
@@ -124,7 +129,7 @@ TESTCASE(TransferOwnership)
124
129
  my_class = nil
125
130
  end)";
126
131
 
127
- m.instance_eval(code);
132
+ m.module_eval(code);
128
133
  rb_gc_start();
129
134
 
130
135
  ASSERT_EQUAL(10, MyClass::constructorCalls);
@@ -147,7 +152,7 @@ TESTCASE(ShareOwnership)
147
152
  my_class.set_flag(i)
148
153
  end)";
149
154
 
150
- m.instance_eval(code);
155
+ m.module_eval(code);
151
156
  rb_gc_start();
152
157
 
153
158
  ASSERT_EQUAL(1, MyClass::constructorCalls);
@@ -168,7 +173,8 @@ TESTCASE(UniquePtrRefParameter)
168
173
  my_class.set_flag(7)
169
174
  extract_flag_unique_ptr_ref(my_class))";
170
175
 
171
- Object result = m.instance_eval(code);
176
+ Object result = m.module_eval(code);
177
+ ASSERT_EQUAL(7, detail::From_Ruby<int>().convert(result));
172
178
  }
173
179
 
174
180
  TESTCASE(SharedPtrParameter)
@@ -179,10 +185,11 @@ TESTCASE(SharedPtrParameter)
179
185
 
180
186
  std::string code = R"(factory = Factory.new
181
187
  my_class = factory.share
182
- my_class.set_flag(7)
188
+ my_class.set_flag(8)
183
189
  extract_flag_shared_ptr(my_class))";
184
-
185
- Object result = m.instance_eval(code);
190
+
191
+ Object result = m.module_eval(code);
192
+ ASSERT_EQUAL(8, detail::From_Ruby<int>().convert(result));
186
193
  }
187
194
 
188
195
  TESTCASE(SharedPtrRefParameter)
@@ -193,8 +200,41 @@ TESTCASE(SharedPtrRefParameter)
193
200
 
194
201
  std::string code = R"(factory = Factory.new
195
202
  my_class = factory.share
196
- my_class.set_flag(7)
203
+ my_class.set_flag(9)
197
204
  extract_flag_shared_ptr_ref(my_class))";
198
205
 
199
- Object result = m.instance_eval(code);
200
- }
206
+ Object result = m.module_eval(code);
207
+ ASSERT_EQUAL(9, detail::From_Ruby<int>().convert(result));
208
+ }
209
+
210
+ TESTCASE(SharedPtrDefaultParameter)
211
+ {
212
+ MyClass::reset();
213
+
214
+ Module m = define_module("TestingModule");
215
+
216
+ std::string code = R"(factory = Factory.new
217
+ my_class = factory.share
218
+ my_class.set_flag(7)
219
+ extract_flag_shared_ptr_with_default())";
220
+
221
+ Object result = m.module_eval(code);
222
+ // The default value kicks in and ignores any previous pointer
223
+ ASSERT_EQUAL(0, detail::From_Ruby<int>().convert(result));
224
+ }
225
+
226
+ TESTCASE(SharedPtrRefDefaultParameter)
227
+ {
228
+ MyClass::reset();
229
+
230
+ Module m = define_module("TestingModule");
231
+
232
+ std::string code = R"(factory = Factory.new
233
+ my_class = factory.share
234
+ my_class.set_flag(7)
235
+ extract_flag_shared_ptr_ref_with_default())";
236
+
237
+ Object result = m.module_eval(code);
238
+ // The default value kicks in and ignores any previous pointer
239
+ ASSERT_EQUAL(0, detail::From_Ruby<int>().convert(result));
240
+ }
@@ -27,7 +27,10 @@ TESTCASE(std_string_to_ruby_encoding)
27
27
  Object object(value);
28
28
  Object encoding = object.call("encoding");
29
29
  Object encodingName = encoding.call("name");
30
- ASSERT_EQUAL("ASCII-8BIT", detail::From_Ruby<std::string>().convert(encodingName));
30
+ std::string result = detail::From_Ruby<std::string>().convert(encodingName);
31
+ if(result != "ASCII-8BIT" && result != "US-ASCII" && result != "UTF-8") {
32
+ FAIL("Encoding incorrect", "ASCII-8BIT, US-ASCII, or UTF-8 (Windows)", result);
33
+ }
31
34
  }
32
35
 
33
36
  TESTCASE(std_string_to_ruby_encoding_utf8)
@@ -71,4 +74,4 @@ TESTCASE(std_string_from_ruby_with_binary)
71
74
  std::string got = detail::From_Ruby<std::string>().convert(rb_str_new("\000test", 5));
72
75
  ASSERT_EQUAL(5ul, got.length());
73
76
  ASSERT_EQUAL(std::string("\000test", 5), got);
74
- }
77
+ }