rice 4.5.0 → 4.6.1

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 (167) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  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/Rakefile +5 -4
  8. data/include/rice/rice.hpp +5619 -3129
  9. data/include/rice/stl.hpp +2319 -1234
  10. data/lib/make_rice_headers.rb +79 -0
  11. data/lib/mkmf-rice.rb +4 -0
  12. data/lib/rice/version.rb +3 -0
  13. data/lib/rice.rb +1 -0
  14. data/lib/rubygems/builder.rb +11 -0
  15. data/lib/rubygems/cmake_builder.rb +113 -0
  16. data/lib/rubygems_plugin.rb +9 -0
  17. data/rice/Arg.hpp +7 -1
  18. data/rice/Arg.ipp +11 -2
  19. data/rice/Buffer.hpp +168 -0
  20. data/rice/Buffer.ipp +788 -0
  21. data/rice/Constructor.ipp +3 -3
  22. data/rice/Data_Object.hpp +2 -3
  23. data/rice/Data_Object.ipp +188 -188
  24. data/rice/Data_Type.hpp +7 -5
  25. data/rice/Data_Type.ipp +79 -52
  26. data/rice/Enum.hpp +0 -1
  27. data/rice/Enum.ipp +26 -23
  28. data/rice/Init.hpp +8 -0
  29. data/rice/Init.ipp +8 -0
  30. data/rice/MemoryView.ipp +1 -41
  31. data/rice/Return.hpp +1 -1
  32. data/rice/Return.ipp +6 -0
  33. data/rice/cpp_api/Array.hpp +209 -0
  34. data/rice/cpp_api/Array.ipp +304 -0
  35. data/rice/cpp_api/Builtin_Object.hpp +31 -0
  36. data/rice/cpp_api/Builtin_Object.ipp +37 -0
  37. data/rice/cpp_api/Class.hpp +70 -0
  38. data/rice/cpp_api/Class.ipp +97 -0
  39. data/rice/cpp_api/Encoding.hpp +32 -0
  40. data/rice/cpp_api/Encoding.ipp +59 -0
  41. data/rice/cpp_api/Hash.hpp +194 -0
  42. data/rice/cpp_api/Hash.ipp +257 -0
  43. data/rice/cpp_api/Identifier.hpp +46 -0
  44. data/rice/cpp_api/Identifier.ipp +31 -0
  45. data/rice/cpp_api/Module.hpp +72 -0
  46. data/rice/cpp_api/Module.ipp +101 -0
  47. data/rice/cpp_api/Object.hpp +272 -0
  48. data/rice/cpp_api/Object.ipp +235 -0
  49. data/rice/cpp_api/String.hpp +74 -0
  50. data/rice/cpp_api/String.ipp +120 -0
  51. data/rice/cpp_api/Struct.hpp +113 -0
  52. data/rice/cpp_api/Struct.ipp +92 -0
  53. data/rice/cpp_api/Symbol.hpp +46 -0
  54. data/rice/cpp_api/Symbol.ipp +93 -0
  55. data/rice/cpp_api/shared_methods.hpp +134 -0
  56. data/rice/detail/MethodInfo.hpp +1 -9
  57. data/rice/detail/MethodInfo.ipp +5 -72
  58. data/rice/detail/Native.hpp +3 -2
  59. data/rice/detail/Native.ipp +32 -4
  60. data/rice/detail/NativeAttributeGet.hpp +3 -2
  61. data/rice/detail/NativeAttributeGet.ipp +20 -3
  62. data/rice/detail/NativeAttributeSet.hpp +3 -2
  63. data/rice/detail/NativeAttributeSet.ipp +11 -23
  64. data/rice/detail/NativeCallbackFFI.ipp +2 -1
  65. data/rice/detail/NativeFunction.hpp +17 -6
  66. data/rice/detail/NativeFunction.ipp +169 -64
  67. data/rice/detail/NativeIterator.hpp +3 -2
  68. data/rice/detail/NativeIterator.ipp +8 -2
  69. data/rice/detail/RubyFunction.ipp +1 -0
  70. data/rice/detail/RubyType.hpp +2 -5
  71. data/rice/detail/RubyType.ipp +50 -5
  72. data/rice/detail/Type.hpp +3 -1
  73. data/rice/detail/Type.ipp +60 -31
  74. data/rice/detail/Wrapper.hpp +68 -33
  75. data/rice/detail/Wrapper.ipp +103 -113
  76. data/rice/detail/from_ruby.hpp +5 -4
  77. data/rice/detail/from_ruby.ipp +737 -365
  78. data/rice/detail/to_ruby.ipp +1092 -186
  79. data/rice/global_function.ipp +1 -1
  80. data/rice/libc/file.hpp +11 -0
  81. data/rice/libc/file.ipp +32 -0
  82. data/rice/rice.hpp +23 -16
  83. data/rice/stl/complex.hpp +6 -0
  84. data/rice/stl/complex.ipp +93 -0
  85. data/rice/stl/exception.hpp +11 -0
  86. data/rice/stl/exception.ipp +29 -0
  87. data/rice/stl/exception_ptr.hpp +6 -0
  88. data/rice/stl/exception_ptr.ipp +27 -0
  89. data/rice/stl/map.hpp +12 -0
  90. data/rice/stl/map.ipp +469 -0
  91. data/rice/stl/monostate.hpp +6 -0
  92. data/rice/stl/monostate.ipp +80 -0
  93. data/rice/stl/multimap.hpp +14 -0
  94. data/rice/stl/multimap.ipp +448 -0
  95. data/rice/stl/optional.hpp +6 -0
  96. data/rice/stl/optional.ipp +118 -0
  97. data/rice/stl/pair.hpp +13 -0
  98. data/rice/stl/pair.ipp +155 -0
  99. data/rice/stl/reference_wrapper.hpp +6 -0
  100. data/rice/stl/reference_wrapper.ipp +41 -0
  101. data/rice/stl/set.hpp +12 -0
  102. data/rice/stl/set.ipp +495 -0
  103. data/rice/stl/shared_ptr.hpp +28 -0
  104. data/rice/stl/shared_ptr.ipp +224 -0
  105. data/rice/stl/string.hpp +6 -0
  106. data/rice/stl/string.ipp +158 -0
  107. data/rice/stl/string_view.hpp +6 -0
  108. data/rice/stl/string_view.ipp +65 -0
  109. data/rice/stl/tuple.hpp +6 -0
  110. data/rice/stl/tuple.ipp +128 -0
  111. data/rice/stl/type_index.hpp +6 -0
  112. data/rice/stl/type_index.ipp +30 -0
  113. data/rice/stl/type_info.hpp +6 -0
  114. data/rice/stl/type_info.ipp +29 -0
  115. data/rice/stl/unique_ptr.hpp +22 -0
  116. data/rice/stl/unique_ptr.ipp +139 -0
  117. data/rice/stl/unordered_map.hpp +12 -0
  118. data/rice/stl/unordered_map.ipp +469 -0
  119. data/rice/stl/variant.hpp +6 -0
  120. data/rice/stl/variant.ipp +242 -0
  121. data/rice/stl/vector.hpp +12 -0
  122. data/rice/stl/vector.ipp +589 -0
  123. data/rice/stl.hpp +7 -3
  124. data/rice/traits/attribute_traits.hpp +26 -0
  125. data/rice/traits/function_traits.hpp +95 -0
  126. data/rice/traits/method_traits.hpp +47 -0
  127. data/rice/traits/rice_traits.hpp +172 -0
  128. data/rice.gemspec +85 -0
  129. data/test/embed_ruby.cpp +3 -0
  130. data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
  131. data/test/test_Array.cpp +6 -3
  132. data/test/test_Attribute.cpp +91 -9
  133. data/test/test_Buffer.cpp +340 -0
  134. data/test/test_Callback.cpp +2 -3
  135. data/test/test_Data_Object.cpp +88 -34
  136. data/test/test_Data_Type.cpp +106 -65
  137. data/test/test_Director.cpp +7 -3
  138. data/test/test_Enum.cpp +5 -2
  139. data/test/test_File.cpp +1 -1
  140. data/test/test_From_Ruby.cpp +180 -113
  141. data/test/test_Iterator.cpp +1 -1
  142. data/test/{test_JumpException.cpp → test_Jump_Exception.cpp} +1 -0
  143. data/test/test_Keep_Alive.cpp +7 -18
  144. data/test/test_Keep_Alive_No_Wrapper.cpp +0 -1
  145. data/test/test_Module.cpp +13 -6
  146. data/test/test_Native_Registry.cpp +0 -1
  147. data/test/test_Overloads.cpp +180 -5
  148. data/test/test_Ownership.cpp +100 -57
  149. data/test/test_Proc.cpp +0 -1
  150. data/test/test_Self.cpp +4 -4
  151. data/test/test_Stl_Map.cpp +37 -39
  152. data/test/test_Stl_Multimap.cpp +693 -0
  153. data/test/test_Stl_Pair.cpp +8 -8
  154. data/test/test_Stl_Reference_Wrapper.cpp +4 -2
  155. data/test/test_Stl_Set.cpp +790 -0
  156. data/test/{test_Stl_SmartPointer.cpp → test_Stl_SharedPtr.cpp} +97 -127
  157. data/test/test_Stl_Tuple.cpp +116 -0
  158. data/test/test_Stl_Type.cpp +1 -1
  159. data/test/test_Stl_UniquePtr.cpp +202 -0
  160. data/test/test_Stl_Unordered_Map.cpp +28 -34
  161. data/test/test_Stl_Variant.cpp +217 -89
  162. data/test/test_Stl_Vector.cpp +209 -83
  163. data/test/test_To_Ruby.cpp +373 -1
  164. data/test/test_Type.cpp +85 -14
  165. data/test/test_global_functions.cpp +17 -4
  166. metadata +94 -10
  167. data/rice/detail/TupleIterator.hpp +0 -14
