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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/CMakeLists.txt +31 -0
- data/CMakePresets.json +75 -0
- data/COPYING +3 -2
- data/FindRuby.cmake +437 -0
- data/Rakefile +5 -4
- data/include/rice/rice.hpp +5436 -3201
- data/include/rice/stl.hpp +2355 -1269
- data/lib/make_rice_headers.rb +79 -0
- data/lib/mkmf-rice.rb +4 -0
- data/lib/rice/version.rb +3 -0
- data/lib/rice.rb +1 -0
- data/lib/rubygems/builder.rb +11 -0
- data/lib/rubygems/cmake_builder.rb +113 -0
- data/lib/rubygems_plugin.rb +9 -0
- data/rice/Arg.hpp +7 -1
- data/rice/Arg.ipp +11 -2
- data/rice/Buffer.hpp +123 -0
- data/rice/Buffer.ipp +599 -0
- data/rice/Constructor.ipp +3 -3
- data/rice/Data_Object.hpp +2 -3
- data/rice/Data_Object.ipp +188 -188
- data/rice/Data_Type.hpp +4 -5
- data/rice/Data_Type.ipp +42 -26
- data/rice/Enum.hpp +0 -1
- data/rice/Enum.ipp +26 -23
- data/rice/Init.hpp +8 -0
- data/rice/Init.ipp +8 -0
- data/rice/MemoryView.ipp +1 -41
- data/rice/Return.hpp +1 -1
- data/rice/Return.ipp +6 -0
- data/rice/cpp_api/Array.hpp +209 -0
- data/rice/cpp_api/Array.ipp +304 -0
- data/rice/cpp_api/Builtin_Object.hpp +31 -0
- data/rice/cpp_api/Builtin_Object.ipp +37 -0
- data/rice/cpp_api/Class.hpp +70 -0
- data/rice/cpp_api/Class.ipp +97 -0
- data/rice/cpp_api/Encoding.hpp +32 -0
- data/rice/cpp_api/Encoding.ipp +59 -0
- data/rice/cpp_api/Hash.hpp +194 -0
- data/rice/cpp_api/Hash.ipp +257 -0
- data/rice/cpp_api/Identifier.hpp +46 -0
- data/rice/cpp_api/Identifier.ipp +31 -0
- data/rice/cpp_api/Module.hpp +72 -0
- data/rice/cpp_api/Module.ipp +101 -0
- data/rice/cpp_api/Object.hpp +272 -0
- data/rice/cpp_api/Object.ipp +235 -0
- data/rice/cpp_api/String.hpp +74 -0
- data/rice/cpp_api/String.ipp +120 -0
- data/rice/cpp_api/Struct.hpp +113 -0
- data/rice/cpp_api/Struct.ipp +92 -0
- data/rice/cpp_api/Symbol.hpp +46 -0
- data/rice/cpp_api/Symbol.ipp +93 -0
- data/rice/cpp_api/shared_methods.hpp +134 -0
- data/rice/detail/MethodInfo.hpp +1 -9
- data/rice/detail/MethodInfo.ipp +5 -72
- data/rice/detail/Native.hpp +3 -2
- data/rice/detail/Native.ipp +32 -4
- data/rice/detail/NativeAttributeGet.hpp +3 -2
- data/rice/detail/NativeAttributeGet.ipp +8 -2
- data/rice/detail/NativeAttributeSet.hpp +3 -2
- data/rice/detail/NativeAttributeSet.ipp +8 -2
- data/rice/detail/NativeCallbackFFI.ipp +1 -1
- data/rice/detail/NativeFunction.hpp +17 -6
- data/rice/detail/NativeFunction.ipp +168 -64
- data/rice/detail/NativeIterator.hpp +3 -2
- data/rice/detail/NativeIterator.ipp +8 -2
- data/rice/detail/RubyType.hpp +2 -5
- data/rice/detail/RubyType.ipp +50 -5
- data/rice/detail/Type.hpp +3 -1
- data/rice/detail/Type.ipp +61 -31
- data/rice/detail/Wrapper.hpp +68 -33
- data/rice/detail/Wrapper.ipp +103 -113
- data/rice/detail/from_ruby.hpp +5 -4
- data/rice/detail/from_ruby.ipp +737 -365
- data/rice/detail/to_ruby.ipp +1092 -186
- data/rice/global_function.ipp +1 -1
- data/rice/libc/file.hpp +11 -0
- data/rice/libc/file.ipp +32 -0
- data/rice/rice.hpp +23 -16
- data/rice/stl/complex.hpp +6 -0
- data/rice/stl/complex.ipp +93 -0
- data/rice/stl/exception.hpp +11 -0
- data/rice/stl/exception.ipp +29 -0
- data/rice/stl/exception_ptr.hpp +6 -0
- data/rice/stl/exception_ptr.ipp +27 -0
- data/rice/stl/map.hpp +12 -0
- data/rice/stl/map.ipp +469 -0
- data/rice/stl/monostate.hpp +6 -0
- data/rice/stl/monostate.ipp +80 -0
- data/rice/stl/multimap.hpp +14 -0
- data/rice/stl/multimap.ipp +448 -0
- data/rice/stl/optional.hpp +6 -0
- data/rice/stl/optional.ipp +118 -0
- data/rice/stl/pair.hpp +13 -0
- data/rice/stl/pair.ipp +155 -0
- data/rice/stl/reference_wrapper.hpp +6 -0
- data/rice/stl/reference_wrapper.ipp +41 -0
- data/rice/stl/set.hpp +12 -0
- data/rice/stl/set.ipp +495 -0
- data/rice/stl/shared_ptr.hpp +28 -0
- data/rice/stl/shared_ptr.ipp +224 -0
- data/rice/stl/string.hpp +6 -0
- data/rice/stl/string.ipp +158 -0
- data/rice/stl/string_view.hpp +6 -0
- data/rice/stl/string_view.ipp +65 -0
- data/rice/stl/tuple.hpp +6 -0
- data/rice/stl/tuple.ipp +128 -0
- data/rice/stl/type_index.hpp +6 -0
- data/rice/stl/type_index.ipp +30 -0
- data/rice/stl/type_info.hpp +6 -0
- data/rice/stl/type_info.ipp +29 -0
- data/rice/stl/unique_ptr.hpp +22 -0
- data/rice/stl/unique_ptr.ipp +139 -0
- data/rice/stl/unordered_map.hpp +12 -0
- data/rice/stl/unordered_map.ipp +469 -0
- data/rice/stl/variant.hpp +6 -0
- data/rice/stl/variant.ipp +242 -0
- data/rice/stl/vector.hpp +12 -0
- data/rice/stl/vector.ipp +590 -0
- data/rice/stl.hpp +7 -3
- data/rice/traits/attribute_traits.hpp +26 -0
- data/rice/traits/function_traits.hpp +95 -0
- data/rice/traits/method_traits.hpp +47 -0
- data/rice/traits/rice_traits.hpp +160 -0
- data/rice.gemspec +85 -0
- data/test/embed_ruby.cpp +3 -0
- data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
- data/test/test_Array.cpp +6 -3
- data/test/test_Attribute.cpp +34 -1
- data/test/test_Buffer.cpp +285 -0
- data/test/test_Callback.cpp +2 -3
- data/test/test_Data_Object.cpp +88 -34
- data/test/test_Data_Type.cpp +106 -65
- data/test/test_Director.cpp +7 -3
- data/test/test_Enum.cpp +5 -2
- data/test/test_File.cpp +1 -1
- data/test/test_From_Ruby.cpp +181 -114
- data/test/test_Iterator.cpp +1 -1
- data/test/{test_JumpException.cpp → test_Jump_Exception.cpp} +1 -0
- data/test/test_Keep_Alive.cpp +7 -18
- data/test/test_Keep_Alive_No_Wrapper.cpp +0 -1
- data/test/test_Module.cpp +13 -6
- data/test/test_Native_Registry.cpp +0 -1
- data/test/test_Overloads.cpp +180 -5
- data/test/test_Ownership.cpp +100 -57
- data/test/test_Proc.cpp +0 -1
- data/test/test_Self.cpp +4 -4
- data/test/test_Stl_Map.cpp +37 -39
- data/test/test_Stl_Multimap.cpp +693 -0
- data/test/test_Stl_Pair.cpp +8 -8
- data/test/test_Stl_Reference_Wrapper.cpp +4 -2
- data/test/test_Stl_Set.cpp +790 -0
- data/test/{test_Stl_SmartPointer.cpp → test_Stl_SharedPtr.cpp} +97 -127
- data/test/test_Stl_Tuple.cpp +116 -0
- data/test/test_Stl_Type.cpp +1 -1
- data/test/test_Stl_UniquePtr.cpp +202 -0
- data/test/test_Stl_Unordered_Map.cpp +28 -34
- data/test/test_Stl_Variant.cpp +217 -89
- data/test/test_Stl_Vector.cpp +209 -83
- data/test/test_To_Ruby.cpp +373 -1
- data/test/test_Type.cpp +85 -14
- data/test/test_global_functions.cpp +17 -4
- metadata +94 -10
- 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
|
+
}
|
data/rice/stl/vector.hpp
ADDED