rice 4.3.3 → 4.6.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 (237) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -26
  3. data/CMakeLists.txt +31 -0
  4. data/CMakePresets.json +75 -0
  5. data/COPYING +3 -2
  6. data/FindRuby.cmake +437 -0
  7. data/README.md +7 -2
  8. data/Rakefile +12 -5
  9. data/include/rice/rice.hpp +9522 -4426
  10. data/include/rice/stl.hpp +2831 -1198
  11. data/lib/make_rice_headers.rb +79 -0
  12. data/lib/mkmf-rice.rb +40 -94
  13. data/lib/rice/version.rb +3 -0
  14. data/lib/rice.rb +1 -0
  15. data/lib/rubygems/builder.rb +11 -0
  16. data/lib/rubygems/cmake_builder.rb +113 -0
  17. data/lib/rubygems_plugin.rb +9 -0
  18. data/rice/Address_Registration_Guard.hpp +72 -3
  19. data/rice/Arg.hpp +26 -6
  20. data/rice/Arg.ipp +35 -2
  21. data/rice/Buffer.hpp +123 -0
  22. data/rice/Buffer.ipp +599 -0
  23. data/rice/Callback.hpp +21 -0
  24. data/rice/Callback.ipp +13 -0
  25. data/rice/Constructor.hpp +4 -27
  26. data/rice/Constructor.ipp +79 -0
  27. data/rice/Data_Object.hpp +73 -3
  28. data/rice/Data_Object.ipp +388 -96
  29. data/rice/Data_Type.hpp +214 -3
  30. data/rice/Data_Type.ipp +144 -67
  31. data/rice/Director.hpp +0 -2
  32. data/rice/Enum.hpp +4 -7
  33. data/rice/Enum.ipp +102 -55
  34. data/rice/Exception.hpp +62 -2
  35. data/rice/Exception.ipp +7 -12
  36. data/rice/Init.hpp +8 -0
  37. data/rice/Init.ipp +8 -0
  38. data/rice/JumpException.hpp +44 -0
  39. data/rice/JumpException.ipp +48 -0
  40. data/rice/MemoryView.hpp +11 -0
  41. data/rice/MemoryView.ipp +3 -0
  42. data/rice/Return.hpp +7 -27
  43. data/rice/Return.ipp +13 -13
  44. data/rice/cpp_api/Array.hpp +209 -0
  45. data/rice/cpp_api/Array.ipp +304 -0
  46. data/rice/cpp_api/Builtin_Object.hpp +31 -0
  47. data/rice/cpp_api/Builtin_Object.ipp +37 -0
  48. data/rice/cpp_api/Class.hpp +70 -0
  49. data/rice/cpp_api/Class.ipp +97 -0
  50. data/rice/cpp_api/Encoding.hpp +32 -0
  51. data/rice/cpp_api/Encoding.ipp +59 -0
  52. data/rice/cpp_api/Hash.hpp +194 -0
  53. data/rice/cpp_api/Hash.ipp +257 -0
  54. data/rice/{Identifier.hpp → cpp_api/Identifier.hpp} +2 -6
  55. data/rice/{Identifier.ipp → cpp_api/Identifier.ipp} +4 -2
  56. data/rice/cpp_api/Module.hpp +72 -0
  57. data/rice/cpp_api/Module.ipp +101 -0
  58. data/rice/cpp_api/Object.hpp +272 -0
  59. data/rice/cpp_api/Object.ipp +235 -0
  60. data/rice/cpp_api/String.hpp +74 -0
  61. data/rice/cpp_api/String.ipp +120 -0
  62. data/rice/cpp_api/Struct.hpp +113 -0
  63. data/rice/cpp_api/Struct.ipp +92 -0
  64. data/rice/cpp_api/Symbol.hpp +46 -0
  65. data/rice/cpp_api/Symbol.ipp +93 -0
  66. data/rice/cpp_api/shared_methods.hpp +134 -0
  67. data/rice/detail/DefaultHandler.hpp +12 -0
  68. data/rice/detail/DefaultHandler.ipp +8 -0
  69. data/rice/detail/HandlerRegistry.hpp +5 -35
  70. data/rice/detail/HandlerRegistry.ipp +7 -11
  71. data/rice/detail/InstanceRegistry.hpp +1 -4
  72. data/rice/detail/MethodInfo.hpp +12 -10
  73. data/rice/detail/MethodInfo.ipp +26 -21
  74. data/rice/detail/Native.hpp +33 -0
  75. data/rice/detail/Native.ipp +157 -0
  76. data/rice/detail/NativeAttributeGet.hpp +52 -0
  77. data/rice/detail/NativeAttributeGet.ipp +57 -0
  78. data/rice/detail/NativeAttributeSet.hpp +44 -0
  79. data/rice/detail/NativeAttributeSet.ipp +88 -0
  80. data/rice/detail/NativeCallbackFFI.hpp +55 -0
  81. data/rice/detail/NativeCallbackFFI.ipp +151 -0
  82. data/rice/detail/NativeCallbackSimple.hpp +30 -0
  83. data/rice/detail/NativeCallbackSimple.ipp +29 -0
  84. data/rice/detail/NativeFunction.hpp +33 -23
  85. data/rice/detail/NativeFunction.ipp +309 -70
  86. data/rice/detail/NativeIterator.hpp +9 -11
  87. data/rice/detail/NativeIterator.ipp +33 -31
  88. data/rice/detail/NativeRegistry.hpp +24 -15
  89. data/rice/detail/NativeRegistry.ipp +23 -48
  90. data/rice/detail/Proc.hpp +4 -0
  91. data/rice/detail/Proc.ipp +85 -0
  92. data/rice/detail/Registries.hpp +0 -7
  93. data/rice/detail/Registries.ipp +0 -18
  94. data/rice/detail/RubyFunction.hpp +0 -3
  95. data/rice/detail/RubyFunction.ipp +4 -8
  96. data/rice/detail/RubyType.hpp +16 -0
  97. data/rice/detail/RubyType.ipp +232 -0
  98. data/rice/detail/Type.hpp +7 -6
  99. data/rice/detail/Type.ipp +192 -45
  100. data/rice/detail/TypeRegistry.hpp +15 -7
  101. data/rice/detail/TypeRegistry.ipp +105 -12
  102. data/rice/detail/Wrapper.hpp +68 -32
  103. data/rice/detail/Wrapper.ipp +121 -109
  104. data/rice/detail/cpp_protect.hpp +5 -6
  105. data/rice/detail/default_allocation_func.ipp +0 -2
  106. data/rice/detail/from_ruby.hpp +38 -3
  107. data/rice/detail/from_ruby.ipp +1321 -492
  108. data/rice/detail/ruby.hpp +18 -0
  109. data/rice/detail/to_ruby.hpp +41 -3
  110. data/rice/detail/to_ruby.ipp +1424 -194
  111. data/rice/global_function.hpp +0 -4
  112. data/rice/global_function.ipp +0 -1
  113. data/rice/libc/file.hpp +11 -0
  114. data/rice/libc/file.ipp +32 -0
  115. data/rice/rice.hpp +116 -26
  116. data/rice/ruby_mark.hpp +4 -3
  117. data/rice/stl/complex.hpp +6 -0
  118. data/rice/stl/complex.ipp +93 -0
  119. data/rice/stl/exception.hpp +11 -0
  120. data/rice/stl/exception.ipp +29 -0
  121. data/rice/stl/exception_ptr.hpp +6 -0
  122. data/rice/stl/exception_ptr.ipp +27 -0
  123. data/rice/stl/map.hpp +12 -0
  124. data/rice/stl/map.ipp +469 -0
  125. data/rice/stl/monostate.hpp +6 -0
  126. data/rice/stl/monostate.ipp +80 -0
  127. data/rice/stl/multimap.hpp +14 -0
  128. data/rice/stl/multimap.ipp +448 -0
  129. data/rice/stl/optional.hpp +6 -0
  130. data/rice/stl/optional.ipp +118 -0
  131. data/rice/stl/pair.hpp +13 -0
  132. data/rice/stl/pair.ipp +155 -0
  133. data/rice/stl/reference_wrapper.hpp +6 -0
  134. data/rice/stl/reference_wrapper.ipp +41 -0
  135. data/rice/stl/set.hpp +12 -0
  136. data/rice/stl/set.ipp +495 -0
  137. data/rice/stl/shared_ptr.hpp +28 -0
  138. data/rice/stl/shared_ptr.ipp +224 -0
  139. data/rice/stl/string.hpp +6 -0
  140. data/rice/stl/string.ipp +158 -0
  141. data/rice/stl/string_view.hpp +6 -0
  142. data/rice/stl/string_view.ipp +65 -0
  143. data/rice/stl/tuple.hpp +6 -0
  144. data/rice/stl/tuple.ipp +128 -0
  145. data/rice/stl/type_index.hpp +6 -0
  146. data/rice/stl/type_index.ipp +30 -0
  147. data/rice/stl/type_info.hpp +6 -0
  148. data/rice/stl/type_info.ipp +29 -0
  149. data/rice/stl/unique_ptr.hpp +22 -0
  150. data/rice/stl/unique_ptr.ipp +139 -0
  151. data/rice/stl/unordered_map.hpp +12 -0
  152. data/rice/stl/unordered_map.ipp +469 -0
  153. data/rice/stl/variant.hpp +6 -0
  154. data/rice/stl/variant.ipp +242 -0
  155. data/rice/stl/vector.hpp +12 -0
  156. data/rice/stl/vector.ipp +590 -0
  157. data/rice/stl.hpp +11 -3
  158. data/rice/traits/attribute_traits.hpp +26 -0
  159. data/rice/traits/function_traits.hpp +95 -0
  160. data/rice/traits/method_traits.hpp +47 -0
  161. data/rice/traits/rice_traits.hpp +160 -0
  162. data/rice.gemspec +85 -0
  163. data/test/embed_ruby.cpp +7 -1
  164. data/test/extconf.rb +2 -0
  165. data/test/test_Address_Registration_Guard.cpp +5 -0
  166. data/test/test_Array.cpp +18 -4
  167. data/test/test_Attribute.cpp +136 -21
  168. data/test/test_Buffer.cpp +285 -0
  169. data/test/test_Builtin_Object.cpp +5 -0
  170. data/test/test_Callback.cpp +230 -0
  171. data/test/test_Class.cpp +5 -31
  172. data/test/test_Constructor.cpp +69 -6
  173. data/test/test_Data_Object.cpp +97 -38
  174. data/test/test_Data_Type.cpp +470 -65
  175. data/test/test_Director.cpp +17 -8
  176. data/test/test_Enum.cpp +155 -40
  177. data/test/test_Exception.cpp +235 -0
  178. data/test/test_File.cpp +70 -0
  179. data/test/test_From_Ruby.cpp +609 -0
  180. data/test/test_Hash.cpp +5 -0
  181. data/test/test_Identifier.cpp +5 -0
  182. data/test/test_Inheritance.cpp +6 -1
  183. data/test/test_Iterator.cpp +6 -1
  184. data/test/test_Jump_Exception.cpp +23 -0
  185. data/test/test_Keep_Alive.cpp +13 -19
  186. data/test/test_Keep_Alive_No_Wrapper.cpp +5 -1
  187. data/test/test_Memory_Management.cpp +5 -0
  188. data/test/test_Module.cpp +128 -67
  189. data/test/test_Native_Registry.cpp +2 -34
  190. data/test/test_Object.cpp +5 -0
  191. data/test/test_Overloads.cpp +806 -0
  192. data/test/test_Ownership.cpp +160 -54
  193. data/test/test_Proc.cpp +44 -0
  194. data/test/test_Self.cpp +9 -4
  195. data/test/test_Stl_Exception.cpp +109 -0
  196. data/test/test_Stl_Map.cpp +54 -42
  197. data/test/test_Stl_Multimap.cpp +693 -0
  198. data/test/test_Stl_Optional.cpp +5 -0
  199. data/test/test_Stl_Pair.cpp +14 -9
  200. data/test/test_Stl_Reference_Wrapper.cpp +9 -2
  201. data/test/test_Stl_Set.cpp +790 -0
  202. data/test/test_Stl_SharedPtr.cpp +458 -0
  203. data/test/test_Stl_String.cpp +5 -0
  204. data/test/test_Stl_String_View.cpp +5 -0
  205. data/test/test_Stl_Tuple.cpp +116 -0
  206. data/test/test_Stl_Type.cpp +147 -0
  207. data/test/test_Stl_UniquePtr.cpp +202 -0
  208. data/test/test_Stl_Unordered_Map.cpp +43 -38
  209. data/test/test_Stl_Variant.cpp +217 -84
  210. data/test/test_Stl_Vector.cpp +306 -58
  211. data/test/test_String.cpp +5 -0
  212. data/test/test_Struct.cpp +5 -0
  213. data/test/test_Symbol.cpp +5 -0
  214. data/test/test_Template.cpp +192 -0
  215. data/test/test_To_Ruby.cpp +524 -0
  216. data/test/test_Tracking.cpp +1 -0
  217. data/test/test_Type.cpp +171 -0
  218. data/test/test_global_functions.cpp +67 -7
  219. data/test/unittest.cpp +8 -0
  220. metadata +127 -26
  221. data/lib/version.rb +0 -3
  222. data/rice/Address_Registration_Guard_defn.hpp +0 -79
  223. data/rice/Data_Object_defn.hpp +0 -84
  224. data/rice/Data_Type_defn.hpp +0 -190
  225. data/rice/Exception_defn.hpp +0 -68
  226. data/rice/HandlerRegistration.hpp +0 -15
  227. data/rice/detail/ExceptionHandler.hpp +0 -8
  228. data/rice/detail/ExceptionHandler.ipp +0 -28
  229. data/rice/detail/ExceptionHandler_defn.hpp +0 -77
  230. data/rice/detail/Jump_Tag.hpp +0 -21
  231. data/rice/detail/NativeAttribute.hpp +0 -64
  232. data/rice/detail/NativeAttribute.ipp +0 -112
  233. data/rice/detail/from_ruby_defn.hpp +0 -38
  234. data/rice/detail/to_ruby_defn.hpp +0 -48
  235. data/test/test_Jump_Tag.cpp +0 -17
  236. data/test/test_Stl_SmartPointer.cpp +0 -283
  237. data/test/test_To_From_Ruby.cpp +0 -399
