rice 4.5.0 → 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 (166) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -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 +5436 -3201
  9. data/include/rice/stl.hpp +2355 -1269
  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 +123 -0
  20. data/rice/Buffer.ipp +599 -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 +4 -5
  25. data/rice/Data_Type.ipp +42 -26
  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 +8 -2
  62. data/rice/detail/NativeAttributeSet.hpp +3 -2
  63. data/rice/detail/NativeAttributeSet.ipp +8 -2
  64. data/rice/detail/NativeCallbackFFI.ipp +1 -1
  65. data/rice/detail/NativeFunction.hpp +17 -6
  66. data/rice/detail/NativeFunction.ipp +168 -64
  67. data/rice/detail/NativeIterator.hpp +3 -2
  68. data/rice/detail/NativeIterator.ipp +8 -2
  69. data/rice/detail/RubyType.hpp +2 -5
  70. data/rice/detail/RubyType.ipp +50 -5
  71. data/rice/detail/Type.hpp +3 -1
  72. data/rice/detail/Type.ipp +61 -31
  73. data/rice/detail/Wrapper.hpp +68 -33
  74. data/rice/detail/Wrapper.ipp +103 -113
  75. data/rice/detail/from_ruby.hpp +5 -4
  76. data/rice/detail/from_ruby.ipp +737 -365
  77. data/rice/detail/to_ruby.ipp +1092 -186
  78. data/rice/global_function.ipp +1 -1
  79. data/rice/libc/file.hpp +11 -0
  80. data/rice/libc/file.ipp +32 -0
  81. data/rice/rice.hpp +23 -16
  82. data/rice/stl/complex.hpp +6 -0
  83. data/rice/stl/complex.ipp +93 -0
  84. data/rice/stl/exception.hpp +11 -0
  85. data/rice/stl/exception.ipp +29 -0
  86. data/rice/stl/exception_ptr.hpp +6 -0
  87. data/rice/stl/exception_ptr.ipp +27 -0
  88. data/rice/stl/map.hpp +12 -0
  89. data/rice/stl/map.ipp +469 -0
  90. data/rice/stl/monostate.hpp +6 -0
  91. data/rice/stl/monostate.ipp +80 -0
  92. data/rice/stl/multimap.hpp +14 -0
  93. data/rice/stl/multimap.ipp +448 -0
  94. data/rice/stl/optional.hpp +6 -0
  95. data/rice/stl/optional.ipp +118 -0
  96. data/rice/stl/pair.hpp +13 -0
  97. data/rice/stl/pair.ipp +155 -0
  98. data/rice/stl/reference_wrapper.hpp +6 -0
  99. data/rice/stl/reference_wrapper.ipp +41 -0
  100. data/rice/stl/set.hpp +12 -0
  101. data/rice/stl/set.ipp +495 -0
  102. data/rice/stl/shared_ptr.hpp +28 -0
  103. data/rice/stl/shared_ptr.ipp +224 -0
  104. data/rice/stl/string.hpp +6 -0
  105. data/rice/stl/string.ipp +158 -0
  106. data/rice/stl/string_view.hpp +6 -0
  107. data/rice/stl/string_view.ipp +65 -0
  108. data/rice/stl/tuple.hpp +6 -0
  109. data/rice/stl/tuple.ipp +128 -0
  110. data/rice/stl/type_index.hpp +6 -0
  111. data/rice/stl/type_index.ipp +30 -0
  112. data/rice/stl/type_info.hpp +6 -0
  113. data/rice/stl/type_info.ipp +29 -0
  114. data/rice/stl/unique_ptr.hpp +22 -0
  115. data/rice/stl/unique_ptr.ipp +139 -0
  116. data/rice/stl/unordered_map.hpp +12 -0
  117. data/rice/stl/unordered_map.ipp +469 -0
  118. data/rice/stl/variant.hpp +6 -0
  119. data/rice/stl/variant.ipp +242 -0
  120. data/rice/stl/vector.hpp +12 -0
  121. data/rice/stl/vector.ipp +590 -0
  122. data/rice/stl.hpp +7 -3
  123. data/rice/traits/attribute_traits.hpp +26 -0
  124. data/rice/traits/function_traits.hpp +95 -0
  125. data/rice/traits/method_traits.hpp +47 -0
  126. data/rice/traits/rice_traits.hpp +160 -0
  127. data/rice.gemspec +85 -0
  128. data/test/embed_ruby.cpp +3 -0
  129. data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
  130. data/test/test_Array.cpp +6 -3
  131. data/test/test_Attribute.cpp +34 -1
  132. data/test/test_Buffer.cpp +285 -0
  133. data/test/test_Callback.cpp +2 -3
  134. data/test/test_Data_Object.cpp +88 -34
  135. data/test/test_Data_Type.cpp +106 -65
  136. data/test/test_Director.cpp +7 -3
  137. data/test/test_Enum.cpp +5 -2
  138. data/test/test_File.cpp +1 -1
  139. data/test/test_From_Ruby.cpp +181 -114
  140. data/test/test_Iterator.cpp +1 -1
  141. data/test/{test_JumpException.cpp → test_Jump_Exception.cpp} +1 -0
  142. data/test/test_Keep_Alive.cpp +7 -18
  143. data/test/test_Keep_Alive_No_Wrapper.cpp +0 -1
  144. data/test/test_Module.cpp +13 -6
  145. data/test/test_Native_Registry.cpp +0 -1
  146. data/test/test_Overloads.cpp +180 -5
  147. data/test/test_Ownership.cpp +100 -57
  148. data/test/test_Proc.cpp +0 -1
  149. data/test/test_Self.cpp +4 -4
  150. data/test/test_Stl_Map.cpp +37 -39
  151. data/test/test_Stl_Multimap.cpp +693 -0
  152. data/test/test_Stl_Pair.cpp +8 -8
  153. data/test/test_Stl_Reference_Wrapper.cpp +4 -2
  154. data/test/test_Stl_Set.cpp +790 -0
  155. data/test/{test_Stl_SmartPointer.cpp → test_Stl_SharedPtr.cpp} +97 -127
  156. data/test/test_Stl_Tuple.cpp +116 -0
  157. data/test/test_Stl_Type.cpp +1 -1
  158. data/test/test_Stl_UniquePtr.cpp +202 -0
  159. data/test/test_Stl_Unordered_Map.cpp +28 -34
  160. data/test/test_Stl_Variant.cpp +217 -89
  161. data/test/test_Stl_Vector.cpp +209 -83
  162. data/test/test_To_Ruby.cpp +373 -1
  163. data/test/test_Type.cpp +85 -14
  164. data/test/test_global_functions.cpp +17 -4
  165. metadata +94 -10
  166. data/rice/detail/TupleIterator.hpp +0 -14
