rice 4.6.1 → 4.7.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 +31 -0
- data/CMakeLists.txt +0 -4
- data/Rakefile +2 -8
- data/bin/rice-doc.rb +212 -0
- data/bin/rice-rbs.rb +93 -0
- data/include/rice/rice.hpp +4972 -4015
- data/include/rice/stl.hpp +822 -294
- data/lib/rice/doc/cpp_reference.rb +166 -0
- data/lib/rice/doc/doxygen.rb +294 -0
- data/lib/rice/doc/mkdocs.rb +298 -0
- data/lib/rice/doc/rice.rb +29 -0
- data/lib/rice/doc/ruby.rb +37 -0
- data/lib/rice/doc.rb +5 -0
- data/lib/{make_rice_headers.rb → rice/make_rice_headers.rb} +3 -0
- data/lib/rice/native.rb +18 -0
- data/lib/rice/native_registry.rb +21 -0
- data/lib/rice/parameter.rb +7 -0
- data/lib/rice/rbs.rb +104 -0
- data/lib/rice/version.rb +1 -1
- data/lib/rice.rb +4 -0
- data/lib/rubygems/cmake_builder.rb +24 -27
- data/rice/Arg.hpp +4 -4
- data/rice/Arg.ipp +4 -4
- data/rice/Buffer.hpp +32 -28
- data/rice/Buffer.ipp +306 -178
- data/rice/Data_Object.ipp +101 -82
- data/rice/Data_Type.hpp +5 -7
- data/rice/Data_Type.ipp +48 -29
- data/rice/Enum.ipp +15 -21
- data/rice/Function.hpp +17 -0
- data/rice/Function.ipp +13 -0
- data/rice/Pointer.hpp +15 -0
- data/rice/Pointer.ipp +49 -0
- data/rice/Return.hpp +1 -1
- data/rice/Return.ipp +2 -2
- data/rice/api.hpp +30 -0
- data/rice/cpp_api/Array.hpp +2 -2
- data/rice/cpp_api/Array.ipp +50 -5
- data/rice/cpp_api/Class.hpp +0 -5
- data/rice/cpp_api/Class.ipp +19 -0
- data/rice/cpp_api/Hash.ipp +20 -0
- data/rice/cpp_api/Module.hpp +6 -3
- data/rice/cpp_api/Module.ipp +49 -11
- data/rice/cpp_api/Object.ipp +31 -2
- data/rice/cpp_api/String.hpp +1 -2
- data/rice/cpp_api/String.ipp +21 -1
- data/rice/cpp_api/Struct.ipp +5 -0
- data/rice/cpp_api/Symbol.ipp +34 -0
- data/rice/cpp_api/shared_methods.hpp +12 -12
- data/rice/detail/MethodInfo.hpp +4 -2
- data/rice/detail/MethodInfo.ipp +19 -3
- data/rice/detail/ModuleRegistry.hpp +18 -0
- data/rice/detail/ModuleRegistry.ipp +25 -0
- data/rice/detail/Native.hpp +45 -2
- data/rice/detail/Native.ipp +196 -2
- data/rice/detail/NativeAttributeGet.hpp +9 -4
- data/rice/detail/NativeAttributeGet.ipp +65 -11
- data/rice/detail/NativeAttributeSet.hpp +4 -0
- data/rice/detail/NativeAttributeSet.ipp +30 -2
- data/rice/detail/NativeCallbackFFI.ipp +2 -2
- data/rice/detail/NativeCallbackSimple.ipp +1 -1
- data/rice/detail/NativeFunction.hpp +11 -49
- data/rice/detail/NativeFunction.ipp +82 -379
- data/rice/detail/NativeInvoker.hpp +74 -0
- data/rice/detail/NativeInvoker.ipp +197 -0
- data/rice/detail/NativeIterator.hpp +4 -0
- data/rice/detail/NativeIterator.ipp +19 -0
- data/rice/detail/NativeMethod.hpp +97 -0
- data/rice/detail/NativeMethod.ipp +332 -0
- data/rice/detail/NativeProc.hpp +51 -0
- data/rice/detail/NativeProc.ipp +133 -0
- data/rice/detail/NativeRegistry.hpp +8 -0
- data/rice/detail/NativeRegistry.ipp +27 -0
- data/rice/detail/Parameter.hpp +47 -0
- data/rice/detail/Parameter.ipp +105 -0
- data/rice/detail/Proc.ipp +14 -13
- data/rice/detail/Registries.hpp +1 -0
- data/rice/detail/RubyType.hpp +0 -2
- data/rice/detail/RubyType.ipp +15 -33
- data/rice/detail/Type.hpp +44 -8
- data/rice/detail/Type.ipp +151 -49
- data/rice/detail/TypeRegistry.hpp +3 -0
- data/rice/detail/TypeRegistry.ipp +17 -27
- data/rice/detail/Types.ipp +430 -0
- data/rice/detail/Wrapper.hpp +12 -0
- data/rice/detail/Wrapper.ipp +45 -2
- data/rice/detail/from_ruby.ipp +567 -1073
- data/rice/detail/ruby.hpp +1 -0
- data/rice/detail/to_ruby.ipp +4 -635
- data/rice/libc/file.ipp +3 -6
- data/rice/rice.hpp +22 -12
- data/rice/rice_api/Arg.hpp +7 -0
- data/rice/rice_api/Arg.ipp +9 -0
- data/rice/rice_api/ModuleRegistry.hpp +7 -0
- data/rice/rice_api/ModuleRegistry.ipp +10 -0
- data/rice/rice_api/Native.hpp +7 -0
- data/rice/rice_api/Native.ipp +52 -0
- data/rice/rice_api/NativeRegistry.hpp +7 -0
- data/rice/rice_api/NativeRegistry.ipp +21 -0
- data/rice/rice_api/Parameter.hpp +7 -0
- data/rice/rice_api/Parameter.ipp +11 -0
- data/rice/rice_api/Registries.hpp +6 -0
- data/rice/rice_api/Registries.ipp +12 -0
- data/rice/rice_api/TypeRegistry.hpp +7 -0
- data/rice/rice_api/TypeRegistry.ipp +10 -0
- data/rice/stl/complex.ipp +35 -0
- data/rice/stl/exception.ipp +20 -7
- data/rice/stl/filesystem.hpp +6 -0
- data/rice/stl/filesystem.ipp +34 -0
- data/rice/stl/map.ipp +13 -21
- data/rice/stl/monostate.ipp +37 -1
- data/rice/stl/multimap.ipp +17 -24
- data/rice/stl/optional.ipp +47 -2
- data/rice/stl/pair.ipp +23 -58
- data/rice/stl/reference_wrapper.ipp +22 -1
- data/rice/stl/set.ipp +17 -9
- data/rice/stl/shared_ptr.ipp +44 -17
- data/rice/stl/string.ipp +175 -7
- data/rice/stl/string_view.ipp +5 -0
- data/rice/stl/tuple.ipp +38 -9
- data/rice/stl/unique_ptr.ipp +46 -2
- data/rice/stl/unordered_map.ipp +13 -21
- data/rice/stl/variant.ipp +47 -11
- data/rice/stl/vector.ipp +183 -104
- data/rice/stl.hpp +1 -0
- data/rice/traits/function_traits.hpp +2 -2
- data/rice/traits/method_traits.hpp +5 -16
- data/rice/traits/rice_traits.hpp +24 -4
- data/rice.gemspec +11 -22
- data/test/embed_ruby.cpp +0 -3
- data/test/test_Array.cpp +38 -38
- data/test/test_Attribute.cpp +187 -2
- data/test/test_Buffer.cpp +302 -26
- data/test/test_Callback.cpp +2 -3
- data/test/test_Class.cpp +5 -5
- data/test/test_Data_Object.cpp +0 -55
- data/test/test_Data_Type.cpp +19 -30
- data/test/test_Enum.cpp +4 -46
- data/test/test_From_Ruby.cpp +88 -81
- data/test/test_GVL.cpp +109 -0
- data/test/test_Iterator.cpp +1 -1
- data/test/test_Keep_Alive_No_Wrapper.cpp +5 -3
- data/test/test_Module.cpp +8 -9
- data/test/test_Object.cpp +1 -1
- data/test/test_Overloads.cpp +3 -3
- data/test/test_Stl_Map.cpp +8 -8
- data/test/test_Stl_Multimap.cpp +4 -4
- data/test/test_Stl_Pair.cpp +5 -3
- data/test/test_Stl_SharedPtr.cpp +24 -12
- data/test/test_Stl_Tuple.cpp +1 -1
- data/test/test_Stl_UniquePtr.cpp +8 -0
- data/test/test_Stl_Unordered_Map.cpp +9 -9
- data/test/test_Stl_Variant.cpp +9 -3
- data/test/test_Stl_Vector.cpp +118 -13
- data/test/test_To_Ruby.cpp +35 -28
- data/test/test_Type.cpp +256 -53
- data/test/unittest.hpp +35 -0
- metadata +66 -34
- data/rice/Init.hpp +0 -8
- data/rice/Init.ipp +0 -8
- data/rice/detail/RubyFunction.hpp +0 -31
- data/rice/detail/RubyFunction.ipp +0 -77
- data/sample/callbacks/extconf.rb +0 -5
- data/sample/callbacks/sample_callbacks.cpp +0 -35
- data/sample/callbacks/test.rb +0 -28
- data/sample/enum/extconf.rb +0 -5
- data/sample/enum/sample_enum.cpp +0 -40
- data/sample/enum/test.rb +0 -8
- data/sample/inheritance/animals.cpp +0 -82
- data/sample/inheritance/extconf.rb +0 -5
- data/sample/inheritance/test.rb +0 -7
- data/sample/map/extconf.rb +0 -5
- data/sample/map/map.cpp +0 -73
- data/sample/map/test.rb +0 -7
- data/test/ext/t1/Foo.hpp +0 -10
- data/test/ext/t1/extconf.rb +0 -4
- data/test/ext/t1/t1.cpp +0 -13
- data/test/ext/t2/extconf.rb +0 -4
- data/test/ext/t2/t2.cpp +0 -11
- data/test/ruby/test_callbacks_sample.rb +0 -28
- data/test/ruby/test_multiple_extensions.rb +0 -18
- data/test/ruby/test_multiple_extensions_same_class.rb +0 -14
- data/test/ruby/test_multiple_extensions_with_inheritance.rb +0 -20
- /data/test/{test_Stl_Type.cpp → test_Stl_Type_Info.cpp} +0 -0
data/rice/detail/MethodInfo.hpp
CHANGED
|
@@ -29,18 +29,20 @@ namespace Rice
|
|
|
29
29
|
Arg* arg(std::string name);
|
|
30
30
|
|
|
31
31
|
int argCount();
|
|
32
|
+
Return* returnInfo();
|
|
33
|
+
Function* function();
|
|
32
34
|
|
|
33
35
|
// Iterator support
|
|
34
36
|
std::vector<Arg>::iterator begin();
|
|
35
37
|
std::vector<Arg>::iterator end();
|
|
36
38
|
|
|
37
|
-
Return returnInfo;
|
|
38
|
-
|
|
39
39
|
private:
|
|
40
40
|
template <typename Arg_T>
|
|
41
41
|
void processArg(const Arg_T& arg);
|
|
42
42
|
|
|
43
43
|
std::vector<Arg> args_;
|
|
44
|
+
Return returnInfo_;
|
|
45
|
+
Function function_;
|
|
44
46
|
};
|
|
45
47
|
}
|
|
46
48
|
#endif // Rice__MethodInfo__hpp_
|
data/rice/detail/MethodInfo.ipp
CHANGED
|
@@ -25,16 +25,22 @@ namespace Rice
|
|
|
25
25
|
template <typename Arg_T>
|
|
26
26
|
inline void MethodInfo::processArg(const Arg_T& arg)
|
|
27
27
|
{
|
|
28
|
-
static_assert(std::is_same_v<Arg_T, Return> || std::is_same_v<Arg_T, Arg>, "Unknown argument type");
|
|
29
|
-
|
|
30
28
|
if constexpr (std::is_same_v<Arg_T, Return>)
|
|
31
29
|
{
|
|
32
|
-
this->
|
|
30
|
+
this->returnInfo_ = arg;
|
|
31
|
+
}
|
|
32
|
+
else if constexpr (std::is_same_v<Arg_T, Function>)
|
|
33
|
+
{
|
|
34
|
+
this->function_ = arg;
|
|
33
35
|
}
|
|
34
36
|
else if constexpr (std::is_same_v<Arg_T, Arg>)
|
|
35
37
|
{
|
|
36
38
|
this->addArg(arg);
|
|
37
39
|
}
|
|
40
|
+
else
|
|
41
|
+
{
|
|
42
|
+
static_assert(true, "Unknown argument type");
|
|
43
|
+
}
|
|
38
44
|
}
|
|
39
45
|
|
|
40
46
|
inline void MethodInfo::addArg(const Arg& arg)
|
|
@@ -71,6 +77,16 @@ namespace Rice
|
|
|
71
77
|
return nullptr;
|
|
72
78
|
}
|
|
73
79
|
|
|
80
|
+
inline Return* MethodInfo::returnInfo()
|
|
81
|
+
{
|
|
82
|
+
return &this->returnInfo_;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
inline Function* MethodInfo::function()
|
|
86
|
+
{
|
|
87
|
+
return &this->function_;
|
|
88
|
+
}
|
|
89
|
+
|
|
74
90
|
inline std::vector<Arg>::iterator MethodInfo::begin()
|
|
75
91
|
{
|
|
76
92
|
return this->args_.begin();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#ifndef Rice__ModuleRegistry__hpp_
|
|
2
|
+
#define Rice__ModuleRegistry__hpp_
|
|
3
|
+
|
|
4
|
+
namespace Rice::detail
|
|
5
|
+
{
|
|
6
|
+
class ModuleRegistry
|
|
7
|
+
{
|
|
8
|
+
public:
|
|
9
|
+
void add(VALUE module);
|
|
10
|
+
// API for access from Ruby
|
|
11
|
+
VALUE modules();
|
|
12
|
+
|
|
13
|
+
private:
|
|
14
|
+
std::set<VALUE> modules_{};
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
#endif // Rice__ModuleRegistry__hpp_
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#include <iostream>
|
|
2
|
+
#include <stdexcept>
|
|
3
|
+
#include <sstream>
|
|
4
|
+
#include <typeindex>
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
namespace Rice::detail
|
|
8
|
+
{
|
|
9
|
+
inline void ModuleRegistry::add(VALUE module)
|
|
10
|
+
{
|
|
11
|
+
this->modules_.insert(module);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
inline VALUE ModuleRegistry::modules()
|
|
15
|
+
{
|
|
16
|
+
Array result;
|
|
17
|
+
|
|
18
|
+
for (const VALUE& value : this->modules_)
|
|
19
|
+
{
|
|
20
|
+
Module module(value);
|
|
21
|
+
result.push(module, false);
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
}
|
data/rice/detail/Native.hpp
CHANGED
|
@@ -16,17 +16,60 @@ namespace Rice::detail
|
|
|
16
16
|
Native* native;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
enum class NativeKind
|
|
20
|
+
{
|
|
21
|
+
Function,
|
|
22
|
+
Method,
|
|
23
|
+
Iterator,
|
|
24
|
+
AttributeReader,
|
|
25
|
+
AttributeWriter,
|
|
26
|
+
Proc
|
|
27
|
+
};
|
|
28
|
+
|
|
19
29
|
class Native
|
|
20
30
|
{
|
|
21
31
|
public:
|
|
22
32
|
static VALUE resolve(int argc, VALUE* argv, VALUE self);
|
|
23
33
|
public:
|
|
34
|
+
Native() = default;
|
|
35
|
+
Native(std::vector<std::unique_ptr<ParameterAbstract>>&& parameters);
|
|
24
36
|
virtual ~Native() = default;
|
|
25
|
-
VALUE call(int argc, VALUE* argv, VALUE self);
|
|
26
37
|
|
|
27
|
-
|
|
38
|
+
Native(const Native&) = delete;
|
|
39
|
+
Native(Native&&) = delete;
|
|
40
|
+
void operator=(const Native&) = delete;
|
|
41
|
+
void operator=(Native&&) = delete;
|
|
42
|
+
|
|
43
|
+
virtual Resolved matches(size_t argc, const VALUE* argv, VALUE self);
|
|
28
44
|
virtual VALUE operator()(size_t argc, const VALUE* argv, VALUE self) = 0;
|
|
29
45
|
virtual std::string toString() = 0;
|
|
46
|
+
|
|
47
|
+
// Ruby API access
|
|
48
|
+
virtual std::string name() = 0;
|
|
49
|
+
virtual NativeKind kind() = 0;
|
|
50
|
+
virtual VALUE returnKlass() = 0;
|
|
51
|
+
std::vector<const ParameterAbstract*> parameters();
|
|
52
|
+
|
|
53
|
+
protected:
|
|
54
|
+
template<typename T>
|
|
55
|
+
static void verify_type(bool isBuffer);
|
|
56
|
+
|
|
57
|
+
template<typename Tuple_T, std::size_t ...Indices>
|
|
58
|
+
static void verify_args(MethodInfo* methodInfo, std::index_sequence<Indices...> indices);
|
|
59
|
+
|
|
60
|
+
std::vector<std::optional<VALUE>> getRubyValues(size_t argc, const VALUE* argv, bool validate);
|
|
61
|
+
ParameterAbstract* getParameterByName(std::string name);
|
|
62
|
+
Convertible matchParameters(std::vector<std::optional<VALUE>>& values);
|
|
63
|
+
|
|
64
|
+
template<typename Tuple_T>
|
|
65
|
+
static std::vector<std::unique_ptr<ParameterAbstract>> create_parameters(MethodInfo* methodInfo);
|
|
66
|
+
|
|
67
|
+
template<typename Tuple_T, std::size_t ...Indices>
|
|
68
|
+
static inline void create_parameters_impl(std::vector<std::unique_ptr<ParameterAbstract>>& parameters, MethodInfo* methodInfo, std::index_sequence<Indices...> indices);
|
|
69
|
+
|
|
70
|
+
protected:
|
|
71
|
+
std::vector<std::unique_ptr<ParameterAbstract>> parameters_;
|
|
72
|
+
|
|
30
73
|
};
|
|
31
74
|
}
|
|
32
75
|
|
data/rice/detail/Native.ipp
CHANGED
|
@@ -79,7 +79,7 @@ namespace Rice::detail
|
|
|
79
79
|
else if (natives.size() == 0)
|
|
80
80
|
{
|
|
81
81
|
Identifier identifier(methodId);
|
|
82
|
-
|
|
82
|
+
rb_enc_raise(rb_utf8_encoding(), rb_eArgError, "Could not find method call for %s#%s", rb_class2name(klass), identifier.c_str());
|
|
83
83
|
}
|
|
84
84
|
else
|
|
85
85
|
{
|
|
@@ -145,7 +145,7 @@ namespace Rice::detail
|
|
|
145
145
|
message << "\n " << resolve.native->toString();
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
rb_enc_raise(rb_utf8_encoding(), rb_eArgError, message.str().c_str(), rb_class2name(klass), identifier.c_str(), natives.size());
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
}
|
|
@@ -154,4 +154,198 @@ namespace Rice::detail
|
|
|
154
154
|
return (*native)(argc, argv, self);
|
|
155
155
|
});
|
|
156
156
|
}
|
|
157
|
+
|
|
158
|
+
inline Native::Native(std::vector<std::unique_ptr<ParameterAbstract>>&& parameters) : parameters_(std::move(parameters))
|
|
159
|
+
{
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
inline ParameterAbstract* Native::getParameterByName(std::string name)
|
|
163
|
+
{
|
|
164
|
+
for (std::unique_ptr<ParameterAbstract>& parameter : this->parameters_)
|
|
165
|
+
{
|
|
166
|
+
if (parameter->arg->name == name)
|
|
167
|
+
{
|
|
168
|
+
return parameter.get();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return nullptr;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// ----------- Helpers ----------------
|
|
176
|
+
template<typename T>
|
|
177
|
+
inline void Native::verify_type(bool isBuffer)
|
|
178
|
+
{
|
|
179
|
+
using Base_T = std::remove_pointer_t<remove_cv_recursive_t<T>>;
|
|
180
|
+
|
|
181
|
+
detail::verifyType<T>();
|
|
182
|
+
|
|
183
|
+
if constexpr (std::is_pointer_v<T> && std::is_fundamental_v<std::remove_pointer_t<T>>)
|
|
184
|
+
{
|
|
185
|
+
Type<Pointer<std::remove_pointer_t<T>>>::verify();
|
|
186
|
+
Type<Buffer<std::remove_pointer_t<T>>>::verify();
|
|
187
|
+
}
|
|
188
|
+
if constexpr (std::is_array_v<T>)
|
|
189
|
+
{
|
|
190
|
+
Type<Pointer<std::remove_extent_t<remove_cv_recursive_t<T>>>>::verify();
|
|
191
|
+
Type<Buffer<std::remove_extent_t<remove_cv_recursive_t<T>>>>::verify();
|
|
192
|
+
}
|
|
193
|
+
else if (isBuffer)
|
|
194
|
+
{
|
|
195
|
+
if constexpr (std::is_pointer_v<T> && !std::is_function_v<Base_T> && !std::is_abstract_v<Base_T>)
|
|
196
|
+
{
|
|
197
|
+
Type<Pointer<Base_T>>::verify();
|
|
198
|
+
Type<Buffer<Base_T>>::verify();
|
|
199
|
+
}
|
|
200
|
+
else
|
|
201
|
+
{
|
|
202
|
+
static_assert(true, "Only pointer types can be marked as buffers");
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
template<typename Tuple_T, std::size_t ...Indices>
|
|
208
|
+
inline void Native::verify_args(MethodInfo* methodInfo, std::index_sequence<Indices...> indices)
|
|
209
|
+
{
|
|
210
|
+
(Native::verify_type<std::tuple_element_t<Indices, Tuple_T>>(methodInfo->arg(Indices)->isBuffer()), ...);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
template<typename Tuple_T, std::size_t ...Indices>
|
|
214
|
+
inline void Native::create_parameters_impl(std::vector<std::unique_ptr<ParameterAbstract>>& parameters, MethodInfo* methodInfo, std::index_sequence<Indices...> indices)
|
|
215
|
+
{
|
|
216
|
+
(parameters.push_back(std::move(std::make_unique<Parameter<std::tuple_element_t<Indices, Tuple_T>>>(methodInfo->arg(Indices)))), ...);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
template<typename Tuple_T>
|
|
220
|
+
inline std::vector<std::unique_ptr<ParameterAbstract>> Native::create_parameters(MethodInfo* methodInfo)
|
|
221
|
+
{
|
|
222
|
+
std::vector<std::unique_ptr<ParameterAbstract>> result;
|
|
223
|
+
auto indices = std::make_index_sequence<std::tuple_size_v<Tuple_T>>{};
|
|
224
|
+
Native::create_parameters_impl<Tuple_T>(result, methodInfo, indices);
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
inline std::vector<std::optional<VALUE>> Native::getRubyValues(size_t argc, const VALUE* argv, bool validate)
|
|
229
|
+
{
|
|
230
|
+
#undef max
|
|
231
|
+
int size = std::max(this->parameters_.size(), argc);
|
|
232
|
+
std::vector<std::optional<VALUE>> result(size);
|
|
233
|
+
|
|
234
|
+
// Keyword handling
|
|
235
|
+
if (rb_keyword_given_p())
|
|
236
|
+
{
|
|
237
|
+
// Keywords are stored in the last element in a hash
|
|
238
|
+
int actualArgc = argc - 1;
|
|
239
|
+
|
|
240
|
+
VALUE value = argv[actualArgc];
|
|
241
|
+
Hash keywords(value);
|
|
242
|
+
|
|
243
|
+
// Copy over leading non-keyword arguments
|
|
244
|
+
for (int i = 0; i < actualArgc; i++)
|
|
245
|
+
{
|
|
246
|
+
result[i] = argv[i];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Copy over keyword arguments
|
|
250
|
+
for (auto pair : keywords)
|
|
251
|
+
{
|
|
252
|
+
Symbol key(pair.first);
|
|
253
|
+
ParameterAbstract* parameter = this->getParameterByName(key.str());
|
|
254
|
+
if (!parameter)
|
|
255
|
+
{
|
|
256
|
+
throw std::invalid_argument("Unknown keyword: " + key.str());
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const Arg* arg = parameter->arg;
|
|
260
|
+
|
|
261
|
+
result[arg->position] = pair.second.value();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
else
|
|
265
|
+
{
|
|
266
|
+
std::copy(argv, argv + argc, result.begin());
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Block handling. If we find a block and the last parameter is missing then
|
|
270
|
+
// set it to the block
|
|
271
|
+
if (rb_block_given_p() && result.size() > 0 && !result.back().has_value())
|
|
272
|
+
{
|
|
273
|
+
VALUE proc = rb_block_proc();
|
|
274
|
+
result.back() = proc;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (validate)
|
|
278
|
+
{
|
|
279
|
+
// Protect against user sending too many arguments
|
|
280
|
+
if (argc > this->parameters_.size())
|
|
281
|
+
{
|
|
282
|
+
std::string message = "wrong number of arguments (given " +
|
|
283
|
+
std::to_string(argc) + ", expected " + std::to_string(this->parameters_.size()) + ")";
|
|
284
|
+
throw std::invalid_argument(message);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
for (size_t i = 0; i < result.size(); i++)
|
|
288
|
+
{
|
|
289
|
+
std::optional<VALUE> value = result[i];
|
|
290
|
+
ParameterAbstract* parameter = this->parameters_[i].get();
|
|
291
|
+
|
|
292
|
+
if (!parameter->arg->hasDefaultValue() && !value.has_value())
|
|
293
|
+
{
|
|
294
|
+
std::string message;
|
|
295
|
+
message = "Missing argument. Name: " + parameter->arg->name + ". Index: " + std::to_string(parameter->arg->position) + ".";
|
|
296
|
+
throw std::invalid_argument(message);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
inline Convertible Native::matchParameters(std::vector<std::optional<VALUE>>& values)
|
|
305
|
+
{
|
|
306
|
+
Convertible result = Convertible::Exact;
|
|
307
|
+
for (size_t i = 0; i < this->parameters_.size(); i++)
|
|
308
|
+
{
|
|
309
|
+
ParameterAbstract* parameter = this->parameters_[i].get();
|
|
310
|
+
std::optional<VALUE>& value = values[i];
|
|
311
|
+
result = result & parameter->matches(value);
|
|
312
|
+
}
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
inline Resolved Native::matches(size_t argc, const VALUE* argv, VALUE self)
|
|
317
|
+
{
|
|
318
|
+
// Return false if Ruby provided more arguments than the C++ method takes
|
|
319
|
+
if (argc > this->parameters_.size())
|
|
320
|
+
return Resolved{ Convertible::None, 0, this };
|
|
321
|
+
|
|
322
|
+
Resolved result{ Convertible::Exact, 1, this };
|
|
323
|
+
|
|
324
|
+
std::vector<std::optional<VALUE>> rubyValues = this->getRubyValues(argc, argv, false);
|
|
325
|
+
result.convertible = this->matchParameters(rubyValues);
|
|
326
|
+
|
|
327
|
+
if (this->parameters_.size() > 0)
|
|
328
|
+
{
|
|
329
|
+
int providedValues = std::count_if(rubyValues.begin(), rubyValues.end(), [](std::optional<VALUE>& value)
|
|
330
|
+
{
|
|
331
|
+
return value.has_value();
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
result.parameterMatch = providedValues / (double)this->parameters_.size();
|
|
335
|
+
}
|
|
336
|
+
return result;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
inline std::vector<const ParameterAbstract*> Native::parameters()
|
|
340
|
+
{
|
|
341
|
+
std::vector<const ParameterAbstract*> result;
|
|
342
|
+
|
|
343
|
+
std::transform(this->parameters_.begin(), this->parameters_.end(), std::back_inserter(result),
|
|
344
|
+
[](std::unique_ptr<ParameterAbstract>& parameter) -> ParameterAbstract*
|
|
345
|
+
{
|
|
346
|
+
return parameter.get();
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
return result;
|
|
350
|
+
}
|
|
157
351
|
}
|
|
@@ -18,13 +18,13 @@ namespace Rice
|
|
|
18
18
|
public:
|
|
19
19
|
using NativeAttribute_T = NativeAttributeGet<Attribute_T>;
|
|
20
20
|
|
|
21
|
-
using
|
|
21
|
+
using Attr_T = typename attribute_traits<Attribute_T>::attr_type;
|
|
22
22
|
using Receiver_T = typename attribute_traits<Attribute_T>::class_type;
|
|
23
|
-
using To_Ruby_T = remove_cv_recursive_t<
|
|
23
|
+
using To_Ruby_T = remove_cv_recursive_t<Attr_T>;
|
|
24
24
|
|
|
25
25
|
public:
|
|
26
26
|
// Register attribute getter with Ruby
|
|
27
|
-
static void define(VALUE klass, std::string name, Attribute_T attribute);
|
|
27
|
+
static void define(VALUE klass, std::string name, Attribute_T attribute, Return returnInfo);
|
|
28
28
|
|
|
29
29
|
public:
|
|
30
30
|
// Disallow creating/copying/moving
|
|
@@ -38,13 +38,18 @@ namespace Rice
|
|
|
38
38
|
VALUE operator()(size_t argc, const VALUE* argv, VALUE self) override;
|
|
39
39
|
std::string toString() override;
|
|
40
40
|
|
|
41
|
+
std::string name() override;
|
|
42
|
+
NativeKind kind() override;
|
|
43
|
+
VALUE returnKlass() override;
|
|
44
|
+
|
|
41
45
|
protected:
|
|
42
|
-
NativeAttributeGet(VALUE klass, std::string name, Attribute_T attr);
|
|
46
|
+
NativeAttributeGet(VALUE klass, std::string name, Attribute_T attr, Return returnInfo);
|
|
43
47
|
|
|
44
48
|
private:
|
|
45
49
|
VALUE klass_;
|
|
46
50
|
std::string name_;
|
|
47
51
|
Attribute_T attribute_;
|
|
52
|
+
Return return_;
|
|
48
53
|
};
|
|
49
54
|
} // detail
|
|
50
55
|
} // Rice
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
#include <array>
|
|
2
2
|
#include <algorithm>
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
namespace Rice::detail
|
|
6
5
|
{
|
|
7
6
|
template<typename Attribute_T>
|
|
8
|
-
void NativeAttributeGet<Attribute_T>::define(VALUE klass, std::string name, Attribute_T attribute)
|
|
7
|
+
void NativeAttributeGet<Attribute_T>::define(VALUE klass, std::string name, Attribute_T attribute, Return returnInfo)
|
|
9
8
|
{
|
|
9
|
+
// Verify attribute type
|
|
10
|
+
Native::verify_type<Attr_T>(returnInfo.isBuffer());
|
|
11
|
+
|
|
10
12
|
// Create a NativeAttributeGet that Ruby will call to read/write C++ variables
|
|
11
|
-
NativeAttribute_T* nativeAttribute = new NativeAttribute_T(klass, name, std::forward<Attribute_T>(attribute));
|
|
13
|
+
NativeAttribute_T* nativeAttribute = new NativeAttribute_T(klass, name, std::forward<Attribute_T>(attribute), returnInfo);
|
|
12
14
|
std::unique_ptr<Native> native(nativeAttribute);
|
|
13
15
|
|
|
14
16
|
detail::protect(rb_define_method, klass, name.c_str(), (RUBY_METHOD_FUNC)&Native::resolve, -1);
|
|
@@ -30,8 +32,8 @@ namespace Rice::detail
|
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
template<typename Attribute_T>
|
|
33
|
-
NativeAttributeGet<Attribute_T>::NativeAttributeGet(VALUE klass, std::string name, Attribute_T attribute)
|
|
34
|
-
: klass_(klass), name_(name), attribute_(attribute)
|
|
35
|
+
NativeAttributeGet<Attribute_T>::NativeAttributeGet(VALUE klass, std::string name, Attribute_T attribute, Return returnInfo)
|
|
36
|
+
: klass_(klass), name_(name), attribute_(attribute), return_(returnInfo)
|
|
35
37
|
{
|
|
36
38
|
}
|
|
37
39
|
|
|
@@ -42,21 +44,45 @@ namespace Rice::detail
|
|
|
42
44
|
{
|
|
43
45
|
Receiver_T* nativeSelf = From_Ruby<Receiver_T*>().convert(self);
|
|
44
46
|
|
|
45
|
-
if constexpr (std::is_fundamental_v<detail::intrinsic_type<To_Ruby_T>>
|
|
46
|
-
(std::is_array_v<To_Ruby_T> && std::is_fundamental_v<std::remove_extent_t<To_Ruby_T>>))
|
|
47
|
+
if constexpr (std::is_fundamental_v<detail::intrinsic_type<To_Ruby_T>>)
|
|
47
48
|
{
|
|
48
|
-
return To_Ruby<To_Ruby_T>().convert(nativeSelf->*attribute_);
|
|
49
|
+
return To_Ruby<To_Ruby_T>(&this->return_).convert(nativeSelf->*attribute_);
|
|
50
|
+
}
|
|
51
|
+
else if constexpr (std::is_array_v<To_Ruby_T>)
|
|
52
|
+
{
|
|
53
|
+
return To_Ruby<To_Ruby_T>(&this->return_).convert(nativeSelf->*attribute_);
|
|
54
|
+
}
|
|
55
|
+
else if constexpr (std::is_pointer_v<To_Ruby_T>)
|
|
56
|
+
{
|
|
57
|
+
return To_Ruby<To_Ruby_T>(&this->return_).convert(nativeSelf->*attribute_);
|
|
49
58
|
}
|
|
50
59
|
else
|
|
51
60
|
{
|
|
52
61
|
// If the attribute is an object return a reference to avoid a copy (and avoid issues with
|
|
53
62
|
// attributes that are not assignable, copy constructible or move constructible)
|
|
54
|
-
return To_Ruby<To_Ruby_T&>().convert(nativeSelf->*attribute_);
|
|
63
|
+
return To_Ruby<To_Ruby_T&>(&this->return_).convert(nativeSelf->*attribute_);
|
|
55
64
|
}
|
|
56
65
|
}
|
|
57
66
|
else
|
|
58
67
|
{
|
|
59
|
-
|
|
68
|
+
if constexpr (std::is_fundamental_v<detail::intrinsic_type<To_Ruby_T>>)
|
|
69
|
+
{
|
|
70
|
+
return To_Ruby<To_Ruby_T>(&this->return_).convert(*attribute_);
|
|
71
|
+
}
|
|
72
|
+
else if constexpr (std::is_array_v<To_Ruby_T>)
|
|
73
|
+
{
|
|
74
|
+
return To_Ruby<To_Ruby_T>(&this->return_).convert(*attribute_);
|
|
75
|
+
}
|
|
76
|
+
else if constexpr (std::is_pointer_v<To_Ruby_T>)
|
|
77
|
+
{
|
|
78
|
+
return To_Ruby<To_Ruby_T>(&this->return_).convert(*attribute_);
|
|
79
|
+
}
|
|
80
|
+
else
|
|
81
|
+
{
|
|
82
|
+
// If the attribute is an object return a reference to avoid a copy (and avoid issues with
|
|
83
|
+
// attributes that are not assignable, copy constructible or move constructible)
|
|
84
|
+
return To_Ruby<To_Ruby_T&>(&this->return_).convert(*attribute_);
|
|
85
|
+
}
|
|
60
86
|
}
|
|
61
87
|
}
|
|
62
88
|
|
|
@@ -65,4 +91,32 @@ namespace Rice::detail
|
|
|
65
91
|
{
|
|
66
92
|
return "";
|
|
67
93
|
}
|
|
68
|
-
|
|
94
|
+
|
|
95
|
+
template<typename Attribute_T>
|
|
96
|
+
inline std::string NativeAttributeGet<Attribute_T>::name()
|
|
97
|
+
{
|
|
98
|
+
return this->name_;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
template<typename Attribute_T>
|
|
102
|
+
inline NativeKind NativeAttributeGet<Attribute_T>::kind()
|
|
103
|
+
{
|
|
104
|
+
return NativeKind::AttributeReader;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
template<typename Attribute_T>
|
|
108
|
+
inline VALUE NativeAttributeGet<Attribute_T>::returnKlass()
|
|
109
|
+
{
|
|
110
|
+
// Check if an array is being returned
|
|
111
|
+
if (this->return_.isBuffer())
|
|
112
|
+
{
|
|
113
|
+
TypeMapper<Pointer<Attr_T>> typeMapper;
|
|
114
|
+
return typeMapper.rubyKlass();
|
|
115
|
+
}
|
|
116
|
+
else
|
|
117
|
+
{
|
|
118
|
+
TypeMapper<Attr_T> typeMapper;
|
|
119
|
+
return typeMapper.rubyKlass();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -30,6 +30,10 @@ namespace Rice
|
|
|
30
30
|
VALUE operator()(size_t argc, const VALUE* argv, VALUE self) override;
|
|
31
31
|
std::string toString() override;
|
|
32
32
|
|
|
33
|
+
std::string name() override;
|
|
34
|
+
NativeKind kind() override;
|
|
35
|
+
VALUE returnKlass() override;
|
|
36
|
+
|
|
33
37
|
protected:
|
|
34
38
|
NativeAttributeSet(VALUE klass, std::string name, Attribute_T attr);
|
|
35
39
|
|
|
@@ -52,7 +52,16 @@ namespace Rice::detail
|
|
|
52
52
|
if constexpr (!std::is_null_pointer_v<Receiver_T>)
|
|
53
53
|
{
|
|
54
54
|
Receiver_T* nativeSelf = From_Ruby<Receiver_T*>().convert(self);
|
|
55
|
-
|
|
55
|
+
|
|
56
|
+
// Deal with pointers to pointes, see Parameter::convertToNative commment
|
|
57
|
+
if constexpr (is_pointer_pointer_v<Attr_T> && !std::is_convertible_v<remove_cv_recursive_t<Attr_T>, Attr_T>)
|
|
58
|
+
{
|
|
59
|
+
nativeSelf->*attribute_ = (Attr_T)From_Ruby<T_Unqualified>().convert(value);
|
|
60
|
+
}
|
|
61
|
+
else
|
|
62
|
+
{
|
|
63
|
+
nativeSelf->*attribute_ = From_Ruby<T_Unqualified>().convert(value);
|
|
64
|
+
}
|
|
56
65
|
}
|
|
57
66
|
else
|
|
58
67
|
{
|
|
@@ -67,4 +76,23 @@ namespace Rice::detail
|
|
|
67
76
|
{
|
|
68
77
|
return "";
|
|
69
78
|
}
|
|
70
|
-
|
|
79
|
+
|
|
80
|
+
template<typename Attribute_T>
|
|
81
|
+
inline std::string NativeAttributeSet<Attribute_T>::name()
|
|
82
|
+
{
|
|
83
|
+
return this->name_;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
template<typename Attribute_T>
|
|
87
|
+
inline NativeKind NativeAttributeSet<Attribute_T>::kind()
|
|
88
|
+
{
|
|
89
|
+
return NativeKind::AttributeWriter;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
template<typename Attribute_T>
|
|
93
|
+
inline VALUE NativeAttributeSet<Attribute_T>::returnKlass()
|
|
94
|
+
{
|
|
95
|
+
TypeMapper<Attr_T> typeMapper;
|
|
96
|
+
return typeMapper.rubyKlass();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -64,7 +64,7 @@ namespace Rice::detail
|
|
|
64
64
|
on the arguments (Arg_Ts) required by the C++ function. Arg_T may have const/volatile while
|
|
65
65
|
the associated From_Ruby<T> template parameter will not. Thus From_Ruby produces non-const values
|
|
66
66
|
which we let the compiler convert to const values as needed. This works except for
|
|
67
|
-
T** -> const T**, see comment in
|
|
67
|
+
T** -> const T**, see comment in convertToNative method. */
|
|
68
68
|
return std::forward_as_tuple(*(std::tuple_element_t<I, Tuple_T>*)(args[I])...);
|
|
69
69
|
}
|
|
70
70
|
|
|
@@ -137,7 +137,7 @@ namespace Rice::detail
|
|
|
137
137
|
VALUE result = detail::protect(rb_funcallv, this->proc_, id.id(), (int)sizeof...(Arg_Ts), values.data());
|
|
138
138
|
if constexpr (!std::is_void_v<Return_T>)
|
|
139
139
|
{
|
|
140
|
-
static From_Ruby<Return_T> fromRuby(dynamic_cast<Arg*>(
|
|
140
|
+
static From_Ruby<Return_T> fromRuby(dynamic_cast<Arg*>(methodInfo_->returnInfo()));
|
|
141
141
|
return fromRuby.convert(result);
|
|
142
142
|
}
|
|
143
143
|
}
|
|
@@ -15,7 +15,7 @@ namespace Rice::detail
|
|
|
15
15
|
VALUE result = detail::protect(rb_funcallv, proc, id.id(), (int)sizeof...(Arg_Ts), values.data());
|
|
16
16
|
if constexpr (!std::is_void_v<Return_T>)
|
|
17
17
|
{
|
|
18
|
-
static From_Ruby<Return_T> fromRuby(dynamic_cast<Arg*>(
|
|
18
|
+
static From_Ruby<Return_T> fromRuby(dynamic_cast<Arg*>(methodInfo_->returnInfo()));
|
|
19
19
|
return fromRuby.convert(result);
|
|
20
20
|
}
|
|
21
21
|
}
|