@@ -0,0 +1,589 @@
1
+ #include <vector>
2
+
3
+ namespace Rice
4
+ {
5
+ namespace stl
6
+ {
7
+ template<typename T>
8
+ class VectorHelper
9
+ {
10
+ // We do NOT use Reference_T and instead use Parameter_T to avoid the weirdness
11
+ // of std::vector<bool>. Reference_T is actually a proxy class that we do not
12
+ // want to have to register with Rice nor do we want to pass it around.
13
+ using Value_T = typename T::value_type;
14
+ using Size_T = typename T::size_type;
15
+ using Difference_T = typename T::difference_type;
16
+ // For To_Ruby_T however we do need to use reference type because this is what
17
+ // will be passed by an interator to To_Ruby#convert
18
+ using Reference_T = typename T::reference;
19
+ using Parameter_T = std::conditional_t<std::is_pointer_v<Value_T>, Value_T, Value_T&>;
20
+ using To_Ruby_T = detail::remove_cv_recursive_t<typename T::reference>;
21
+
22
+ public:
23
+ VectorHelper(Data_Type<T> klass) : klass_(klass)
24
+ {
25
+ this->define_constructors();
26
+ this->define_constructable_methods();
27
+ this->define_capacity_methods();
28
+ this->define_access_methods();
29
+ this->define_comparable_methods();
30
+ this->define_modify_methods();
31
+ this->define_enumerable();
32
+ this->define_to_array();
33
+ this->define_to_s();
34
+ }
35
+
36
+ private:
37
+
38
+ // Helper method to translate Ruby indices to vector indices
39
+ Difference_T normalizeIndex(Size_T size, Difference_T index, bool enforceBounds = false)
40
+ {
41
+ // Negative indices mean count from the right. Note that negative indices
42
+ // wrap around!
43
+ if (index < 0)
44
+ {
45
+ index = ((-index) % size);
46
+ index = index > 0 ? size - index : index;
47
+ }
48
+
49
+ if (enforceBounds && (index < 0 || index >= (Difference_T)size))
50
+ {
51
+ throw std::out_of_range("Invalid index: " + std::to_string(index));
52
+ }
53
+
54
+ return index;
55
+ };
56
+
57
+ void define_constructors()
58
+ {
59
+ klass_.define_constructor(Constructor<T>())
60
+ .define_constructor(Constructor<T, Size_T, const Parameter_T>())
61
+ .define_constructor(Constructor<T, const T&>());
62
+
63
+ if constexpr (std::is_default_constructible_v<Value_T>)
64
+ {
65
+ klass_.define_constructor(Constructor<T, Size_T>());
66
+ }
67
+
68
+ // Allow creation of a vector from a Ruby Array
69
+ klass_.define_method("initialize", [](VALUE self, Array array) -> void
70
+ {
71
+ // Create a new vector from the array
72
+ T* data = new T();
73
+ data->reserve(array.size());
74
+
75
+ detail::From_Ruby<Value_T> fromRuby;
76
+
77
+ for (long i = 0; i < array.size(); i++)
78
+ {
79
+ VALUE element = detail::protect(rb_ary_entry, array, i);
80
+ data->push_back(fromRuby.convert(element));
81
+ }
82
+
83
+ // Wrap the vector
84
+ detail::wrapConstructed<T>(self, Data_Type<T>::ruby_data_type(), data, true);
85
+ });
86
+ }
87
+
88
+ void define_constructable_methods()
89
+ {
90
+ if constexpr (std::is_default_constructible_v<Value_T> && std::is_same_v<Value_T, bool>)
91
+ {
92
+ klass_.define_method("resize", static_cast<void (T::*)(const size_t, bool)>(&T::resize));
93
+ }
94
+ else if constexpr (std::is_default_constructible_v<Value_T>)
95
+ {
96
+ klass_.define_method("resize", static_cast<void (T::*)(const size_t)>(&T::resize));
97
+ }
98
+ else
99
+ {
100
+ klass_.define_method("resize", [](const T& vector, Size_T newSize)
101
+ {
102
+ // Do nothing
103
+ });
104
+ }
105
+ }
106
+
107
+ void define_capacity_methods()
108
+ {
109
+ klass_.define_method("empty?", &T::empty)
110
+ .define_method("capacity", &T::capacity)
111
+ .define_method("max_size", &T::max_size)
112
+ .define_method("reserve", &T::reserve)
113
+ .define_method("size", &T::size);
114
+
115
+ rb_define_alias(klass_, "count", "size");
116
+ rb_define_alias(klass_, "length", "size");
117
+ //detail::protect(rb_define_alias, klass_, "count", "size");
118
+ //detail::protect(rb_define_alias, klass_, "length", "size");
119
+ }
120
+
121
+ void define_access_methods()
122
+ {
123
+ // Access methods
124
+ klass_.define_method("first", [](const T& vector) -> std::optional<Value_T>
125
+ {
126
+ if (vector.size() > 0)
127
+ {
128
+ return vector.front();
129
+ }
130
+ else
131
+ {
132
+ return std::nullopt;
133
+ }
134
+ })
135
+ .define_method("last", [](const T& vector) -> std::optional<Value_T>
136
+ {
137
+ if (vector.size() > 0)
138
+ {
139
+ return vector.back();
140
+ }
141
+ else
142
+ {
143
+ return std::nullopt;
144
+ }
145
+ })
146
+ .define_method("[]", [this](const T& vector, Difference_T index) -> std::optional<Value_T>
147
+ {
148
+ index = normalizeIndex(vector.size(), index);
149
+ if (index < 0 || index >= (Difference_T)vector.size())
150
+ {
151
+ return std::nullopt;
152
+ }
153
+ else
154
+ {
155
+ return vector[index];
156
+ }
157
+ })
158
+ .define_method("[]", [this](const T& vector, Difference_T start, Difference_T length) -> VALUE
159
+ {
160
+ start = normalizeIndex(vector.size(), start);
161
+ if (start < 0 || start >= (Difference_T)vector.size())
162
+ {
163
+ return rb_ary_new();
164
+ }
165
+ else
166
+ {
167
+ auto begin = vector.begin() + start;
168
+
169
+ // Ruby does not throw an exception when the length is too long
170
+ Difference_T size = (Difference_T)vector.size();
171
+ if (start + length > size)
172
+ {
173
+ length = size - start;
174
+ }
175
+
176
+ auto finish = vector.begin() + start + length;
177
+ T slice(begin, finish);
178
+
179
+ VALUE result = rb_ary_new();
180
+ std::for_each(slice.begin(), slice.end(), [&result](const Reference_T element)
181
+ {
182
+ VALUE value = detail::To_Ruby<Parameter_T>().convert(element);
183
+ rb_ary_push(result, value);
184
+ });
185
+
186
+ return result;
187
+ }
188
+ }, Return().setValue());
189
+
190
+ if constexpr (!std::is_same_v<Value_T, bool>)
191
+ {
192
+ define_buffer<Value_T>();
193
+ klass_.template define_method<Value_T*(T::*)()>("data", &T::data);
194
+ }
195
+
196
+ rb_define_alias(klass_, "at", "[]");
197
+ }
198
+
199
+ // Methods that require Value_T to support operator==
200
+ void define_comparable_methods()
201
+ {
202
+ if constexpr (detail::is_comparable_v<T>)
203
+ {
204
+ klass_.define_method("delete", [](T& vector, Parameter_T element) -> std::optional<Value_T>
205
+ {
206
+ auto iter = std::find(vector.begin(), vector.end(), element);
207
+ if (iter == vector.end())
208
+ {
209
+ return std::nullopt;
210
+ }
211
+ else
212
+ {
213
+ Value_T result = *iter;
214
+ vector.erase(iter);
215
+ return result;
216
+ }
217
+ })
218
+ .define_method("include?", [](T& vector, Parameter_T element)
219
+ {
220
+ return std::find(vector.begin(), vector.end(), element) != vector.end();
221
+ })
222
+ .define_method("index", [](T& vector, Parameter_T element) -> std::optional<Difference_T>
223
+ {
224
+ auto iter = std::find(vector.begin(), vector.end(), element);
225
+ if (iter == vector.end())
226
+ {
227
+ return std::nullopt;
228
+ }
229
+ else
230
+ {
231
+ return iter - vector.begin();
232
+ }
233
+ });
234
+ }
235
+ else
236
+ {
237
+ klass_.define_method("delete", [](T& vector, Parameter_T element) -> std::optional<Value_T>
238
+ {
239
+ return std::nullopt;
240
+ })
241
+ .define_method("include?", [](const T& vector, Parameter_T element)
242
+ {
243
+ return false;
244
+ })
245
+ .define_method("index", [](const T& vector, Parameter_T element) -> std::optional<Difference_T>
246
+ {
247
+ return std::nullopt;
248
+ });
249
+ }
250
+ }
251
+
252
+ void define_modify_methods()
253
+ {
254
+ klass_.define_method("clear", &T::clear)
255
+ .define_method("delete_at", [](T& vector, const size_t& pos)
256
+ {
257
+ auto iter = vector.begin() + pos;
258
+ Value_T result = *iter;
259
+ vector.erase(iter);
260
+ return result;
261
+ })
262
+ .define_method("insert", [this](T& vector, Difference_T index, Parameter_T element) -> T&
263
+ {
264
+ index = normalizeIndex(vector.size(), index, true);
265
+ auto iter = vector.begin() + index;
266
+ vector.insert(iter, element);
267
+ return vector;
268
+ })
269
+ .define_method("pop", [](T& vector) -> std::optional<Value_T>
270
+ {
271
+ if (vector.size() > 0)
272
+ {
273
+ Value_T result = vector.back();
274
+ vector.pop_back();
275
+ return result;
276
+ }
277
+ else
278
+ {
279
+ return std::nullopt;
280
+ }
281
+ })
282
+ .define_method("push", [](T& vector, Parameter_T element) -> T&
283
+ {
284
+ vector.push_back(element);
285
+ return vector;
286
+ })
287
+ .define_method("shrink_to_fit", &T::shrink_to_fit)
288
+ .define_method("[]=", [this](T& vector, Difference_T index, Parameter_T element) -> Parameter_T
289
+ {
290
+ index = normalizeIndex(vector.size(), index, true);
291
+ vector[index] = element;
292
+ return element;
293
+ });
294
+
295
+ rb_define_alias(klass_, "push_back", "push");
296
+ rb_define_alias(klass_, "<<", "push");
297
+ rb_define_alias(klass_, "append", "push");
298
+ }
299
+
300
+ void define_enumerable()
301
+ {
302
+ // Add enumerable support
303
+ klass_.template define_iterator<typename T::iterator(T::*)()>(&T::begin, &T::end);
304
+ }
305
+
306
+ void define_to_array()
307
+ {
308
+ // Add enumerable support
309
+ klass_.define_method("to_a", [](T& vector)
310
+ {
311
+ VALUE result = rb_ary_new();
312
+ std::for_each(vector.begin(), vector.end(), [&result](const Reference_T element)
313
+ {
314
+ VALUE value = detail::To_Ruby<Parameter_T>().convert(element);
315
+ rb_ary_push(result, value);
316
+ });
317
+
318
+ return result;
319
+ }, Return().setValue());
320
+ }
321
+
322
+ void define_to_s()
323
+ {
324
+ if constexpr (detail::is_ostreamable_v<Value_T>)
325
+ {
326
+ klass_.define_method("to_s", [](const T& vector)
327
+ {
328
+ auto iter = vector.begin();
329
+ auto finish = vector.size() > 1000 ? vector.begin() + 1000 : vector.end();
330
+
331
+ std::stringstream stream;
332
+ stream << "[";
333
+
334
+ for (; iter != finish; iter++)
335
+ {
336
+ if (iter == vector.begin())
337
+ {
338
+ stream << *iter;
339
+ }
340
+ else
341
+ {
342
+ stream << ", " << *iter;
343
+ }
344
+ }
345
+
346
+ stream << "]";
347
+ return stream.str();
348
+ });
349
+ }
350
+ else
351
+ {
352
+ klass_.define_method("to_s", [](const T& vector)
353
+ {
354
+ return "[Not printable]";
355
+ });
356
+ }
357
+ }
358
+
359
+ private:
360
+ Data_Type<T> klass_;
361
+ };
362
+ } // namespace
363
+
364
+ template<typename T>
365
+ Data_Type<std::vector<T>> define_vector(std::string klassName)
366
+ {
367
+ using Vector_T = std::vector<T>;
368
+ using Data_Type_T = Data_Type<Vector_T>;
369
+
370
+ if (klassName.empty())
371
+ {
372
+ std::string typeName = detail::typeName(typeid(Vector_T));
373
+ klassName = detail::rubyClassName(typeName);
374
+ }
375
+
376
+ Module rb_mStd = define_module("Std");
377
+ if (Data_Type_T::check_defined(klassName, rb_mStd))
378
+ {
379
+ return Data_Type_T();
380
+ }
381
+
382
+ Identifier id(klassName);
383
+ Data_Type_T result = define_class_under<detail::intrinsic_type<Vector_T>>(rb_mStd, id);
384
+ stl::VectorHelper helper(result);
385
+ return result;
386
+ }
387
+
388
+
389
+ namespace detail
390
+ {
391
+ template<typename T>
392
+ struct Type<std::vector<T>>
393
+ {
394
+ static bool verify()
395
+ {
396
+ Type<intrinsic_type<T>>::verify();
397
+
398
+ if (!Data_Type<std::vector<T>>::is_defined())
399
+ {
400
+ define_vector<T>();
401
+ }
402
+
403
+ return true;
404
+ }
405
+ };
406
+
407
+ template<typename T>
408
+ class From_Ruby<std::vector<T>>
409
+ {
410
+ public:
411
+ From_Ruby() = default;
412
+
413
+ explicit From_Ruby(Arg * arg) : arg_(arg)
414
+ {
415
+ }
416
+
417
+ Convertible is_convertible(VALUE value)
418
+ {
419
+ switch (rb_type(value))
420
+ {
421
+ case RUBY_T_DATA:
422
+ return Data_Type<std::vector<T>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
423
+ break;
424
+ case RUBY_T_ARRAY:
425
+ if constexpr (std::is_default_constructible_v<T>)
426
+ {
427
+ return Convertible::Cast;
428
+ }
429
+ default:
430
+ return Convertible::None;
431
+ }
432
+ }
433
+
434
+ std::vector<T> convert(VALUE value)
435
+ {
436
+ switch (rb_type(value))
437
+ {
438
+ case RUBY_T_DATA:
439
+ {
440
+ // This is a wrapped vector (hopefully!)
441
+ return *detail::unwrap<std::vector<T>>(value, Data_Type<std::vector<T>>::ruby_data_type(), false);
442
+ }
443
+ case RUBY_T_ARRAY:
444
+ {
445
+ // If this an Ruby array and the vector type is copyable
446
+ if constexpr (std::is_default_constructible_v<T>)
447
+ {
448
+ return Array(value).to_vector<T>();
449
+ }
450
+ }
451
+ default:
452
+ {
453
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
454
+ detail::protect(rb_obj_classname, value), "std::vector");
455
+ }
456
+ }
457
+ }
458
+
459
+ private:
460
+ Arg* arg_ = nullptr;
461
+ };
462
+
463
+ template<typename T>
464
+ class From_Ruby<std::vector<T>&>
465
+ {
466
+ public:
467
+ From_Ruby() = default;
468
+
469
+ explicit From_Ruby(Arg * arg) : arg_(arg)
470
+ {
471
+ }
472
+
473
+ Convertible is_convertible(VALUE value)
474
+ {
475
+ switch (rb_type(value))
476
+ {
477
+ case RUBY_T_DATA:
478
+ return Data_Type<std::vector<T>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
479
+ break;
480
+ case RUBY_T_ARRAY:
481
+ if constexpr (std::is_default_constructible_v<T>)
482
+ {
483
+ return Convertible::Cast;
484
+ }
485
+ default:
486
+ return Convertible::None;
487
+ }
488
+ }
489
+
490
+ std::vector<T>& convert(VALUE value)
491
+ {
492
+ switch (rb_type(value))
493
+ {
494
+ case RUBY_T_DATA:
495
+ {
496
+ // This is a wrapped vector (hopefully!)
497
+ return *detail::unwrap<std::vector<T>>(value, Data_Type<std::vector<T>>::ruby_data_type(), false);
498
+ }
499
+ case RUBY_T_ARRAY:
500
+ {
501
+ // If this an Ruby array and the vector type is copyable
502
+ if constexpr (std::is_default_constructible_v<T>)
503
+ {
504
+ this->converted_ = Array(value).to_vector<T>();
505
+ return this->converted_;
506
+ }
507
+ }
508
+ default:
509
+ {
510
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
511
+ detail::protect(rb_obj_classname, value), "std::vector");
512
+ }
513
+ }
514
+ }
515
+
516
+ private:
517
+ Arg* arg_ = nullptr;
518
+ std::vector<T> converted_;
519
+ };
520
+
521
+ template<typename T>
522
+ class From_Ruby<std::vector<T>*>
523
+ {
524
+ public:
525
+ Convertible is_convertible(VALUE value)
526
+ {
527
+ switch (rb_type(value))
528
+ {
529
+ case RUBY_T_DATA:
530
+ return Data_Type<std::vector<T>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
531
+ break;
532
+ case RUBY_T_NIL:
533
+ return Convertible::Exact;
534
+ break;
535
+ case RUBY_T_ARRAY:
536
+ if constexpr (std::is_default_constructible_v<T>)
537
+ {
538
+ return Convertible::Cast;
539
+ }
540
+ default:
541
+ return Convertible::None;
542
+ }
543
+ }
544
+
545
+ std::vector<T>* convert(VALUE value)
546
+ {
547
+ switch (rb_type(value))
548
+ {
549
+ case RUBY_T_DATA:
550
+ {
551
+ // This is a wrapped vector (hopefully!)
552
+ return detail::unwrap<std::vector<T>>(value, Data_Type<std::vector<T>>::ruby_data_type(), false);
553
+ }
554
+ case RUBY_T_ARRAY:
555
+ {
556
+ // If this a Ruby array and the vector type is copyable
557
+ if constexpr (std::is_default_constructible_v<T>)
558
+ {
559
+ this->converted_ = Array(value).to_vector<T>();
560
+ return &this->converted_;
561
+ }
562
+ }
563
+ default:
564
+ {
565
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
566
+ detail::protect(rb_obj_classname, value), "std::vector");
567
+ }
568
+ }
569
+ }
570
+
571
+ private:
572
+ std::vector<T> converted_;
573
+ };
574
+ }
575
+
576
+ // Special handling for std::vector<bool>
577
+ namespace detail
578
+ {
579
+ template<>
580
+ class To_Ruby<std::vector<bool>::reference>
581
+ {
582
+ public:
583
+ VALUE convert(const std::vector<bool>::reference& value)
584
+ {
585
+ return value ? Qtrue : Qfalse;
586
+ }
587
+ };
588
+ }
589
+ }
data/rice/stl.hpp CHANGED
@@ -8,13 +8,17 @@
8
8
  #include "stl/complex.hpp"
