rice 4.7.1 → 4.8.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 +29 -1
- data/CMakeLists.txt +14 -22
- data/CMakePresets.json +203 -75
- data/FindRuby.cmake +358 -123
- data/bin/rice-doc.rb +56 -141
- data/include/rice/api.hpp +248 -0
- data/include/rice/rice.hpp +2237 -1657
- data/include/rice/stl.hpp +346 -443
- data/lib/rice/doc/config.rb +70 -0
- data/lib/rice/doc/cpp_reference.rb +1 -4
- data/lib/rice/doc/mkdocs.rb +58 -20
- data/lib/rice/doc/rice.rb +20 -0
- data/lib/rice/doc.rb +1 -0
- data/lib/rice/make_rice_headers.rb +7 -0
- data/lib/rice/native_registry.rb +2 -2
- data/lib/rice/rbs.rb +2 -2
- data/lib/rice/version.rb +1 -1
- data/lib/rubygems_plugin.rb +12 -9
- data/rice/Arg.hpp +12 -6
- data/rice/Arg.ipp +14 -7
- data/rice/Buffer.ipp +44 -40
- data/rice/Callback.hpp +1 -1
- data/rice/Callback.ipp +2 -7
- data/rice/Constructor.hpp +1 -1
- data/rice/Constructor.ipp +11 -11
- data/rice/Data_Object.ipp +15 -15
- data/rice/Data_Type.hpp +9 -10
- data/rice/Data_Type.ipp +22 -25
- data/rice/Director.hpp +1 -0
- data/rice/Enum.ipp +58 -39
- data/rice/Exception.hpp +4 -4
- data/rice/Exception.ipp +7 -7
- data/rice/NoGVL.hpp +13 -0
- data/rice/Reference.hpp +56 -0
- data/rice/Reference.ipp +96 -0
- data/rice/Return.hpp +4 -1
- data/rice/Return.ipp +0 -6
- data/rice/cpp_api/Array.hpp +41 -4
- data/rice/cpp_api/Array.ipp +105 -9
- data/rice/cpp_api/Class.hpp +2 -2
- data/rice/cpp_api/Class.ipp +4 -4
- data/rice/cpp_api/Hash.ipp +7 -4
- data/rice/cpp_api/Module.hpp +4 -4
- data/rice/cpp_api/Module.ipp +12 -10
- data/rice/cpp_api/Object.hpp +4 -4
- data/rice/cpp_api/Object.ipp +15 -12
- data/rice/cpp_api/String.hpp +2 -2
- data/rice/cpp_api/String.ipp +11 -8
- data/rice/cpp_api/Symbol.ipp +7 -7
- data/rice/cpp_api/shared_methods.hpp +5 -9
- data/rice/detail/InstanceRegistry.hpp +0 -2
- data/rice/detail/Native.hpp +31 -21
- data/rice/detail/Native.ipp +282 -130
- data/rice/detail/NativeAttributeGet.hpp +5 -7
- data/rice/detail/NativeAttributeGet.ipp +26 -26
- data/rice/detail/NativeAttributeSet.hpp +2 -4
- data/rice/detail/NativeAttributeSet.ipp +20 -16
- data/rice/detail/NativeCallback.hpp +77 -0
- data/rice/detail/NativeCallback.ipp +280 -0
- data/rice/detail/NativeFunction.hpp +11 -21
- data/rice/detail/NativeFunction.ipp +58 -119
- data/rice/detail/NativeInvoker.hpp +4 -4
- data/rice/detail/NativeInvoker.ipp +7 -7
- data/rice/detail/NativeIterator.hpp +2 -4
- data/rice/detail/NativeIterator.ipp +18 -14
- data/rice/detail/NativeMethod.hpp +10 -20
- data/rice/detail/NativeMethod.ipp +54 -114
- data/rice/detail/NativeProc.hpp +5 -7
- data/rice/detail/NativeProc.ipp +39 -28
- data/rice/detail/NativeRegistry.hpp +0 -1
- data/rice/detail/Parameter.hpp +15 -8
- data/rice/detail/Parameter.ipp +102 -43
- data/rice/detail/Proc.ipp +14 -28
- data/rice/detail/RubyType.ipp +2 -53
- data/rice/detail/Type.hpp +23 -7
- data/rice/detail/Type.ipp +73 -93
- data/rice/detail/TypeRegistry.ipp +5 -4
- data/rice/detail/Wrapper.hpp +1 -1
- data/rice/detail/Wrapper.ipp +18 -10
- data/rice/detail/from_ruby.hpp +8 -6
- data/rice/detail/from_ruby.ipp +306 -173
- data/rice/detail/ruby.hpp +23 -0
- data/rice/libc/file.hpp +4 -4
- data/rice/rice.hpp +6 -8
- data/rice/rice_api/Native.ipp +5 -1
- data/rice/rice_api/Parameter.ipp +1 -1
- data/rice/ruby_mark.hpp +2 -1
- data/rice/stl/complex.ipp +12 -8
- data/rice/stl/map.ipp +27 -22
- data/rice/stl/monostate.ipp +16 -12
- data/rice/stl/multimap.hpp +0 -2
- data/rice/stl/multimap.ipp +27 -22
- data/rice/stl/optional.ipp +27 -11
- data/rice/stl/pair.ipp +5 -5
- data/rice/stl/reference_wrapper.ipp +5 -4
- data/rice/stl/set.ipp +16 -16
- data/rice/stl/shared_ptr.hpp +0 -16
- data/rice/stl/shared_ptr.ipp +34 -190
- data/rice/stl/string.ipp +18 -18
- data/rice/stl/string_view.ipp +1 -1
- data/rice/stl/tuple.ipp +15 -36
- data/rice/stl/unique_ptr.ipp +18 -8
- data/rice/stl/unordered_map.ipp +20 -15
- data/rice/stl/variant.ipp +37 -21
- data/rice/stl/vector.ipp +41 -36
- data/rice/traits/function_traits.hpp +19 -19
- data/rice/traits/method_traits.hpp +4 -4
- data/rice/traits/rice_traits.hpp +162 -39
- data/rice.gemspec +1 -3
- data/test/test_Array.cpp +261 -3
- data/test/test_Attribute.cpp +6 -3
- data/test/test_Buffer.cpp +6 -42
- data/test/test_Callback.cpp +77 -23
- data/test/test_Data_Object.cpp +1 -1
- data/test/test_Data_Type.cpp +21 -22
- data/test/test_Director.cpp +2 -4
- data/test/test_Enum.cpp +34 -5
- data/test/test_File.cpp +9 -5
- data/test/test_From_Ruby.cpp +4 -3
- data/test/test_GVL.cpp +3 -3
- data/test/test_Hash.cpp +1 -1
- data/test/test_Iterator.cpp +54 -22
- data/test/test_Keep_Alive.cpp +1 -1
- data/test/test_Keep_Alive_No_Wrapper.cpp +1 -1
- data/test/test_Module.cpp +5 -5
- data/test/test_Overloads.cpp +345 -48
- data/test/test_Proc.cpp +54 -0
- data/test/test_Reference.cpp +181 -0
- data/test/test_Self.cpp +2 -2
- data/test/test_Stl_Set.cpp +6 -6
- data/test/test_Stl_SharedPtr.cpp +54 -30
- data/test/test_Stl_String_View.cpp +4 -2
- data/test/test_Stl_Tuple.cpp +1 -1
- data/test/test_Stl_Variant.cpp +6 -14
- data/test/test_Stl_Vector.cpp +61 -30
- data/test/test_String.cpp +4 -2
- data/test/test_Struct.cpp +1 -1
- data/test/test_Symbol.cpp +1 -1
- data/test/test_To_Ruby.cpp +1 -0
- data/test/test_Type.cpp +36 -35
- data/test/test_global_functions.cpp +1 -1
- data/test/unittest.cpp +1 -1
- data/test/unittest.hpp +5 -5
- metadata +10 -10
- data/rice/Function.hpp +0 -17
- data/rice/Function.ipp +0 -13
- data/rice/detail/MethodInfo.hpp +0 -48
- data/rice/detail/MethodInfo.ipp +0 -99
- data/rice/detail/NativeCallbackFFI.hpp +0 -55
- data/rice/detail/NativeCallbackFFI.ipp +0 -152
- data/rice/detail/NativeCallbackSimple.hpp +0 -30
- data/rice/detail/NativeCallbackSimple.ipp +0 -29
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
|
|
7
7
|
namespace Rice::detail
|
|
8
8
|
{
|
|
9
|
-
template<typename Class_T, typename Method_T>
|
|
10
|
-
|
|
9
|
+
template<typename Class_T, typename Method_T, bool NoGVL>
|
|
10
|
+
template<typename ...Arg_Ts>
|
|
11
|
+
void NativeMethod<Class_T, Method_T, NoGVL>::define(VALUE klass, std::string method_name, Method_T method, Arg_Ts&& ...args)
|
|
11
12
|
{
|
|
12
|
-
// Verify return
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Native::
|
|
13
|
+
// Verify return type
|
|
14
|
+
using Arg_Tuple = std::tuple<Arg_Ts...>;
|
|
15
|
+
constexpr bool isBuffer = tuple_element_index_v<Arg_Tuple, ReturnBuffer> < std::tuple_size_v<Arg_Tuple>;
|
|
16
|
+
Native::verify_type<Return_T, isBuffer>();
|
|
16
17
|
|
|
17
18
|
// Have we defined this method yet in Ruby?
|
|
18
19
|
Identifier identifier(method_name);
|
|
@@ -23,24 +24,29 @@ namespace Rice::detail
|
|
|
23
24
|
detail::protect(rb_define_method, klass, method_name.c_str(), (RUBY_METHOD_FUNC)&Native::resolve, -1);
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
// Create
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
// Create method parameters - this will also validate their types
|
|
28
|
+
std::vector<std::unique_ptr<ParameterAbstract>> parameters = Native::create_parameters<Parameter_Ts>(args...);
|
|
29
|
+
|
|
30
|
+
// Create return info
|
|
31
|
+
std::unique_ptr<Return> returnInfo = Native::create_return<Arg_Ts...>(args...);
|
|
32
|
+
|
|
33
|
+
// Create native method
|
|
34
|
+
NativeMethod_T* nativeMethod = new NativeMethod_T(klass, method_name, std::forward<Method_T>(method), std::move(returnInfo), std::move(parameters));
|
|
35
|
+
std::unique_ptr<Native> native(nativeMethod);
|
|
36
|
+
|
|
37
|
+
// Register the native method
|
|
30
38
|
detail::Registries::instance.natives.add(klass, identifier.id(), native);
|
|
31
39
|
}
|
|
32
40
|
|
|
33
|
-
template<typename Class_T, typename Method_T>
|
|
34
|
-
NativeMethod<Class_T, Method_T>::NativeMethod(VALUE klass, std::string method_name, Method_T method,
|
|
35
|
-
: Native(
|
|
36
|
-
klass_(klass),
|
|
37
|
-
toRuby_(methodInfo->returnInfo())
|
|
41
|
+
template<typename Class_T, typename Method_T, bool NoGVL>
|
|
42
|
+
NativeMethod<Class_T, Method_T, NoGVL>::NativeMethod(VALUE klass, std::string method_name, Method_T method, std::unique_ptr<Return>&& returnInfo, std::vector<std::unique_ptr<ParameterAbstract>>&& parameters)
|
|
43
|
+
: Native(method_name, std::move(returnInfo), std::move(parameters)),
|
|
44
|
+
klass_(klass), method_(method), toRuby_(returnInfo_.get())
|
|
38
45
|
{
|
|
39
46
|
}
|
|
40
47
|
|
|
41
|
-
template<typename Class_T, typename Method_T>
|
|
42
|
-
|
|
43
|
-
std::vector<std::string> NativeMethod<Class_T, Method_T>::argTypeNames(std::ostringstream& stream, std::index_sequence<I...>& indices)
|
|
48
|
+
template<typename Class_T, typename Method_T, bool NoGVL>
|
|
49
|
+
std::vector<std::string> NativeMethod<Class_T, Method_T, NoGVL>::argTypeNames()
|
|
44
50
|
{
|
|
45
51
|
std::vector<std::string> result;
|
|
46
52
|
for (std::unique_ptr<ParameterAbstract>& parameter : this->parameters_)
|
|
@@ -50,26 +56,25 @@ namespace Rice::detail
|
|
|
50
56
|
return result;
|
|
51
57
|
}
|
|
52
58
|
|
|
53
|
-
template<typename Class_T, typename Method_T>
|
|
54
|
-
std::string NativeMethod<Class_T, Method_T>::toString()
|
|
59
|
+
template<typename Class_T, typename Method_T, bool NoGVL>
|
|
60
|
+
std::string NativeMethod<Class_T, Method_T, NoGVL>::toString()
|
|
55
61
|
{
|
|
56
62
|
std::ostringstream result;
|
|
57
63
|
|
|
58
|
-
detail::
|
|
59
|
-
result <<
|
|
64
|
+
detail::TypeIndexParser typeIndexParserReturn(typeid(Return_T), std::is_fundamental_v<detail::intrinsic_type<Return_T>>);
|
|
65
|
+
result << typeIndexParserReturn.simplifiedName() << " ";
|
|
60
66
|
|
|
61
67
|
if (!std::is_null_pointer_v<Receiver_T>)
|
|
62
68
|
{
|
|
63
|
-
detail::
|
|
64
|
-
result <<
|
|
69
|
+
detail::TypeIndexParser typeIndexParserReceiver(typeid(Receiver_T), std::is_fundamental_v<detail::intrinsic_type<Receiver_T>>);
|
|
70
|
+
result << typeIndexParserReceiver.simplifiedName() << "::";
|
|
65
71
|
}
|
|
66
72
|
|
|
67
|
-
result << this->
|
|
73
|
+
result << this->name();
|
|
68
74
|
|
|
69
75
|
result << "(";
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
std::vector<std::string> argTypeNames = this->argTypeNames(result, indices);
|
|
77
|
+
std::vector<std::string> argTypeNames = this->argTypeNames();
|
|
73
78
|
for (size_t i = 0; i < argTypeNames.size(); i++)
|
|
74
79
|
{
|
|
75
80
|
result << argTypeNames[i];
|
|
@@ -80,22 +85,22 @@ namespace Rice::detail
|
|
|
80
85
|
return result.str();
|
|
81
86
|
}
|
|
82
87
|
|
|
83
|
-
template<typename Class_T, typename Method_T>
|
|
88
|
+
template<typename Class_T, typename Method_T, bool NoGVL>
|
|
84
89
|
template<std::size_t... I>
|
|
85
|
-
typename NativeMethod<Class_T, Method_T>::Apply_Args_T NativeMethod<Class_T, Method_T>::getNativeValues(VALUE self, std::vector<std::optional<VALUE>>& values, std::index_sequence<I...>&
|
|
90
|
+
typename NativeMethod<Class_T, Method_T, NoGVL>::Apply_Args_T NativeMethod<Class_T, Method_T, NoGVL>::getNativeValues(VALUE self, std::vector<std::optional<VALUE>>& values, const std::index_sequence<I...>&)
|
|
86
91
|
{
|
|
87
92
|
/* Loop over each value returned from Ruby and convert it to the appropriate C++ type based
|
|
88
|
-
on the arguments (
|
|
93
|
+
on the arguments (Parameter_Ts) required by the C++ method. Arg_T may have const/volatile while
|
|
89
94
|
the associated From_Ruby<T> template parameter will not. Thus From_Ruby produces non-const values
|
|
90
95
|
which we let the compiler convert to const values as needed. This works except for
|
|
91
96
|
T** -> const T**, see comment in convertToNative method. */
|
|
92
97
|
return std::forward_as_tuple(this->getReceiver(self),
|
|
93
|
-
(dynamic_cast<Parameter<std::tuple_element_t<I,
|
|
98
|
+
(dynamic_cast<Parameter<std::tuple_element_t<I, Parameter_Ts>>*>(this->parameters_[I].get()))->
|
|
94
99
|
convertToNative(values[I])...);
|
|
95
100
|
}
|
|
96
101
|
|
|
97
|
-
template<typename Class_T, typename Method_T>
|
|
98
|
-
typename NativeMethod<Class_T, Method_T>::Receiver_T NativeMethod<Class_T, Method_T>::getReceiver(VALUE self)
|
|
102
|
+
template<typename Class_T, typename Method_T, bool NoGVL>
|
|
103
|
+
typename NativeMethod<Class_T, Method_T, NoGVL>::Receiver_T NativeMethod<Class_T, Method_T, NoGVL>::getReceiver(VALUE self)
|
|
99
104
|
{
|
|
100
105
|
// Self parameter is a Ruby VALUE so no conversion is needed
|
|
101
106
|
if constexpr (std::is_same_v<Receiver_T, VALUE>)
|
|
@@ -129,8 +134,8 @@ namespace Rice::detail
|
|
|
129
134
|
}
|
|
130
135
|
}
|
|
131
136
|
|
|
132
|
-
template<typename Class_T, typename Method_T>
|
|
133
|
-
inline VALUE NativeMethod<Class_T, Method_T>::invoke(VALUE self, Apply_Args_T&& nativeArgs)
|
|
137
|
+
template<typename Class_T, typename Method_T, bool NoGVL>
|
|
138
|
+
inline VALUE NativeMethod<Class_T, Method_T, NoGVL>::invoke(VALUE self, Apply_Args_T&& nativeArgs)
|
|
134
139
|
{
|
|
135
140
|
if constexpr (std::is_void_v<Return_T>)
|
|
136
141
|
{
|
|
@@ -173,8 +178,8 @@ namespace Rice::detail
|
|
|
173
178
|
}
|
|
174
179
|
}
|
|
175
180
|
|
|
176
|
-
template<typename Class_T, typename Method_T>
|
|
177
|
-
inline VALUE NativeMethod<Class_T, Method_T>::invokeNoGVL(VALUE self, Apply_Args_T&& nativeArgs)
|
|
181
|
+
template<typename Class_T, typename Method_T, bool NoGVL>
|
|
182
|
+
inline VALUE NativeMethod<Class_T, Method_T, NoGVL>::invokeNoGVL(VALUE self, Apply_Args_T&& nativeArgs)
|
|
178
183
|
{
|
|
179
184
|
if constexpr (std::is_void_v<Return_T>)
|
|
180
185
|
{
|
|
@@ -217,77 +222,17 @@ namespace Rice::detail
|
|
|
217
222
|
}
|
|
218
223
|
}
|
|
219
224
|
|
|
220
|
-
template<typename Class_T, typename Method_T>
|
|
221
|
-
|
|
222
|
-
{
|
|
223
|
-
std::stringstream message;
|
|
224
|
-
|
|
225
|
-
message << "When calling the method `";
|
|
226
|
-
message << this->method_name_;
|
|
227
|
-
message << "' we could not find the wrapper for the '";
|
|
228
|
-
message << rb_obj_classname(klass);
|
|
229
|
-
message << "' ";
|
|
230
|
-
message << wrapper;
|
|
231
|
-
message << " type. You should not use keepAlive() on a Return or Arg that is a builtin Rice type.";
|
|
232
|
-
|
|
233
|
-
throw std::runtime_error(message.str());
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
template<typename Class_T, typename Method_T>
|
|
237
|
-
void NativeMethod<Class_T, Method_T>::checkKeepAlive(VALUE self, VALUE returnValue, std::vector<std::optional<VALUE>>& rubyValues)
|
|
238
|
-
{
|
|
239
|
-
// Self will be Qnil for wrapped procs
|
|
240
|
-
if (self == Qnil)
|
|
241
|
-
return;
|
|
242
|
-
|
|
243
|
-
// selfWrapper will be nullptr if this(self) is a builtin type and not an external(wrapped) type
|
|
244
|
-
// it is highly unlikely that keepAlive is used in this case but we check anyway
|
|
245
|
-
WrapperBase* selfWrapper = getWrapper(self);
|
|
246
|
-
|
|
247
|
-
// Check method arguments
|
|
248
|
-
for (const Arg& arg : (*this->methodInfo_))
|
|
249
|
-
{
|
|
250
|
-
if (arg.isKeepAlive())
|
|
251
|
-
{
|
|
252
|
-
if (selfWrapper == nullptr)
|
|
253
|
-
{
|
|
254
|
-
noWrapper(self, "self");
|
|
255
|
-
}
|
|
256
|
-
selfWrapper->addKeepAlive(rubyValues[arg.position].value());
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// Check return value
|
|
261
|
-
if (this->methodInfo_->returnInfo()->isKeepAlive())
|
|
262
|
-
{
|
|
263
|
-
if (selfWrapper == nullptr)
|
|
264
|
-
{
|
|
265
|
-
noWrapper(self, "self");
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// returnWrapper will be nullptr if returnValue is a built-in type and not an external(wrapped) type
|
|
269
|
-
WrapperBase* returnWrapper = getWrapper(returnValue);
|
|
270
|
-
if (returnWrapper == nullptr)
|
|
271
|
-
{
|
|
272
|
-
noWrapper(returnValue, "return");
|
|
273
|
-
}
|
|
274
|
-
returnWrapper->addKeepAlive(self);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
template<typename Class_T, typename Method_T>
|
|
279
|
-
VALUE NativeMethod<Class_T, Method_T>::operator()(size_t argc, const VALUE* argv, VALUE self)
|
|
225
|
+
template<typename Class_T, typename Method_T, bool NoGVL>
|
|
226
|
+
VALUE NativeMethod<Class_T, Method_T, NoGVL>::operator()(std::map<std::string, VALUE>& values, VALUE self)
|
|
280
227
|
{
|
|
281
228
|
// Get the ruby values and make sure we have the correct number
|
|
282
|
-
std::vector<std::optional<VALUE>> rubyValues = this->getRubyValues(
|
|
283
|
-
auto indices = std::make_index_sequence<std::tuple_size_v<
|
|
229
|
+
std::vector<std::optional<VALUE>> rubyValues = this->getRubyValues(values, true);
|
|
230
|
+
auto indices = std::make_index_sequence<std::tuple_size_v<Parameter_Ts>>{};
|
|
284
231
|
Apply_Args_T nativeArgs = this->getNativeValues(self, rubyValues, indices);
|
|
285
232
|
|
|
286
|
-
bool noGvl = this->methodInfo_->function()->isNoGvl();
|
|
287
|
-
|
|
288
233
|
VALUE result = Qnil;
|
|
289
234
|
|
|
290
|
-
if (
|
|
235
|
+
if constexpr (NoGVL)
|
|
291
236
|
{
|
|
292
237
|
result = this->invokeNoGVL(self, std::forward<Apply_Args_T>(nativeArgs));
|
|
293
238
|
}
|
|
@@ -302,25 +247,20 @@ namespace Rice::detail
|
|
|
302
247
|
return result;
|
|
303
248
|
}
|
|
304
249
|
|
|
305
|
-
template<typename Class_T, typename Method_T>
|
|
306
|
-
inline
|
|
307
|
-
{
|
|
308
|
-
return this->method_name_;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
template<typename Class_T, typename Method_T>
|
|
312
|
-
inline NativeKind NativeMethod<Class_T, Method_T>::kind()
|
|
250
|
+
template<typename Class_T, typename Method_T, bool NoGVL>
|
|
251
|
+
inline NativeKind NativeMethod<Class_T, Method_T, NoGVL>::kind()
|
|
313
252
|
{
|
|
314
253
|
return NativeKind::Method;
|
|
315
254
|
}
|
|
316
255
|
|
|
317
|
-
template<typename Class_T, typename Method_T>
|
|
318
|
-
inline VALUE NativeMethod<Class_T, Method_T>::returnKlass()
|
|
256
|
+
template<typename Class_T, typename Method_T, bool NoGVL>
|
|
257
|
+
inline VALUE NativeMethod<Class_T, Method_T, NoGVL>::returnKlass()
|
|
319
258
|
{
|
|
320
259
|
// Check if an array is being returned
|
|
321
|
-
|
|
260
|
+
bool isBuffer = dynamic_cast<ReturnBuffer*>(this->returnInfo_.get()) ? true : false;
|
|
261
|
+
if (isBuffer)
|
|
322
262
|
{
|
|
323
|
-
TypeMapper<Pointer<Return_T
|
|
263
|
+
TypeMapper<Pointer<detail::remove_cv_recursive_t<std::remove_pointer_t<Return_T>>>> typeMapper;
|
|
324
264
|
return typeMapper.rubyKlass();
|
|
325
265
|
}
|
|
326
266
|
else
|
data/rice/detail/NativeProc.hpp
CHANGED
|
@@ -12,7 +12,7 @@ namespace Rice::detail
|
|
|
12
12
|
// We remove const to avoid an explosion of To_Ruby specializations and Ruby doesn't
|
|
13
13
|
// have the concept of constants anyways
|
|
14
14
|
using Return_T = typename function_traits<Proc_T>::return_type;
|
|
15
|
-
using
|
|
15
|
+
using Parameter_Ts = typename function_traits<Proc_T>::arg_types;
|
|
16
16
|
using To_Ruby_T = remove_cv_recursive_t<Return_T>;
|
|
17
17
|
|
|
18
18
|
// Define a new Ruby Proc to wrap a C++ function
|
|
@@ -23,11 +23,10 @@ namespace Rice::detail
|
|
|
23
23
|
static VALUE resolve(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg);
|
|
24
24
|
|
|
25
25
|
public:
|
|
26
|
-
NativeProc(Proc_T proc,
|
|
27
|
-
VALUE operator()(
|
|
26
|
+
NativeProc(Proc_T proc, std::unique_ptr<Return>&& returnInfo, std::vector<std::unique_ptr<ParameterAbstract>>&& parameters);
|
|
27
|
+
VALUE operator()(std::map<std::string, VALUE>& values, VALUE self) override;
|
|
28
28
|
std::string toString() override;
|
|
29
29
|
|
|
30
|
-
std::string name() override;
|
|
31
30
|
NativeKind kind() override;
|
|
32
31
|
VALUE returnKlass() override;
|
|
33
32
|
|
|
@@ -36,14 +35,13 @@ namespace Rice::detail
|
|
|
36
35
|
|
|
37
36
|
// Convert Ruby values to C++ values
|
|
38
37
|
template<typename std::size_t...I>
|
|
39
|
-
|
|
38
|
+
Parameter_Ts getNativeValues(std::vector<std::optional<VALUE>>& values, std::index_sequence<I...>& indices);
|
|
40
39
|
|
|
41
40
|
// Call the underlying C++ function
|
|
42
|
-
VALUE invoke(
|
|
41
|
+
VALUE invoke(Parameter_Ts&& nativeArgs);
|
|
43
42
|
|
|
44
43
|
private:
|
|
45
44
|
Proc_T proc_;
|
|
46
|
-
std::unique_ptr<MethodInfo> methodInfo_;
|
|
47
45
|
To_Ruby<To_Ruby_T> toRuby_;
|
|
48
46
|
};
|
|
49
47
|
}
|
data/rice/detail/NativeProc.ipp
CHANGED
|
@@ -9,8 +9,13 @@ namespace Rice::detail
|
|
|
9
9
|
template<typename Proc_T>
|
|
10
10
|
NativeProc<Proc_T>* NativeProc<Proc_T>::define(Proc_T proc)
|
|
11
11
|
{
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
// Create proc parameters
|
|
13
|
+
std::vector<std::unique_ptr<ParameterAbstract>> parameters = Native::create_parameters<Parameter_Ts>();
|
|
14
|
+
|
|
15
|
+
// Create return info
|
|
16
|
+
std::unique_ptr<Return> returnInfo = std::make_unique<Return>();
|
|
17
|
+
|
|
18
|
+
return new NativeProc_T(std::forward<Proc_T>(proc), std::move(returnInfo), std::move(parameters));
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
template<typename Proc_T>
|
|
@@ -30,19 +35,20 @@ namespace Rice::detail
|
|
|
30
35
|
|
|
31
36
|
// Ruby calls this method when invoking a proc that was defined as a C++ function
|
|
32
37
|
template<typename Proc_T>
|
|
33
|
-
VALUE NativeProc<Proc_T>::resolve(VALUE
|
|
38
|
+
VALUE NativeProc<Proc_T>::resolve(VALUE, VALUE callback_arg, int argc, const VALUE* argv, VALUE)
|
|
34
39
|
{
|
|
35
40
|
return cpp_protect([&]
|
|
36
41
|
{
|
|
42
|
+
std::map<std::string, VALUE> values = readRubyArgs(argc, argv);
|
|
37
43
|
NativeProc_T * native = (NativeProc_T*)callback_arg;
|
|
38
|
-
return (*native)(
|
|
44
|
+
return (*native)(values, Qnil);
|
|
39
45
|
});
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
// Ruby calls this method if an instance of a NativeProc is owned by a Ruby proc. That happens when C++
|
|
43
49
|
// returns a function back to Ruby
|
|
44
50
|
template<typename Proc_T>
|
|
45
|
-
VALUE NativeProc<Proc_T>::finalizerCallback(VALUE
|
|
51
|
+
VALUE NativeProc<Proc_T>::finalizerCallback(VALUE, VALUE callback_arg, int, const VALUE*, VALUE)
|
|
46
52
|
{
|
|
47
53
|
NativeProc_T* native = (NativeProc_T*)callback_arg;
|
|
48
54
|
delete native;
|
|
@@ -50,8 +56,9 @@ namespace Rice::detail
|
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
template<typename Proc_T>
|
|
53
|
-
NativeProc<Proc_T>::NativeProc(Proc_T proc,
|
|
54
|
-
|
|
59
|
+
NativeProc<Proc_T>::NativeProc(Proc_T proc, std::unique_ptr<Return>&& returnInfo, std::vector<std::unique_ptr<ParameterAbstract>>&& parameters)
|
|
60
|
+
: Native("proc", std::move(returnInfo), std::move(parameters)),
|
|
61
|
+
proc_(proc), toRuby_(returnInfo_.get())
|
|
55
62
|
{
|
|
56
63
|
}
|
|
57
64
|
|
|
@@ -63,32 +70,32 @@ namespace Rice::detail
|
|
|
63
70
|
|
|
64
71
|
template<typename Proc_T>
|
|
65
72
|
template<std::size_t... I>
|
|
66
|
-
typename NativeProc<Proc_T>::
|
|
67
|
-
std::index_sequence<I...>&
|
|
73
|
+
typename NativeProc<Proc_T>::Parameter_Ts NativeProc<Proc_T>::getNativeValues(std::vector<std::optional<VALUE>>& values,
|
|
74
|
+
std::index_sequence<I...>&)
|
|
68
75
|
{
|
|
69
76
|
/* Loop over each value returned from Ruby and convert it to the appropriate C++ type based
|
|
70
|
-
on the arguments (
|
|
77
|
+
on the arguments (Parameter_Ts) required by the C++ function. Arg_T may have const/volatile while
|
|
71
78
|
the associated From_Ruby<T> template parameter will not. Thus From_Ruby produces non-const values
|
|
72
79
|
which we let the compiler convert to const values as needed. This works except for
|
|
73
80
|
T** -> const T**, see comment in convertToNative method. */
|
|
74
|
-
//return std::forward_as_tuple(this->getNativeValue<std::tuple_element_t<I,
|
|
81
|
+
//return std::forward_as_tuple(this->getNativeValue<std::tuple_element_t<I, Parameter_Ts>, I>(values)...);
|
|
75
82
|
return std::forward_as_tuple(
|
|
76
|
-
(dynamic_cast<Parameter<std::tuple_element_t<I,
|
|
83
|
+
(dynamic_cast<Parameter<std::tuple_element_t<I, Parameter_Ts>>*>(this->parameters_[I].get()))->
|
|
77
84
|
convertToNative(values[I])...);
|
|
78
85
|
}
|
|
79
86
|
|
|
80
87
|
template<typename Proc_T>
|
|
81
|
-
VALUE NativeProc<Proc_T>::invoke(
|
|
88
|
+
VALUE NativeProc<Proc_T>::invoke(Parameter_Ts&& nativeArgs)
|
|
82
89
|
{
|
|
83
90
|
if constexpr (std::is_void_v<Return_T>)
|
|
84
91
|
{
|
|
85
|
-
std::apply(this->proc_, std::forward<
|
|
92
|
+
std::apply(this->proc_, std::forward<Parameter_Ts>(nativeArgs));
|
|
86
93
|
return Qnil;
|
|
87
94
|
}
|
|
88
95
|
else
|
|
89
96
|
{
|
|
90
97
|
// Call the native method and get the result
|
|
91
|
-
Return_T nativeResult = std::apply(this->proc_, std::forward<
|
|
98
|
+
Return_T nativeResult = std::apply(this->proc_, std::forward<Parameter_Ts>(nativeArgs));
|
|
92
99
|
|
|
93
100
|
// Return the result
|
|
94
101
|
return this->toRuby_.convert(std::forward<Return_T>(nativeResult));
|
|
@@ -96,28 +103,22 @@ namespace Rice::detail
|
|
|
96
103
|
}
|
|
97
104
|
|
|
98
105
|
template<typename Proc_T>
|
|
99
|
-
VALUE NativeProc<Proc_T>::operator()(
|
|
106
|
+
VALUE NativeProc<Proc_T>::operator()(std::map<std::string, VALUE>& values, VALUE)
|
|
100
107
|
{
|
|
101
108
|
// Get the ruby values and make sure we have the correct number
|
|
102
|
-
std::vector<std::optional<VALUE>> rubyValues = this->getRubyValues(
|
|
109
|
+
std::vector<std::optional<VALUE>> rubyValues = this->getRubyValues(values, true);
|
|
103
110
|
|
|
104
|
-
auto indices = std::make_index_sequence<std::tuple_size_v<
|
|
111
|
+
auto indices = std::make_index_sequence<std::tuple_size_v<Parameter_Ts>>{};
|
|
105
112
|
|
|
106
113
|
// Convert the Ruby values to native values
|
|
107
|
-
|
|
114
|
+
Parameter_Ts nativeValues = this->getNativeValues(rubyValues, indices);
|
|
108
115
|
|
|
109
116
|
// Now call the native method
|
|
110
|
-
VALUE result = this->invoke(std::forward<
|
|
117
|
+
VALUE result = this->invoke(std::forward<Parameter_Ts>(nativeValues));
|
|
111
118
|
|
|
112
119
|
return result;
|
|
113
120
|
}
|
|
114
121
|
|
|
115
|
-
template<typename Proc_T>
|
|
116
|
-
inline std::string NativeProc< Proc_T>::name()
|
|
117
|
-
{
|
|
118
|
-
return "proc";
|
|
119
|
-
}
|
|
120
|
-
|
|
121
122
|
template<typename Proc_T>
|
|
122
123
|
inline NativeKind NativeProc< Proc_T>::kind()
|
|
123
124
|
{
|
|
@@ -127,7 +128,17 @@ namespace Rice::detail
|
|
|
127
128
|
template<typename Proc_T>
|
|
128
129
|
inline VALUE NativeProc<Proc_T>::returnKlass()
|
|
129
130
|
{
|
|
130
|
-
|
|
131
|
-
|
|
131
|
+
// Check if an array is being returned
|
|
132
|
+
bool isBuffer = dynamic_cast<ReturnBuffer*>(this->returnInfo_.get()) ? true : false;
|
|
133
|
+
if (isBuffer)
|
|
134
|
+
{
|
|
135
|
+
TypeMapper<Pointer<detail::remove_cv_recursive_t<std::remove_pointer_t<Return_T>>>> typeMapper;
|
|
136
|
+
return typeMapper.rubyKlass();
|
|
137
|
+
}
|
|
138
|
+
else
|
|
139
|
+
{
|
|
140
|
+
TypeMapper<Return_T> typeMapper;
|
|
141
|
+
return typeMapper.rubyKlass();
|
|
142
|
+
}
|
|
132
143
|
}
|
|
133
144
|
}
|
data/rice/detail/Parameter.hpp
CHANGED
|
@@ -8,19 +8,22 @@ namespace Rice::detail
|
|
|
8
8
|
class ParameterAbstract
|
|
9
9
|
{
|
|
10
10
|
public:
|
|
11
|
-
ParameterAbstract()
|
|
12
|
-
ParameterAbstract(Arg* arg);
|
|
11
|
+
ParameterAbstract(std::unique_ptr<Arg>&& arg);
|
|
13
12
|
virtual ~ParameterAbstract() = default;
|
|
14
13
|
|
|
14
|
+
ParameterAbstract(const ParameterAbstract& other);
|
|
15
15
|
ParameterAbstract(ParameterAbstract&& other) = default;
|
|
16
16
|
ParameterAbstract& operator=(ParameterAbstract&& other) = default;
|
|
17
17
|
|
|
18
|
-
virtual
|
|
18
|
+
virtual VALUE defaultValueRuby() = 0;
|
|
19
|
+
virtual double matches(std::optional<VALUE>& valueOpt) = 0;
|
|
19
20
|
virtual std::string cppTypeName() = 0;
|
|
20
21
|
virtual VALUE klass() = 0;
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
Arg* arg();
|
|
24
|
+
|
|
25
|
+
private:
|
|
26
|
+
std::unique_ptr<Arg> arg_;
|
|
24
27
|
};
|
|
25
28
|
|
|
26
29
|
template<typename T>
|
|
@@ -29,19 +32,23 @@ namespace Rice::detail
|
|
|
29
32
|
public:
|
|
30
33
|
using Type = T;
|
|
31
34
|
|
|
32
|
-
Parameter()
|
|
33
|
-
Parameter(
|
|
35
|
+
Parameter(std::unique_ptr<Arg>&& arg);
|
|
36
|
+
Parameter(const Parameter& other) = default;
|
|
34
37
|
Parameter(Parameter&& other) = default;
|
|
35
38
|
Parameter& operator=(Parameter&& other) = default;
|
|
36
39
|
|
|
37
40
|
T convertToNative(std::optional<VALUE>& valueOpt);
|
|
38
|
-
|
|
41
|
+
VALUE convertToRuby(T& object);
|
|
42
|
+
VALUE defaultValueRuby() override;
|
|
43
|
+
|
|
44
|
+
double matches(std::optional<VALUE>& valueOpt) override;
|
|
39
45
|
std::string cppTypeName() override;
|
|
40
46
|
VALUE klass() override;
|
|
41
47
|
|
|
42
48
|
// std::string typeName() override;
|
|
43
49
|
private:
|
|
44
50
|
From_Ruby<remove_cv_recursive_t<T>> fromRuby_;
|
|
51
|
+
To_Ruby<remove_cv_recursive_t<T>> toRuby_;
|
|
45
52
|
};
|
|
46
53
|
}
|
|
47
54
|
#endif // Rice__detail__Parameter__hpp_
|