rice 4.6.1 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/CMakeLists.txt +0 -4
- data/Rakefile +2 -8
- data/bin/rice-doc.rb +212 -0
- data/bin/rice-rbs.rb +93 -0
- data/include/rice/rice.hpp +4972 -4015
- data/include/rice/stl.hpp +822 -294
- data/lib/rice/doc/cpp_reference.rb +166 -0
- data/lib/rice/doc/doxygen.rb +294 -0
- data/lib/rice/doc/mkdocs.rb +298 -0
- data/lib/rice/doc/rice.rb +29 -0
- data/lib/rice/doc/ruby.rb +37 -0
- data/lib/rice/doc.rb +5 -0
- data/lib/{make_rice_headers.rb → rice/make_rice_headers.rb} +3 -0
- data/lib/rice/native.rb +18 -0
- data/lib/rice/native_registry.rb +21 -0
- data/lib/rice/parameter.rb +7 -0
- data/lib/rice/rbs.rb +104 -0
- data/lib/rice/version.rb +1 -1
- data/lib/rice.rb +4 -0
- data/lib/rubygems/cmake_builder.rb +24 -27
- data/rice/Arg.hpp +4 -4
- data/rice/Arg.ipp +4 -4
- data/rice/Buffer.hpp +32 -28
- data/rice/Buffer.ipp +306 -178
- data/rice/Data_Object.ipp +101 -82
- data/rice/Data_Type.hpp +5 -7
- data/rice/Data_Type.ipp +48 -29
- data/rice/Enum.ipp +15 -21
- data/rice/Function.hpp +17 -0
- data/rice/Function.ipp +13 -0
- data/rice/Pointer.hpp +15 -0
- data/rice/Pointer.ipp +49 -0
- data/rice/Return.hpp +1 -1
- data/rice/Return.ipp +2 -2
- data/rice/api.hpp +30 -0
- data/rice/cpp_api/Array.hpp +2 -2
- data/rice/cpp_api/Array.ipp +50 -5
- data/rice/cpp_api/Class.hpp +0 -5
- data/rice/cpp_api/Class.ipp +19 -0
- data/rice/cpp_api/Hash.ipp +20 -0
- data/rice/cpp_api/Module.hpp +6 -3
- data/rice/cpp_api/Module.ipp +49 -11
- data/rice/cpp_api/Object.ipp +31 -2
- data/rice/cpp_api/String.hpp +1 -2
- data/rice/cpp_api/String.ipp +21 -1
- data/rice/cpp_api/Struct.ipp +5 -0
- data/rice/cpp_api/Symbol.ipp +34 -0
- data/rice/cpp_api/shared_methods.hpp +12 -12
- data/rice/detail/MethodInfo.hpp +4 -2
- data/rice/detail/MethodInfo.ipp +19 -3
- data/rice/detail/ModuleRegistry.hpp +18 -0
- data/rice/detail/ModuleRegistry.ipp +25 -0
- data/rice/detail/Native.hpp +45 -2
- data/rice/detail/Native.ipp +196 -2
- data/rice/detail/NativeAttributeGet.hpp +9 -4
- data/rice/detail/NativeAttributeGet.ipp +65 -11
- data/rice/detail/NativeAttributeSet.hpp +4 -0
- data/rice/detail/NativeAttributeSet.ipp +30 -2
- data/rice/detail/NativeCallbackFFI.ipp +2 -2
- data/rice/detail/NativeCallbackSimple.ipp +1 -1
- data/rice/detail/NativeFunction.hpp +11 -49
- data/rice/detail/NativeFunction.ipp +82 -379
- data/rice/detail/NativeInvoker.hpp +74 -0
- data/rice/detail/NativeInvoker.ipp +197 -0
- data/rice/detail/NativeIterator.hpp +4 -0
- data/rice/detail/NativeIterator.ipp +19 -0
- data/rice/detail/NativeMethod.hpp +97 -0
- data/rice/detail/NativeMethod.ipp +332 -0
- data/rice/detail/NativeProc.hpp +51 -0
- data/rice/detail/NativeProc.ipp +133 -0
- data/rice/detail/NativeRegistry.hpp +8 -0
- data/rice/detail/NativeRegistry.ipp +27 -0
- data/rice/detail/Parameter.hpp +47 -0
- data/rice/detail/Parameter.ipp +105 -0
- data/rice/detail/Proc.ipp +14 -13
- data/rice/detail/Registries.hpp +1 -0
- data/rice/detail/RubyType.hpp +0 -2
- data/rice/detail/RubyType.ipp +15 -33
- data/rice/detail/Type.hpp +44 -8
- data/rice/detail/Type.ipp +151 -49
- data/rice/detail/TypeRegistry.hpp +3 -0
- data/rice/detail/TypeRegistry.ipp +17 -27
- data/rice/detail/Types.ipp +430 -0
- data/rice/detail/Wrapper.hpp +12 -0
- data/rice/detail/Wrapper.ipp +45 -2
- data/rice/detail/from_ruby.ipp +567 -1073
- data/rice/detail/ruby.hpp +1 -0
- data/rice/detail/to_ruby.ipp +4 -635
- data/rice/libc/file.ipp +3 -6
- data/rice/rice.hpp +22 -12
- data/rice/rice_api/Arg.hpp +7 -0
- data/rice/rice_api/Arg.ipp +9 -0
- data/rice/rice_api/ModuleRegistry.hpp +7 -0
- data/rice/rice_api/ModuleRegistry.ipp +10 -0
- data/rice/rice_api/Native.hpp +7 -0
- data/rice/rice_api/Native.ipp +52 -0
- data/rice/rice_api/NativeRegistry.hpp +7 -0
- data/rice/rice_api/NativeRegistry.ipp +21 -0
- data/rice/rice_api/Parameter.hpp +7 -0
- data/rice/rice_api/Parameter.ipp +11 -0
- data/rice/rice_api/Registries.hpp +6 -0
- data/rice/rice_api/Registries.ipp +12 -0
- data/rice/rice_api/TypeRegistry.hpp +7 -0
- data/rice/rice_api/TypeRegistry.ipp +10 -0
- data/rice/stl/complex.ipp +35 -0
- data/rice/stl/exception.ipp +20 -7
- data/rice/stl/filesystem.hpp +6 -0
- data/rice/stl/filesystem.ipp +34 -0
- data/rice/stl/map.ipp +13 -21
- data/rice/stl/monostate.ipp +37 -1
- data/rice/stl/multimap.ipp +17 -24
- data/rice/stl/optional.ipp +47 -2
- data/rice/stl/pair.ipp +23 -58
- data/rice/stl/reference_wrapper.ipp +22 -1
- data/rice/stl/set.ipp +17 -9
- data/rice/stl/shared_ptr.ipp +44 -17
- data/rice/stl/string.ipp +175 -7
- data/rice/stl/string_view.ipp +5 -0
- data/rice/stl/tuple.ipp +38 -9
- data/rice/stl/unique_ptr.ipp +46 -2
- data/rice/stl/unordered_map.ipp +13 -21
- data/rice/stl/variant.ipp +47 -11
- data/rice/stl/vector.ipp +183 -104
- data/rice/stl.hpp +1 -0
- data/rice/traits/function_traits.hpp +2 -2
- data/rice/traits/method_traits.hpp +5 -16
- data/rice/traits/rice_traits.hpp +24 -4
- data/rice.gemspec +11 -22
- data/test/embed_ruby.cpp +0 -3
- data/test/test_Array.cpp +38 -38
- data/test/test_Attribute.cpp +187 -2
- data/test/test_Buffer.cpp +302 -26
- data/test/test_Callback.cpp +2 -3
- data/test/test_Class.cpp +5 -5
- data/test/test_Data_Object.cpp +0 -55
- data/test/test_Data_Type.cpp +19 -30
- data/test/test_Enum.cpp +4 -46
- data/test/test_From_Ruby.cpp +88 -81
- data/test/test_GVL.cpp +109 -0
- data/test/test_Iterator.cpp +1 -1
- data/test/test_Keep_Alive_No_Wrapper.cpp +5 -3
- data/test/test_Module.cpp +8 -9
- data/test/test_Object.cpp +1 -1
- data/test/test_Overloads.cpp +3 -3
- data/test/test_Stl_Map.cpp +8 -8
- data/test/test_Stl_Multimap.cpp +4 -4
- data/test/test_Stl_Pair.cpp +5 -3
- data/test/test_Stl_SharedPtr.cpp +24 -12
- data/test/test_Stl_Tuple.cpp +1 -1
- data/test/test_Stl_UniquePtr.cpp +8 -0
- data/test/test_Stl_Unordered_Map.cpp +9 -9
- data/test/test_Stl_Variant.cpp +9 -3
- data/test/test_Stl_Vector.cpp +118 -13
- data/test/test_To_Ruby.cpp +35 -28
- data/test/test_Type.cpp +256 -53
- data/test/unittest.hpp +35 -0
- metadata +66 -34
- data/rice/Init.hpp +0 -8
- data/rice/Init.ipp +0 -8
- data/rice/detail/RubyFunction.hpp +0 -31
- data/rice/detail/RubyFunction.ipp +0 -77
- data/sample/callbacks/extconf.rb +0 -5
- data/sample/callbacks/sample_callbacks.cpp +0 -35
- data/sample/callbacks/test.rb +0 -28
- data/sample/enum/extconf.rb +0 -5
- data/sample/enum/sample_enum.cpp +0 -40
- data/sample/enum/test.rb +0 -8
- data/sample/inheritance/animals.cpp +0 -82
- data/sample/inheritance/extconf.rb +0 -5
- data/sample/inheritance/test.rb +0 -7
- data/sample/map/extconf.rb +0 -5
- data/sample/map/map.cpp +0 -73
- data/sample/map/test.rb +0 -7
- data/test/ext/t1/Foo.hpp +0 -10
- data/test/ext/t1/extconf.rb +0 -4
- data/test/ext/t1/t1.cpp +0 -13
- data/test/ext/t2/extconf.rb +0 -4
- data/test/ext/t2/t2.cpp +0 -11
- data/test/ruby/test_callbacks_sample.rb +0 -28
- data/test/ruby/test_multiple_extensions.rb +0 -18
- data/test/ruby/test_multiple_extensions_same_class.rb +0 -14
- data/test/ruby/test_multiple_extensions_with_inheritance.rb +0 -20
- /data/test/{test_Stl_Type.cpp → test_Stl_Type_Info.cpp} +0 -0
data/rice/Data_Object.ipp
CHANGED
|
@@ -6,9 +6,18 @@ namespace Rice
|
|
|
6
6
|
template <typename T>
|
|
7
7
|
Exception create_type_exception(VALUE value)
|
|
8
8
|
{
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
if constexpr (std::is_pointer_v<T>)
|
|
10
|
+
{
|
|
11
|
+
return Exception(rb_eTypeError, "Wrong argument type. Expected: %s. Received: %s.",
|
|
12
|
+
detail::protect(rb_class2name, Data_Type<Pointer<std::remove_cv_t<std::remove_pointer_t<T>>>>::klass().value()),
|
|
13
|
+
detail::protect(rb_obj_classname, value));
|
|
14
|
+
}
|
|
15
|
+
else
|
|
16
|
+
{
|
|
17
|
+
return Exception(rb_eTypeError, "Wrong argument type. Expected: %s. Received: %s.",
|
|
18
|
+
detail::protect(rb_class2name, Data_Type<detail::intrinsic_type<T>>::klass().value()),
|
|
19
|
+
detail::protect(rb_obj_classname, value));
|
|
20
|
+
}
|
|
12
21
|
}
|
|
13
22
|
|
|
14
23
|
template<typename T>
|
|
@@ -102,6 +111,12 @@ namespace Rice::detail
|
|
|
102
111
|
"Please include rice/stl.hpp header for STL support");
|
|
103
112
|
|
|
104
113
|
public:
|
|
114
|
+
To_Ruby() = default;
|
|
115
|
+
|
|
116
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
117
|
+
{
|
|
118
|
+
}
|
|
119
|
+
|
|
105
120
|
template<typename U>
|
|
106
121
|
VALUE convert(U& data)
|
|
107
122
|
{
|
|
@@ -123,6 +138,9 @@ namespace Rice::detail
|
|
|
123
138
|
// matched <typename T> thus we have to tell wrap to copy the reference we are sending to it
|
|
124
139
|
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
|
125
140
|
}
|
|
141
|
+
|
|
142
|
+
private:
|
|
143
|
+
Arg* arg_ = nullptr;
|
|
126
144
|
};
|
|
127
145
|
|
|
128
146
|
template <typename T>
|
|
@@ -141,7 +159,7 @@ namespace Rice::detail
|
|
|
141
159
|
public:
|
|
142
160
|
To_Ruby() = default;
|
|
143
161
|
|
|
144
|
-
explicit To_Ruby(
|
|
162
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
145
163
|
{
|
|
146
164
|
}
|
|
147
165
|
|
|
@@ -152,19 +170,45 @@ namespace Rice::detail
|
|
|
152
170
|
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
|
153
171
|
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(data);
|
|
154
172
|
|
|
155
|
-
bool isOwner = (this->
|
|
173
|
+
bool isOwner = (this->arg_ && this->arg_->isOwner());
|
|
156
174
|
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
|
157
175
|
}
|
|
158
176
|
private:
|
|
159
|
-
|
|
177
|
+
Arg* arg_ = nullptr;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
template <typename T, int N>
|
|
181
|
+
class To_Ruby<T[N]>
|
|
182
|
+
{
|
|
183
|
+
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
|
184
|
+
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
|
185
|
+
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
|
186
|
+
!std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
|
|
187
|
+
!std::is_same_v<T, std::vector<T>>,
|
|
188
|
+
"Please include rice/stl.hpp header for STL support");
|
|
189
|
+
|
|
190
|
+
public:
|
|
191
|
+
To_Ruby() = default;
|
|
192
|
+
|
|
193
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
194
|
+
{
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
template<typename U>
|
|
198
|
+
VALUE convert(U data[N])
|
|
199
|
+
{
|
|
200
|
+
Buffer<T> buffer(data, N);
|
|
201
|
+
Data_Object<Buffer<T>> dataObject(std::move(buffer));
|
|
202
|
+
return dataObject.value();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private:
|
|
206
|
+
Arg* arg_ = nullptr;
|
|
160
207
|
};
|
|
161
208
|
|
|
162
209
|
template <typename T>
|
|
163
210
|
class To_Ruby<T*>
|
|
164
211
|
{
|
|
165
|
-
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
|
166
|
-
"Data_Object cannot be used with fundamental types");
|
|
167
|
-
|
|
168
212
|
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
|
169
213
|
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
|
170
214
|
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
|
@@ -175,25 +219,24 @@ namespace Rice::detail
|
|
|
175
219
|
public:
|
|
176
220
|
To_Ruby() = default;
|
|
177
221
|
|
|
178
|
-
explicit To_Ruby(
|
|
222
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
179
223
|
{
|
|
180
224
|
}
|
|
181
225
|
|
|
182
226
|
template<typename U>
|
|
183
227
|
VALUE convert(U* data)
|
|
184
228
|
{
|
|
185
|
-
bool isOwner = this->
|
|
229
|
+
bool isOwner = this->arg_ && this->arg_->isOwner();
|
|
230
|
+
bool isBuffer = this->arg_ && this->arg_->isBuffer();
|
|
186
231
|
|
|
187
232
|
if (data == nullptr)
|
|
188
233
|
{
|
|
189
234
|
return Qnil;
|
|
190
235
|
}
|
|
191
|
-
else if (
|
|
236
|
+
else if (std::is_fundamental_v<std::remove_pointer_t<T>> || isBuffer)
|
|
192
237
|
{
|
|
193
|
-
using
|
|
194
|
-
|
|
195
|
-
buffer.setOwner(isOwner);
|
|
196
|
-
return detail::wrap(Data_Type<Buffer_T>::klass(), Data_Type<Buffer_T>::ruby_data_type(), buffer, true);
|
|
238
|
+
using Pointer_T = Pointer<remove_cv_recursive_t<U>>;
|
|
239
|
+
return detail::wrap(Data_Type<Pointer_T>::klass(), Data_Type<Pointer_T>::ruby_data_type(), data, isOwner);
|
|
197
240
|
}
|
|
198
241
|
else
|
|
199
242
|
{
|
|
@@ -205,15 +248,12 @@ namespace Rice::detail
|
|
|
205
248
|
}
|
|
206
249
|
|
|
207
250
|
private:
|
|
208
|
-
|
|
251
|
+
Arg* arg_ = nullptr;
|
|
209
252
|
};
|
|
210
253
|
|
|
211
254
|
template <typename T>
|
|
212
|
-
|
|
255
|
+
class To_Ruby<T*&>
|
|
213
256
|
{
|
|
214
|
-
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
|
215
|
-
"Data_Object cannot be used with fundamental types");
|
|
216
|
-
|
|
217
257
|
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
|
218
258
|
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
|
219
259
|
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
|
@@ -224,25 +264,29 @@ namespace Rice::detail
|
|
|
224
264
|
public:
|
|
225
265
|
To_Ruby() = default;
|
|
226
266
|
|
|
227
|
-
explicit To_Ruby(
|
|
267
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
228
268
|
{
|
|
229
269
|
}
|
|
230
270
|
|
|
231
271
|
template<typename U>
|
|
232
272
|
VALUE convert(U* data)
|
|
233
273
|
{
|
|
234
|
-
bool isOwner = this->
|
|
235
|
-
|
|
274
|
+
bool isOwner = this->arg_ && this->arg_->isOwner();
|
|
275
|
+
bool isBuffer = this->arg_ && this->arg_->isBuffer();
|
|
276
|
+
|
|
236
277
|
if (data == nullptr)
|
|
237
278
|
{
|
|
238
279
|
return Qnil;
|
|
239
280
|
}
|
|
240
|
-
else if
|
|
281
|
+
else if constexpr (std::is_const_v<U>)
|
|
241
282
|
{
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
283
|
+
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(*data);
|
|
284
|
+
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
|
285
|
+
}
|
|
286
|
+
else if (std::is_fundamental_v<T> || isBuffer)
|
|
287
|
+
{
|
|
288
|
+
using Pointer_T = Pointer<remove_cv_recursive_t<U>>;
|
|
289
|
+
return detail::wrap(Data_Type<Pointer_T>::klass(), Data_Type<Pointer_T>::ruby_data_type(), data, isOwner);
|
|
246
290
|
}
|
|
247
291
|
else
|
|
248
292
|
{
|
|
@@ -254,26 +298,16 @@ namespace Rice::detail
|
|
|
254
298
|
}
|
|
255
299
|
|
|
256
300
|
private:
|
|
257
|
-
|
|
301
|
+
Arg* arg_ = nullptr;
|
|
258
302
|
};
|
|
259
303
|
|
|
260
304
|
template <typename T>
|
|
261
305
|
class To_Ruby<T**>
|
|
262
306
|
{
|
|
263
|
-
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
|
264
|
-
"Data_Object cannot be used with fundamental types");
|
|
265
|
-
|
|
266
|
-
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
|
267
|
-
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
|
268
|
-
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
|
269
|
-
!std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
|
|
270
|
-
!std::is_same_v<T, std::vector<T>>,
|
|
271
|
-
"Please include rice/stl.hpp header for STL support");
|
|
272
|
-
|
|
273
307
|
public:
|
|
274
308
|
To_Ruby() = default;
|
|
275
309
|
|
|
276
|
-
explicit To_Ruby(
|
|
310
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
277
311
|
{
|
|
278
312
|
}
|
|
279
313
|
|
|
@@ -282,11 +316,9 @@ namespace Rice::detail
|
|
|
282
316
|
{
|
|
283
317
|
if (data)
|
|
284
318
|
{
|
|
285
|
-
bool isOwner = this->
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
using Buffer_T = Buffer<intrinsic_type<T>*>;
|
|
289
|
-
return detail::wrap(Data_Type<Buffer_T>::klass(), Data_Type<Buffer_T>::ruby_data_type(), buffer, true);
|
|
319
|
+
bool isOwner = this->arg_ && this->arg_->isOwner();
|
|
320
|
+
using Pointer_T = Pointer<remove_cv_recursive_t<U>*>;
|
|
321
|
+
return detail::wrap(Data_Type<Pointer_T>::klass(), Data_Type<Pointer_T>::ruby_data_type(), data, isOwner);
|
|
290
322
|
}
|
|
291
323
|
else
|
|
292
324
|
{
|
|
@@ -295,7 +327,7 @@ namespace Rice::detail
|
|
|
295
327
|
}
|
|
296
328
|
|
|
297
329
|
private:
|
|
298
|
-
|
|
330
|
+
Arg* arg_ = nullptr;
|
|
299
331
|
};
|
|
300
332
|
|
|
301
333
|
template<typename T>
|
|
@@ -448,13 +480,9 @@ namespace Rice::detail
|
|
|
448
480
|
|
|
449
481
|
// 99% of the time a T* represents a wrapped C++ object that we want to call methods on. However, T*
|
|
450
482
|
// could also be a pointer to an array of T objects, so T[]. OpenCV for example has API calls like this.
|
|
451
|
-
// In that case, the Ruby VALUE will be a Buffer<T> instance
|
|
452
483
|
template<typename T>
|
|
453
484
|
class From_Ruby<T*>
|
|
454
485
|
{
|
|
455
|
-
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
|
456
|
-
"Data_Object cannot be used with fundamental types");
|
|
457
|
-
|
|
458
486
|
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
|
459
487
|
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
|
460
488
|
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
|
@@ -475,22 +503,19 @@ namespace Rice::detail
|
|
|
475
503
|
{
|
|
476
504
|
switch (rb_type(value))
|
|
477
505
|
{
|
|
506
|
+
case RUBY_T_NIL:
|
|
507
|
+
return Convertible::Exact;
|
|
508
|
+
break;
|
|
478
509
|
case RUBY_T_DATA:
|
|
479
|
-
if (
|
|
510
|
+
if (Data_Type<T>::is_descendant(value))
|
|
480
511
|
{
|
|
481
|
-
return
|
|
512
|
+
return Convertible::Exact;
|
|
482
513
|
}
|
|
483
|
-
else
|
|
514
|
+
else if (Data_Type<Pointer<T>>::is_descendant(value))
|
|
484
515
|
{
|
|
485
|
-
return
|
|
516
|
+
return Convertible::Exact;
|
|
486
517
|
}
|
|
487
|
-
|
|
488
|
-
case RUBY_T_NIL:
|
|
489
|
-
return Convertible::Exact;
|
|
490
|
-
break;
|
|
491
|
-
case RUBY_T_ARRAY:
|
|
492
|
-
return Convertible::Exact;
|
|
493
|
-
break;
|
|
518
|
+
[[fallthrough]];
|
|
494
519
|
default:
|
|
495
520
|
return Convertible::None;
|
|
496
521
|
}
|
|
@@ -498,6 +523,8 @@ namespace Rice::detail
|
|
|
498
523
|
|
|
499
524
|
T* convert(VALUE value)
|
|
500
525
|
{
|
|
526
|
+
bool isOwner = this->arg_ && this->arg_->isOwner();
|
|
527
|
+
|
|
501
528
|
switch (rb_type(value))
|
|
502
529
|
{
|
|
503
530
|
case RUBY_T_NIL:
|
|
@@ -507,20 +534,19 @@ namespace Rice::detail
|
|
|
507
534
|
}
|
|
508
535
|
case RUBY_T_DATA:
|
|
509
536
|
{
|
|
510
|
-
if (
|
|
537
|
+
if (Data_Type<T>::is_descendant(value))
|
|
511
538
|
{
|
|
512
|
-
|
|
513
|
-
Buffer_T* buffer = detail::unwrap<Buffer_T>(value, Data_Type<Buffer_T>::ruby_data_type(), this->arg_ && this->arg_->isOwner());
|
|
514
|
-
return buffer->ptr();
|
|
539
|
+
return detail::unwrap<Intrinsic_T>(value, Data_Type<Intrinsic_T>::ruby_data_type(), isOwner);
|
|
515
540
|
}
|
|
516
|
-
else
|
|
541
|
+
else if (Data_Type<Pointer<T>>::is_descendant(value))
|
|
517
542
|
{
|
|
518
|
-
return detail::unwrap<
|
|
543
|
+
return detail::unwrap<T>(value, Data_Type<Pointer<T>>::ruby_data_type(), isOwner);
|
|
519
544
|
}
|
|
545
|
+
[[fallthrough]];
|
|
520
546
|
}
|
|
521
547
|
default:
|
|
522
548
|
{
|
|
523
|
-
throw create_type_exception<
|
|
549
|
+
throw create_type_exception<T*>(value);
|
|
524
550
|
}
|
|
525
551
|
}
|
|
526
552
|
}
|
|
@@ -532,9 +558,6 @@ namespace Rice::detail
|
|
|
532
558
|
template<typename T>
|
|
533
559
|
class From_Ruby<T*&>
|
|
534
560
|
{
|
|
535
|
-
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
|
536
|
-
"Data_Object cannot be used with fundamental types");
|
|
537
|
-
|
|
538
561
|
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
|
539
562
|
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
|
540
563
|
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
|
@@ -582,9 +605,6 @@ namespace Rice::detail
|
|
|
582
605
|
template<typename T>
|
|
583
606
|
class From_Ruby<T**>
|
|
584
607
|
{
|
|
585
|
-
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
|
586
|
-
"Data_Object cannot be used with fundamental types");
|
|
587
|
-
|
|
588
608
|
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
|
589
609
|
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
|
590
610
|
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
|
@@ -605,14 +625,11 @@ namespace Rice::detail
|
|
|
605
625
|
switch (rb_type(value))
|
|
606
626
|
{
|
|
607
627
|
case RUBY_T_DATA:
|
|
608
|
-
return Data_Type<
|
|
628
|
+
return Data_Type<Pointer<T*>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
|
|
609
629
|
break;
|
|
610
630
|
case RUBY_T_NIL:
|
|
611
631
|
return Convertible::Exact;
|
|
612
632
|
break;
|
|
613
|
-
case RUBY_T_ARRAY:
|
|
614
|
-
return Convertible::Exact;
|
|
615
|
-
break;
|
|
616
633
|
default:
|
|
617
634
|
return Convertible::None;
|
|
618
635
|
}
|
|
@@ -620,12 +637,14 @@ namespace Rice::detail
|
|
|
620
637
|
|
|
621
638
|
T** convert(VALUE value)
|
|
622
639
|
{
|
|
640
|
+
bool isOwner = this->arg_ && this->arg_->isOwner();
|
|
641
|
+
|
|
623
642
|
switch (rb_type(value))
|
|
624
643
|
{
|
|
625
644
|
case RUBY_T_DATA:
|
|
626
645
|
{
|
|
627
|
-
|
|
628
|
-
return
|
|
646
|
+
T** result = detail::unwrap<Intrinsic_T*>(value, Data_Type<Pointer<T*>>::ruby_data_type(), isOwner);
|
|
647
|
+
return result;
|
|
629
648
|
break;
|
|
630
649
|
}
|
|
631
650
|
case RUBY_T_NIL:
|
|
@@ -635,7 +654,7 @@ namespace Rice::detail
|
|
|
635
654
|
}
|
|
636
655
|
default:
|
|
637
656
|
{
|
|
638
|
-
throw create_type_exception<
|
|
657
|
+
throw create_type_exception<T**>(value);
|
|
639
658
|
}
|
|
640
659
|
}
|
|
641
660
|
}
|
data/rice/Data_Type.hpp
CHANGED
|
@@ -12,8 +12,6 @@ namespace Rice
|
|
|
12
12
|
template<typename T>
|
|
13
13
|
class Data_Type : public Class
|
|
14
14
|
{
|
|
15
|
-
static_assert(std::is_same_v<detail::intrinsic_type<T>, T>);
|
|
16
|
-
|
|
17
15
|
public:
|
|
18
16
|
using type = T;
|
|
19
17
|
|
|
@@ -137,10 +135,10 @@ namespace Rice
|
|
|
137
135
|
Data_Type<T>& define_iterator(Iterator_Func_T begin, Iterator_Func_T end, std::string name = "each");
|
|
138
136
|
|
|
139
137
|
template <typename Attribute_T>
|
|
140
|
-
Data_Type<T>& define_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite);
|
|
138
|
+
Data_Type<T>& define_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite, Return returnInfo = Return());
|
|
141
139
|
|
|
142
140
|
template <typename Attribute_T>
|
|
143
|
-
Data_Type<T>& define_singleton_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite);
|
|
141
|
+
Data_Type<T>& define_singleton_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite, Return returnInfo = Return());
|
|
144
142
|
|
|
145
143
|
#include "cpp_api/shared_methods.hpp"
|
|
146
144
|
protected:
|
|
@@ -163,11 +161,11 @@ namespace Rice
|
|
|
163
161
|
template<typename T_, typename Base_T>
|
|
164
162
|
friend Rice::Data_Type<T_> define_class(char const * name);
|
|
165
163
|
|
|
166
|
-
template<
|
|
167
|
-
void
|
|
164
|
+
template<typename Method_T>
|
|
165
|
+
void wrap_native_method(VALUE klass, std::string name, Method_T&& function, MethodInfo* methodInfo);
|
|
168
166
|
|
|
169
167
|
template <typename Attribute_T>
|
|
170
|
-
Data_Type<T>& define_attr_internal(VALUE klass, std::string name, Attribute_T attribute, AttrAccess access);
|
|
168
|
+
Data_Type<T>& define_attr_internal(VALUE klass, std::string name, Attribute_T attribute, AttrAccess access, Return returnInfo);
|
|
171
169
|
|
|
172
170
|
private:
|
|
173
171
|
template<typename T_>
|
data/rice/Data_Type.ipp
CHANGED
|
@@ -37,7 +37,8 @@ namespace Rice
|
|
|
37
37
|
{
|
|
38
38
|
if (is_bound())
|
|
39
39
|
{
|
|
40
|
-
|
|
40
|
+
detail::TypeMapper<T> typeMapper;
|
|
41
|
+
std::string message = "Type " + typeMapper.name() + " is already bound to a different type";
|
|
41
42
|
throw std::runtime_error(message.c_str());
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -56,9 +57,6 @@ namespace Rice
|
|
|
56
57
|
rb_data_type_->parent = Data_Type<Base_T>::ruby_data_type();
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
// Now register with the type registry
|
|
60
|
-
detail::Registries::instance.types.add<T>(klass_, rb_data_type_);
|
|
61
|
-
|
|
62
60
|
auto instances = unbound_instances();
|
|
63
61
|
for (auto instance: instances)
|
|
64
62
|
{
|
|
@@ -66,7 +64,21 @@ namespace Rice
|
|
|
66
64
|
}
|
|
67
65
|
instances.clear();
|
|
68
66
|
|
|
69
|
-
|
|
67
|
+
// Register with the type registry
|
|
68
|
+
detail::Registries::instance.types.add<T>(klass_, rb_data_type_);
|
|
69
|
+
|
|
70
|
+
// Add a method to get the source C++ class name from Ruby
|
|
71
|
+
Data_Type<T> dataType;
|
|
72
|
+
dataType.define_singleton_method("cpp_class", [](VALUE klass) -> VALUE
|
|
73
|
+
{
|
|
74
|
+
detail::TypeMapper<T> typeMapper;
|
|
75
|
+
std::string cppClassName = typeMapper.simplifiedName();
|
|
76
|
+
Return returnInfo;
|
|
77
|
+
returnInfo.takeOwnership();
|
|
78
|
+
return detail::To_Ruby<char*>(&returnInfo).convert(cppClassName.c_str());
|
|
79
|
+
}, Arg("klass").setValue(), Return().setValue());
|
|
80
|
+
|
|
81
|
+
return dataType;
|
|
70
82
|
}
|
|
71
83
|
|
|
72
84
|
template<typename T>
|
|
@@ -206,8 +218,14 @@ namespace Rice
|
|
|
206
218
|
template<typename T>
|
|
207
219
|
inline bool Data_Type<T>::is_descendant(VALUE value)
|
|
208
220
|
{
|
|
209
|
-
|
|
210
|
-
|
|
221
|
+
if (is_bound())
|
|
222
|
+
{
|
|
223
|
+
return detail::protect(rb_obj_is_kind_of, value, klass_) == Qtrue;
|
|
224
|
+
}
|
|
225
|
+
else
|
|
226
|
+
{
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
211
229
|
}
|
|
212
230
|
|
|
213
231
|
template<typename T>
|
|
@@ -215,7 +233,8 @@ namespace Rice
|
|
|
215
233
|
{
|
|
216
234
|
if (!is_bound())
|
|
217
235
|
{
|
|
218
|
-
|
|
236
|
+
detail::TypeMapper<T> typeMapper;
|
|
237
|
+
std::string message = "Type is not defined with Rice: " + typeMapper.name();
|
|
219
238
|
throw std::invalid_argument(message.c_str());
|
|
220
239
|
}
|
|
221
240
|
}
|
|
@@ -312,52 +331,58 @@ namespace Rice
|
|
|
312
331
|
|
|
313
332
|
template <typename T>
|
|
314
333
|
template <typename Attribute_T>
|
|
315
|
-
inline Data_Type<T>& Data_Type<T>::define_attr(std::string name, Attribute_T attribute, AttrAccess access)
|
|
334
|
+
inline Data_Type<T>& Data_Type<T>::define_attr(std::string name, Attribute_T attribute, AttrAccess access, Return returnInfo)
|
|
316
335
|
{
|
|
317
|
-
return this->define_attr_internal<Attribute_T>(this->klass_, name, std::forward<Attribute_T>(attribute), access);
|
|
336
|
+
return this->define_attr_internal<Attribute_T>(this->klass_, name, std::forward<Attribute_T>(attribute), access, returnInfo);
|
|
318
337
|
}
|
|
319
338
|
|
|
320
339
|
template <typename T>
|
|
321
340
|
template <typename Attribute_T>
|
|
322
|
-
inline Data_Type<T>& Data_Type<T>::define_singleton_attr(std::string name, Attribute_T attribute, AttrAccess access)
|
|
341
|
+
inline Data_Type<T>& Data_Type<T>::define_singleton_attr(std::string name, Attribute_T attribute, AttrAccess access, Return returnInfo)
|
|
323
342
|
{
|
|
324
343
|
VALUE singleton = detail::protect(rb_singleton_class, this->value());
|
|
325
|
-
return this->define_attr_internal<Attribute_T>(singleton, name, std::forward<Attribute_T>(attribute), access);
|
|
344
|
+
return this->define_attr_internal<Attribute_T>(singleton, name, std::forward<Attribute_T>(attribute), access, returnInfo);
|
|
326
345
|
}
|
|
327
346
|
|
|
328
347
|
template <typename T>
|
|
329
348
|
template <typename Attribute_T>
|
|
330
|
-
inline Data_Type<T>& Data_Type<T>::define_attr_internal(VALUE klass, std::string name, Attribute_T attribute, AttrAccess access)
|
|
349
|
+
inline Data_Type<T>& Data_Type<T>::define_attr_internal(VALUE klass, std::string name, Attribute_T attribute, AttrAccess access, Return returnInfo)
|
|
331
350
|
{
|
|
332
351
|
using Attr_T = typename detail::attribute_traits<Attribute_T>::attr_type;
|
|
333
352
|
|
|
334
|
-
// Make sure the Attribute type has been previously seen by Rice
|
|
335
|
-
detail::verifyType<Attr_T>();
|
|
336
|
-
|
|
337
353
|
// Define attribute getter
|
|
338
354
|
if (access == AttrAccess::ReadWrite || access == AttrAccess::Read)
|
|
339
355
|
{
|
|
340
|
-
detail::NativeAttributeGet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute));
|
|
356
|
+
detail::NativeAttributeGet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute), returnInfo);
|
|
341
357
|
}
|
|
342
358
|
|
|
359
|
+
// Define attribute setter
|
|
343
360
|
// Define attribute setter
|
|
344
361
|
if (access == AttrAccess::ReadWrite || access == AttrAccess::Write)
|
|
345
362
|
{
|
|
363
|
+
// This seems super hacky - must be a better way?
|
|
364
|
+
constexpr bool checkWriteAccess = !std::is_reference_v<Attr_T> &&
|
|
365
|
+
!std::is_pointer_v<Attr_T> &&
|
|
366
|
+
!std::is_fundamental_v<Attr_T> &&
|
|
367
|
+
!std::is_enum_v<Attr_T>;
|
|
368
|
+
|
|
346
369
|
if constexpr (std::is_const_v<Attr_T>)
|
|
347
370
|
{
|
|
348
371
|
throw std::runtime_error("Cannot define attribute writer for a const attribute: " + name);
|
|
349
372
|
}
|
|
350
|
-
|
|
373
|
+
// Attributes are set using assignment operator like this:
|
|
374
|
+
// myInstance.attribute = newvalue
|
|
375
|
+
else if constexpr (checkWriteAccess && !std::is_assignable_v<Attr_T, Attr_T>)
|
|
351
376
|
{
|
|
352
377
|
throw std::runtime_error("Cannot define attribute writer for a non assignable attribute: " + name);
|
|
353
378
|
}
|
|
354
|
-
|
|
379
|
+
// From_Ruby returns a copy of the value for non-reference and non-pointers, thus needs to be copy constructable
|
|
380
|
+
else if constexpr (checkWriteAccess && !std::is_copy_constructible_v<Attr_T>)
|
|
355
381
|
{
|
|
356
382
|
throw std::runtime_error("Cannot define attribute writer for a non copy constructible attribute: " + name);
|
|
357
383
|
}
|
|
358
384
|
else
|
|
359
385
|
{
|
|
360
|
-
// Define native attribute setter
|
|
361
386
|
detail::NativeAttributeSet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute));
|
|
362
387
|
}
|
|
363
388
|
}
|
|
@@ -366,15 +391,9 @@ namespace Rice
|
|
|
366
391
|
}
|
|
367
392
|
|
|
368
393
|
template <typename T>
|
|
369
|
-
template<
|
|
370
|
-
inline void Data_Type<T>::
|
|
394
|
+
template<typename Method_T>
|
|
395
|
+
inline void Data_Type<T>::wrap_native_method(VALUE klass, std::string name, Method_T&& method, MethodInfo* methodInfo)
|
|
371
396
|
{
|
|
372
|
-
|
|
373
|
-
using traits = detail::method_traits<Function_T, IsMethod>;
|
|
374
|
-
detail::verifyType<typename traits::Return_T>();
|
|
375
|
-
detail::verifyTypes<typename traits::Arg_Ts>();
|
|
376
|
-
|
|
377
|
-
// Define a NativeFunction to bridge Ruby to C++
|
|
378
|
-
detail::NativeFunction<T, Function_T, IsMethod>::define(klass, name, std::forward<Function_T>(function), methodInfo);
|
|
397
|
+
Module::wrap_native_method<T, Method_T>(klass, name, std::forward<Method_T>(method), methodInfo);
|
|
379
398
|
}
|
|
380
399
|
}
|
data/rice/Enum.ipp
CHANGED
|
@@ -49,8 +49,8 @@ namespace Rice
|
|
|
49
49
|
Enum_T otherEnum = (Enum_T)other;
|
|
50
50
|
|
|
51
51
|
Array result;
|
|
52
|
-
result.push(self);
|
|
53
|
-
result.push(otherEnum);
|
|
52
|
+
result.push(self, false);
|
|
53
|
+
result.push(otherEnum, true);
|
|
54
54
|
return result;
|
|
55
55
|
})
|
|
56
56
|
.define_method("inspect", [](Enum_T& self)
|
|
@@ -95,25 +95,19 @@ namespace Rice
|
|
|
95
95
|
}
|
|
96
96
|
});
|
|
97
97
|
|
|
98
|
-
// Add
|
|
99
|
-
klass.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
VALUE value = detail::To_Ruby<Enum_T>().convert(enumValue);
|
|
112
|
-
detail::protect(rb_yield, value);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return ruby_klass;
|
|
116
|
-
}, Return().setValue());
|
|
98
|
+
// Add ability to get enum values
|
|
99
|
+
klass.define_singleton_method("values", [](VALUE ruby_klass) -> VALUE
|
|
100
|
+
{
|
|
101
|
+
Array result;
|
|
102
|
+
|
|
103
|
+
for (auto& pair : valuesToNames_)
|
|
104
|
+
{
|
|
105
|
+
Object enumValue = Class(ruby_klass).const_get(pair.second);
|
|
106
|
+
result.push(enumValue, false);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return result;
|
|
110
|
+
}, Return().setValue());
|
|
117
111
|
|
|
118
112
|
// Add bitwise operators
|
|
119
113
|
klass.define_method("&", [](Enum_T& self, Enum_T& other) -> Underlying_T
|
data/rice/Function.hpp
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#ifndef Rice__Function__hpp_
|
|
2
|
+
#define Rice__Function__hpp_
|
|
3
|
+
|
|
4
|
+
namespace Rice
|
|
5
|
+
{
|
|
6
|
+
class Function
|
|
7
|
+
{
|
|
8
|
+
public:
|
|
9
|
+
Function& setNoGvl();
|
|
10
|
+
bool isNoGvl() const;
|
|
11
|
+
|
|
12
|
+
private:
|
|
13
|
+
bool isNoGvl_ = false;
|
|
14
|
+
};
|
|
15
|
+
} // Rice
|
|
16
|
+
|
|
17
|
+
#endif // Rice__Function__hpp_
|
data/rice/Function.ipp
ADDED
data/rice/Pointer.hpp
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#ifndef Rice__Pointer__hpp_
|
|
2
|
+
#define Rice__Pointer__hpp_
|
|
3
|
+
|
|
4
|
+
namespace Rice
|
|
5
|
+
{
|
|
6
|
+
template<typename T>
|
|
7
|
+
class Pointer
|
|
8
|
+
{
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
template<typename T>
|
|
12
|
+
Data_Type<Pointer<T>> define_pointer(std::string klassName = "");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#endif // Rice__Pointer__hpp_
|