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
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#ifndef Rice__detail__Native_Proc__hpp_
|
|
2
|
+
#define Rice__detail__Native_Proc__hpp_
|
|
3
|
+
|
|
4
|
+
namespace Rice::detail
|
|
5
|
+
{
|
|
6
|
+
template<typename Proc_T>
|
|
7
|
+
class NativeProc: Native
|
|
8
|
+
{
|
|
9
|
+
public:
|
|
10
|
+
using NativeProc_T = NativeProc<Proc_T>;
|
|
11
|
+
|
|
12
|
+
// We remove const to avoid an explosion of To_Ruby specializations and Ruby doesn't
|
|
13
|
+
// have the concept of constants anyways
|
|
14
|
+
using Return_T = typename function_traits<Proc_T>::return_type;
|
|
15
|
+
using Arg_Ts = typename function_traits<Proc_T>::arg_types;
|
|
16
|
+
using To_Ruby_T = remove_cv_recursive_t<Return_T>;
|
|
17
|
+
|
|
18
|
+
// Define a new Ruby Proc to wrap a C++ function
|
|
19
|
+
static VALUE createRubyProc(Proc_T proc);
|
|
20
|
+
static NativeProc<Proc_T>* define(Proc_T proc);
|
|
21
|
+
|
|
22
|
+
// This is the method Ruby calls when invoking the proc
|
|
23
|
+
static VALUE resolve(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg);
|
|
24
|
+
|
|
25
|
+
public:
|
|
26
|
+
NativeProc(Proc_T proc, MethodInfo* methodInfo);
|
|
27
|
+
VALUE operator()(size_t argc, const VALUE* argv, VALUE self) override;
|
|
28
|
+
std::string toString() override;
|
|
29
|
+
|
|
30
|
+
std::string name() override;
|
|
31
|
+
NativeKind kind() override;
|
|
32
|
+
VALUE returnKlass() override;
|
|
33
|
+
|
|
34
|
+
private:
|
|
35
|
+
static VALUE finalizerCallback(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg);
|
|
36
|
+
|
|
37
|
+
// Convert Ruby values to C++ values
|
|
38
|
+
template<typename std::size_t...I>
|
|
39
|
+
Arg_Ts getNativeValues(std::vector<std::optional<VALUE>>& values, std::index_sequence<I...>& indices);
|
|
40
|
+
|
|
41
|
+
// Call the underlying C++ function
|
|
42
|
+
VALUE invoke(Arg_Ts&& nativeArgs);
|
|
43
|
+
|
|
44
|
+
private:
|
|
45
|
+
Proc_T proc_;
|
|
46
|
+
std::unique_ptr<MethodInfo> methodInfo_;
|
|
47
|
+
To_Ruby<To_Ruby_T> toRuby_;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
#endif // Rice__detail__Native_Proc__hpp_
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#include <algorithm>
|
|
2
|
+
#include <array>
|
|
3
|
+
#include <stdexcept>
|
|
4
|
+
#include <sstream>
|
|
5
|
+
#include <tuple>
|
|
6
|
+
|
|
7
|
+
namespace Rice::detail
|
|
8
|
+
{
|
|
9
|
+
template<typename Proc_T>
|
|
10
|
+
NativeProc<Proc_T>* NativeProc<Proc_T>::define(Proc_T proc)
|
|
11
|
+
{
|
|
12
|
+
MethodInfo* methodInfo = new MethodInfo(detail::function_traits<Proc_T>::arity);
|
|
13
|
+
return new NativeProc_T(std::forward<Proc_T>(proc), methodInfo);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
template<typename Proc_T>
|
|
17
|
+
VALUE NativeProc<Proc_T>::createRubyProc(Proc_T proc)
|
|
18
|
+
{
|
|
19
|
+
NativeProc_T* nativeProc = NativeProc_T::define(std::forward<Proc_T>(proc));
|
|
20
|
+
|
|
21
|
+
// Create a Ruby proc to wrap it and pass the NativeProc as a callback parameter
|
|
22
|
+
VALUE result = rb_proc_new(NativeProc_T::resolve, (VALUE)nativeProc);
|
|
23
|
+
|
|
24
|
+
// Tie the lifetime of the NativeProc to the Ruby Proc
|
|
25
|
+
VALUE finalizer = rb_proc_new(NativeProc_T::finalizerCallback, (VALUE)nativeProc);
|
|
26
|
+
rb_define_finalizer(result, finalizer);
|
|
27
|
+
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Ruby calls this method when invoking a proc that was defined as a C++ function
|
|
32
|
+
template<typename Proc_T>
|
|
33
|
+
VALUE NativeProc<Proc_T>::resolve(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg)
|
|
34
|
+
{
|
|
35
|
+
return cpp_protect([&]
|
|
36
|
+
{
|
|
37
|
+
NativeProc_T * native = (NativeProc_T*)callback_arg;
|
|
38
|
+
return (*native)(argc, argv, Qnil);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Ruby calls this method if an instance of a NativeProc is owned by a Ruby proc. That happens when C++
|
|
43
|
+
// returns a function back to Ruby
|
|
44
|
+
template<typename Proc_T>
|
|
45
|
+
VALUE NativeProc<Proc_T>::finalizerCallback(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg)
|
|
46
|
+
{
|
|
47
|
+
NativeProc_T* native = (NativeProc_T*)callback_arg;
|
|
48
|
+
delete native;
|
|
49
|
+
return Qnil;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
template<typename Proc_T>
|
|
53
|
+
NativeProc<Proc_T>::NativeProc(Proc_T proc, MethodInfo* methodInfo) : Native(Native::create_parameters<Arg_Ts>(methodInfo)),
|
|
54
|
+
proc_(proc), methodInfo_(methodInfo)
|
|
55
|
+
{
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
template<typename Proc_T>
|
|
59
|
+
std::string NativeProc<Proc_T>::toString()
|
|
60
|
+
{
|
|
61
|
+
return "Proc";
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
template<typename Proc_T>
|
|
65
|
+
template<std::size_t... I>
|
|
66
|
+
typename NativeProc<Proc_T>::Arg_Ts NativeProc<Proc_T>::getNativeValues(std::vector<std::optional<VALUE>>& values,
|
|
67
|
+
std::index_sequence<I...>& indices)
|
|
68
|
+
{
|
|
69
|
+
/* Loop over each value returned from Ruby and convert it to the appropriate C++ type based
|
|
70
|
+
on the arguments (Arg_Ts) required by the C++ function. Arg_T may have const/volatile while
|
|
71
|
+
the associated From_Ruby<T> template parameter will not. Thus From_Ruby produces non-const values
|
|
72
|
+
which we let the compiler convert to const values as needed. This works except for
|
|
73
|
+
T** -> const T**, see comment in convertToNative method. */
|
|
74
|
+
//return std::forward_as_tuple(this->getNativeValue<std::tuple_element_t<I, Arg_Ts>, I>(values)...);
|
|
75
|
+
return std::forward_as_tuple(
|
|
76
|
+
(dynamic_cast<Parameter<std::tuple_element_t<I, Arg_Ts>>*>(this->parameters_[I].get()))->
|
|
77
|
+
convertToNative(values[I])...);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
template<typename Proc_T>
|
|
81
|
+
VALUE NativeProc<Proc_T>::invoke(Arg_Ts&& nativeArgs)
|
|
82
|
+
{
|
|
83
|
+
if constexpr (std::is_void_v<Return_T>)
|
|
84
|
+
{
|
|
85
|
+
std::apply(this->proc_, std::forward<Arg_Ts>(nativeArgs));
|
|
86
|
+
return Qnil;
|
|
87
|
+
}
|
|
88
|
+
else
|
|
89
|
+
{
|
|
90
|
+
// Call the native method and get the result
|
|
91
|
+
Return_T nativeResult = std::apply(this->proc_, std::forward<Arg_Ts>(nativeArgs));
|
|
92
|
+
|
|
93
|
+
// Return the result
|
|
94
|
+
return this->toRuby_.convert(std::forward<Return_T>(nativeResult));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
template<typename Proc_T>
|
|
99
|
+
VALUE NativeProc<Proc_T>::operator()(size_t argc, const VALUE* argv, VALUE self)
|
|
100
|
+
{
|
|
101
|
+
// Get the ruby values and make sure we have the correct number
|
|
102
|
+
std::vector<std::optional<VALUE>> rubyValues = this->getRubyValues(argc, argv, true);
|
|
103
|
+
|
|
104
|
+
auto indices = std::make_index_sequence<std::tuple_size_v<Arg_Ts>>{};
|
|
105
|
+
|
|
106
|
+
// Convert the Ruby values to native values
|
|
107
|
+
Arg_Ts nativeValues = this->getNativeValues(rubyValues, indices);
|
|
108
|
+
|
|
109
|
+
// Now call the native method
|
|
110
|
+
VALUE result = this->invoke(std::forward<Arg_Ts>(nativeValues));
|
|
111
|
+
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
template<typename Proc_T>
|
|
116
|
+
inline std::string NativeProc< Proc_T>::name()
|
|
117
|
+
{
|
|
118
|
+
return "proc";
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
template<typename Proc_T>
|
|
122
|
+
inline NativeKind NativeProc< Proc_T>::kind()
|
|
123
|
+
{
|
|
124
|
+
return NativeKind::Proc;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
template<typename Proc_T>
|
|
128
|
+
inline VALUE NativeProc<Proc_T>::returnKlass()
|
|
129
|
+
{
|
|
130
|
+
TypeMapper<Return_T> typeMapper;
|
|
131
|
+
return typeMapper.rubyKlass();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -25,8 +25,16 @@ namespace Rice::detail
|
|
|
25
25
|
class NativeRegistry
|
|
26
26
|
{
|
|
27
27
|
public:
|
|
28
|
+
// std::is_copy_constructible returns true for std::vector<std::unique_ptr> - so we need
|
|
29
|
+
// to force the issue
|
|
30
|
+
NativeRegistry() = default;
|
|
31
|
+
NativeRegistry(const NativeRegistry& other) = delete;
|
|
32
|
+
NativeRegistry& operator=(const NativeRegistry& other) = delete;
|
|
33
|
+
|
|
28
34
|
void add(VALUE klass, ID methodId, std::unique_ptr<Native>& native);
|
|
29
35
|
void reset(VALUE klass);
|
|
36
|
+
|
|
37
|
+
const std::vector<Native*> lookup(VALUE klass);
|
|
30
38
|
const std::vector<std::unique_ptr<Native>>& lookup(VALUE klass, ID methodId);
|
|
31
39
|
|
|
32
40
|
private:
|
|
@@ -33,6 +33,32 @@ namespace Rice::detail
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
inline const std::vector<Native*> NativeRegistry::lookup(VALUE klass)
|
|
37
|
+
{
|
|
38
|
+
std::vector<Native*> result;
|
|
39
|
+
|
|
40
|
+
if (rb_type(klass) == T_ICLASS)
|
|
41
|
+
{
|
|
42
|
+
klass = detail::protect(rb_class_of, klass);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for (auto& pair : this->natives_)
|
|
46
|
+
{
|
|
47
|
+
const std::pair<VALUE, ID>& key = pair.first;
|
|
48
|
+
|
|
49
|
+
if (klass == key.first)
|
|
50
|
+
{
|
|
51
|
+
const std::vector<std::unique_ptr<Native>>& value = pair.second;
|
|
52
|
+
for (auto& native : value)
|
|
53
|
+
{
|
|
54
|
+
result.push_back(native.get());
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
|
|
36
62
|
inline const std::vector<std::unique_ptr<Native>>& NativeRegistry::lookup(VALUE klass, ID methodId)
|
|
37
63
|
{
|
|
38
64
|
if (rb_type(klass) == T_ICLASS)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#ifndef Rice__detail__Parameter__hpp_
|
|
2
|
+
#define Rice__detail__Parameter__hpp_
|
|
3
|
+
|
|
4
|
+
#include <optional>
|
|
5
|
+
|
|
6
|
+
namespace Rice::detail
|
|
7
|
+
{
|
|
8
|
+
class ParameterAbstract
|
|
9
|
+
{
|
|
10
|
+
public:
|
|
11
|
+
ParameterAbstract() = default;
|
|
12
|
+
ParameterAbstract(Arg* arg);
|
|
13
|
+
virtual ~ParameterAbstract() = default;
|
|
14
|
+
|
|
15
|
+
ParameterAbstract(ParameterAbstract&& other) = default;
|
|
16
|
+
ParameterAbstract& operator=(ParameterAbstract&& other) = default;
|
|
17
|
+
|
|
18
|
+
virtual Convertible matches(std::optional<VALUE>& valueOpt) = 0;
|
|
19
|
+
virtual std::string cppTypeName() = 0;
|
|
20
|
+
virtual VALUE klass() = 0;
|
|
21
|
+
|
|
22
|
+
public:
|
|
23
|
+
Arg* arg = nullptr;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
template<typename T>
|
|
27
|
+
class Parameter: public ParameterAbstract
|
|
28
|
+
{
|
|
29
|
+
public:
|
|
30
|
+
using Type = T;
|
|
31
|
+
|
|
32
|
+
Parameter() = default;
|
|
33
|
+
Parameter(Arg* arg);
|
|
34
|
+
Parameter(Parameter&& other) = default;
|
|
35
|
+
Parameter& operator=(Parameter&& other) = default;
|
|
36
|
+
|
|
37
|
+
T convertToNative(std::optional<VALUE>& valueOpt);
|
|
38
|
+
Convertible matches(std::optional<VALUE>& valueOpt) override;
|
|
39
|
+
std::string cppTypeName() override;
|
|
40
|
+
VALUE klass() override;
|
|
41
|
+
|
|
42
|
+
// std::string typeName() override;
|
|
43
|
+
private:
|
|
44
|
+
From_Ruby<remove_cv_recursive_t<T>> fromRuby_;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
#endif // Rice__detail__Parameter__hpp_
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
namespace Rice::detail
|
|
2
|
+
{
|
|
3
|
+
// ----------- ParameterAbstract ----------------
|
|
4
|
+
inline ParameterAbstract::ParameterAbstract(Arg* arg) : arg(arg)
|
|
5
|
+
{
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// ----------- Parameter ----------------
|
|
9
|
+
template<typename T>
|
|
10
|
+
inline Parameter<T>::Parameter(Arg* arg) : ParameterAbstract(arg), fromRuby_(arg)
|
|
11
|
+
{
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
template<typename T>
|
|
15
|
+
inline Convertible Parameter<T>::matches(std::optional<VALUE>& valueOpt)
|
|
16
|
+
{
|
|
17
|
+
Convertible result = Convertible::None;
|
|
18
|
+
|
|
19
|
+
// Is a VALUE being passed directly to C++ ?
|
|
20
|
+
if (valueOpt.has_value())
|
|
21
|
+
{
|
|
22
|
+
VALUE value = valueOpt.value();
|
|
23
|
+
if (this->arg->isValue())
|
|
24
|
+
{
|
|
25
|
+
result = Convertible::Exact;
|
|
26
|
+
}
|
|
27
|
+
// If index is less than argc then check with FromRuby if the VALUE is convertible
|
|
28
|
+
// to C++.
|
|
29
|
+
else
|
|
30
|
+
{
|
|
31
|
+
result = this->fromRuby_.is_convertible(value);
|
|
32
|
+
|
|
33
|
+
// If this is an exact match check if the const-ness of the value and the parameter match
|
|
34
|
+
if (result == Convertible::Exact && rb_type(value) == RUBY_T_DATA)
|
|
35
|
+
{
|
|
36
|
+
// Check the constness of the Ruby wrapped value and the parameter
|
|
37
|
+
WrapperBase* wrapper = getWrapper(value);
|
|
38
|
+
|
|
39
|
+
// Do not send a const value to a non-const parameter
|
|
40
|
+
if (wrapper->isConst() && !is_const_any_v<T>)
|
|
41
|
+
{
|
|
42
|
+
result = Convertible::None;
|
|
43
|
+
}
|
|
44
|
+
// It is ok to send a non-const value to a const parameter but
|
|
45
|
+
// prefer non-const to non-const by slighly decreasing the convertible value
|
|
46
|
+
else if (!wrapper->isConst() && is_const_any_v<T>)
|
|
47
|
+
{
|
|
48
|
+
result = Convertible::Const;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Last check if a default value has been set
|
|
54
|
+
else if (this->arg->hasDefaultValue())
|
|
55
|
+
{
|
|
56
|
+
result = Convertible::Exact;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
template<typename T>
|
|
63
|
+
inline T Parameter<T>::convertToNative(std::optional<VALUE>& valueOpt)
|
|
64
|
+
{
|
|
65
|
+
/* In general the compiler will convert T to const T, but that does not work for converting
|
|
66
|
+
T** to const T** (see see https://isocpp.org/wiki/faq/const-correctness#constptrptr-conversion)
|
|
67
|
+
which comes up in the OpenCV bindings.
|
|
68
|
+
|
|
69
|
+
An alternative solution is updating From_Ruby#convert to become a templated function that specifies
|
|
70
|
+
the return type. That works but requires a lot more code changes for this one case and is not
|
|
71
|
+
backwards compatible. */
|
|
72
|
+
|
|
73
|
+
if constexpr (is_pointer_pointer_v<T> && !std::is_convertible_v<remove_cv_recursive_t<T>, T>)
|
|
74
|
+
{
|
|
75
|
+
return (T)this->fromRuby_.convert(valueOpt.value());
|
|
76
|
+
}
|
|
77
|
+
else if (valueOpt.has_value())
|
|
78
|
+
{
|
|
79
|
+
return this->fromRuby_.convert(valueOpt.value());
|
|
80
|
+
}
|
|
81
|
+
else if constexpr (std::is_constructible_v<std::remove_cv_t<T>, std::remove_cv_t<std::remove_reference_t<T>>&>)
|
|
82
|
+
{
|
|
83
|
+
if (this->arg->hasDefaultValue())
|
|
84
|
+
{
|
|
85
|
+
return this->arg->template defaultValue<T>();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
throw std::invalid_argument("Could not convert Rubyy value");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
template<typename T>
|
|
93
|
+
inline std::string Parameter<T>::cppTypeName()
|
|
94
|
+
{
|
|
95
|
+
detail::TypeMapper<T> typeMapper;
|
|
96
|
+
return typeMapper.simplifiedName();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
template<typename T>
|
|
100
|
+
inline VALUE Parameter<T>::klass()
|
|
101
|
+
{
|
|
102
|
+
TypeMapper<T> typeMapper;
|
|
103
|
+
return typeMapper.rubyKlass();
|
|
104
|
+
}
|
|
105
|
+
}
|
data/rice/detail/Proc.ipp
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
namespace Rice::detail
|
|
2
2
|
{
|
|
3
|
-
// Note Return_T(Arg_Ts...) is intentional versus Return_T(*)(Arg_Ts...). That is
|
|
4
|
-
// because the Type machinery strips all pointers/references/const/val etc to avoid
|
|
5
|
-
// having an explosion of Type definitions
|
|
6
3
|
template<typename Return_T, typename ...Arg_Ts>
|
|
7
|
-
struct Type<Return_T(Arg_Ts...)>
|
|
4
|
+
struct Type<Return_T(*)(Arg_Ts...)>
|
|
8
5
|
{
|
|
9
6
|
static bool verify()
|
|
10
7
|
{
|
|
11
8
|
return true;
|
|
12
9
|
}
|
|
10
|
+
|
|
11
|
+
static VALUE rubyKlass()
|
|
12
|
+
{
|
|
13
|
+
return rb_cProc;
|
|
14
|
+
}
|
|
13
15
|
};
|
|
14
16
|
|
|
15
17
|
// Wraps a C++ function as a Ruby proc
|
|
@@ -19,17 +21,16 @@ namespace Rice::detail
|
|
|
19
21
|
public:
|
|
20
22
|
using Proc_T = Return_T(*)(Arg_Ts...);
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
using NativeFunction_T = NativeFunction<void, Proc_T, false>;
|
|
25
|
-
auto native = new NativeFunction_T(proc);
|
|
26
|
-
VALUE result = rb_proc_new(NativeFunction_T::procEntry, (VALUE)native);
|
|
24
|
+
To_Ruby() = default;
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
explicit To_Ruby(Arg* arg)
|
|
27
|
+
{
|
|
28
|
+
}
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
VALUE convert(Proc_T proc)
|
|
31
|
+
{
|
|
32
|
+
// Wrap the C+++ function pointer as a Ruby Proc
|
|
33
|
+
return NativeProc<Proc_T>::createRubyProc(std::forward<Proc_T>(proc));
|
|
33
34
|
}
|
|
34
35
|
};
|
|
35
36
|
|
data/rice/detail/Registries.hpp
CHANGED
data/rice/detail/RubyType.hpp
CHANGED
data/rice/detail/RubyType.ipp
CHANGED
|
@@ -11,6 +11,7 @@ namespace Rice::detail
|
|
|
11
11
|
static inline std::set<ruby_value_type> Castable = { RUBY_T_NIL };
|
|
12
12
|
static inline std::set<ruby_value_type> Narrowable = { };
|
|
13
13
|
static inline std::string packTemplate = "not supported";
|
|
14
|
+
static inline std::string name = "bool";
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
template<>
|
|
@@ -24,6 +25,7 @@ namespace Rice::detail
|
|
|
24
25
|
static inline std::set<ruby_value_type> Castable = { RUBY_T_STRING };
|
|
25
26
|
static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
|
|
26
27
|
static inline std::string packTemplate = CHAR_MIN < 0 ? "c*" : "C*";
|
|
28
|
+
static inline std::string name = "String";
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
template<>
|
|
@@ -38,6 +40,7 @@ namespace Rice::detail
|
|
|
38
40
|
static inline std::set<ruby_value_type> Castable = { RUBY_T_STRING };
|
|
39
41
|
static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
|
|
40
42
|
static inline std::string packTemplate = "c*";
|
|
43
|
+
static inline std::string name = "String";
|
|
41
44
|
};
|
|
42
45
|
|
|
43
46
|
template<>
|
|
@@ -52,6 +55,7 @@ namespace Rice::detail
|
|
|
52
55
|
static inline std::set<ruby_value_type> Castable = { RUBY_T_STRING };
|
|
53
56
|
static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
|
|
54
57
|
static inline std::string packTemplate = "C*";
|
|
58
|
+
static inline std::string name = "String";
|
|
55
59
|
};
|
|
56
60
|
|
|
57
61
|
template<>
|
|
@@ -65,6 +69,7 @@ namespace Rice::detail
|
|
|
65
69
|
static inline std::set<ruby_value_type> Castable = { };
|
|
66
70
|
static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
|
|
67
71
|
static inline std::string packTemplate = "s*";
|
|
72
|
+
static inline std::string name = "Integer";
|
|
68
73
|
};
|
|
69
74
|
|
|
70
75
|
template<>
|
|
@@ -78,6 +83,7 @@ namespace Rice::detail
|
|
|
78
83
|
static inline std::set<ruby_value_type> Castable = { };
|
|
79
84
|
static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
|
|
80
85
|
static inline std::string packTemplate = "S*";
|
|
86
|
+
static inline std::string name = "Integer";
|
|
81
87
|
};
|
|
82
88
|
|
|
83
89
|
template<>
|
|
@@ -93,6 +99,7 @@ namespace Rice::detail
|
|
|
93
99
|
// while int can go up to 4 billion
|
|
94
100
|
static inline std::set<ruby_value_type> Narrowable = { RUBY_T_BIGNUM };
|
|
95
101
|
static inline std::string packTemplate = "i*";
|
|
102
|
+
static inline std::string name = "Integer";
|
|
96
103
|
};
|
|
97
104
|
|
|
98
105
|
template<>
|
|
@@ -108,6 +115,7 @@ namespace Rice::detail
|
|
|
108
115
|
// while int can go up to 4 billion
|
|
109
116
|
static inline std::set<ruby_value_type> Narrowable = { RUBY_T_BIGNUM };
|
|
110
117
|
static inline std::string packTemplate = "I*";
|
|
118
|
+
static inline std::string name = "Integer";
|
|
111
119
|
};
|
|
112
120
|
|
|
113
121
|
template<>
|
|
@@ -121,6 +129,7 @@ namespace Rice::detail
|
|
|
121
129
|
static inline std::set<ruby_value_type> Castable = { };
|
|
122
130
|
static inline std::set<ruby_value_type> Narrowable = { RUBY_T_BIGNUM };
|
|
123
131
|
static inline std::string packTemplate = "l_*";
|
|
132
|
+
static inline std::string name = "Integer";
|
|
124
133
|
};
|
|
125
134
|
|
|
126
135
|
template<>
|
|
@@ -134,6 +143,7 @@ namespace Rice::detail
|
|
|
134
143
|
static inline std::set<ruby_value_type> Castable = { };
|
|
135
144
|
static inline std::set<ruby_value_type> Narrowable = { RUBY_T_BIGNUM};
|
|
136
145
|
static inline std::string packTemplate = "L_*";
|
|
146
|
+
static inline std::string name = "Integer";
|
|
137
147
|
};
|
|
138
148
|
|
|
139
149
|
template<>
|
|
@@ -147,6 +157,7 @@ namespace Rice::detail
|
|
|
147
157
|
static inline std::set<ruby_value_type> Castable = { };
|
|
148
158
|
static inline std::set<ruby_value_type> Narrowable = { };
|
|
149
159
|
static inline std::string packTemplate = "q_*";
|
|
160
|
+
static inline std::string name = "Integer";
|
|
150
161
|
};
|
|
151
162
|
|
|
152
163
|
template<>
|
|
@@ -160,6 +171,7 @@ namespace Rice::detail
|
|
|
160
171
|
static inline std::set<ruby_value_type> Castable = { };
|
|
161
172
|
static inline std::set<ruby_value_type> Narrowable = { };
|
|
162
173
|
static inline std::string packTemplate = "Q_*";
|
|
174
|
+
static inline std::string name = "Integer";
|
|
163
175
|
};
|
|
164
176
|
|
|
165
177
|
template<>
|
|
@@ -173,6 +185,7 @@ namespace Rice::detail
|
|
|
173
185
|
static inline std::set<ruby_value_type> Castable = { RUBY_T_FIXNUM };
|
|
174
186
|
static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FLOAT };
|
|
175
187
|
static inline std::string packTemplate = "f*";
|
|
188
|
+
static inline std::string name = "Float";
|
|
176
189
|
};
|
|
177
190
|
|
|
178
191
|
template<>
|
|
@@ -186,6 +199,7 @@ namespace Rice::detail
|
|
|
186
199
|
static inline std::set<ruby_value_type> Castable = { RUBY_T_FIXNUM, RUBY_T_BIGNUM };
|
|
187
200
|
static inline std::set<ruby_value_type> Narrowable = { };
|
|
188
201
|
static inline std::string packTemplate = "d*";
|
|
202
|
+
static inline std::string name = "Float";
|
|
189
203
|
};
|
|
190
204
|
|
|
191
205
|
template<>
|
|
@@ -195,38 +209,6 @@ namespace Rice::detail
|
|
|
195
209
|
static inline std::set<ruby_value_type> Exact = { };
|
|
196
210
|
static inline std::set<ruby_value_type> Castable = { };
|
|
197
211
|
static inline std::set<ruby_value_type> Narrowable = { };
|
|
212
|
+
static inline std::string name = "void";
|
|
198
213
|
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
namespace Rice::detail
|
|
202
|
-
{
|
|
203
|
-
template<typename T>
|
|
204
|
-
inline Data_Type<T> define_ruby_type()
|
|
205
|
-
{
|
|
206
|
-
std::string name = detail::typeName(typeid(T*));
|
|
207
|
-
std::string klassName = detail::rubyClassName(name);
|
|
208
|
-
Identifier id(klassName);
|
|
209
|
-
|
|
210
|
-
Module rb_mRice = define_module("Rice");
|
|
211
|
-
return define_class_under<T>(rb_mRice, id);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
inline void define_ruby_types()
|
|
215
|
-
{
|
|
216
|
-
define_ruby_type<bool>();
|
|
217
|
-
define_ruby_type<char>();
|
|
218
|
-
define_ruby_type<signed char>();
|
|
219
|
-
define_ruby_type<unsigned char>();
|
|
220
|
-
define_ruby_type<short>();
|
|
221
|
-
define_ruby_type<unsigned short>();
|
|
222
|
-
define_ruby_type<int>();
|
|
223
|
-
define_ruby_type<unsigned int>();
|
|
224
|
-
define_ruby_type<long>();
|
|
225
|
-
define_ruby_type<unsigned long>();
|
|
226
|
-
define_ruby_type<long long>();
|
|
227
|
-
define_ruby_type<unsigned long long>();
|
|
228
|
-
define_ruby_type<float>();
|
|
229
|
-
define_ruby_type<double>();
|
|
230
|
-
define_ruby_type<void>();
|
|
231
|
-
}
|
|
232
214
|
}
|
data/rice/detail/Type.hpp
CHANGED
|
@@ -11,14 +11,50 @@ namespace Rice::detail
|
|
|
11
11
|
static bool verify();
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
template<typename T>
|
|
15
|
+
struct Type<T&>
|
|
16
|
+
{
|
|
17
|
+
static bool verify();
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
template<typename T>
|
|
21
|
+
struct Type<T&&>
|
|
22
|
+
{
|
|
23
|
+
static bool verify();
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
template<typename T>
|
|
27
|
+
struct Type<T*>
|
|
28
|
+
{
|
|
29
|
+
static bool verify();
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
template<typename T>
|
|
33
|
+
struct Type<T**>
|
|
34
|
+
{
|
|
35
|
+
static bool verify();
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
template<typename T>
|
|
39
|
+
class TypeMapper
|
|
40
|
+
{
|
|
41
|
+
public:
|
|
42
|
+
std::string name();
|
|
43
|
+
std::string name(const std::type_index& typeIndex);
|
|
44
|
+
std::string simplifiedName();
|
|
45
|
+
std::string rubyName();
|
|
46
|
+
VALUE rubyKlass();
|
|
47
|
+
|
|
48
|
+
// public only for testing
|
|
49
|
+
std::string findGroup(std::string& string, size_t start = 0);
|
|
50
|
+
private:
|
|
51
|
+
std::string demangle(char const* mangled_name);
|
|
52
|
+
std::string rubyTypeName();
|
|
53
|
+
void removeGroup(std::string& string, std::regex regex);
|
|
54
|
+
void replaceGroup(std::string& string, std::regex regex, std::string replacement);
|
|
55
|
+
void replaceAll(std::string& string, std::regex regex, std::string replacement);
|
|
56
|
+
void capitalizeHelper(std::string& content, std::regex& regex);
|
|
57
|
+
};
|
|
22
58
|
|
|
23
59
|
template<typename T>
|
|
24
60
|
void verifyType();
|