rice 4.0.4 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }