rice 4.6.1 → 4.7.1
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 +38 -0
- data/CMakeLists.txt +0 -4
- data/Rakefile +2 -8
- data/bin/rice-doc.rb +211 -0
- data/bin/rice-rbs.rb +92 -0
- data/include/rice/rice.hpp +4694 -3704
- data/include/rice/stl.hpp +840 -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 +136 -88
- 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 +4 -4
- 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 +43 -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 -6
- 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 +26 -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 +23 -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 +10 -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 +1 -56
- data/test/test_Data_Type.cpp +20 -30
- data/test/test_Enum.cpp +4 -46
- data/test/test_From_Ruby.cpp +89 -82
- 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 +58 -10
- 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_String_View.cpp +10 -0
- 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_Symbol.cpp +12 -0
- data/test/test_To_Ruby.cpp +35 -28
- data/test/test_Type.cpp +256 -53
- data/test/unittest.hpp +35 -0
- metadata +52 -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/cpp_api/Symbol.ipp
CHANGED
|
@@ -54,22 +54,62 @@ namespace Rice::detail
|
|
|
54
54
|
{
|
|
55
55
|
return true;
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
static VALUE rubyKlass()
|
|
59
|
+
{
|
|
60
|
+
return rb_cSymbol;
|
|
61
|
+
}
|
|
57
62
|
};
|
|
58
63
|
|
|
59
64
|
template<>
|
|
60
65
|
class To_Ruby<Symbol>
|
|
61
66
|
{
|
|
62
67
|
public:
|
|
68
|
+
To_Ruby() = default;
|
|
69
|
+
|
|
70
|
+
explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
|
|
71
|
+
{
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
VALUE convert(Symbol const& x)
|
|
75
|
+
{
|
|
76
|
+
return x.value();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private:
|
|
80
|
+
Return* returnInfo_ = nullptr;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
template<>
|
|
85
|
+
class To_Ruby<Symbol&>
|
|
86
|
+
{
|
|
87
|
+
public:
|
|
88
|
+
To_Ruby() = default;
|
|
89
|
+
|
|
90
|
+
explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
|
|
91
|
+
{
|
|
92
|
+
}
|
|
93
|
+
|
|
63
94
|
VALUE convert(Symbol const& x)
|
|
64
95
|
{
|
|
65
96
|
return x.value();
|
|
66
97
|
}
|
|
98
|
+
|
|
99
|
+
private:
|
|
100
|
+
Return* returnInfo_ = nullptr;
|
|
67
101
|
};
|
|
68
102
|
|
|
69
103
|
template<>
|
|
70
104
|
class From_Ruby<Symbol>
|
|
71
105
|
{
|
|
72
106
|
public:
|
|
107
|
+
From_Ruby() = default;
|
|
108
|
+
|
|
109
|
+
explicit From_Ruby(Arg* arg) : arg_(arg)
|
|
110
|
+
{
|
|
111
|
+
}
|
|
112
|
+
|
|
73
113
|
Convertible is_convertible(VALUE value)
|
|
74
114
|
{
|
|
75
115
|
switch (rb_type(value))
|
|
@@ -89,5 +129,8 @@ namespace Rice::detail
|
|
|
89
129
|
{
|
|
90
130
|
return Symbol(value);
|
|
91
131
|
}
|
|
132
|
+
|
|
133
|
+
private:
|
|
134
|
+
Arg* arg_ = nullptr;
|
|
92
135
|
};
|
|
93
136
|
}
|
|
@@ -30,11 +30,11 @@ inline auto& include_module(Module const& inc)
|
|
|
30
30
|
* \param args a list of Arg instance used to define default parameters.
|
|
31
31
|
* \return *this
|
|
32
32
|
*/
|
|
33
|
-
template<typename
|
|
34
|
-
inline auto& define_method(std::string name,
|
|
33
|
+
template<typename Method_T, typename...Arg_Ts>
|
|
34
|
+
inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...args)
|
|
35
35
|
{
|
|
36
|
-
MethodInfo* methodInfo = new MethodInfo(detail::method_traits<
|
|
37
|
-
this->
|
|
36
|
+
MethodInfo* methodInfo = new MethodInfo(detail::method_traits<Method_T>::arity, args...);
|
|
37
|
+
this->wrap_native_method(this->value(), name, std::forward<Method_T>(method), methodInfo);
|
|
38
38
|
return *this;
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -52,8 +52,8 @@ inline auto& define_method(std::string name, Function_T&& func, const Arg_Ts&...
|
|
|
52
52
|
template<typename Function_T, typename...Arg_Ts>
|
|
53
53
|
inline auto& define_function(std::string name, Function_T&& func, const Arg_Ts&...args)
|
|
54
54
|
{
|
|
55
|
-
MethodInfo* methodInfo = new MethodInfo(detail::
|
|
56
|
-
this->
|
|
55
|
+
MethodInfo* methodInfo = new MethodInfo(detail::function_traits<Function_T>::arity, args...);
|
|
56
|
+
this->wrap_native_function(this->value(), name, std::forward<Function_T>(func), methodInfo);
|
|
57
57
|
return *this;
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -72,11 +72,11 @@ inline auto& define_function(std::string name, Function_T&& func, const Arg_Ts&.
|
|
|
72
72
|
* \param args a list of Arg instance used to define default parameters (optional)
|
|
73
73
|
* \return *this
|
|
74
74
|
*/
|
|
75
|
-
template<typename
|
|
76
|
-
inline auto& define_singleton_method(std::string name,
|
|
75
|
+
template<typename Method_T, typename...Arg_Ts>
|
|
76
|
+
inline auto& define_singleton_method(std::string name, Method_T&& method, const Arg_Ts&...args)
|
|
77
77
|
{
|
|
78
|
-
MethodInfo* methodInfo = new MethodInfo(detail::method_traits<
|
|
79
|
-
this->
|
|
78
|
+
MethodInfo* methodInfo = new MethodInfo(detail::method_traits<Method_T>::arity, args...);
|
|
79
|
+
this->wrap_native_method(rb_singleton_class(*this), name, std::forward<Method_T>(method), methodInfo);
|
|
80
80
|
return *this;
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -94,8 +94,8 @@ inline auto& define_singleton_method(std::string name, Function_T&& func, const
|
|
|
94
94
|
template<typename Function_T, typename...Arg_Ts>
|
|
95
95
|
inline auto& define_singleton_function(std::string name, Function_T&& func, const Arg_Ts& ...args)
|
|
96
96
|
{
|
|
97
|
-
MethodInfo* methodInfo = new MethodInfo(detail::
|
|
98
|
-
this->
|
|
97
|
+
MethodInfo* methodInfo = new MethodInfo(detail::function_traits<Function_T>::arity, args...);
|
|
98
|
+
this->wrap_native_function(rb_singleton_class(*this), name, std::forward<Function_T>(func), methodInfo);
|
|
99
99
|
return *this;
|
|
100
100
|
}
|
|
101
101
|
|
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
|
@@ -66,10 +66,6 @@ namespace Rice::detail
|
|
|
66
66
|
// Execute the function but make sure to catch any C++ exceptions!
|
|
67
67
|
return cpp_protect([&]
|
|
68
68
|
{
|
|
69
|
-
Identifier id(methodId);
|
|
70
|
-
std::string methodName = id.str();
|
|
71
|
-
std::string className = rb_class2name(klass);
|
|
72
|
-
|
|
73
69
|
const std::vector<std::unique_ptr<Native>>& natives = Registries::instance.natives.lookup(klass, methodId);
|
|
74
70
|
|
|
75
71
|
if (natives.size() == 1)
|
|
@@ -79,7 +75,7 @@ namespace Rice::detail
|
|
|
79
75
|
else if (natives.size() == 0)
|
|
80
76
|
{
|
|
81
77
|
Identifier identifier(methodId);
|
|
82
|
-
|
|
78
|
+
rb_enc_raise(rb_utf8_encoding(), rb_eArgError, "Could not find method call for %s#%s", rb_class2name(klass), identifier.c_str());
|
|
83
79
|
}
|
|
84
80
|
else
|
|
85
81
|
{
|
|
@@ -145,7 +141,7 @@ namespace Rice::detail
|
|
|
145
141
|
message << "\n " << resolve.native->toString();
|
|
146
142
|
}
|
|
147
143
|
|
|
148
|
-
|
|
144
|
+
rb_enc_raise(rb_utf8_encoding(), rb_eArgError, message.str().c_str(), rb_class2name(klass), identifier.c_str(), natives.size());
|
|
149
145
|
}
|
|
150
146
|
}
|
|
151
147
|
}
|
|
@@ -154,4 +150,198 @@ namespace Rice::detail
|
|
|
154
150
|
return (*native)(argc, argv, self);
|
|
155
151
|
});
|
|
156
152
|
}
|
|
153
|
+
|
|
154
|
+
inline Native::Native(std::vector<std::unique_ptr<ParameterAbstract>>&& parameters) : parameters_(std::move(parameters))
|
|
155
|
+
{
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
inline ParameterAbstract* Native::getParameterByName(std::string name)
|
|
159
|
+
{
|
|
160
|
+
for (std::unique_ptr<ParameterAbstract>& parameter : this->parameters_)
|
|
161
|
+
{
|
|
162
|
+
if (parameter->arg->name == name)
|
|
163
|
+
{
|
|
164
|
+
return parameter.get();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return nullptr;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ----------- Helpers ----------------
|
|
172
|
+
template<typename T>
|
|
173
|
+
inline void Native::verify_type(bool isBuffer)
|
|
174
|
+
{
|
|
175
|
+
using Base_T = std::remove_pointer_t<remove_cv_recursive_t<T>>;
|
|
176
|
+
|
|
177
|
+
detail::verifyType<T>();
|
|
178
|
+
|
|
179
|
+
if constexpr (std::is_pointer_v<T> && std::is_fundamental_v<std::remove_pointer_t<T>>)
|
|
180
|
+
{
|
|
181
|
+
Type<Pointer<Base_T>>::verify();
|
|
182
|
+
Type<Buffer<Base_T>>::verify();
|
|
183
|
+
}
|
|
184
|
+
else if constexpr (std::is_array_v<T>)
|
|
185
|
+
{
|
|
186
|
+
Type<Pointer<std::remove_extent_t<remove_cv_recursive_t<T>>>>::verify();
|
|
187
|
+
Type<Buffer<std::remove_extent_t<remove_cv_recursive_t<T>>>>::verify();
|
|
188
|
+
}
|
|
189
|
+
else if (isBuffer)
|
|
190
|
+
{
|
|
191
|
+
if constexpr (std::is_pointer_v<T> && !std::is_function_v<Base_T> && !std::is_abstract_v<Base_T>)
|
|
192
|
+
{
|
|
193
|
+
Type<Pointer<Base_T>>::verify();
|
|
194
|
+
Type<Buffer<Base_T>>::verify();
|
|
195
|
+
}
|
|
196
|
+
else
|
|
197
|
+
{
|
|
198
|
+
static_assert(true, "Only pointer types can be marked as buffers");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
template<typename Tuple_T, std::size_t ...Indices>
|
|
204
|
+
inline void Native::verify_args(MethodInfo* methodInfo, std::index_sequence<Indices...> indices)
|
|
205
|
+
{
|
|
206
|
+
(Native::verify_type<std::tuple_element_t<Indices, Tuple_T>>(methodInfo->arg(Indices)->isBuffer()), ...);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
template<typename Tuple_T, std::size_t ...Indices>
|
|
210
|
+
inline void Native::create_parameters_impl(std::vector<std::unique_ptr<ParameterAbstract>>& parameters, MethodInfo* methodInfo, std::index_sequence<Indices...> indices)
|
|
211
|
+
{
|
|
212
|
+
(parameters.push_back(std::move(std::make_unique<Parameter<std::tuple_element_t<Indices, Tuple_T>>>(methodInfo->arg(Indices)))), ...);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
template<typename Tuple_T>
|
|
216
|
+
inline std::vector<std::unique_ptr<ParameterAbstract>> Native::create_parameters(MethodInfo* methodInfo)
|
|
217
|
+
{
|
|
218
|
+
std::vector<std::unique_ptr<ParameterAbstract>> result;
|
|
219
|
+
auto indices = std::make_index_sequence<std::tuple_size_v<Tuple_T>>{};
|
|
220
|
+
Native::create_parameters_impl<Tuple_T>(result, methodInfo, indices);
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
inline std::vector<std::optional<VALUE>> Native::getRubyValues(size_t argc, const VALUE* argv, bool validate)
|
|
225
|
+
{
|
|
226
|
+
#undef max
|
|
227
|
+
int size = std::max(this->parameters_.size(), argc);
|
|
228
|
+
std::vector<std::optional<VALUE>> result(size);
|
|
229
|
+
|
|
230
|
+
// Keyword handling
|
|
231
|
+
if (rb_keyword_given_p())
|
|
232
|
+
{
|
|
233
|
+
// Keywords are stored in the last element in a hash
|
|
234
|
+
int actualArgc = argc - 1;
|
|
235
|
+
|
|
236
|
+
VALUE value = argv[actualArgc];
|
|
237
|
+
Hash keywords(value);
|
|
238
|
+
|
|
239
|
+
// Copy over leading non-keyword arguments
|
|
240
|
+
for (int i = 0; i < actualArgc; i++)
|
|
241
|
+
{
|
|
242
|
+
result[i] = argv[i];
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Copy over keyword arguments
|
|
246
|
+
for (auto pair : keywords)
|
|
247
|
+
{
|
|
248
|
+
Symbol key(pair.first);
|
|
249
|
+
ParameterAbstract* parameter = this->getParameterByName(key.str());
|
|
250
|
+
if (!parameter)
|
|
251
|
+
{
|
|
252
|
+
throw std::invalid_argument("Unknown keyword: " + key.str());
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const Arg* arg = parameter->arg;
|
|
256
|
+
|
|
257
|
+
result[arg->position] = pair.second.value();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else
|
|
261
|
+
{
|
|
262
|
+
std::copy(argv, argv + argc, result.begin());
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Block handling. If we find a block and the last parameter is missing then
|
|
266
|
+
// set it to the block
|
|
267
|
+
if (rb_block_given_p() && result.size() > 0 && !result.back().has_value())
|
|
268
|
+
{
|
|
269
|
+
VALUE proc = rb_block_proc();
|
|
270
|
+
result.back() = proc;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (validate)
|
|
274
|
+
{
|
|
275
|
+
// Protect against user sending too many arguments
|
|
276
|
+
if (argc > this->parameters_.size())
|
|
277
|
+
{
|
|
278
|
+
std::string message = "wrong number of arguments (given " +
|
|
279
|
+
std::to_string(argc) + ", expected " + std::to_string(this->parameters_.size()) + ")";
|
|
280
|
+
throw std::invalid_argument(message);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
for (size_t i = 0; i < result.size(); i++)
|
|
284
|
+
{
|
|
285
|
+
std::optional<VALUE> value = result[i];
|
|
286
|
+
ParameterAbstract* parameter = this->parameters_[i].get();
|
|
287
|
+
|
|
288
|
+
if (!parameter->arg->hasDefaultValue() && !value.has_value())
|
|
289
|
+
{
|
|
290
|
+
std::string message;
|
|
291
|
+
message = "Missing argument. Name: " + parameter->arg->name + ". Index: " + std::to_string(parameter->arg->position) + ".";
|
|
292
|
+
throw std::invalid_argument(message);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return result;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
inline Convertible Native::matchParameters(std::vector<std::optional<VALUE>>& values)
|
|
301
|
+
{
|
|
302
|
+
Convertible result = Convertible::Exact;
|
|
303
|
+
for (size_t i = 0; i < this->parameters_.size(); i++)
|
|
304
|
+
{
|
|
305
|
+
ParameterAbstract* parameter = this->parameters_[i].get();
|
|
306
|
+
std::optional<VALUE>& value = values[i];
|
|
307
|
+
result = result & parameter->matches(value);
|
|
308
|
+
}
|
|
309
|
+
return result;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
inline Resolved Native::matches(size_t argc, const VALUE* argv, VALUE self)
|
|
313
|
+
{
|
|
314
|
+
// Return false if Ruby provided more arguments than the C++ method takes
|
|
315
|
+
if (argc > this->parameters_.size())
|
|
316
|
+
return Resolved{ Convertible::None, 0, this };
|
|
317
|
+
|
|
318
|
+
Resolved result{ Convertible::Exact, 1, this };
|
|
319
|
+
|
|
320
|
+
std::vector<std::optional<VALUE>> rubyValues = this->getRubyValues(argc, argv, false);
|
|
321
|
+
result.convertible = this->matchParameters(rubyValues);
|
|
322
|
+
|
|
323
|
+
if (this->parameters_.size() > 0)
|
|
324
|
+
{
|
|
325
|
+
int providedValues = std::count_if(rubyValues.begin(), rubyValues.end(), [](std::optional<VALUE>& value)
|
|
326
|
+
{
|
|
327
|
+
return value.has_value();
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
result.parameterMatch = providedValues / (double)this->parameters_.size();
|
|
331
|
+
}
|
|
332
|
+
return result;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
inline std::vector<const ParameterAbstract*> Native::parameters()
|
|
336
|
+
{
|
|
337
|
+
std::vector<const ParameterAbstract*> result;
|
|
338
|
+
|
|
339
|
+
std::transform(this->parameters_.begin(), this->parameters_.end(), std::back_inserter(result),
|
|
340
|
+
[](std::unique_ptr<ParameterAbstract>& parameter) -> ParameterAbstract*
|
|
341
|
+
{
|
|
342
|
+
return parameter.get();
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
return result;
|
|
346
|
+
}
|
|
157
347
|
}
|
|
@@ -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
|
|