9
9
  #include "stl/optional.hpp"
10
10
  #include "stl/reference_wrapper.hpp"
11
- #include "stl/smart_ptr.hpp"
11
+ #include "stl/pair.hpp"
12
+ #include "stl/map.hpp"
12
13
  #include "stl/monostate.hpp"
14
+ #include "stl/multimap.hpp"
15
+ #include "stl/set.hpp"
16
+ #include "stl/shared_ptr.hpp"
17
+ #include "stl/tuple.hpp"
13
18
  #include "stl/type_index.hpp"
14
19
  #include "stl/type_info.hpp"
15
20
  #include "stl/variant.hpp"
16
- #include "stl/pair.hpp"
17
- #include "stl/map.hpp"
21
+ #include "stl/unique_ptr.hpp"
18
22
  #include "stl/unordered_map.hpp"
19
23
  #include "stl/vector.hpp"
20
24
 
@@ -0,0 +1,26 @@
1
+ #ifndef Rice__detail__attribute_traits__hpp_
2
+ #define Rice__detail__attribute_traits__hpp_
3
+
4
+ #include <tuple>
5
+
6
+ namespace Rice::detail
7
+ {
8
+ // Base class
9
+ template<typename Attribute_T>
10
+ struct attribute_traits;
11
+
12
+ template<typename Attribute_T>
13
+ struct attribute_traits<Attribute_T*>
14
+ {
15
+ using attr_type = Attribute_T;
16
+ using class_type = std::nullptr_t;
17
+ };
18
+
19
+ template<typename Attribute_T, typename Class_T>
20
+ struct attribute_traits<Attribute_T(Class_T::*)>
21
+ {
22
+ using attr_type = Attribute_T;
23
+ using class_type = Class_T;
24
+ };
25
+ }
26
+ #endif // Rice__detail__attribute_traits__hpp_