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
@@ -0,0 +1,590 @@
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
+ define_buffer<Value_T*>();
194
+ klass_.template define_method<Value_T*(T::*)()>("data", &T::data);
195
+ }
196
+
197
+ rb_define_alias(klass_, "at", "[]");
198
+ }
199
+
200
+ // Methods that require Value_T to support operator==
201
+ void define_comparable_methods()
202
+ {
203
+ if constexpr (detail::is_comparable_v<T>)
204
+ {
205
+ klass_.define_method("delete", [](T& vector, Parameter_T element) -> std::optional<Value_T>
206
+ {
207
+ auto iter = std::find(vector.begin(), vector.end(), element);
208
+ if (iter == vector.end())
209
+ {
210
+ return std::nullopt;
211
+ }
212
+ else
213
+ {
214
+ Value_T result = *iter;
215
+ vector.erase(iter);
216
+ return result;
217
+ }
218
+ })
219
+ .define_method("include?", [](T& vector, Parameter_T element)
220
+ {
221
+ return std::find(vector.begin(), vector.end(), element) != vector.end();
222
+ })
223
+ .define_method("index", [](T& vector, Parameter_T element) -> std::optional<Difference_T>
224
+ {
225
+ auto iter = std::find(vector.begin(), vector.end(), element);
226
+ if (iter == vector.end())
227
+ {
228
+ return std::nullopt;
229
+ }
230
+ else
231
+ {
232
+ return iter - vector.begin();
233
+ }
234
+ });
235
+ }
236
+ else
237
+ {
238
+ klass_.define_method("delete", [](T& vector, Parameter_T element) -> std::optional<Value_T>
239
+ {
240
+ return std::nullopt;
241
+ })
242
+ .define_method("include?", [](const T& vector, Parameter_T element)
243
+ {
244
+ return false;
245
+ })
246
+ .define_method("index", [](const T& vector, Parameter_T element) -> std::optional<Difference_T>
247
+ {
248
+ return std::nullopt;
249
+ });
250
+ }
251
+ }
252
+
253
+ void define_modify_methods()
254
+ {
255
+ klass_.define_method("clear", &T::clear)
256
+ .define_method("delete_at", [](T& vector, const size_t& pos)
257
+ {
258
+ auto iter = vector.begin() + pos;
259
+ Value_T result = *iter;
260
+ vector.erase(iter);
261
+ return result;
262
+ })
263
+ .define_method("insert", [this](T& vector, Difference_T index, Parameter_T element) -> T&
264
+ {
265
+ index = normalizeIndex(vector.size(), index, true);
266
+ auto iter = vector.begin() + index;
267
+ vector.insert(iter, element);
268
+ return vector;
269
+ })
270
+ .define_method("pop", [](T& vector) -> std::optional<Value_T>
271
+ {
272
+ if (vector.size() > 0)
273
+ {
274
+ Value_T result = vector.back();
275
+ vector.pop_back();
276
+ return result;
277
+ }
278
+ else
279
+ {
280
+ return std::nullopt;
281
+ }
282
+ })
283
+ .define_method("push", [](T& vector, Parameter_T element) -> T&
284
+ {
285
+ vector.push_back(element);
286
+ return vector;
287
+ })
288
+ .define_method("shrink_to_fit", &T::shrink_to_fit)
289
+ .define_method("[]=", [this](T& vector, Difference_T index, Parameter_T element) -> Parameter_T
290
+ {
291
+ index = normalizeIndex(vector.size(), index, true);
292
+ vector[index] = element;
293
+ return element;
294
+ });
295
+
296
+ rb_define_alias(klass_, "push_back", "push");
297
+ rb_define_alias(klass_, "<<", "push");
298
+ rb_define_alias(klass_, "append", "push");
299
+ }
300
+
301
+ void define_enumerable()
302
+ {
303
+ // Add enumerable support
304
+ klass_.template define_iterator<typename T::iterator(T::*)()>(&T::begin, &T::end);
305
+ }
306
+
307
+ void define_to_array()
308
+ {
309
+ // Add enumerable support
310
+ klass_.define_method("to_a", [](T& vector)
311
+ {
312
+ VALUE result = rb_ary_new();
313
+ std::for_each(vector.begin(), vector.end(), [&result](const Reference_T element)
314
+ {
315
+ VALUE value = detail::To_Ruby<Parameter_T>().convert(element);
316
+ rb_ary_push(result, value);
317
+ });
318
+
319
+ return result;
320
+ }, Return().setValue());
321
+ }
322
+
323
+ void define_to_s()
324
+ {
325
+ if constexpr (detail::is_ostreamable_v<Value_T>)
326
+ {
327
+ klass_.define_method("to_s", [](const T& vector)
328
+ {
329
+ auto iter = vector.begin();
330
+ auto finish = vector.size() > 1000 ? vector.begin() + 1000 : vector.end();
331
+
332
+ std::stringstream stream;
333
+ stream << "[";
334
+
335
+ for (; iter != finish; iter++)
336
+ {
337
+ if (iter == vector.begin())
338
+ {
339
+ stream << *iter;
340
+ }
341
+ else
342
+ {
343
+ stream << ", " << *iter;
344
+ }
345
+ }
346
+
347
+ stream << "]";
348
+ return stream.str();
349
+ });
350
+ }
351
+ else
352
+ {
353
+ klass_.define_method("to_s", [](const T& vector)
354
+ {
355
+ return "[Not printable]";
356
+ });
357
+ }
358
+ }
359
+
360
+ private:
361
+ Data_Type<T> klass_;
362
+ };
363
+ } // namespace
364
+
365
+ template<typename T>
366
+ Data_Type<std::vector<T>> define_vector(std::string klassName)
367
+ {
368
+ using Vector_T = std::vector<T>;
369
+ using Data_Type_T = Data_Type<Vector_T>;
370
+
371
+ if (klassName.empty())
372
+ {
373
+ std::string typeName = detail::typeName(typeid(Vector_T));
374
+ klassName = detail::rubyClassName(typeName);
375
+ }
376
+
377
+ Module rb_mStd = define_module("Std");
378
+ if (Data_Type_T::check_defined(klassName, rb_mStd))
379
+ {
380
+ return Data_Type_T();
381
+ }
382
+
383
+ Identifier id(klassName);
384
+ Data_Type_T result = define_class_under<detail::intrinsic_type<Vector_T>>(rb_mStd, id);
385
+ stl::VectorHelper helper(result);
386
+ return result;
387
+ }
388
+
389
+
390
+ namespace detail
391
+ {
392
+ template<typename T>
393
+ struct Type<std::vector<T>>
394
+ {
395
+ static bool verify()
396
+ {
397
+ Type<intrinsic_type<T>>::verify();
398
+
399
+ if (!Data_Type<std::vector<T>>::is_defined())
400
+ {
401
+ define_vector<T>();
402
+ }
403
+
404
+ return true;
405
+ }
406
+ };
407
+
408
+ template<typename T>
409
+ class From_Ruby<std::vector<T>>
410
+ {
411
+ public:
412
+ From_Ruby() = default;
413
+
414
+ explicit From_Ruby(Arg * arg) : arg_(arg)
415
+ {
416
+ }
417
+
418
+ Convertible is_convertible(VALUE value)
419
+ {
420
+ switch (rb_type(value))
421
+ {
422
+ case RUBY_T_DATA:
423
+ return Data_Type<std::vector<T>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
424
+ break;
425
+ case RUBY_T_ARRAY:
426
+ if constexpr (std::is_default_constructible_v<T>)
427
+ {
428
+ return Convertible::Cast;
429
+ }
430
+ default:
431
+ return Convertible::None;
432
+ }
433
+ }
434
+
435
+ std::vector<T> convert(VALUE value)
436
+ {
437
+ switch (rb_type(value))
438
+ {
439
+ case RUBY_T_DATA:
440
+ {
441
+ // This is a wrapped vector (hopefully!)
442
+ return *detail::unwrap<std::vector<T>>(value, Data_Type<std::vector<T>>::ruby_data_type(), false);
443
+ }
444
+ case RUBY_T_ARRAY:
445
+ {
446
+ // If this an Ruby array and the vector type is copyable
447
+ if constexpr (std::is_default_constructible_v<T>)
448
+ {
449
+ return Array(value).to_vector<T>();
450
+ }
451
+ }
452
+ default:
453
+ {
454
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
455
+ detail::protect(rb_obj_classname, value), "std::vector");
456
+ }
457
+ }
458
+ }
459
+
460
+ private:
461
+ Arg* arg_ = nullptr;
462
+ };
463
+
464
+ template<typename T>
465
+ class From_Ruby<std::vector<T>&>
466
+ {
467
+ public:
468
+ From_Ruby() = default;
469
+
470
+ explicit From_Ruby(Arg * arg) : arg_(arg)
471
+ {
472
+ }
473
+
474
+ Convertible is_convertible(VALUE value)
475
+ {
476
+ switch (rb_type(value))
477
+ {
478
+ case RUBY_T_DATA:
479
+ return Data_Type<std::vector<T>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
480
+ break;
481
+ case RUBY_T_ARRAY:
482
+ if constexpr (std::is_default_constructible_v<T>)
483
+ {
484
+ return Convertible::Cast;
485
+ }
486
+ default:
487
+ return Convertible::None;
488
+ }
489
+ }
490
+
491
+ std::vector<T>& convert(VALUE value)
492
+ {
493
+ switch (rb_type(value))
494
+ {
495
+ case RUBY_T_DATA:
496
+ {
497
+ // This is a wrapped vector (hopefully!)
498
+ return *detail::unwrap<std::vector<T>>(value, Data_Type<std::vector<T>>::ruby_data_type(), false);
499
+ }
500
+ case RUBY_T_ARRAY:
501
+ {
502
+ // If this an Ruby array and the vector type is copyable
503
+ if constexpr (std::is_default_constructible_v<T>)
504
+ {
505
+ this->converted_ = Array(value).to_vector<T>();
506
+ return this->converted_;
507
+ }
508
+ }
509
+ default:
510
+ {
511
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
512
+ detail::protect(rb_obj_classname, value), "std::vector");
513
+ }
514
+ }
515
+ }
516
+
517
+ private:
518
+ Arg* arg_ = nullptr;
519
+ std::vector<T> converted_;
520
+ };
521
+
522
+ template<typename T>
523
+ class From_Ruby<std::vector<T>*>
524
+ {
525
+ public:
526
+ Convertible is_convertible(VALUE value)
527
+ {
528
+ switch (rb_type(value))
529
+ {
530
+ case RUBY_T_DATA:
531
+ return Data_Type<std::vector<T>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
532
+ break;
533
+ case RUBY_T_NIL:
534
+ return Convertible::Exact;
535
+ break;
536
+ case RUBY_T_ARRAY:
537
+ if constexpr (std::is_default_constructible_v<T>)
538
+ {
539
+ return Convertible::Cast;
540
+ }
541
+ default:
542
+ return Convertible::None;
543
+ }
544
+ }
545
+
546
+ std::vector<T>* convert(VALUE value)
547
+ {
548
+ switch (rb_type(value))
549
+ {
550
+ case RUBY_T_DATA:
551
+ {
552
+ // This is a wrapped vector (hopefully!)
553
+ return detail::unwrap<std::vector<T>>(value, Data_Type<std::vector<T>>::ruby_data_type(), false);
554
+ }
555
+ case RUBY_T_ARRAY:
556
+ {
557
+ // If this a Ruby array and the vector type is copyable
558
+ if constexpr (std::is_default_constructible_v<T>)
559
+ {
560
+ this->converted_ = Array(value).to_vector<T>();
561
+ return &this->converted_;
562
+ }
563
+ }
564
+ default:
565
+ {
566
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
567
+ detail::protect(rb_obj_classname, value), "std::vector");
568
+ }
569
+ }
570
+ }
571
+
572
+ private:
573
+ std::vector<T> converted_;
574
+ };
575
+ }
576
+
577
+ // Special handling for std::vector<bool>
578
+ namespace detail
579
+ {
580
+ template<>
581
+ class To_Ruby<std::vector<bool>::reference>
582
+ {
583
+ public:
584
+ VALUE convert(const std::vector<bool>::reference& value)
585
+ {
586
+ return value ? Qtrue : Qfalse;
587
+ }
588
+ };
589
+ }
590
+ }
data/rice/stl.hpp CHANGED
@@ -1,16 +1,24 @@
1
1
  #ifndef Rice__stl__hpp_