@@ -14,12 +14,23 @@ SETUP(Attribute)
14
14
  embed_ruby();
15
15
  }
16
16
 
17
+ TEARDOWN(Attribute)
18
+ {
19
+ Rice::detail::Registries::instance.types.clearUnverifiedTypes();
20
+ rb_gc_start();
21
+ }
22
+
17
23
  namespace
18
24
  {
19
25
  class SomeClass
20
26
  {
21
27
  };
22
28
 
29
+ class NotAssignable
30
+ {
31
+ NotAssignable& operator=(const NotAssignable&) = delete;
32
+ };
33
+
23
34
  struct DataStruct
24
35
  {
25
36
  static inline float staticFloat = 1.0;
@@ -29,7 +40,9 @@ namespace
29
40
  std::string readWriteString = "Read Write";
30
41
  int writeInt = 0;
31
42
  const char* readChars = "Read some chars!";
43
+ const int constInt = 5;
32
44
  SomeClass someClass;
45
+ NotAssignable notAssignable;
33
46
 
34
47
  std::string inspect()
35
48
  {
@@ -40,6 +53,21 @@ namespace
40
53
  bool globalBool = true;
41
54
  const DataStruct* globalStruct = new DataStruct();
42
55
 
56
+ class VecStruct
57
+ {
58
+ public:
59
+ std::vector<double> vector;
60
+
61
+ VecStruct(std::vector<double> aVector) : vector(aVector)
62
+ {
63
+ }
64
+
65
+ size_t vecSize()
66
+ {
67
+ return this->vector.size();
68
+ }
69
+ };
70
+
43
71
  } // namespace
44
72
 
45
73
  TESTCASE(attributes)
@@ -57,21 +85,28 @@ TESTCASE(attributes)
57
85
  // Test readonly attribute
58
86
  Object result = o.call("read_chars");
59
87
  ASSERT_EQUAL("Read some chars!", detail::From_Ruby<char*>().convert(result));
60
- ASSERT_EXCEPTION_CHECK(
61
- Exception,
62
- o.call("read_char=", "some text"),
63
- ASSERT(std::string(ex.what()).find("undefined method `read_char='") == 0)
64
- );
65
88
 
89
+ if constexpr (!oldRuby)
90
+ {
91
+ ASSERT_EXCEPTION_CHECK(
92
+ Exception,
93
+ o.call("read_char=", "some text"),
94
+ ASSERT(std::string(ex.what()).find("undefined method `read_char='") == 0)
95
+ );
96
+ }
66
97
  // Test writeonly attribute
67
98
  result = o.call("write_int=", 5);
68
99
  ASSERT_EQUAL(5, detail::From_Ruby<int>().convert(result.value()));
69
100
  ASSERT_EQUAL(5, dataStruct->writeInt);
70
- ASSERT_EXCEPTION_CHECK(
71
- Exception,
72
- o.call("write_int", 3),
73
- ASSERT(std::string(ex.what()).find("undefined method `write_int'") == 0)
74
- );
101
+
102
+ if constexpr (!oldRuby)
103
+ {
104
+ ASSERT_EXCEPTION_CHECK(
105
+ Exception,
106
+ o.call("write_int", 3),
107
+ ASSERT(std::string(ex.what()).find("undefined method `write_int'") == 0)
108
+ );
109
+ }
75
110
 
76
111
  // Test readwrite attribute
77
112
  result = o.call("read_write_string=", "Set a string");
@@ -82,6 +117,66 @@ TESTCASE(attributes)
82
117
  ASSERT_EQUAL("Set a string", detail::From_Ruby<std::string>().convert(result.value()));
83
118
  }
84
119
 
120
+ TESTCASE(vector)
121
+ {
122
+ // See https ://github.com/ruby-rice/rice/issues/283
123
+ Module m = define_module("Testing");
124
+
125
+ define_class<VecStruct>("VecStruct")
126
+ .define_constructor(Constructor<VecStruct, std::vector<double>>())
127
+ .define_attr("vector", &VecStruct::vector, Rice::AttrAccess::Read)
128
+ .define_method("vector_size", &VecStruct::vecSize);
129
+
130
+ std::string code = R"(struct = VecStruct.new([1, 2])
131
+ # Access the attribute
132
+ array = struct.vector.to_a
133
+ struct.vector_size)";
134
+
135
+ Object result = m.module_eval(code);
136
+ ASSERT_EQUAL(2, detail::From_Ruby<int>().convert(result));
137
+ }
138
+
139
+ TESTCASE(const_attribute)
140
+ {
141
+ Class c = define_class<DataStruct>("DataStruct")
142
+ .define_constructor(Constructor<DataStruct>())
143
+ .define_attr("const_int", &DataStruct::constInt);
144
+
145
+ Data_Object<DataStruct> o = c.call("new");
146
+
147
+ if constexpr (!oldRuby)
148
+ {
149
+ ASSERT_EXCEPTION_CHECK(
150
+ Exception,
151
+ o.call("const_int=", 5),
152
+ ASSERT(std::string(ex.what()).find("undefined method `const_int='") == 0)
153
+ );
154
+ }
155
+ }
156
+
157
+ TESTCASE(not_copyable_attribute)
158
+ {
159
+ Class notAssignableClass = define_class<NotAssignable>("NotAssignable")
160
+ .define_constructor(Constructor<NotAssignable>());
161
+
162
+ Class c = define_class<DataStruct>("DataStruct")
163
+ .define_constructor(Constructor<DataStruct>())
164
+ .define_attr("not_assignable", &DataStruct::notAssignable);
165
+
166
+ Data_Object<NotAssignable> notAssignable = notAssignableClass.call("new");
167
+
168
+ Data_Object<DataStruct> o = c.call("new");
169
+
170
+ if constexpr (!oldRuby)
171
+ {
172
+ ASSERT_EXCEPTION_CHECK(
173
+ Exception,
174
+ o.call("not_assignable=", notAssignable),
175
+ ASSERT(std::string(ex.what()).find("undefined method `not_assignable='") == 0)
176
+ );
177
+ }
178
+ }
179
+
85
180
  TESTCASE(static_attributes)
