rice 4.3.3 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -26
  3. data/CMakeLists.txt +31 -0
  4. data/CMakePresets.json +75 -0
  5. data/COPYING +3 -2
  6. data/FindRuby.cmake +437 -0
  7. data/README.md +7 -2
  8. data/Rakefile +12 -5
  9. data/include/rice/rice.hpp +9522 -4426
  10. data/include/rice/stl.hpp +2831 -1198
  11. data/lib/make_rice_headers.rb +79 -0
  12. data/lib/mkmf-rice.rb +40 -94
  13. data/lib/rice/version.rb +3 -0
  14. data/lib/rice.rb +1 -0
  15. data/lib/rubygems/builder.rb +11 -0
  16. data/lib/rubygems/cmake_builder.rb +113 -0
  17. data/lib/rubygems_plugin.rb +9 -0
  18. data/rice/Address_Registration_Guard.hpp +72 -3
  19. data/rice/Arg.hpp +26 -6
  20. data/rice/Arg.ipp +35 -2
  21. data/rice/Buffer.hpp +123 -0
  22. data/rice/Buffer.ipp +599 -0
  23. data/rice/Callback.hpp +21 -0
  24. data/rice/Callback.ipp +13 -0
  25. data/rice/Constructor.hpp +4 -27
  26. data/rice/Constructor.ipp +79 -0
  27. data/rice/Data_Object.hpp +73 -3
  28. data/rice/Data_Object.ipp +388 -96
  29. data/rice/Data_Type.hpp +214 -3
  30. data/rice/Data_Type.ipp +144 -67
  31. data/rice/Director.hpp +0 -2
  32. data/rice/Enum.hpp +4 -7
  33. data/rice/Enum.ipp +102 -55
  34. data/rice/Exception.hpp +62 -2
  35. data/rice/Exception.ipp +7 -12
  36. data/rice/Init.hpp +8 -0
  37. data/rice/Init.ipp +8 -0
  38. data/rice/JumpException.hpp +44 -0
  39. data/rice/JumpException.ipp +48 -0
  40. data/rice/MemoryView.hpp +11 -0
  41. data/rice/MemoryView.ipp +3 -0
  42. data/rice/Return.hpp +7 -27
  43. data/rice/Return.ipp +13 -13
  44. data/rice/cpp_api/Array.hpp +209 -0
  45. data/rice/cpp_api/Array.ipp +304 -0
  46. data/rice/cpp_api/Builtin_Object.hpp +31 -0
  47. data/rice/cpp_api/Builtin_Object.ipp +37 -0
  48. data/rice/cpp_api/Class.hpp +70 -0
  49. data/rice/cpp_api/Class.ipp +97 -0
  50. data/rice/cpp_api/Encoding.hpp +32 -0
  51. data/rice/cpp_api/Encoding.ipp +59 -0
  52. data/rice/cpp_api/Hash.hpp +194 -0
  53. data/rice/cpp_api/Hash.ipp +257 -0
  54. data/rice/{Identifier.hpp → cpp_api/Identifier.hpp} +2 -6
  55. data/rice/{Identifier.ipp → cpp_api/Identifier.ipp} +4 -2
  56. data/rice/cpp_api/Module.hpp +72 -0
  57. data/rice/cpp_api/Module.ipp +101 -0
  58. data/rice/cpp_api/Object.hpp +272 -0
  59. data/rice/cpp_api/Object.ipp +235 -0
  60. data/rice/cpp_api/String.hpp +74 -0
  61. data/rice/cpp_api/String.ipp +120 -0
  62. data/rice/cpp_api/Struct.hpp +113 -0
  63. data/rice/cpp_api/Struct.ipp +92 -0
  64. data/rice/cpp_api/Symbol.hpp +46 -0
  65. data/rice/cpp_api/Symbol.ipp +93 -0
  66. data/rice/cpp_api/shared_methods.hpp +134 -0
  67. data/rice/detail/DefaultHandler.hpp +12 -0
  68. data/rice/detail/DefaultHandler.ipp +8 -0
  69. data/rice/detail/HandlerRegistry.hpp +5 -35
  70. data/rice/detail/HandlerRegistry.ipp +7 -11
  71. data/rice/detail/InstanceRegistry.hpp +1 -4
  72. data/rice/detail/MethodInfo.hpp +12 -10
  73. data/rice/detail/MethodInfo.ipp +26 -21
  74. data/rice/detail/Native.hpp +33 -0
  75. data/rice/detail/Native.ipp +157 -0
  76. data/rice/detail/NativeAttributeGet.hpp +52 -0
  77. data/rice/detail/NativeAttributeGet.ipp +57 -0
  78. data/rice/detail/NativeAttributeSet.hpp +44 -0
  79. data/rice/detail/NativeAttributeSet.ipp +88 -0
  80. data/rice/detail/NativeCallbackFFI.hpp +55 -0
  81. data/rice/detail/NativeCallbackFFI.ipp +151 -0
  82. data/rice/detail/NativeCallbackSimple.hpp +30 -0
  83. data/rice/detail/NativeCallbackSimple.ipp +29 -0
  84. data/rice/detail/NativeFunction.hpp +33 -23
  85. data/rice/detail/NativeFunction.ipp +309 -70
  86. data/rice/detail/NativeIterator.hpp +9 -11
  87. data/rice/detail/NativeIterator.ipp +33 -31
  88. data/rice/detail/NativeRegistry.hpp +24 -15
  89. data/rice/detail/NativeRegistry.ipp +23 -48
  90. data/rice/detail/Proc.hpp +4 -0
  91. data/rice/detail/Proc.ipp +85 -0
  92. data/rice/detail/Registries.hpp +0 -7
  93. data/rice/detail/Registries.ipp +0 -18
  94. data/rice/detail/RubyFunction.hpp +0 -3
  95. data/rice/detail/RubyFunction.ipp +4 -8
  96. data/rice/detail/RubyType.hpp +16 -0
  97. data/rice/detail/RubyType.ipp +232 -0
  98. data/rice/detail/Type.hpp +7 -6
  99. data/rice/detail/Type.ipp +192 -45
  100. data/rice/detail/TypeRegistry.hpp +15 -7
  101. data/rice/detail/TypeRegistry.ipp +105 -12
  102. data/rice/detail/Wrapper.hpp +68 -32
  103. data/rice/detail/Wrapper.ipp +121 -109
  104. data/rice/detail/cpp_protect.hpp +5 -6
  105. data/rice/detail/default_allocation_func.ipp +0 -2
  106. data/rice/detail/from_ruby.hpp +38 -3
  107. data/rice/detail/from_ruby.ipp +1321 -492
  108. data/rice/detail/ruby.hpp +18 -0
  109. data/rice/detail/to_ruby.hpp +41 -3
  110. data/rice/detail/to_ruby.ipp +1424 -194
  111. data/rice/global_function.hpp +0 -4
  112. data/rice/global_function.ipp +0 -1
  113. data/rice/libc/file.hpp +11 -0
  114. data/rice/libc/file.ipp +32 -0
  115. data/rice/rice.hpp +116 -26
  116. data/rice/ruby_mark.hpp +4 -3
  117. data/rice/stl/complex.hpp +6 -0
  118. data/rice/stl/complex.ipp +93 -0
  119. data/rice/stl/exception.hpp +11 -0
  120. data/rice/stl/exception.ipp +29 -0
  121. data/rice/stl/exception_ptr.hpp +6 -0
  122. data/rice/stl/exception_ptr.ipp +27 -0
  123. data/rice/stl/map.hpp +12 -0
  124. data/rice/stl/map.ipp +469 -0
  125. data/rice/stl/monostate.hpp +6 -0
  126. data/rice/stl/monostate.ipp +80 -0
  127. data/rice/stl/multimap.hpp +14 -0
  128. data/rice/stl/multimap.ipp +448 -0
  129. data/rice/stl/optional.hpp +6 -0
  130. data/rice/stl/optional.ipp +118 -0
  131. data/rice/stl/pair.hpp +13 -0
  132. data/rice/stl/pair.ipp +155 -0
  133. data/rice/stl/reference_wrapper.hpp +6 -0
  134. data/rice/stl/reference_wrapper.ipp +41 -0
  135. data/rice/stl/set.hpp +12 -0
  136. data/rice/stl/set.ipp +495 -0
  137. data/rice/stl/shared_ptr.hpp +28 -0
  138. data/rice/stl/shared_ptr.ipp +224 -0
  139. data/rice/stl/string.hpp +6 -0
  140. data/rice/stl/string.ipp +158 -0
  141. data/rice/stl/string_view.hpp +6 -0
  142. data/rice/stl/string_view.ipp +65 -0
  143. data/rice/stl/tuple.hpp +6 -0
  144. data/rice/stl/tuple.ipp +128 -0
  145. data/rice/stl/type_index.hpp +6 -0
  146. data/rice/stl/type_index.ipp +30 -0
  147. data/rice/stl/type_info.hpp +6 -0
  148. data/rice/stl/type_info.ipp +29 -0
  149. data/rice/stl/unique_ptr.hpp +22 -0
  150. data/rice/stl/unique_ptr.ipp +139 -0
  151. data/rice/stl/unordered_map.hpp +12 -0
  152. data/rice/stl/unordered_map.ipp +469 -0
  153. data/rice/stl/variant.hpp +6 -0
  154. data/rice/stl/variant.ipp +242 -0
  155. data/rice/stl/vector.hpp +12 -0
  156. data/rice/stl/vector.ipp +590 -0
  157. data/rice/stl.hpp +11 -3
  158. data/rice/traits/attribute_traits.hpp +26 -0
  159. data/rice/traits/function_traits.hpp +95 -0
  160. data/rice/traits/method_traits.hpp +47 -0
  161. data/rice/traits/rice_traits.hpp +160 -0
  162. data/rice.gemspec +85 -0
  163. data/test/embed_ruby.cpp +7 -1
  164. data/test/extconf.rb +2 -0
  165. data/test/test_Address_Registration_Guard.cpp +5 -0
  166. data/test/test_Array.cpp +18 -4
  167. data/test/test_Attribute.cpp +136 -21
  168. data/test/test_Buffer.cpp +285 -0
  169. data/test/test_Builtin_Object.cpp +5 -0
  170. data/test/test_Callback.cpp +230 -0
  171. data/test/test_Class.cpp +5 -31
  172. data/test/test_Constructor.cpp +69 -6
  173. data/test/test_Data_Object.cpp +97 -38
  174. data/test/test_Data_Type.cpp +470 -65
  175. data/test/test_Director.cpp +17 -8
  176. data/test/test_Enum.cpp +155 -40
  177. data/test/test_Exception.cpp +235 -0
  178. data/test/test_File.cpp +70 -0
  179. data/test/test_From_Ruby.cpp +609 -0
  180. data/test/test_Hash.cpp +5 -0
  181. data/test/test_Identifier.cpp +5 -0
  182. data/test/test_Inheritance.cpp +6 -1
  183. data/test/test_Iterator.cpp +6 -1
  184. data/test/test_Jump_Exception.cpp +23 -0
  185. data/test/test_Keep_Alive.cpp +13 -19
  186. data/test/test_Keep_Alive_No_Wrapper.cpp +5 -1
  187. data/test/test_Memory_Management.cpp +5 -0
  188. data/test/test_Module.cpp +128 -67
  189. data/test/test_Native_Registry.cpp +2 -34
  190. data/test/test_Object.cpp +5 -0
  191. data/test/test_Overloads.cpp +806 -0
  192. data/test/test_Ownership.cpp +160 -54
  193. data/test/test_Proc.cpp +44 -0
  194. data/test/test_Self.cpp +9 -4
  195. data/test/test_Stl_Exception.cpp +109 -0
  196. data/test/test_Stl_Map.cpp +54 -42
  197. data/test/test_Stl_Multimap.cpp +693 -0
  198. data/test/test_Stl_Optional.cpp +5 -0
  199. data/test/test_Stl_Pair.cpp +14 -9
  200. data/test/test_Stl_Reference_Wrapper.cpp +9 -2
  201. data/test/test_Stl_Set.cpp +790 -0
  202. data/test/test_Stl_SharedPtr.cpp +458 -0
  203. data/test/test_Stl_String.cpp +5 -0
  204. data/test/test_Stl_String_View.cpp +5 -0
  205. data/test/test_Stl_Tuple.cpp +116 -0
  206. data/test/test_Stl_Type.cpp +147 -0
  207. data/test/test_Stl_UniquePtr.cpp +202 -0
  208. data/test/test_Stl_Unordered_Map.cpp +43 -38
  209. data/test/test_Stl_Variant.cpp +217 -84
  210. data/test/test_Stl_Vector.cpp +306 -58
  211. data/test/test_String.cpp +5 -0
  212. data/test/test_Struct.cpp +5 -0
  213. data/test/test_Symbol.cpp +5 -0
  214. data/test/test_Template.cpp +192 -0
  215. data/test/test_To_Ruby.cpp +524 -0
  216. data/test/test_Tracking.cpp +1 -0
  217. data/test/test_Type.cpp +171 -0
  218. data/test/test_global_functions.cpp +67 -7
  219. data/test/unittest.cpp +8 -0
  220. metadata +127 -26
  221. data/lib/version.rb +0 -3
  222. data/rice/Address_Registration_Guard_defn.hpp +0 -79
  223. data/rice/Data_Object_defn.hpp +0 -84
  224. data/rice/Data_Type_defn.hpp +0 -190
  225. data/rice/Exception_defn.hpp +0 -68
  226. data/rice/HandlerRegistration.hpp +0 -15
  227. data/rice/detail/ExceptionHandler.hpp +0 -8
  228. data/rice/detail/ExceptionHandler.ipp +0 -28
  229. data/rice/detail/ExceptionHandler_defn.hpp +0 -77
  230. data/rice/detail/Jump_Tag.hpp +0 -21
  231. data/rice/detail/NativeAttribute.hpp +0 -64
  232. data/rice/detail/NativeAttribute.ipp +0 -112
  233. data/rice/detail/from_ruby_defn.hpp +0 -38
  234. data/rice/detail/to_ruby_defn.hpp +0 -48
  235. data/test/test_Jump_Tag.cpp +0 -17
  236. data/test/test_Stl_SmartPointer.cpp +0 -283
  237. data/test/test_To_From_Ruby.cpp +0 -399
