rice 4.6.0 → 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 +41 -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 +5221 -4009
- data/include/rice/stl.hpp +822 -295
- 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 +77 -28
- data/rice/Buffer.ipp +500 -183
- data/rice/Data_Object.ipp +101 -82
- data/rice/Data_Type.hpp +7 -6
- data/rice/Data_Type.ipp +77 -47
- 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 +73 -8
- data/rice/detail/NativeAttributeSet.hpp +4 -0
- data/rice/detail/NativeAttributeSet.ipp +33 -23
- data/rice/detail/NativeCallbackFFI.ipp +3 -2
- data/rice/detail/NativeCallbackSimple.ipp +1 -1
- data/rice/detail/NativeFunction.hpp +11 -49
- data/rice/detail/NativeFunction.ipp +83 -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 +150 -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 +182 -104
- data/rice/stl.hpp +1 -0
- data/rice/traits/attribute_traits.hpp +6 -6
- data/rice/traits/function_traits.hpp +2 -2
- data/rice/traits/method_traits.hpp +5 -16
- data/rice/traits/rice_traits.hpp +36 -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 +244 -10
- data/test/test_Buffer.cpp +344 -13
- 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 +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 +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 -76
- 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,8 +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);
|
|
166
|
+
|
|
167
|
+
template <typename Attribute_T>
|
|
168
|
+
Data_Type<T>& define_attr_internal(VALUE klass, std::string name, Attribute_T attribute, AttrAccess access, Return returnInfo);
|
|
168
169
|
|
|
169
170
|
private:
|
|
170
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,17 +57,28 @@ 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
|
+
{
|
|
65
63
|
instance->set_value(klass);
|
|
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
|
}
|
|
@@ -240,7 +259,7 @@ namespace Rice
|
|
|
240
259
|
return false;
|
|
241
260
|
}
|
|
242
261
|
}
|
|
243
|
-
|
|
262
|
+
|
|
244
263
|
template<typename Base_T>
|
|
245
264
|
inline Class get_superklass()
|
|
246
265
|
{
|
|
@@ -280,7 +299,7 @@ namespace Rice
|
|
|
280
299
|
Class superKlass = get_superklass<Base_T>();
|
|
281
300
|
return define_class_under<T, Base_T>(parent, id, superKlass);
|
|
282
301
|
}
|
|
283
|
-
|
|
302
|
+
|
|
284
303
|
template<typename T, typename Base_T>
|
|
285
304
|
inline Data_Type<T> define_class(char const* name)
|
|
286
305
|
{
|
|
@@ -312,58 +331,69 @@ 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
|
-
|
|
318
|
-
detail::verifyType<typename detail::attribute_traits<Attribute_T>::attr_type>();
|
|
319
|
-
|
|
320
|
-
// Define native attribute getter
|
|
321
|
-
if (access == AttrAccess::ReadWrite || access == AttrAccess::Read)
|
|
322
|
-
detail::NativeAttributeGet<Attribute_T>::define(klass_, name, std::forward<Attribute_T>(attribute));
|
|
323
|
-
|
|
324
|
-
using Attr_T = typename detail::NativeAttributeSet<Attribute_T>::Attr_T;
|
|
325
|
-
if constexpr (!std::is_const_v<Attr_T> &&
|
|
326
|
-
(std::is_fundamental_v<Attr_T> || std::is_assignable_v<Attr_T, Attr_T>))
|
|
327
|
-
{
|
|
328
|
-
// Define native attribute setter
|
|
329
|
-
if (access == AttrAccess::ReadWrite || access == AttrAccess::Write)
|
|
330
|
-
detail::NativeAttributeSet<Attribute_T>::define(klass_, name, std::forward<Attribute_T>(attribute));
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
return *this;
|
|
336
|
+
return this->define_attr_internal<Attribute_T>(this->klass_, name, std::forward<Attribute_T>(attribute), access, returnInfo);
|
|
334
337
|
}
|
|
335
338
|
|
|
336
339
|
template <typename T>
|
|
337
340
|
template <typename Attribute_T>
|
|
338
|
-
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)
|
|
339
342
|
{
|
|
340
|
-
// Make sure the Attribute type has been previously seen by Rice
|
|
341
|
-
detail::verifyType<typename detail::attribute_traits<Attribute_T>::attr_type>();
|
|
342
|
-
|
|
343
|
-
// Define native attribute
|
|
344
343
|
VALUE singleton = detail::protect(rb_singleton_class, this->value());
|
|
344
|
+
return this->define_attr_internal<Attribute_T>(singleton, name, std::forward<Attribute_T>(attribute), access, returnInfo);
|
|
345
|
+
}
|
|
345
346
|
|
|
346
|
-
|
|
347
|
+
template <typename T>
|
|
348
|
+
template <typename Attribute_T>
|
|
349
|
+
inline Data_Type<T>& Data_Type<T>::define_attr_internal(VALUE klass, std::string name, Attribute_T attribute, AttrAccess access, Return returnInfo)
|
|
350
|
+
{
|
|
351
|
+
using Attr_T = typename detail::attribute_traits<Attribute_T>::attr_type;
|
|
352
|
+
|
|
353
|
+
// Define attribute getter
|
|
347
354
|
if (access == AttrAccess::ReadWrite || access == AttrAccess::Read)
|
|
348
|
-
|
|
355
|
+
{
|
|
356
|
+
detail::NativeAttributeGet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute), returnInfo);
|
|
357
|
+
}
|
|
349
358
|
|
|
350
|
-
// Define
|
|
359
|
+
// Define attribute setter
|
|
360
|
+
// Define attribute setter
|
|
351
361
|
if (access == AttrAccess::ReadWrite || access == AttrAccess::Write)
|
|
352
|
-
|
|
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
|
+
|
|
369
|
+
if constexpr (std::is_const_v<Attr_T>)
|
|
370
|
+
{
|
|
371
|
+
throw std::runtime_error("Cannot define attribute writer for a const attribute: " + name);
|
|
372
|
+
}
|
|
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>)
|
|
376
|
+
{
|
|
377
|
+
throw std::runtime_error("Cannot define attribute writer for a non assignable attribute: " + name);
|
|
378
|
+
}
|
|
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>)
|
|
381
|
+
{
|
|
382
|
+
throw std::runtime_error("Cannot define attribute writer for a non copy constructible attribute: " + name);
|
|
383
|
+
}
|
|
384
|
+
else
|
|
385
|
+
{
|
|
386
|
+
detail::NativeAttributeSet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute));
|
|
387
|
+
}
|
|
388
|
+
}
|
|
353
389
|
|
|
354
390
|
return *this;
|
|
355
391
|
}
|
|
356
392
|
|
|
357
393
|
template <typename T>
|
|
358
|
-
template<
|
|
359
|
-
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)
|
|
360
396
|
{
|
|
361
|
-
|
|
362
|
-
using traits = detail::method_traits<Function_T, IsMethod>;
|
|
363
|
-
detail::verifyType<typename traits::Return_T>();
|
|
364
|
-
detail::verifyTypes<typename traits::Arg_Ts>();
|
|
365
|
-
|
|
366
|
-
// Define a NativeFunction to bridge Ruby to C++
|
|
367
|
-
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);
|
|
368
398
|
}
|
|
369
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_
|