86
181
  {
87
182
  Class c = define_class<DataStruct>("DataStruct")
@@ -98,11 +193,15 @@ TESTCASE(static_attributes)
98
193
 
99
194
  result = c.call("static_string");
100
195
  ASSERT_EQUAL("Static string", detail::From_Ruby<std::string>().convert(result.value()));
101
- ASSERT_EXCEPTION_CHECK(
102
- Exception,
103
- c.call("static_string=", true),
104
- ASSERT(std::string(ex.what()).find("undefined method `static_string='") == 0)
105
- );
196
+
197
+ if constexpr (!oldRuby)
198
+ {
199
+ ASSERT_EXCEPTION_CHECK(
200
+ Exception,
201
+ c.call("static_string=", true),
202
+ ASSERT(std::string(ex.what()).find("undefined method `static_string='") == 0)
203
+ );
204
+ }
106
205
  }
107
206
 
108
207
  TESTCASE(global_attributes)
@@ -128,20 +227,36 @@ TESTCASE(not_defined)
128
227
  Data_Type<DataStruct> c = define_class<DataStruct>("DataStruct");
129
228
 
130
229
  #ifdef _MSC_VER
131
- const char* message = "Type is not defined with Rice: class `anonymous namespace'::SomeClass";
230
+ const char* message = "The following types are not registered with Rice:\n class `anonymous namespace'::SomeClass\n";
132
231
  #else