@@ -0,0 +1,55 @@
1
+ #ifndef Rice__detail__Native_Callback_Ffi_hpp_
2
+ #define Rice__detail__Native_Callback_Ffi_hpp_
3
+
4
+ #ifdef HAVE_LIBFFI
5
+
6
+ #include <ffi.h>
7
+
8
+ namespace Rice::detail
9
+ {
10
+ template<typename Callback_T>
11
+ class NativeCallbackFFI;
12
+
13
+ template<typename Return_T, typename ...Arg_Ts>
14
+ class NativeCallbackFFI<Return_T(*)(Arg_Ts...)>
15
+ {
16
+ public:
17
+ using Callback_T = Return_T(Arg_Ts...);
18
+ using Tuple_T = std::tuple<Arg_Ts...>;
19
+ static void ffiCallback(ffi_cif* cif, void* ret, void* args[], void* instance);
20
+ static VALUE finalizerCallback(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg);
21
+ static void setMethodInfo(MethodInfo* methodInfo);
22
+
23
+ public:
24
+ NativeCallbackFFI(VALUE proc);
25
+ ~NativeCallbackFFI();
26
+ NativeCallbackFFI(const NativeCallbackFFI&) = delete;
27
+ NativeCallbackFFI(NativeCallbackFFI&&) = delete;
28
+ void operator=(const NativeCallbackFFI&) = delete;
29
+ void operator=(NativeCallbackFFI&&) = delete;
30
+
31
+ Return_T operator()(Arg_Ts...args);
32
+ Callback_T* callback();
33
+
34
+ private:
35
+ template <typename Arg_T>
36
+ static ffi_type* ffiType();
37
+
38
+ template<std::size_t... I>
39
+ static Tuple_T convertArgsToTuple(void* args[], std::index_sequence<I...>& indices);
40
+
41
+ static inline std::array<ffi_type*, sizeof...(Arg_Ts)> args_ = { ffiType<Arg_Ts>()... };
42
+ static inline ffi_cif cif_;
43
+ static inline ffi_closure* closure_ = nullptr;
44
+ static inline Callback_T* callback_ = nullptr;
45
+ static inline std::unique_ptr<MethodInfo> methodInfo_ = std::make_unique<MethodInfo>();
46
+
47
+ template<std::size_t... I>
48
+ Return_T callRuby(std::index_sequence<I...>& indices, Arg_Ts...args);
49
+ private:
50
+ VALUE proc_;
51
+ };
52
+ }
53
+ #endif // HAVE_LIBFFI
54
+
55
+ #endif // Rice__detail__Native_Callback_Ffi_hpp_
@@ -0,0 +1,151 @@
1
+ #ifdef HAVE_LIBFFI
2
+ #include <ffi.h>
3
+
4
+ namespace Rice::detail
5
+ {
6
+ template<typename Return_T, typename ...Arg_Ts>
7
+ template<typename Arg_T>
8
+ ffi_type* NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::ffiType()
9
+ {
10
+ std::map<std::type_index, ffi_type*> nativeToFfiMapping = {
11
+ {std::type_index(typeid(bool)), &ffi_type_uint8},
12
+ {std::type_index(typeid(bool)), &ffi_type_uint8},
13
+ {std::type_index(typeid(char)), &ffi_type_schar},
14
+ {std::type_index(typeid(unsigned char)), &ffi_type_uchar},
15
+ {std::type_index(typeid(signed char)), &ffi_type_schar},
16
+ {std::type_index(typeid(uint8_t)), &ffi_type_uint8},
17
+ {std::type_index(typeid(unsigned short)), &ffi_type_uint8},
18
+ {std::type_index(typeid(int8_t)), &ffi_type_sint8},
19
+ {std::type_index(typeid(short)), &ffi_type_sint8},
20
+ {std::type_index(typeid(uint16_t)), &ffi_type_uint16},
21
+ {std::type_index(typeid(int16_t)), &ffi_type_sint16},
22
+ {std::type_index(typeid(uint32_t)), &ffi_type_uint32},
23
+ {std::type_index(typeid(unsigned int)), &ffi_type_uint32},
24
+ {std::type_index(typeid(signed int)), &ffi_type_uint32},
25
+ {std::type_index(typeid(int32_t)), &ffi_type_sint32},
26
+ {std::type_index(typeid(uint64_t)), &ffi_type_uint64},
27
+ {std::type_index(typeid(unsigned long long)), &ffi_type_uint64},
28
+ {std::type_index(typeid(int64_t)), &ffi_type_sint64},
29
+ {std::type_index(typeid(signed long long)), &ffi_type_sint64},
30
+ {std::type_index(typeid(float)), &ffi_type_float},
31
+ {std::type_index(typeid(double)), &ffi_type_double},
32
+ {std::type_index(typeid(void)), &ffi_type_pointer},
33
+ {std::type_index(typeid(long double)), &ffi_type_longdouble}
34
+ };
35
+
36
+ if (sizeof(long) == 32)
37
+ {
38
+ nativeToFfiMapping[std::type_index(typeid(unsigned long))] = &ffi_type_uint32;
39
+ nativeToFfiMapping[std::type_index(typeid(long))] = &ffi_type_sint32;
40
+ }
41
+ else if (sizeof(long) == 64)
42
+ {
43
+ nativeToFfiMapping[std::type_index(typeid(unsigned long))] = &ffi_type_uint64;
44
+ nativeToFfiMapping[std::type_index(typeid(long))] = &ffi_type_sint64;
45
+ }
46
+
47
+ if (std::is_pointer_v<Arg_T>)
48
+ {
49
+ return &ffi_type_pointer;
50
+ }
51
+ else
52
+ {
53
+ const std::type_index& key = std::type_index(typeid(Arg_T));
54
+ return nativeToFfiMapping[key];
55
+ }
56
+ }
57
+
58
+ template<typename Return_T, typename ...Arg_Ts>
59
+ template<std::size_t... I>
60
+ typename NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::Tuple_T NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::convertArgsToTuple(void* args[], std::index_sequence<I...>& indices)
61
+ {
62
+ /* Loop over each value returned from Ruby and convert it to the appropriate C++ type based
63
+ on the arguments (Arg_Ts) required by the C++ function. Arg_T may have const/volatile while
64
+ the associated From_Ruby<T> template parameter will not. Thus From_Ruby produces non-const values
65
+ which we let the compiler convert to const values as needed. This works except for
66
+ T** -> const T**, see comment in getNativeValue method. */
67
+ return std::forward_as_tuple(*(std::tuple_element_t<I, Tuple_T>*)(args[I])...);
68
+ }
69
+
70
+ template<typename Return_T, typename ...Arg_Ts>
71
+ void NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::ffiCallback(ffi_cif* cif, void* ret, void* args[], void* instance)
72
+ {
73
+ using Self_T = NativeCallbackFFI<Return_T(*)(Arg_Ts...)>;
74
+ Self_T* self = (Self_T*)instance;
75
+
76
+ auto indices = std::make_index_sequence<sizeof...(Arg_Ts)>{};
77
+
78
+ if constexpr (sizeof...(Arg_Ts) == 0)
79
+ {
80
+ *(Return_T*)ret = self->operator()();
81
+ }
82
+ else
83
+ {
84
+ std::tuple<Arg_Ts...> tuple = convertArgsToTuple(args, indices);
85
+ *(Return_T*)ret = std::apply(*self, tuple);
86
+ }
87
+ }
88
+
89
+ template<typename Return_T, typename ...Arg_Ts>
90
+ void NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::setMethodInfo(MethodInfo* methodInfo)
91
+ {
92
+ methodInfo_.reset(methodInfo);
93
+ }
94
+
95
+ template<typename Return_T, typename ...Arg_Ts>
96
+ NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::~NativeCallbackFFI()
97
+ {
98
+ this->proc_ = Qnil;
99
+ }
100
+
101
+ template<typename Return_T, typename ...Arg_Ts>
102
+ VALUE NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::finalizerCallback(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg)
103
+ {
104
+ using NativeCallback_T = NativeCallbackFFI<Return_T(*)(Arg_Ts...)>;
105
+ NativeCallback_T* nativeCallback = (NativeCallback_T*)callback_arg;
106
+ delete nativeCallback;
107
+ return Qnil;
108
+ }
109
+
110
+ template<typename Return_T, typename ...Arg_Ts>
111
+ NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::NativeCallbackFFI(VALUE proc) : proc_(proc)
112
+ {
113
+ // First setup desccription of callback
114
+ if (cif_.bytes == 0)
115
+ {
116
+ ffi_prep_cif(&cif_, FFI_DEFAULT_ABI, sizeof...(Arg_Ts), &ffi_type_pointer, args_.data());
117
+ }
118
+
119
+ // Create FFI closure
120
+ this->closure_ = (ffi_closure *)ffi_closure_alloc(sizeof(ffi_closure) + sizeof(void*), (void**)(&this->callback_));
121
+ ffi_prep_closure_loc(this->closure_, &cif_, ffiCallback, (void*)this, (void*)this->callback_);
122
+ }
123
+
124
+ template<typename Return_T, typename ...Arg_Ts>
125
+ typename NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::Callback_T* NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::callback()
126
+ {
127
+ return (Callback_T*)this->callback_;
128
+ }
129
+
130
+ template<typename Return_T, typename ...Arg_Ts>
131
+ template<std::size_t... I>
132
+ Return_T NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::callRuby(std::index_sequence<I...>& indices, Arg_Ts...args)
133
+ {
134
+ static Identifier id("call");
135
+ std::array<VALUE, sizeof...(Arg_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Arg_Ts>>(methodInfo_->arg(I)).convert(args)... };
136
+ VALUE result = detail::protect(rb_funcallv, this->proc_, id.id(), (int)sizeof...(Arg_Ts), values.data());
137
+ if constexpr (!std::is_void_v<Return_T>)
138
+ {
139
+ static From_Ruby<Return_T> fromRuby(dynamic_cast<Arg*>(&methodInfo_->returnInfo));
140
+ return fromRuby.convert(result);
141
+ }
142
+ }
143
+
144
+ template<typename Return_T, typename ...Arg_Ts>
145
+ Return_T NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::operator()(Arg_Ts...args)
146
+ {
147
+ auto indices = std::make_index_sequence<sizeof...(Arg_Ts)>{};
148
+ return NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::callRuby(indices, args...);
149
+ }
150
+ }
151
+ #endif // HAVE_LIBFFI
@@ -0,0 +1,30 @@
1
+ #ifndef Rice__detail__Native_Callback_Simple_hpp_
2
+ #define Rice__detail__Native_Callback_Simple_hpp_
3
+
4
+ namespace Rice::detail
5
+ {
6
+ template<typename Callback_T>
7
+ class NativeCallbackSimple;
8
+
9
+ template<typename Return_T, typename ...Arg_Ts>
10
+ class NativeCallbackSimple<Return_T(*)(Arg_Ts...)>
11
+ {
12
+ public:
13
+ static Return_T callback(Arg_Ts...args);
14
+ static inline VALUE proc = Qnil;
15
+ static void setMethodInfo(MethodInfo* methodInfo);
16
+
17
+ public:
18
+ NativeCallbackSimple() = delete;
19
+ NativeCallbackSimple(const NativeCallbackSimple&) = delete;
20
+ NativeCallbackSimple(NativeCallbackSimple&&) = delete;
21
+ void operator=(const NativeCallbackSimple&) = delete;
22
+ void operator=(NativeCallbackSimple&&) = delete;
23
+
24
+ private:
25
+ template<std::size_t... I>
26
+ static Return_T callRuby(std::index_sequence<I...>& indices, Arg_Ts...args);
27
+ static inline std::unique_ptr<MethodInfo> methodInfo_ = std::make_unique<MethodInfo>();
28
+ };
29
+ }
30
+ #endif // Rice__detail__Native_Callback_Simple_hpp_
@@ -0,0 +1,29 @@
1
+ namespace Rice::detail
2
+ {
3
+ template<typename Return_T, typename ...Arg_Ts>
4
+ void NativeCallbackSimple<Return_T(*)(Arg_Ts...)>::setMethodInfo(MethodInfo* methodInfo)
5
+ {
6
+ methodInfo_.reset(methodInfo);
7
+ }
8
+
9
+ template<typename Return_T, typename ...Arg_Ts>
10
+ template<std::size_t... I>
11
+ Return_T NativeCallbackSimple<Return_T(*)(Arg_Ts...)>::callRuby(std::index_sequence<I...>& indices, Arg_Ts...args)
12
+ {
13
+ static Identifier id("call");
14
+ std::array<VALUE, sizeof...(Arg_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Arg_Ts>>(methodInfo_->arg(I)).convert(args)... };
15
+ VALUE result = detail::protect(rb_funcallv, proc, id.id(), (int)sizeof...(Arg_Ts), values.data());
16
+ if constexpr (!std::is_void_v<Return_T>)
17
+ {
18
+ static From_Ruby<Return_T> fromRuby(dynamic_cast<Arg*>(&methodInfo_->returnInfo));
19
+ return fromRuby.convert(result);
20
+ }
21
+ }
22
+
23
+ template<typename Return_T, typename ...Arg_Ts>
24
+ Return_T NativeCallbackSimple<Return_T(*)(Arg_Ts...)>::callback(Arg_Ts...args)
25
+ {
26
+ auto indices = std::make_index_sequence<sizeof...(Arg_Ts)>{};
27
+ return NativeCallbackSimple<Return_T(*)(Arg_Ts...)>::callRuby(indices, args...);
28
+ }
29
+ }
@@ -1,13 +1,6 @@
1
1
  #ifndef Rice__detail__Native_Function__hpp_