@@ -0,0 +1,242 @@
1
+ #include <variant>
2
+
3
+ namespace Rice::detail
4
+ {
5
+ template<typename...Types>
6
+ struct Type<std::variant<Types...>>
7
+ {
8
+ using Tuple_T = std::tuple<Types...>;
9
+
10
+ template<std::size_t... I>
11
+ constexpr static bool verifyTypes(std::index_sequence<I...>& indices)
12
+ {
13
+ return (Type<std::tuple_element_t<I, Tuple_T>>::verify() && ...);
14
+ }
15
+
16
+ template<std::size_t... I>
17
+ constexpr static bool verify()
18
+ {
19
+ auto indices = std::make_index_sequence<std::variant_size_v<std::variant<Types...>>>{};
20
+ return verifyTypes(indices);
21
+ }
22
+ };
23
+
24
+ template<typename...Types>
25
+ class To_Ruby<std::variant<Types...>>
26
+ {
27
+ public:
28
+
29
+ template<typename U, typename V>
30
+ static VALUE convertElement(U& data, bool takeOwnership)
31
+ {
32
+ return To_Ruby<V>().convert(std::forward<V>(std::get<V>(data)));
33
+ }
34
+
35
+ template<typename U, std::size_t... I>
36
+ static VALUE convertIterator(U& data, bool takeOwnership, std::index_sequence<I...>& indices)
37
+ {
38
+ // Create a tuple of the variant types so we can look over the tuple's types
39
+ using Tuple_T = std::tuple<Types...>;
40
+
41
+ /* This is a fold expression. In pseudo code:
42
+
43
+ for (type in variant.types)
44
+ {
45
+ if (variant.has_value<type>())
46
+ return ToRuby<type>().convert(variant.getValue<type>)
47
+ }
48
+
49
+ The list of variant types is stored in Tuple_T. The number of types is stored in I.
50
+ Starting with index 0, get the variant type using td::tuple_element_t<I, Tuple_T>>.
51
+ Next check if the variant has a value for that type using std::holds_alternative<T>.
52
+ If yes, then call convertElement and save the return value to result. Then use the
53
+ comma operator to return true to the fold expression. If the variant does not have
54
+ a value for the type then return false.
55
+
56
+ The fold operator is or (||). If an index returns false, then the next index is evaluated
57
+ up until I.
58
+
59
+ Code inspired by https://www.foonathan.net/2020/05/fold-tricks/ */
60
+
61
+ VALUE result = Qnil;
62
+
63
+ #if defined(__GNUC__) || defined(__clang__)
64
+ #pragma GCC diagnostic push
65
+ #pragma GCC diagnostic ignored "-Wunused-value"
66
+ #endif
67
+
68
+ ((std::holds_alternative<std::tuple_element_t<I, Tuple_T>>(data) ?
69
+ (result = convertElement<U, std::tuple_element_t<I, Tuple_T>>(data, takeOwnership), true) : false) || ...);
70
+
71
+ #if defined(__GNUC__) || defined(__clang__)
72
+ #pragma GCC diagnostic pop
73
+ #endif
74
+
75
+ return result;
76
+ }
77
+
78
+ template<typename U>
79
+ static VALUE convert(U& data, bool takeOwnership = false)
80
+ {
81
+ auto indices = std::make_index_sequence<std::variant_size_v<std::variant<Types...>>>{};
82
+ return convertIterator(data, takeOwnership, indices);
83
+ }
84
+
85
+ template<typename U>
86
+ static VALUE convert(U&& data, bool takeOwnership = false)
87
+ {
88
+ auto indices = std::make_index_sequence<std::variant_size_v<std::variant<Types...>>>{};
89
+ return convertIterator(data, takeOwnership, indices);
90
+ }
91
+ };
92
+
93
+ template<typename...Types>
94
+ class To_Ruby<std::variant<Types...>&>
95
+ {
96
+ public:
97
+ template<typename U, typename V>
98
+ static VALUE convertElement(U& data, bool takeOwnership)
99
+ {
100
+ if constexpr (std::is_const_v<U>)
101
+ {
102
+ return To_Ruby<V>().convert(std::get<V>(data));
103
+ }
104
+ else
105
+ {
106
+ return To_Ruby<V>().convert(std::forward<V>(std::get<V>(data)));
107
+ }
108
+ }
109
+
110
+ template<typename U, std::size_t... I>
111
+ static VALUE convertIterator(U& data, bool takeOwnership, std::index_sequence<I...>& indices)
112
+ {
113
+ // Create a tuple of the variant types so we can look over the tuple's types
114
+ using Tuple_T = std::tuple<Types...>;
115
+
116
+ // See comments above for explanation of this code
117
+ VALUE result = Qnil;
118
+
119
+ #if defined(__GNUC__) || defined(__clang__)
120
+ #pragma GCC diagnostic push
121
+ #pragma GCC diagnostic ignored "-Wunused-value"
122
+ #endif
123
+
124
+ ((std::holds_alternative<std::tuple_element_t<I, Tuple_T>>(data) ?
125
+ (result = convertElement<U, std::tuple_element_t<I, Tuple_T>>(data, takeOwnership), true) : false) || ...);
126
+
127
+ #if defined(__GNUC__) || defined(__clang__)
128
+ #pragma GCC diagnostic pop
129
+ #endif
130
+
131
+ return result;
132
+ }
133
+
134
+ template<typename U>
135
+ static VALUE convert(U& data, bool takeOwnership = false)
136
+ {
137
+ auto indices = std::make_index_sequence<std::variant_size_v<std::variant<Types...>>>{};
138
+ return convertIterator(data, takeOwnership, indices);
139
+ }
140
+ };
141
+
142
+ template<typename...Types>
143
+ class From_Ruby<std::variant<Types...>>
144
+ {
145
+ public:
146
+ Convertible is_convertible(VALUE value)
147
+ {
148
+ Convertible result = Convertible::None;
149
+
150
+ for_each_tuple(this->fromRubys_,
151
+ [&](auto& fromRuby)
152
+ {
153
+ result = result | fromRuby.is_convertible(value);
154
+ });
155
+
156
+ return result;
157
+ }
158
+
159
+ // This method search through a variant's types to figure out which one the
160
+ // currently Ruby value best matches. It then returns the index of the type.
161
+ int figureIndex(VALUE value)
162
+ {
163
+ int i = 0;
164
+ int index = -1;
165
+ Convertible foundConversion = Convertible::None;
166
+
167
+ for_each_tuple(this->fromRubys_,
168
+ [&](auto& fromRuby)
169
+ {
170
+ Convertible isConvertible = fromRuby.is_convertible(value);
171
+
172
+ if (isConvertible > foundConversion)
173
+ {
174
+ index = i;
175
+ foundConversion = isConvertible;
176
+ }
177
+ i++;
178
+ });
179
+
180
+ if (index == -1)
181
+ {
182
+ rb_raise(rb_eArgError, "Could not find converter for variant");
183
+ }
184
+
185
+ return index;
186
+ }
187
+
188
+ /* This method loops over each type in the variant, creates a From_Ruby converter,
189
+ and then check if the converter can work with the provided Rby value (it checks
190
+ the type of the Ruby object to see if it matches the variant type).
191
+ If yes, then the converter runs. If no, then the method recursively calls itself
192
+ increasing the index.
193
+
194
+ We use recursion, with a constexpr, to avoid having to instantiate an instance
195
+ of the variant to store results from a fold expression like the To_Ruby code
196
+ does above. That allows us to process variants with non default constructible
197
+ arguments like std::reference_wrapper. */
198
+ template <std::size_t I = 0>
199
+ std::variant<Types...> convertInternal(VALUE value, int index)
200
+ {
201
+ if constexpr (I < std::variant_size_v<std::variant<Types...>>)
202
+ {
203
+ if (I == index)
204
+ {
205
+ auto fromRuby = std::get<I>(this->fromRubys_);
206
+ return fromRuby.convert(value);
207
+ }
208
+ else
209
+ {
210
+ return convertInternal<I + 1>(value, index);
211
+ }
212
+ }
213
+ rb_raise(rb_eArgError, "Could not find converter for variant");
214
+ }
215
+
216
+ std::variant<Types...> convert(VALUE value)
217
+ {
218
+ int index = this->figureIndex(value);
219
+ return this->convertInternal(value, index);
220
+ }
221
+
222
+ private:
223
+ // Possible converters we could use for this variant
224
+ using From_Ruby_Ts = std::tuple<From_Ruby<Types>...>;
225
+ From_Ruby_Ts fromRubys_;
226
+ };
227
+
228
+ template<typename...Types>
229
+ class From_Ruby<std::variant<Types...>&> : public From_Ruby<std::variant<Types...>>
230
+ {
231
+ public:
232
+ std::variant<Types...>& convert(VALUE value)
233
+ {
234
+ int index = this->figureIndex(value);
235
+ this->converted_ = this->convertInternal(value, index);
236
+ return this->converted_;
237
+ }
238
+
239
+ private:
240
+ std::variant<Types...> converted_;
241
+ };
242
+ }
@@ -0,0 +1,12 @@
1
+ #ifndef Rice__stl__vector__hpp_
2
+ #define Rice__stl__vector__hpp_
3
+
4
+ namespace Rice
5
+ {
6
+ template<typename T>
7
+ Data_Type<std::vector<T>> define_vector(std::string name = "" );
8
+ }
9
+
10
+ #include "vector.ipp"
11
+
12
+ #endif // Rice__stl__vector__hpp_