2
2
  #define Rice__stl__hpp_
3
3
 
4
+ #include "stl/exception.hpp"
5
+ #include "stl/exception_ptr.hpp"
4
6
  #include "stl/string.hpp"
5
7
  #include "stl/string_view.hpp"
6
8
  #include "stl/complex.hpp"
7
9
  #include "stl/optional.hpp"
8
10
  #include "stl/reference_wrapper.hpp"
9
- #include "stl/smart_ptr.hpp"
10
- #include "stl/monostate.hpp"
11
- #include "stl/variant.hpp"
12
11
  #include "stl/pair.hpp"
13
12
  #include "stl/map.hpp"
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"
18
+ #include "stl/type_index.hpp"
19
+ #include "stl/type_info.hpp"
20
+ #include "stl/variant.hpp"
21
+ #include "stl/unique_ptr.hpp"
14
22
  #include "stl/unordered_map.hpp"
15
23
  #include "stl/vector.hpp"
16
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 Attr_T>
13
+ struct attribute_traits<Attr_T*>
14
+ {
15
+ using attr_type = Attr_T;
16
+ using class_type = std::nullptr_t;
17
+ };
18
+
19
+ template<typename Attr_T, typename Class_T>
20
+ struct attribute_traits<Attr_T Class_T::*>
21
+ {
22
+ using attr_type = Attr_T;
23
+ using class_type = Class_T;
24
+ };
25
+ }
26
+ #endif // Rice__detail__attribute_traits__hpp_