2
2
  #define Rice__detail__Native_Function__hpp_
3
3
 
4
- #include "ruby.hpp"
5
- #include "ExceptionHandler_defn.hpp"
6
- #include "MethodInfo.hpp"
7
- #include "../traits/function_traits.hpp"
8
- #include "../traits/method_traits.hpp"
9
- #include "from_ruby.hpp"
10
-
11
4
  namespace Rice::detail
12
5
  {
13
6
  //! The NativeFunction class calls C++ functions/methods/lambdas on behalf of Ruby
@@ -43,24 +36,26 @@ namespace Rice::detail
43
36
  */
44
37
 
45
38
  template<typename Class_T, typename Function_T, bool IsMethod>
46
- class NativeFunction
39
+ class NativeFunction: Native
47
40
  {
48
41
  public:
49
42
  using NativeFunction_T = NativeFunction<Class_T, Function_T, IsMethod>;
50
43
 
51
44
  // We remove const to avoid an explosion of To_Ruby specializations and Ruby doesn't
52
45
  // have the concept of constants anyways
53
- using Return_T = remove_cv_recursive_t<typename function_traits<Function_T>::return_type>;
46
+ using Return_T = typename function_traits<Function_T>::return_type;
54
47
  using Receiver_T = typename method_traits<Function_T, IsMethod>::Class_T;
55
48
  using Arg_Ts = typename method_traits<Function_T, IsMethod>::Arg_Ts;
49
+ static constexpr std::size_t arity = method_traits<Function_T, IsMethod>::arity;
56
50
  using From_Ruby_Args_Ts = typename tuple_map<From_Ruby, Arg_Ts>::type;
51
+ using To_Ruby_T = remove_cv_recursive_t<Return_T>;
57
52
 
58
53
  // Register function with Ruby
59
54
  static void define(VALUE klass, std::string method_name, Function_T function, MethodInfo* methodInfo);
60
55
 
61
- // Static member function that Ruby calls
62
- static VALUE call(int argc, VALUE* argv, VALUE self);
63
-
56
+ // Proc entry
57
+ static VALUE procEntry(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg);
58
+ static VALUE finalizerCallback(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg);
64
59
  public:
65
60
  // Disallow creating/copying/moving
66
61
  NativeFunction() = delete;
@@ -69,13 +64,25 @@ namespace Rice::detail
69
64
  void operator=(const NativeFunction_T&) = delete;
70
65
  void operator=(NativeFunction_T&&) = delete;
71
66
 
72
- // Invokes the wrapped function
73
- VALUE operator()(int argc, VALUE* argv, VALUE self);
67
+ Resolved matches(size_t argc, const VALUE* argv, VALUE self) override;
68
+ VALUE operator()(size_t argc, const VALUE* argv, VALUE self) override;
69
+ std::string toString() override;
74
70
 
75
- protected:
71
+ NativeFunction(Function_T function);
76
72
  NativeFunction(VALUE klass, std::string method_name, Function_T function, MethodInfo* methodInfo);
77
73
 
74
+ protected:
75
+
78
76
  private:
77
+ template<int I>
78
+ Convertible matchParameter(std::vector<std::optional<VALUE>>& value);
79
+
80
+ template<std::size_t...I>
81
+ Convertible matchParameters(std::vector<std::optional<VALUE>>& values, std::index_sequence<I...>& indices);
82
+
83
+ template<std::size_t...I>
84
+ std::vector<std::string> argTypeNames(std::ostringstream& stream, std::index_sequence<I...>& indices);
85
+
79
86
  template<typename T, std::size_t I>
80
87
  From_Ruby<T> createFromRuby();
81
88
 
@@ -83,14 +90,18 @@ namespace Rice::detail
83
90
  template<std::size_t...I>
84
91
  From_Ruby_Args_Ts createFromRuby(std::index_sequence<I...>& indices);
85
92
 
86
- To_Ruby<Return_T> createToRuby();
93
+ // Convert C++ value to Ruby
94
+ To_Ruby<To_Ruby_T> createToRuby();
87
95
 
88
96
  // Convert Ruby argv pointer to Ruby values
89
- std::vector<VALUE> getRubyValues(int argc, VALUE* argv);
97
+ std::vector<std::optional<VALUE>> getRubyValues(size_t argc, const VALUE* argv, bool validate);
98
+
99
+ template<typename Arg_T, int I>
100
+ Arg_T getNativeValue(std::vector<std::optional<VALUE>>& values);
90
101
 
91
102
  // Convert Ruby values to C++ values
92
103
  template<typename std::size_t...I>
93
- Arg_Ts getNativeValues(std::vector<VALUE>& values, std::index_sequence<I...>& indices);
104
+ Arg_Ts getNativeValues(std::vector<std::optional<VALUE>>& values, std::index_sequence<I...>& indices);
94
105
 
95
106
  // Figure out what self is
96
107
  Receiver_T getReceiver(VALUE self);
@@ -99,21 +110,20 @@ namespace Rice::detail
99
110
  [[noreturn]] void noWrapper(const VALUE klass, const std::string& wrapper);
100
111
 
101
112
  // Do we need to keep alive any arguments?
102
- void checkKeepAlive(VALUE self, VALUE returnValue, std::vector<VALUE>& rubyValues);
113
+ void checkKeepAlive(VALUE self, VALUE returnValue, std::vector<std::optional<VALUE>>& rubyValues);
103
114
 
104
115
  // Call the underlying C++ function
105
- VALUE invokeNativeFunction(const Arg_Ts& nativeArgs);
106
- VALUE invokeNativeMethod(VALUE self, const Arg_Ts& nativeArgs);
116
+ VALUE invokeNativeFunction(Arg_Ts&& nativeArgs);
117
+ VALUE invokeNativeMethod(VALUE self, Arg_Ts&& nativeArgs);
107
118
 
108
119
  private:
109
120
  VALUE klass_;
110
121
  std::string method_name_;
111
122
  Function_T function_;
112
123
  From_Ruby_Args_Ts fromRubys_;
113
- To_Ruby<Return_T> toRuby_;
124
+ To_Ruby<To_Ruby_T> toRuby_;
114
125
  std::unique_ptr<MethodInfo> methodInfo_;
115
126
  };
116
127
  }
117
- #include "NativeFunction.ipp"
118
128
 
119
129
  #endif // Rice__detail__Native_Function__hpp_