133
- const char* message = "Type is not defined with Rice: (anonymous namespace)::SomeClass";
232
+ const char* message = "The following types are not registered with Rice:\n (anonymous namespace)::SomeClass\n";
134
233
  #endif
135
234
 
235
+ c.define_singleton_attr("some_class_static", &DataStruct::someClassStatic);
236
+
136
237
  ASSERT_EXCEPTION_CHECK(
137
238
  std::invalid_argument,
138
- c.define_singleton_attr("some_class_static", &DataStruct::someClassStatic),
239
+ Rice::detail::Registries::instance.types.validateTypes(),
139
240
  ASSERT_EQUAL(message, ex.what())
140
241
  );
141
242
 
243
+ #ifdef _MSC_VER
244
+ message = "Type is not registered with Rice: class `anonymous namespace'::SomeClass";
245
+ #else
246
+ message = "Type is not registered with Rice: (anonymous namespace)::SomeClass";
247
+ #endif
248
+
142
249
  ASSERT_EXCEPTION_CHECK(
143
- std::invalid_argument,
144
- c.define_attr("some_class", &DataStruct::someClass),
250
+ Rice::Exception,
251
+ c.call("some_class_static"),
145
252
  ASSERT_EQUAL(message, ex.what())
146
253
  );
147
- }
254
+
255
+ c.define_attr("some_class", &DataStruct::someClass);
256
+ Object o = c.call("new");
257
+ ASSERT_EXCEPTION_CHECK(
258
+ Rice::Exception,
259
+ o.call("some_class"),
260
+ ASSERT_EQUAL(message, ex.what())
261
+ );
262
+ }
@@ -0,0 +1,285 @@
1
+ #include "unittest.hpp"
2
+ #include "embed_ruby.hpp"
3
+ #include <rice/rice.hpp>
4
+
5
+ #include <limits>
6
+ #include <cmath>
7
+
8
+ using namespace Rice;
9
+
10
+ TESTSUITE(Buffer);
11
+
12
+ SETUP(Buffer)
13
+ {
14
+ embed_ruby();
15
+ }
16
+
17
+ TEARDOWN(Buffer)
18
+ {
19
+ rb_gc_start();
20
+ }
21
+
22
+ TESTCASE(Char)
23
+ {
24
+ define_buffer<char>();
25
+
26
+ Module m = define_module("BufferTesting");
27
+
28
+ std::string code = R"(Rice::Buffer≺char≻.new("my string"))";
29
+ Object result = m.instance_eval(code);
30
+
31
+ ASSERT_EQUAL("Rice::Buffer≺char≻", result.class_name().c_str());
32
+ ASSERT_EQUAL("my string", String(result.call("bytes")).c_str());
33
+
34
+ Array array = result.call("to_ary");
35
+ ASSERT_EQUAL("109, 121, 32, 115, 116, 114, 105, 110, 103", array.join(", ").c_str());
36
+
37
+ Object size = result.call("size");
38
+ ASSERT_EQUAL(9, detail::From_Ruby<int>().convert(size));
39
+
40
+ Data_Object<Buffer<char>> dataObject(result);
41
+ Buffer<char> buffer = std::move(*dataObject);
42
+ ASSERT_EQUAL("my string", buffer.ptr());
43
+ ASSERT_EQUAL(9, (int)buffer.size());
44
+ }
45
+
46
+ TESTCASE(CharArray)
47
+ {
48
+ define_buffer<char>();
49
+
50
+ Module m = define_module("BufferTesting");
51
+
52
+ std::string code = R"(Rice::Buffer≺char≻.new([0, 127, 128, 255, 256, -128, -129, -255]))";
53
+ Data_Object<Buffer<char>> result = m.instance_eval(code);
54
+ Buffer<char> buffer = std::move(*result);
55
+ char* data = buffer.ptr();
56
+
57
+ ASSERT_EQUAL(data[0], 0);
58
+ ASSERT_EQUAL(data[1], 127);
59
+ ASSERT_EQUAL(data[2], -128);
60
+ ASSERT_EQUAL(data[3], -1);
61
+ ASSERT_EQUAL(data[4], 0);
62
+ ASSERT_EQUAL(data[5], -128);
63
+ ASSERT_EQUAL(data[6], 127);
64
+ ASSERT_EQUAL(data[7], 1);
65
+ }
66
+
67
+ TESTCASE(signed_char_pointer)
68
+ {
69
+ define_buffer<signed char>();
70
+ Module m = define_module("Testing");
71
+
72
+ std::string code = R"(Rice::Buffer≺signed char≻.new("my string"))";
73
+ Data_Object<Buffer<signed char>> result = m.instance_eval(code);
74
+ Buffer<signed char> buffer = std::move(*result);
75
+ signed char* data = buffer.ptr();
76
+
77
+ signed char* expected = (signed char*)"my string";
78
+ ASSERT_EQUAL(*expected, *data);
79
+
80
+ code = R"(Rice::Buffer≺signed char≻.new([0, 127, 128, 255, 256, -128, -129, -255]))";
81
+ result = m.instance_eval(code);
82
+ buffer = std::move(*result);
83
+ data = buffer.ptr();
84
+
85
+ ASSERT_EQUAL(data[0], 0);
86
+ ASSERT_EQUAL(data[1], 127);
87
+ ASSERT_EQUAL(data[2], -128);
88
+ ASSERT_EQUAL(data[3], -1);
89
+ ASSERT_EQUAL(data[4], 0);
90
+ ASSERT_EQUAL(data[5], -128);
91
+ ASSERT_EQUAL(data[6], 127);
92
+ ASSERT_EQUAL(data[7], 1);
93
+ }
94
+
95
+ TESTCASE(char_pointer_const)
96
+ {
97
+ define_buffer<char>();
98
+ Module m = define_module("Testing");
99
+
100
+ std::string code = R"(Rice::Buffer≺char≻.new("my string"))";
101
+
102
+ Data_Object<Buffer<char>> result = m.instance_eval(code);
103
+ Buffer<char> buffer = std::move(*result);
104
+ char* data = buffer.ptr();
105
+
106
+ const char* expected = "my string";
107
+ ASSERT_EQUAL(expected, data);
108
+
109
+ code = R"(Rice::Buffer≺char≻.new(""))";
110
+ result = m.instance_eval(code);
111
+ buffer = std::move(*result);
112
+ data = buffer.ptr();
113
+
114
+ expected = "";
115
+ ASSERT_EQUAL(expected, data);
116
+ }
117
+
118
+ TESTCASE(unsigned_char_pointer)
119
+ {
120
+ define_buffer<unsigned char>();
121
+ Module m = define_module("Testing");
122
+
123
+ std::string code = R"(Rice::Buffer≺unsigned char≻.new([0, 127, 128, 255, 256, -128, -129, -255]))";
124
+ Data_Object<Buffer<unsigned char>> result = m.instance_eval(code);
125
+ Buffer<unsigned char> buffer = std::move(*result);
126
+ unsigned char* data = buffer.ptr();
127
+
128
+ ASSERT_EQUAL(data[0], 0x0);
129
+ ASSERT_EQUAL(data[1], 0x7F);
130
+ ASSERT_EQUAL(data[2], 0x80);
131
+ ASSERT_EQUAL(data[3], 0xFF);
132
+ ASSERT_EQUAL(data[4], 0x00);
133
+ ASSERT_EQUAL(data[5], 0x80);
134
+ ASSERT_EQUAL(data[6], 0x7F);
135
+ ASSERT_EQUAL(data[7], 0x01);
136
+
137
+ code = R"(array = [0, 127, 128, 255, 256, -128, -129, -255]
138
+ packed = array.pack("C*")
139
+ Rice::Buffer≺unsigned char≻.new(packed))";
140
+ result = m.instance_eval(code);
141
+ buffer = std::move(*result);
142
+ data = buffer.ptr();
143
+
144
+ ASSERT_EQUAL(data[0], 0x0);
145
+ ASSERT_EQUAL(data[1], 0x7F);
146
+ ASSERT_EQUAL(data[2], 0x80);
147
+ ASSERT_EQUAL(data[3], 0xFF);
148
+ ASSERT_EQUAL(data[4], 0x00);
149
+ ASSERT_EQUAL(data[5], 0x80);
150
+ ASSERT_EQUAL(data[6], 0x7F);
151
+ ASSERT_EQUAL(data[7], 0x01);
152
+ }
153
+
154
+ TESTCASE(float_array_array)
155
+ {
156
+ define_buffer<float*>();
157
+ Module m = define_module("Testing");
158
+
159
+ std::string code = R"(Rice::Buffer≺float∗≻.new([[1.1, 2.2], [3.3, 4.4], [5.5, 6.6]]))";
160
+ Data_Object<Buffer<float*>> result = m.instance_eval(code);
161
+ Buffer<float*> buffer = std::move(*result);
162
+
163
+ ASSERT_EQUAL(3, (int)buffer.size());
164
+
165
+ const Buffer<float>& bufferInner1 = buffer[0];
166
+ ASSERT_EQUAL(2, (int)bufferInner1.size());
167
+
168
+ const Buffer<float>& bufferInner2 = buffer[1];
169
+ ASSERT_EQUAL(2, (int)bufferInner2.size());
170
+
171
+ const Buffer<float>& bufferInner3 = buffer[2];
172
+ ASSERT_EQUAL(2, (int)bufferInner3.size());
173
+ }
174
+
175
+ TESTCASE(wrong_type)
176
+ {
177
+ define_buffer<float*>();
178
+ Module m = define_module("Testing");
179
+
180
+ std::string code = R"(Rice::Buffer≺float∗≻.new([[4, "bad"], [2, 1]]))";
181
+
182
+ ASSERT_EXCEPTION_CHECK(
183
+ Exception,
184
+ m.module_eval(code),
185
+ ASSERT_EQUAL("can't convert String into Float", ex.what())
186
+ );
187
+ }
188
+
189
+ namespace
190
+ {
191
+ void updateRef(int& ref)
192
+ {
193
+ ref = 4;
194
+ }
195
+
196
+ void updatePtr(int* ptr)
197
+ {
198
+ *ptr = 5;
199
+ }
200
+ }
201
+
202
+ TESTCASE(update_reference)
203
+ {
204
+ define_buffer<int>();
205
+ Module m = define_module("Testing");
206
+ m.define_module_function("update_reference", &updateRef);
207
+
208
+ std::string code = R"(buffer = Rice::Buffer≺int≻.new(0)
209
+ update_reference(buffer)
210
+ buffer.to_ary(1).first)";
211
+
212
+ Object result = m.module_eval(code);
213
+ ASSERT_EQUAL(4, detail::From_Ruby<int>().convert(result));
214
+
215
+ code = R"(buffer = Rice::Buffer≺int≻.new(0)
216
+ update_reference(buffer)
217
+ buffer[0])";
218
+
219
+ result = m.module_eval(code);
220
+ ASSERT_EQUAL(4, detail::From_Ruby<int>().convert(result));
221
+
222
+ code = R"(buffer = Rice::Buffer≺int≻.new(0)
223
+ update_reference(buffer)
224
+ buffer[1])";
225
+
226
+ ASSERT_EXCEPTION_CHECK(
227
+ Exception,
228
+ m.module_eval(code),
229
+ ASSERT_EQUAL("index 1 outside of bounds: 0..1", ex.what())
230
+ );
231
+ }
232
+
233
+ TESTCASE(update_ptr)
234
+ {
235
+ define_buffer<int>();
236
+ Module m = define_module("Testing");
237
+ m.define_module_function("update_pointer", &updatePtr);
238
+
239
+ std::string code = R"(buffer = Rice::Buffer≺int≻.new(0)
240
+ update_pointer(buffer)
241
+ buffer.to_ary(1).first)";
242
+
243
+ Object result = m.module_eval(code);
244
+ ASSERT_EQUAL(5, detail::From_Ruby<int>().convert(result));
245
+
246
+ code = R"(buffer = Rice::Buffer≺int≻.new(0)
247
+ update_pointer(buffer)
248
+ buffer[0])";
249
+
250
+ result = m.module_eval(code);
251
+ ASSERT_EQUAL(5, detail::From_Ruby<int>().convert(result));
252
+
253
+ code = R"(buffer = Rice::Buffer≺int≻.new(0)
254
+ update_pointer(buffer)
255
+ buffer[1])";
256
+
257
+ ASSERT_EXCEPTION_CHECK(
258
+ Exception,
259
+ m.module_eval(code),
260
+ ASSERT_EQUAL("index 1 outside of bounds: 0..1", ex.what())
261
+ );
262
+ }
263
+
264
+ TESTCASE(update_buffer)
265
+ {
266
+ define_buffer<int>();
267
+ Module m = define_module("Testing");
268
+
269
+ std::string code = R"(buffer = Rice::Buffer≺int≻.new(0)
270
+ buffer[0] = 8
271
+ buffer[0])";
272
+
273
+ Object result = m.module_eval(code);
274
+ ASSERT_EQUAL(8, detail::From_Ruby<int>().convert(result));
275
+
276
+ code = R"(buffer = Rice::Buffer≺int≻.new(0)
277
+ buffer[1] = 9
278
+ buffer[1])";
279
+
280
+ ASSERT_EXCEPTION_CHECK(
281
+ Exception,
282
+ m.module_eval(code),
283
+ ASSERT_EQUAL("index 1 outside of bounds: 0..1", ex.what())
284
+ );
285
+ }
@@ -11,6 +11,11 @@ SETUP(Builtin_Object)
11
11
  embed_ruby();
12
12
  }
13
13
 
14
+ TEARDOWN(Builtin_Object)
15
+ {
16
+ rb_gc_start();
17
+ }
18
+
14
19
  TESTCASE(construct_with_object)
15
20
  {
16
21
  Class c(rb_cObject);