rice 2.1.3 → 4.0.2
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 +121 -0
- data/CONTRIBUTORS.md +19 -0
- data/COPYING +2 -2
- data/Gemfile +3 -0
- data/README.md +45 -1028
- data/Rakefile +95 -12
- data/include/rice/rice.hpp +7766 -0
- data/include/rice/stl.hpp +1113 -0
- data/lib/mkmf-rice.rb +127 -0
- data/lib/version.rb +3 -0
- data/rice/Address_Registration_Guard.ipp +75 -32
- data/rice/Address_Registration_Guard_defn.hpp +60 -56
- data/rice/Arg.hpp +80 -4
- data/rice/Arg.ipp +51 -0
- data/rice/Constructor.hpp +30 -376
- data/rice/Data_Object.ipp +234 -107
- data/rice/Data_Object_defn.hpp +77 -117
- data/rice/Data_Type.hpp +1 -2
- data/rice/Data_Type.ipp +251 -295
- data/rice/Data_Type_defn.hpp +175 -243
- data/rice/Director.hpp +14 -9
- data/rice/Enum.hpp +54 -104
- data/rice/Enum.ipp +104 -230
- data/rice/Exception.hpp +2 -8
- data/rice/Exception.ipp +65 -0
- data/rice/Exception_defn.hpp +46 -47
- data/rice/Identifier.hpp +28 -28
- data/rice/Identifier.ipp +23 -27
- data/rice/Return.hpp +39 -0
- data/rice/Return.ipp +33 -0
- data/rice/detail/Exception_Handler.ipp +22 -62
- data/rice/detail/Exception_Handler_defn.hpp +76 -91
- data/rice/detail/Iterator.hpp +18 -88
- data/rice/detail/Iterator.ipp +47 -0
- data/rice/detail/Jump_Tag.hpp +21 -0
- data/rice/detail/MethodInfo.hpp +44 -0
- data/rice/detail/MethodInfo.ipp +78 -0
- data/rice/detail/NativeAttribute.hpp +53 -0
- data/rice/detail/NativeAttribute.ipp +83 -0
- data/rice/detail/NativeFunction.hpp +69 -0
- data/rice/detail/NativeFunction.ipp +248 -0
- data/rice/detail/RubyFunction.hpp +39 -0
- data/rice/detail/RubyFunction.ipp +92 -0
- data/rice/detail/Type.hpp +29 -0
- data/rice/detail/Type.ipp +138 -0
- data/rice/detail/TypeRegistry.hpp +50 -0
- data/rice/detail/TypeRegistry.ipp +106 -0
- data/rice/detail/Wrapper.hpp +51 -0
- data/rice/detail/Wrapper.ipp +151 -0
- data/rice/detail/default_allocation_func.hpp +8 -19
- data/rice/detail/default_allocation_func.ipp +9 -8
- data/rice/detail/from_ruby.hpp +2 -37
- data/rice/detail/from_ruby.ipp +1020 -46
- data/rice/detail/from_ruby_defn.hpp +38 -0
- data/rice/detail/function_traits.hpp +124 -0
- data/rice/detail/method_data.hpp +23 -15
- data/rice/detail/method_data.ipp +53 -0
- data/rice/detail/rice_traits.hpp +116 -0
- data/rice/detail/ruby.hpp +9 -50
- data/rice/detail/to_ruby.hpp +3 -17
- data/rice/detail/to_ruby.ipp +409 -31
- data/rice/detail/to_ruby_defn.hpp +48 -0
- data/rice/forward_declares.ipp +82 -0
- data/rice/global_function.hpp +16 -20
- data/rice/global_function.ipp +8 -17
- data/rice/rice.hpp +59 -0
- data/rice/ruby_mark.hpp +5 -3
- data/rice/ruby_try_catch.hpp +4 -4
- data/rice/stl.hpp +11 -0
- data/sample/callbacks/extconf.rb +6 -0
- data/sample/callbacks/sample_callbacks.cpp +35 -0
- data/sample/callbacks/test.rb +28 -0
- data/sample/enum/extconf.rb +3 -0
- data/sample/enum/sample_enum.cpp +3 -17
- data/sample/enum/test.rb +2 -2
- data/sample/inheritance/animals.cpp +8 -24
- data/sample/inheritance/extconf.rb +3 -0
- data/sample/inheritance/test.rb +1 -1
- data/sample/map/extconf.rb +3 -0
- data/sample/map/map.cpp +10 -18
- data/sample/map/test.rb +1 -1
- data/test/embed_ruby.cpp +34 -0
- data/test/embed_ruby.hpp +4 -0
- data/test/ext/t1/extconf.rb +3 -0
- data/test/ext/t1/t1.cpp +1 -3
- data/test/ext/t2/extconf.rb +3 -0
- data/test/ext/t2/t2.cpp +1 -1
- data/test/extconf.rb +23 -0
- data/test/ruby/test_callbacks_sample.rb +28 -0
- data/test/ruby/test_multiple_extensions.rb +18 -0
- data/test/ruby/test_multiple_extensions_same_class.rb +14 -0
- data/test/ruby/test_multiple_extensions_with_inheritance.rb +20 -0
- data/test/test_Address_Registration_Guard.cpp +25 -11
- data/test/test_Array.cpp +131 -74
- data/test/test_Attribute.cpp +147 -0
- data/test/test_Builtin_Object.cpp +36 -15
- data/test/test_Class.cpp +151 -276
- data/test/test_Constructor.cpp +10 -9
- data/test/test_Data_Object.cpp +135 -193
- data/test/test_Data_Type.cpp +323 -252
- data/test/test_Director.cpp +56 -42
- data/test/test_Enum.cpp +230 -104
- data/test/test_Exception.cpp +7 -7
- data/test/test_Hash.cpp +33 -31
- data/test/test_Identifier.cpp +6 -6
- data/test/test_Inheritance.cpp +221 -0
- data/test/test_Iterator.cpp +161 -0
- data/test/test_Jump_Tag.cpp +1 -1
- data/test/test_Keep_Alive.cpp +161 -0
- data/test/test_Memory_Management.cpp +4 -5
- data/test/test_Module.cpp +169 -111
- data/test/test_Object.cpp +51 -19
- data/test/test_Ownership.cpp +275 -0
- data/test/test_Self.cpp +205 -0
- data/test/test_Stl_Optional.cpp +90 -0
- data/test/test_Stl_Pair.cpp +144 -0
- data/test/test_Stl_SmartPointer.cpp +200 -0
- data/test/test_Stl_String.cpp +74 -0
- data/test/test_Stl_Vector.cpp +652 -0
- data/test/test_String.cpp +3 -3
- data/test/test_Struct.cpp +31 -40
- data/test/test_Symbol.cpp +3 -3
- data/test/test_To_From_Ruby.cpp +283 -218
- data/test/test_global_functions.cpp +41 -20
- data/test/unittest.cpp +34 -8
- data/test/unittest.hpp +0 -4
- metadata +121 -136
- data/Doxyfile +0 -2268
- data/Makefile.am +0 -26
- data/Makefile.in +0 -923
- data/README.mingw +0 -8
- data/aclocal.m4 +0 -1088
- data/bootstrap +0 -8
- data/check_stdcxx_11.ac +0 -103
- data/config.guess +0 -1421
- data/config.sub +0 -1807
- data/configure +0 -7367
- data/configure.ac +0 -55
- data/depcomp +0 -791
- data/doxygen.ac +0 -314
- data/doxygen.am +0 -186
- data/extconf.rb +0 -69
- data/install-sh +0 -501
- data/missing +0 -215
- data/post-autoconf.rb +0 -22
- data/post-automake.rb +0 -28
- data/rice/Address_Registration_Guard.cpp +0 -22
- data/rice/Arg_impl.hpp +0 -129
- data/rice/Arg_operators.cpp +0 -21
- data/rice/Arg_operators.hpp +0 -19
- data/rice/Array.hpp +0 -214
- data/rice/Array.ipp +0 -256
- data/rice/Builtin_Object.hpp +0 -8
- data/rice/Builtin_Object.ipp +0 -50
- data/rice/Builtin_Object_defn.hpp +0 -50
- data/rice/Class.cpp +0 -57
- data/rice/Class.hpp +0 -8
- data/rice/Class.ipp +0 -6
- data/rice/Class_defn.hpp +0 -83
- data/rice/Data_Type.cpp +0 -54
- data/rice/Data_Type_fwd.hpp +0 -12
- data/rice/Director.cpp +0 -13
- data/rice/Exception.cpp +0 -59
- data/rice/Exception_Base.hpp +0 -8
- data/rice/Exception_Base.ipp +0 -13
- data/rice/Exception_Base_defn.hpp +0 -27
- data/rice/Hash.hpp +0 -227
- data/rice/Hash.ipp +0 -329
- data/rice/Identifier.cpp +0 -8
- data/rice/Jump_Tag.hpp +0 -24
- data/rice/Makefile.am +0 -125
- data/rice/Makefile.in +0 -888
- data/rice/Module.cpp +0 -84
- data/rice/Module.hpp +0 -8
- data/rice/Module.ipp +0 -6
- data/rice/Module_defn.hpp +0 -88
- data/rice/Module_impl.hpp +0 -281
- data/rice/Module_impl.ipp +0 -345
- data/rice/Object.cpp +0 -169
- data/rice/Object.hpp +0 -8
- data/rice/Object.ipp +0 -19
- data/rice/Object_defn.hpp +0 -191
- data/rice/Require_Guard.hpp +0 -21
- data/rice/String.cpp +0 -94
- data/rice/String.hpp +0 -91
- data/rice/Struct.cpp +0 -117
- data/rice/Struct.hpp +0 -162
- data/rice/Struct.ipp +0 -26
- data/rice/Symbol.cpp +0 -25
- data/rice/Symbol.hpp +0 -66
- data/rice/Symbol.ipp +0 -44
- data/rice/config.hpp +0 -47
- data/rice/config.hpp.in +0 -46
- data/rice/detail/Arguments.hpp +0 -118
- data/rice/detail/Auto_Function_Wrapper.hpp +0 -898
- data/rice/detail/Auto_Function_Wrapper.ipp +0 -3694
- data/rice/detail/Auto_Member_Function_Wrapper.hpp +0 -897
- data/rice/detail/Auto_Member_Function_Wrapper.ipp +0 -2774
- data/rice/detail/Caster.hpp +0 -103
- data/rice/detail/Not_Copyable.hpp +0 -25
- data/rice/detail/Wrapped_Function.hpp +0 -33
- data/rice/detail/cfp.hpp +0 -24
- data/rice/detail/cfp.ipp +0 -51
- data/rice/detail/check_ruby_type.cpp +0 -27
- data/rice/detail/check_ruby_type.hpp +0 -23
- data/rice/detail/creation_funcs.hpp +0 -37
- data/rice/detail/creation_funcs.ipp +0 -36
- data/rice/detail/define_method_and_auto_wrap.hpp +0 -31
- data/rice/detail/define_method_and_auto_wrap.ipp +0 -30
- data/rice/detail/demangle.cpp +0 -56
- data/rice/detail/demangle.hpp +0 -19
- data/rice/detail/env.hpp +0 -11
- data/rice/detail/method_data.cpp +0 -86
- data/rice/detail/node.hpp +0 -13
- data/rice/detail/object_call.hpp +0 -69
- data/rice/detail/object_call.ipp +0 -131
- data/rice/detail/protect.cpp +0 -29
- data/rice/detail/protect.hpp +0 -34
- data/rice/detail/ruby_version_code.hpp +0 -6
- data/rice/detail/ruby_version_code.hpp.in +0 -6
- data/rice/detail/st.hpp +0 -22
- data/rice/detail/traits.hpp +0 -43
- data/rice/detail/win32.hpp +0 -16
- data/rice/detail/wrap_function.hpp +0 -341
- data/rice/detail/wrap_function.ipp +0 -514
- data/rice/protect.hpp +0 -92
- data/rice/protect.ipp +0 -1134
- data/rice/rubypp.rb +0 -97
- data/rice/to_from_ruby.hpp +0 -8
- data/rice/to_from_ruby.ipp +0 -294
- data/rice/to_from_ruby_defn.hpp +0 -70
- data/ruby.ac +0 -135
- data/ruby/Makefile.am +0 -1
- data/ruby/Makefile.in +0 -628
- data/ruby/lib/Makefile.am +0 -3
- data/ruby/lib/Makefile.in +0 -506
- data/ruby/lib/mkmf-rice.rb.in +0 -217
- data/ruby/lib/version.rb +0 -3
- data/sample/Makefile.am +0 -47
- data/sample/Makefile.in +0 -489
- data/test/Makefile.am +0 -72
- data/test/Makefile.in +0 -1213
- data/test/ext/Makefile.am +0 -41
- data/test/ext/Makefile.in +0 -483
- data/test/test_rice.rb +0 -41
@@ -0,0 +1,53 @@
|
|
1
|
+
#ifndef Rice__detail__Native_Attribute__hpp_
|
2
|
+
#define Rice__detail__Native_Attribute__hpp_
|
3
|
+
|
4
|
+
#include "ruby.hpp"
|
5
|
+
#include "Exception_Handler_defn.hpp"
|
6
|
+
#include "MethodInfo.hpp"
|
7
|
+
|
8
|
+
namespace Rice
|
9
|
+
{
|
10
|
+
enum class AttrAccess
|
11
|
+
{
|
12
|
+
ReadWrite,
|
13
|
+
Read,
|
14
|
+
Write
|
15
|
+
};
|
16
|
+
|
17
|
+
namespace detail
|
18
|
+
{
|
19
|
+
template<typename Return_T, typename Attr_T, typename Self_T = void>
|
20
|
+
class NativeAttribute
|
21
|
+
{
|
22
|
+
public:
|
23
|
+
using Native_Return_T = Return_T;
|
24
|
+
|
25
|
+
// Static member functions that Ruby calls
|
26
|
+
static VALUE get(VALUE self);
|
27
|
+
static VALUE set(VALUE self, VALUE value);
|
28
|
+
|
29
|
+
public:
|
30
|
+
NativeAttribute(Attr_T attr, AttrAccess access = AttrAccess::ReadWrite);
|
31
|
+
|
32
|
+
// Invokes the wrapped function
|
33
|
+
VALUE read(VALUE self);
|
34
|
+
VALUE write(VALUE self, VALUE value);
|
35
|
+
|
36
|
+
private:
|
37
|
+
Attr_T attr_;
|
38
|
+
AttrAccess access_;
|
39
|
+
};
|
40
|
+
|
41
|
+
// A plain function or static member call
|
42
|
+
template<typename T>
|
43
|
+
auto* Make_Native_Attribute(T* attr, AttrAccess access);
|
44
|
+
|
45
|
+
// Lambda function that does not take Self as first parameter
|
46
|
+
template<typename Class_T, typename T>
|
47
|
+
auto* Make_Native_Attribute(T Class_T::* attr, AttrAccess access);
|
48
|
+
} // detail
|
49
|
+
} // Rice
|
50
|
+
|
51
|
+
#include "NativeAttribute.ipp"
|
52
|
+
|
53
|
+
#endif // Rice__detail__Native_Attribute__hpp_
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#include <array>
|
2
|
+
#include <algorithm>
|
3
|
+
|
4
|
+
#include "rice_traits.hpp"
|
5
|
+
#include "method_data.hpp"
|
6
|
+
#include "to_ruby_defn.hpp"
|
7
|
+
#include "../ruby_try_catch.hpp"
|
8
|
+
|
9
|
+
namespace Rice::detail
|
10
|
+
{
|
11
|
+
template<typename Return_T, typename Attr_T, typename Self_T>
|
12
|
+
inline VALUE NativeAttribute<Return_T, Attr_T, Self_T>::get(VALUE self)
|
13
|
+
{
|
14
|
+
RUBY_TRY
|
15
|
+
{
|
16
|
+
using Native_Attr_T = NativeAttribute<Return_T, Attr_T, Self_T>;
|
17
|
+
Native_Attr_T* attr = detail::MethodData::data<Native_Attr_T*>();
|
18
|
+
return attr->read(self);
|
19
|
+
}
|
20
|
+
RUBY_CATCH
|
21
|
+
}
|
22
|
+
|
23
|
+
template<typename Return_T, typename Attr_T, typename Self_T>
|
24
|
+
inline VALUE NativeAttribute<Return_T, Attr_T, Self_T>::set(VALUE self, VALUE value)
|
25
|
+
{
|
26
|
+
RUBY_TRY
|
27
|
+
{
|
28
|
+
using Native_Attr_T = NativeAttribute<Return_T, Attr_T, Self_T>;
|
29
|
+
Native_Attr_T* attr = detail::MethodData::data<Native_Attr_T*>();
|
30
|
+
return attr->write(self, value);
|
31
|
+
}
|
32
|
+
RUBY_CATCH
|
33
|
+
}
|
34
|
+
|
35
|
+
template<typename Return_T, typename Attr_T, typename Self_T>
|
36
|
+
NativeAttribute<Return_T, Attr_T, Self_T>::NativeAttribute(Attr_T attr, AttrAccess access)
|
37
|
+
: attr_(attr), access_(access)
|
38
|
+
{
|
39
|
+
}
|
40
|
+
|
41
|
+
template<typename Return_T, typename Attr_T, typename Self_T>
|
42
|
+
inline VALUE NativeAttribute<Return_T, Attr_T, Self_T>::read(VALUE self)
|
43
|
+
{
|
44
|
+
using Unqualified_T = remove_cv_recursive_t<Return_T>;
|
45
|
+
if constexpr (std::is_member_object_pointer_v<Attr_T>)
|
46
|
+
{
|
47
|
+
Self_T* nativeSelf = From_Ruby<Self_T*>().convert(self);
|
48
|
+
return To_Ruby<Unqualified_T>().convert(nativeSelf->*attr_);
|
49
|
+
}
|
50
|
+
else
|
51
|
+
{
|
52
|
+
return To_Ruby<Unqualified_T>().convert(*attr_);
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
template<typename Return_T, typename Attr_T, typename Self_T>
|
57
|
+
inline VALUE NativeAttribute<Return_T, Attr_T, Self_T>::write(VALUE self, VALUE value)
|
58
|
+
{
|
59
|
+
if constexpr (!std::is_const_v<std::remove_pointer_t<Attr_T>> && std::is_member_object_pointer_v<Attr_T>)
|
60
|
+
{
|
61
|
+
Self_T* nativeSelf = From_Ruby<Self_T*>().convert(self);
|
62
|
+
nativeSelf->*attr_ = From_Ruby<Return_T>().convert(value);
|
63
|
+
}
|
64
|
+
else if constexpr (!std::is_const_v<std::remove_pointer_t<Attr_T>>)
|
65
|
+
{
|
66
|
+
*attr_ = From_Ruby<Return_T>().convert(value);
|
67
|
+
}
|
68
|
+
return value;
|
69
|
+
}
|
70
|
+
|
71
|
+
template<typename T>
|
72
|
+
auto* Make_Native_Attribute(T* attr, AttrAccess access)
|
73
|
+
{
|
74
|
+
return new NativeAttribute<T, T*>(attr, access);
|
75
|
+
}
|
76
|
+
|
77
|
+
template<typename Class_T, typename T>
|
78
|
+
auto* Make_Native_Attribute(T Class_T::* attr, AttrAccess access)
|
79
|
+
{
|
80
|
+
using Attr_T = T Class_T::*;
|
81
|
+
return new NativeAttribute<T, Attr_T, Class_T>(attr, access);
|
82
|
+
}
|
83
|
+
} // Rice
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#ifndef Rice__detail__Native_Function__hpp_
|
2
|
+
#define Rice__detail__Native_Function__hpp_
|
3
|
+
|
4
|
+
#include "ruby.hpp"
|
5
|
+
#include "Exception_Handler_defn.hpp"
|
6
|
+
#include "MethodInfo.hpp"
|
7
|
+
#include "function_traits.hpp"
|
8
|
+
#include "from_ruby.hpp"
|
9
|
+
|
10
|
+
namespace Rice::detail
|
11
|
+
{
|
12
|
+
template<typename Function_T, bool IsMethod>
|
13
|
+
class NativeFunction
|
14
|
+
{
|
15
|
+
public:
|
16
|
+
// We remove const to avoid an explosion of To_Ruby specializations and Ruby doesn't
|
17
|
+
// have the concept of constants anyways
|
18
|
+
using Return_T = remove_cv_recursive_t<typename function_traits<Function_T>::return_type>;
|
19
|
+
using Self_T = typename method_traits<Function_T, IsMethod>::Self_T;
|
20
|
+
using Arg_Ts = typename method_traits<Function_T, IsMethod>::Arg_Ts;
|
21
|
+
using From_Ruby_Ts = typename tuple_map<From_Ruby, Arg_Ts>::type;
|
22
|
+
|
23
|
+
// Static member function that Ruby calls
|
24
|
+
static VALUE call(int argc, VALUE* argv, VALUE self);
|
25
|
+
|
26
|
+
public:
|
27
|
+
NativeFunction(Function_T func, std::shared_ptr<Exception_Handler> handler, MethodInfo* methodInfo);
|
28
|
+
|
29
|
+
// Invokes the wrapped function
|
30
|
+
VALUE operator()(int argc, VALUE* argv, VALUE self);
|
31
|
+
|
32
|
+
private:
|
33
|
+
template<typename T, std::size_t I>
|
34
|
+
From_Ruby<T> createFromRuby();
|
35
|
+
|
36
|
+
// Create NativeArgs which are used to convert values from Ruby to C++
|
37
|
+
template<std::size_t...I>
|
38
|
+
From_Ruby_Ts createFromRuby(std::index_sequence<I...>& indices);
|
39
|
+
|
40
|
+
To_Ruby<Return_T> createToRuby();
|
41
|
+
|
42
|
+
// Convert Ruby argv pointer to Ruby values
|
43
|
+
std::vector<VALUE> getRubyValues(int argc, VALUE* argv);
|
44
|
+
|
45
|
+
// Convert Ruby values to C++ values
|
46
|
+
template<typename std::size_t...I>
|
47
|
+
Arg_Ts getNativeValues(std::vector<VALUE>& values, std::index_sequence<I...>& indices);
|
48
|
+
|
49
|
+
// Figure out what self is
|
50
|
+
Self_T getSelf(VALUE self);
|
51
|
+
|
52
|
+
// Do we need to keep alive any arguments?
|
53
|
+
void checkKeepAlive(VALUE self, VALUE returnValue, std::vector<VALUE>& rubyValues);
|
54
|
+
|
55
|
+
// Call the underlying C++ function
|
56
|
+
VALUE invokeNativeFunction(Arg_Ts& nativeArgs);
|
57
|
+
VALUE invokeNativeMethod(VALUE self, Arg_Ts& nativeArgs);
|
58
|
+
|
59
|
+
private:
|
60
|
+
Function_T func_;
|
61
|
+
From_Ruby_Ts fromRubys_;
|
62
|
+
To_Ruby<Return_T> toRuby_;
|
63
|
+
std::shared_ptr<Exception_Handler> handler_;
|
64
|
+
std::unique_ptr<MethodInfo> methodInfo_;
|
65
|
+
};
|
66
|
+
}
|
67
|
+
#include "NativeFunction.ipp"
|
68
|
+
|
69
|
+
#endif // Rice__detail__Native_Function__hpp_
|
@@ -0,0 +1,248 @@
|
|
1
|
+
#include <array>
|
2
|
+
#include <algorithm>
|
3
|
+
#include <stdexcept>
|
4
|
+
|
5
|
+
#include "method_data.hpp"
|
6
|
+
#include "to_ruby_defn.hpp"
|
7
|
+
#include "../ruby_try_catch.hpp"
|
8
|
+
|
9
|
+
namespace Rice::detail
|
10
|
+
{
|
11
|
+
template<typename Function_T, bool IsMethod>
|
12
|
+
VALUE NativeFunction<Function_T, IsMethod>::call(int argc, VALUE* argv, VALUE self)
|
13
|
+
{
|
14
|
+
using Wrapper_T = NativeFunction<Function_T, IsMethod>;
|
15
|
+
Wrapper_T* wrapper = detail::MethodData::data<Wrapper_T*>();
|
16
|
+
return wrapper->operator()(argc, argv, self);
|
17
|
+
}
|
18
|
+
|
19
|
+
template<typename Function_T, bool IsMethod>
|
20
|
+
NativeFunction<Function_T, IsMethod>::NativeFunction(Function_T func, std::shared_ptr<Exception_Handler> handler, MethodInfo* methodInfo)
|
21
|
+
: func_(func), handler_(handler), methodInfo_(methodInfo)
|
22
|
+
{
|
23
|
+
// Create a tuple of NativeArgs that will convert the Ruby values to native values. For
|
24
|
+
// builtin types NativeArgs will keep a copy of the native value so that it
|
25
|
+
// can be passed by reference or pointer to the native function. For non-builtin types
|
26
|
+
// it will just pass the value through.
|
27
|
+
auto indices = std::make_index_sequence<std::tuple_size_v<Arg_Ts>>{};
|
28
|
+
this->fromRubys_ = this->createFromRuby(indices);
|
29
|
+
|
30
|
+
this->toRuby_ = this->createToRuby();
|
31
|
+
}
|
32
|
+
|
33
|
+
template<typename Function_T, bool IsMethod>
|
34
|
+
template<typename T, std::size_t I>
|
35
|
+
From_Ruby<T> NativeFunction<Function_T, IsMethod>::createFromRuby()
|
36
|
+
{
|
37
|
+
// Does the From_Ruby instantiation work with Arg?
|
38
|
+
if constexpr (std::is_constructible_v<From_Ruby<T>, Arg*>)
|
39
|
+
{
|
40
|
+
return From_Ruby<T>(&this->methodInfo_->arg(I));
|
41
|
+
}
|
42
|
+
else
|
43
|
+
{
|
44
|
+
return From_Ruby<T>();
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
template<typename Function_T, bool IsMethod>
|
49
|
+
To_Ruby<typename NativeFunction<Function_T, IsMethod>::Return_T> NativeFunction<Function_T, IsMethod>::createToRuby()
|
50
|
+
{
|
51
|
+
// Does the From_Ruby instantiation work with ReturnInfo?
|
52
|
+
if constexpr (std::is_constructible_v<To_Ruby<Return_T>, Return*>)
|
53
|
+
{
|
54
|
+
return To_Ruby<Return_T>(&this->methodInfo_->returnInfo);
|
55
|
+
}
|
56
|
+
else
|
57
|
+
{
|
58
|
+
return To_Ruby<Return_T>();
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
template<typename Function_T, bool IsMethod>
|
63
|
+
template<std::size_t... I>
|
64
|
+
typename NativeFunction<Function_T, IsMethod>::From_Ruby_Ts NativeFunction<Function_T, IsMethod>::createFromRuby(std::index_sequence<I...>& indices)
|
65
|
+
{
|
66
|
+
return std::make_tuple(createFromRuby<remove_cv_recursive_t<typename std::tuple_element<I, Arg_Ts>::type>, I>()...);
|
67
|
+
}
|
68
|
+
|
69
|
+
template<typename Function_T, bool IsMethod>
|
70
|
+
std::vector<VALUE> NativeFunction<Function_T, IsMethod>::getRubyValues(int argc, VALUE* argv)
|
71
|
+
{
|
72
|
+
// Setup a tuple to contain required methodInfo to rb_scan_args
|
73
|
+
std::string scanFormat = this->methodInfo_->formatString();
|
74
|
+
std::tuple<int, VALUE*, const char*> rbScanMandatory = std::forward_as_tuple(argc, argv, scanFormat.c_str());
|
75
|
+
|
76
|
+
// Create a vector to store the variable number of Ruby Values
|
77
|
+
std::vector<VALUE> rbScanArgsOptional(std::tuple_size_v<Arg_Ts>, Qnil);
|
78
|
+
|
79
|
+
// Convert the vector to an array so it can then be concatenated to a tuple
|
80
|
+
std::array<VALUE*, std::tuple_size_v<Arg_Ts>> rbScanArgsOptionalPointers;
|
81
|
+
std::transform(rbScanArgsOptional.begin(), rbScanArgsOptional.end(), rbScanArgsOptionalPointers.begin(),
|
82
|
+
[](VALUE& value)
|
83
|
+
{
|
84
|
+
return &value;
|
85
|
+
});
|
86
|
+
|
87
|
+
// Combine the tuples and call rb_scan_args
|
88
|
+
auto rbScanArgs = std::tuple_cat(rbScanMandatory, rbScanArgsOptionalPointers);
|
89
|
+
std::apply(rb_scan_args, rbScanArgs);
|
90
|
+
|
91
|
+
return rbScanArgsOptional;
|
92
|
+
}
|
93
|
+
|
94
|
+
template<typename Function_T, bool IsMethod>
|
95
|
+
template<std::size_t... I>
|
96
|
+
typename NativeFunction<Function_T, IsMethod>::Arg_Ts NativeFunction<Function_T, IsMethod>::getNativeValues(std::vector<VALUE>& values,
|
97
|
+
std::index_sequence<I...>& indices)
|
98
|
+
{
|
99
|
+
// Convert each Ruby value to its native value by calling the appropriate fromRuby instance.
|
100
|
+
// Note that for fundamental types From_Ruby<Arg_Ts> will keep a copy of the native value
|
101
|
+
// so it can be passed by reference or pointer to a native function.
|
102
|
+
return std::forward_as_tuple(std::get<I>(this->fromRubys_).convert(values[I])...);
|
103
|
+
}
|
104
|
+
|
105
|
+
template<typename Function_T, bool IsMethod>
|
106
|
+
typename NativeFunction<Function_T, IsMethod>::Self_T NativeFunction<Function_T, IsMethod>::getSelf(VALUE self)
|
107
|
+
{
|
108
|
+
// There is no self parameter
|
109
|
+
if constexpr (std::is_same_v<Self_T, std::nullptr_t>)
|
110
|
+
{
|
111
|
+
return nullptr;
|
112
|
+
}
|
113
|
+
// Self parameter is a Ruby VALUE so no conversion is needed
|
114
|
+
else if constexpr (std::is_same_v<Self_T, VALUE>)
|
115
|
+
{
|
116
|
+
return self;
|
117
|
+
}
|
118
|
+
// Self parameter could be derived from Object or it is an C++ instdance and
|
119
|
+
// needs to be unwrapped from Ruby
|
120
|
+
else
|
121
|
+
{
|
122
|
+
return From_Ruby<Self_T>().convert(self);
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
template<typename Function_T, bool IsMethod>
|
127
|
+
VALUE NativeFunction<Function_T, IsMethod>::invokeNativeFunction(Arg_Ts& nativeArgs)
|
128
|
+
{
|
129
|
+
if constexpr (std::is_void_v<Return_T>)
|
130
|
+
{
|
131
|
+
std::apply(this->func_, nativeArgs);
|
132
|
+
return Qnil;
|
133
|
+
}
|
134
|
+
else
|
135
|
+
{
|
136
|
+
// Call the native method and get the result
|
137
|
+
Return_T nativeResult = std::apply(this->func_, nativeArgs);
|
138
|
+
|
139
|
+
// Return the result
|
140
|
+
return this->toRuby_.convert(nativeResult);
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
template<typename Function_T, bool IsMethod>
|
145
|
+
VALUE NativeFunction<Function_T, IsMethod>::invokeNativeMethod(VALUE self, Arg_Ts& nativeArgs)
|
146
|
+
{
|
147
|
+
Self_T receiver = this->getSelf(self);
|
148
|
+
auto selfAndNativeArgs = std::tuple_cat(std::forward_as_tuple(receiver), nativeArgs);
|
149
|
+
|
150
|
+
if constexpr (std::is_void_v<Return_T>)
|
151
|
+
{
|
152
|
+
std::apply(this->func_, selfAndNativeArgs);
|
153
|
+
return Qnil;
|
154
|
+
}
|
155
|
+
else
|
156
|
+
{
|
157
|
+
Return_T nativeResult = (Return_T)std::apply(this->func_, selfAndNativeArgs);
|
158
|
+
|
159
|
+
// Special handling if the method returns self. If so we do not want
|
160
|
+
// to create a new Ruby wrapper object and instead return self.
|
161
|
+
if constexpr (std::is_same_v<intrinsic_type<Return_T>, intrinsic_type<Self_T>>)
|
162
|
+
{
|
163
|
+
if constexpr (std::is_pointer_v<Return_T> && std::is_pointer_v<Self_T>)
|
164
|
+
{
|
165
|
+
if (nativeResult == receiver)
|
166
|
+
return self;
|
167
|
+
}
|
168
|
+
else if constexpr (std::is_pointer_v<Return_T> && std::is_reference_v<Self_T>)
|
169
|
+
{
|
170
|
+
if (nativeResult == &receiver)
|
171
|
+
return self;
|
172
|
+
}
|
173
|
+
else if constexpr (std::is_reference_v<Return_T> && std::is_pointer_v<Self_T>)
|
174
|
+
{
|
175
|
+
if (&nativeResult == receiver)
|
176
|
+
return self;
|
177
|
+
}
|
178
|
+
else if constexpr (std::is_reference_v<Return_T> && std::is_reference_v<Self_T>)
|
179
|
+
{
|
180
|
+
if (&nativeResult == &receiver)
|
181
|
+
return self;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
return this->toRuby_.convert(nativeResult);
|
186
|
+
}
|
187
|
+
}
|
188
|
+
|
189
|
+
template<typename Function_T, bool IsMethod>
|
190
|
+
void NativeFunction<Function_T, IsMethod>::checkKeepAlive(VALUE self, VALUE returnValue, std::vector<VALUE>& rubyValues)
|
191
|
+
{
|
192
|
+
// Check function arguments
|
193
|
+
Wrapper* selfWrapper = getWrapper(self);
|
194
|
+
for (const Arg& arg : (*this->methodInfo_))
|
195
|
+
{
|
196
|
+
if (arg.isKeepAlive)
|
197
|
+
{
|
198
|
+
selfWrapper->addKeepAlive(rubyValues[arg.position]);
|
199
|
+
}
|
200
|
+
}
|
201
|
+
|
202
|
+
// Check return value
|
203
|
+
if (this->methodInfo_->returnInfo.isKeepAlive)
|
204
|
+
{
|
205
|
+
Wrapper* returnWrapper = getWrapper(returnValue);
|
206
|
+
returnWrapper->addKeepAlive(self);
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
template<typename Function_T, bool IsMethod>
|
211
|
+
VALUE NativeFunction<Function_T, IsMethod>::operator()(int argc, VALUE* argv, VALUE self)
|
212
|
+
{
|
213
|
+
try
|
214
|
+
{
|
215
|
+
// Get the ruby values
|
216
|
+
std::vector<VALUE> rubyValues = this->getRubyValues(argc, argv);
|
217
|
+
|
218
|
+
auto indices = std::make_index_sequence<std::tuple_size_v<Arg_Ts>>{};
|
219
|
+
|
220
|
+
// Convert the Ruby values to native values
|
221
|
+
Arg_Ts nativeValues = this->getNativeValues(rubyValues, indices);
|
222
|
+
|
223
|
+
// Now call the native method
|
224
|
+
VALUE result = Qnil;
|
225
|
+
if constexpr (std::is_same_v<Self_T, std::nullptr_t>)
|
226
|
+
{
|
227
|
+
result = this->invokeNativeFunction(nativeValues);
|
228
|
+
}
|
229
|
+
else
|
230
|
+
{
|
231
|
+
result = this->invokeNativeMethod(self, nativeValues);
|
232
|
+
}
|
233
|
+
|
234
|
+
// Check if any function arguments or return values need to have their lifetimes tied to the receiver
|
235
|
+
this->checkKeepAlive(self, result, rubyValues);
|
236
|
+
|
237
|
+
return result;
|
238
|
+
}
|
239
|
+
catch (...)
|
240
|
+
{
|
241
|
+
RUBY_TRY
|
242
|
+
{
|
243
|
+
return this->handler_->handle_exception();
|
244
|
+
}
|
245
|
+
RUBY_CATCH
|
246
|
+
}
|
247
|
+
}
|
248
|
+
}
|