rice 4.6.1 → 4.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +38 -0
- data/CMakeLists.txt +0 -4
- data/Rakefile +2 -8
- data/bin/rice-doc.rb +211 -0
- data/bin/rice-rbs.rb +92 -0
- data/include/rice/rice.hpp +4694 -3704
- data/include/rice/stl.hpp +840 -294
- data/lib/rice/doc/cpp_reference.rb +166 -0
- data/lib/rice/doc/doxygen.rb +294 -0
- data/lib/rice/doc/mkdocs.rb +298 -0
- data/lib/rice/doc/rice.rb +29 -0
- data/lib/rice/doc/ruby.rb +37 -0
- data/lib/rice/doc.rb +5 -0
- data/lib/{make_rice_headers.rb → rice/make_rice_headers.rb} +3 -0
- data/lib/rice/native.rb +18 -0
- data/lib/rice/native_registry.rb +21 -0
- data/lib/rice/parameter.rb +7 -0
- data/lib/rice/rbs.rb +104 -0
- data/lib/rice/version.rb +1 -1
- data/lib/rice.rb +4 -0
- data/lib/rubygems/cmake_builder.rb +24 -27
- data/rice/Arg.hpp +4 -4
- data/rice/Arg.ipp +4 -4
- data/rice/Buffer.hpp +32 -28
- data/rice/Buffer.ipp +306 -178
- data/rice/Data_Object.ipp +136 -88
- data/rice/Data_Type.hpp +5 -7
- data/rice/Data_Type.ipp +48 -29
- data/rice/Enum.ipp +15 -21
- data/rice/Function.hpp +17 -0
- data/rice/Function.ipp +13 -0
- data/rice/Pointer.hpp +15 -0
- data/rice/Pointer.ipp +49 -0
- data/rice/Return.hpp +1 -1
- data/rice/Return.ipp +2 -2
- data/rice/api.hpp +30 -0
- data/rice/cpp_api/Array.hpp +4 -4
- data/rice/cpp_api/Array.ipp +50 -5
- data/rice/cpp_api/Class.hpp +0 -5
- data/rice/cpp_api/Class.ipp +19 -0
- data/rice/cpp_api/Hash.ipp +20 -0
- data/rice/cpp_api/Module.hpp +6 -3
- data/rice/cpp_api/Module.ipp +49 -11
- data/rice/cpp_api/Object.ipp +31 -2
- data/rice/cpp_api/String.hpp +1 -2
- data/rice/cpp_api/String.ipp +21 -1
- data/rice/cpp_api/Struct.ipp +5 -0
- data/rice/cpp_api/Symbol.ipp +43 -0
- data/rice/cpp_api/shared_methods.hpp +12 -12
- data/rice/detail/MethodInfo.hpp +4 -2
- data/rice/detail/MethodInfo.ipp +19 -3
- data/rice/detail/ModuleRegistry.hpp +18 -0
- data/rice/detail/ModuleRegistry.ipp +25 -0
- data/rice/detail/Native.hpp +45 -2
- data/rice/detail/Native.ipp +196 -6
- data/rice/detail/NativeAttributeGet.hpp +9 -4
- data/rice/detail/NativeAttributeGet.ipp +65 -11
- data/rice/detail/NativeAttributeSet.hpp +4 -0
- data/rice/detail/NativeAttributeSet.ipp +30 -2
- data/rice/detail/NativeCallbackFFI.ipp +2 -2
- data/rice/detail/NativeCallbackSimple.ipp +1 -1
- data/rice/detail/NativeFunction.hpp +11 -49
- data/rice/detail/NativeFunction.ipp +82 -379
- data/rice/detail/NativeInvoker.hpp +74 -0
- data/rice/detail/NativeInvoker.ipp +197 -0
- data/rice/detail/NativeIterator.hpp +4 -0
- data/rice/detail/NativeIterator.ipp +19 -0
- data/rice/detail/NativeMethod.hpp +97 -0
- data/rice/detail/NativeMethod.ipp +332 -0
- data/rice/detail/NativeProc.hpp +51 -0
- data/rice/detail/NativeProc.ipp +133 -0
- data/rice/detail/NativeRegistry.hpp +8 -0
- data/rice/detail/NativeRegistry.ipp +26 -0
- data/rice/detail/Parameter.hpp +47 -0
- data/rice/detail/Parameter.ipp +105 -0
- data/rice/detail/Proc.ipp +14 -13
- data/rice/detail/Registries.hpp +1 -0
- data/rice/detail/RubyType.hpp +0 -2
- data/rice/detail/RubyType.ipp +15 -33
- data/rice/detail/Type.hpp +44 -8
- data/rice/detail/Type.ipp +151 -49
- data/rice/detail/TypeRegistry.hpp +3 -0
- data/rice/detail/TypeRegistry.ipp +17 -27
- data/rice/detail/Types.ipp +430 -0
- data/rice/detail/Wrapper.hpp +12 -0
- data/rice/detail/Wrapper.ipp +45 -2
- data/rice/detail/from_ruby.ipp +567 -1073
- data/rice/detail/ruby.hpp +1 -0
- data/rice/detail/to_ruby.ipp +4 -635
- data/rice/libc/file.ipp +3 -6
- data/rice/rice.hpp +22 -12
- data/rice/rice_api/Arg.hpp +7 -0
- data/rice/rice_api/Arg.ipp +9 -0
- data/rice/rice_api/ModuleRegistry.hpp +7 -0
- data/rice/rice_api/ModuleRegistry.ipp +10 -0
- data/rice/rice_api/Native.hpp +7 -0
- data/rice/rice_api/Native.ipp +52 -0
- data/rice/rice_api/NativeRegistry.hpp +7 -0
- data/rice/rice_api/NativeRegistry.ipp +21 -0
- data/rice/rice_api/Parameter.hpp +7 -0
- data/rice/rice_api/Parameter.ipp +11 -0
- data/rice/rice_api/Registries.hpp +6 -0
- data/rice/rice_api/Registries.ipp +12 -0
- data/rice/rice_api/TypeRegistry.hpp +7 -0
- data/rice/rice_api/TypeRegistry.ipp +10 -0
- data/rice/stl/complex.ipp +35 -0
- data/rice/stl/exception.ipp +20 -7
- data/rice/stl/filesystem.hpp +6 -0
- data/rice/stl/filesystem.ipp +34 -0
- data/rice/stl/map.ipp +13 -21
- data/rice/stl/monostate.ipp +37 -1
- data/rice/stl/multimap.ipp +17 -24
- data/rice/stl/optional.ipp +47 -2
- data/rice/stl/pair.ipp +23 -58
- data/rice/stl/reference_wrapper.ipp +22 -1
- data/rice/stl/set.ipp +17 -9
- data/rice/stl/shared_ptr.ipp +44 -17
- data/rice/stl/string.ipp +175 -7
- data/rice/stl/string_view.ipp +23 -0
- data/rice/stl/tuple.ipp +38 -9
- data/rice/stl/unique_ptr.ipp +46 -2
- data/rice/stl/unordered_map.ipp +13 -21
- data/rice/stl/variant.ipp +47 -11
- data/rice/stl/vector.ipp +183 -104
- data/rice/stl.hpp +1 -0
- data/rice/traits/function_traits.hpp +2 -2
- data/rice/traits/method_traits.hpp +5 -16
- data/rice/traits/rice_traits.hpp +24 -4
- data/rice.gemspec +10 -22
- data/test/embed_ruby.cpp +0 -3
- data/test/test_Array.cpp +38 -38
- data/test/test_Attribute.cpp +187 -2
- data/test/test_Buffer.cpp +302 -26
- data/test/test_Callback.cpp +2 -3
- data/test/test_Class.cpp +5 -5
- data/test/test_Data_Object.cpp +1 -56
- data/test/test_Data_Type.cpp +20 -30
- data/test/test_Enum.cpp +4 -46
- data/test/test_From_Ruby.cpp +89 -82
- data/test/test_GVL.cpp +109 -0
- data/test/test_Iterator.cpp +1 -1
- data/test/test_Keep_Alive_No_Wrapper.cpp +5 -3
- data/test/test_Module.cpp +8 -9
- data/test/test_Object.cpp +1 -1
- data/test/test_Overloads.cpp +58 -10
- data/test/test_Stl_Map.cpp +8 -8
- data/test/test_Stl_Multimap.cpp +4 -4
- data/test/test_Stl_Pair.cpp +5 -3
- data/test/test_Stl_SharedPtr.cpp +24 -12
- data/test/test_Stl_String_View.cpp +10 -0
- data/test/test_Stl_Tuple.cpp +1 -1
- data/test/test_Stl_UniquePtr.cpp +8 -0
- data/test/test_Stl_Unordered_Map.cpp +9 -9
- data/test/test_Stl_Variant.cpp +9 -3
- data/test/test_Stl_Vector.cpp +118 -13
- data/test/test_Symbol.cpp +12 -0
- data/test/test_To_Ruby.cpp +35 -28
- data/test/test_Type.cpp +256 -53
- data/test/unittest.hpp +35 -0
- metadata +52 -34
- data/rice/Init.hpp +0 -8
- data/rice/Init.ipp +0 -8
- data/rice/detail/RubyFunction.hpp +0 -31
- data/rice/detail/RubyFunction.ipp +0 -77
- data/sample/callbacks/extconf.rb +0 -5
- data/sample/callbacks/sample_callbacks.cpp +0 -35
- data/sample/callbacks/test.rb +0 -28
- data/sample/enum/extconf.rb +0 -5
- data/sample/enum/sample_enum.cpp +0 -40
- data/sample/enum/test.rb +0 -8
- data/sample/inheritance/animals.cpp +0 -82
- data/sample/inheritance/extconf.rb +0 -5
- data/sample/inheritance/test.rb +0 -7
- data/sample/map/extconf.rb +0 -5
- data/sample/map/map.cpp +0 -73
- data/sample/map/test.rb +0 -7
- data/test/ext/t1/Foo.hpp +0 -10
- data/test/ext/t1/extconf.rb +0 -4
- data/test/ext/t1/t1.cpp +0 -13
- data/test/ext/t2/extconf.rb +0 -4
- data/test/ext/t2/t2.cpp +0 -11
- data/test/ruby/test_callbacks_sample.rb +0 -28
- data/test/ruby/test_multiple_extensions.rb +0 -18
- data/test/ruby/test_multiple_extensions_same_class.rb +0 -14
- data/test/ruby/test_multiple_extensions_with_inheritance.rb +0 -20
- /data/test/{test_Stl_Type.cpp → test_Stl_Type_Info.cpp} +0 -0
data/rice/Data_Object.ipp
CHANGED
|
@@ -6,9 +6,19 @@ namespace Rice
|
|
|
6
6
|
template <typename T>
|
|
7
7
|
Exception create_type_exception(VALUE value)
|
|
8
8
|
{
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
if (Data_Type<T>::is_bound())
|
|
10
|
+
{
|
|
11
|
+
return Exception(rb_eTypeError, "Wrong argument type. Expected %s. Received %s.",
|
|
12
|
+
detail::protect(rb_class2name, Data_Type<T>::klass().value()),
|
|
13
|
+
detail::protect(rb_obj_classname, value));
|
|
14
|
+
}
|
|
15
|
+
else
|
|
16
|
+
{
|
|
17
|
+
detail::TypeMapper<T> typeMapper;
|
|
18
|
+
return Exception(rb_eTypeError, "Wrong argument type. Expected %s. Received %s.",
|
|
19
|
+
typeMapper.simplifiedName().c_str(),
|
|
20
|
+
detail::protect(rb_obj_classname, value));
|
|
21
|
+
}
|
|
12
22
|
}
|
|
13
23
|
|
|
14
24
|
template<typename T>
|
|
@@ -102,6 +112,12 @@ namespace Rice::detail
|
|
|
102
112
|
"Please include rice/stl.hpp header for STL support");
|
|
103
113
|
|
|
104
114
|
public:
|
|
115
|
+
To_Ruby() = default;
|
|
116
|
+
|
|
117
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
118
|
+
{
|
|
119
|
+
}
|
|
120
|
+
|
|
105
121
|
template<typename U>
|
|
106
122
|
VALUE convert(U& data)
|
|
107
123
|
{
|
|
@@ -123,6 +139,9 @@ namespace Rice::detail
|
|
|
123
139
|
// matched <typename T> thus we have to tell wrap to copy the reference we are sending to it
|
|
124
140
|
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
|
125
141
|
}
|
|
142
|
+
|
|
143
|
+
private:
|
|
144
|
+
Arg* arg_ = nullptr;
|
|
126
145
|
};
|
|
127
146
|
|
|
128
147
|
template <typename T>
|
|
@@ -141,7 +160,7 @@ namespace Rice::detail
|
|
|
141
160
|
public:
|
|
142
161
|
To_Ruby() = default;
|
|
143
162
|
|
|
144
|
-
explicit To_Ruby(
|
|
163
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
145
164
|
{
|
|
146
165
|
}
|
|
147
166
|
|
|
@@ -152,19 +171,45 @@ namespace Rice::detail
|
|
|
152
171
|
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
|
153
172
|
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(data);
|
|
154
173
|
|
|
155
|
-
bool isOwner = (this->
|
|
174
|
+
bool isOwner = (this->arg_ && this->arg_->isOwner());
|
|
156
175
|
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
|
157
176
|
}
|
|
158
177
|
private:
|
|
159
|
-
|
|
178
|
+
Arg* arg_ = nullptr;
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
template <typename T, int N>
|
|
182
|
+
class To_Ruby<T[N]>
|
|
183
|
+
{
|
|
184
|
+
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
|
185
|
+
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
|
186
|
+
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
|
187
|
+
!std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
|
|
188
|
+
!std::is_same_v<T, std::vector<T>>,
|
|
189
|
+
"Please include rice/stl.hpp header for STL support");
|
|
190
|
+
|
|
191
|
+
public:
|
|
192
|
+
To_Ruby() = default;
|
|
193
|
+
|
|
194
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
195
|
+
{
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
template<typename U>
|
|
199
|
+
VALUE convert(U data[N])
|
|
200
|
+
{
|
|
201
|
+
Buffer<T> buffer(data, N);
|
|
202
|
+
Data_Object<Buffer<T>> dataObject(std::move(buffer));
|
|
203
|
+
return dataObject.value();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
private:
|
|
207
|
+
Arg* arg_ = nullptr;
|
|
160
208
|
};
|
|
161
209
|
|
|
162
210
|
template <typename T>
|
|
163
211
|
class To_Ruby<T*>
|
|
164
212
|
{
|
|
165
|
-
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
|
166
|
-
"Data_Object cannot be used with fundamental types");
|
|
167
|
-
|
|
168
213
|
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
|
169
214
|
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
|
170
215
|
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
|
@@ -175,25 +220,24 @@ namespace Rice::detail
|
|
|
175
220
|
public:
|
|
176
221
|
To_Ruby() = default;
|
|
177
222
|
|
|
178
|
-
explicit To_Ruby(
|
|
223
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
179
224
|
{
|
|
180
225
|
}
|
|
181
226
|
|
|
182
227
|
template<typename U>
|
|
183
228
|
VALUE convert(U* data)
|
|
184
229
|
{
|
|
185
|
-
bool isOwner = this->
|
|
230
|
+
bool isOwner = this->arg_ && this->arg_->isOwner();
|
|
231
|
+
bool isBuffer = this->arg_ && this->arg_->isBuffer();
|
|
186
232
|
|
|
187
233
|
if (data == nullptr)
|
|
188
234
|
{
|
|
189
235
|
return Qnil;
|
|
190
236
|
}
|
|
191
|
-
else if (
|
|
237
|
+
else if (std::is_fundamental_v<std::remove_pointer_t<T>> || isBuffer)
|
|
192
238
|
{
|
|
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);
|
|
239
|
+
using Pointer_T = Pointer<remove_cv_recursive_t<U>>;
|
|
240
|
+
return detail::wrap(Data_Type<Pointer_T>::klass(), Data_Type<Pointer_T>::ruby_data_type(), data, isOwner);
|
|
197
241
|
}
|
|
198
242
|
else
|
|
199
243
|
{
|
|
@@ -205,15 +249,12 @@ namespace Rice::detail
|
|
|
205
249
|
}
|
|
206
250
|
|
|
207
251
|
private:
|
|
208
|
-
|
|
252
|
+
Arg* arg_ = nullptr;
|
|
209
253
|
};
|
|
210
254
|
|
|
211
255
|
template <typename T>
|
|
212
|
-
|
|
256
|
+
class To_Ruby<T*&>
|
|
213
257
|
{
|
|
214
|
-
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
|
215
|
-
"Data_Object cannot be used with fundamental types");
|
|
216
|
-
|
|
217
258
|
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
|
218
259
|
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
|
219
260
|
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
|
@@ -224,25 +265,29 @@ namespace Rice::detail
|
|
|
224
265
|
public:
|
|
225
266
|
To_Ruby() = default;
|
|
226
267
|
|
|
227
|
-
explicit To_Ruby(
|
|
268
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
228
269
|
{
|
|
229
270
|
}
|
|
230
271
|
|
|
231
272
|
template<typename U>
|
|
232
273
|
VALUE convert(U* data)
|
|
233
274
|
{
|
|
234
|
-
bool isOwner = this->
|
|
235
|
-
|
|
275
|
+
bool isOwner = this->arg_ && this->arg_->isOwner();
|
|
276
|
+
bool isBuffer = this->arg_ && this->arg_->isBuffer();
|
|
277
|
+
|
|
236
278
|
if (data == nullptr)
|
|
237
279
|
{
|
|
238
280
|
return Qnil;
|
|
239
281
|
}
|
|
240
|
-
else if
|
|
282
|
+
else if constexpr (std::is_const_v<U>)
|
|
283
|
+
{
|
|
284
|
+
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(*data);
|
|
285
|
+
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
|
286
|
+
}
|
|
287
|
+
else if (std::is_fundamental_v<T> || isBuffer)
|
|
241
288
|
{
|
|
242
|
-
using
|
|
243
|
-
|
|
244
|
-
buffer.setOwner(isOwner);
|
|
245
|
-
return detail::wrap(Data_Type<Buffer_T>::klass(), Data_Type<Buffer_T>::ruby_data_type(), buffer, true);
|
|
289
|
+
using Pointer_T = Pointer<remove_cv_recursive_t<U>>;
|
|
290
|
+
return detail::wrap(Data_Type<Pointer_T>::klass(), Data_Type<Pointer_T>::ruby_data_type(), data, isOwner);
|
|
246
291
|
}
|
|
247
292
|
else
|
|
248
293
|
{
|
|
@@ -254,26 +299,16 @@ namespace Rice::detail
|
|
|
254
299
|
}
|
|
255
300
|
|
|
256
301
|
private:
|
|
257
|
-
|
|
302
|
+
Arg* arg_ = nullptr;
|
|
258
303
|
};
|
|
259
304
|
|
|
260
305
|
template <typename T>
|
|
261
306
|
class To_Ruby<T**>
|
|
262
307
|
{
|
|
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
308
|
public:
|
|
274
309
|
To_Ruby() = default;
|
|
275
310
|
|
|
276
|
-
explicit To_Ruby(
|
|
311
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
277
312
|
{
|
|
278
313
|
}
|
|
279
314
|
|
|
@@ -282,11 +317,9 @@ namespace Rice::detail
|
|
|
282
317
|
{
|
|
283
318
|
if (data)
|
|
284
319
|
{
|
|
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);
|
|
320
|
+
bool isOwner = this->arg_ && this->arg_->isOwner();
|
|
321
|
+
using Pointer_T = Pointer<remove_cv_recursive_t<U>*>;
|
|
322
|
+
return detail::wrap(Data_Type<Pointer_T>::klass(), Data_Type<Pointer_T>::ruby_data_type(), data, isOwner);
|
|
290
323
|
}
|
|
291
324
|
else
|
|
292
325
|
{
|
|
@@ -295,7 +328,7 @@ namespace Rice::detail
|
|
|
295
328
|
}
|
|
296
329
|
|
|
297
330
|
private:
|
|
298
|
-
|
|
331
|
+
Arg* arg_ = nullptr;
|
|
299
332
|
};
|
|
300
333
|
|
|
301
334
|
template<typename T>
|
|
@@ -448,13 +481,9 @@ namespace Rice::detail
|
|
|
448
481
|
|
|
449
482
|
// 99% of the time a T* represents a wrapped C++ object that we want to call methods on. However, T*
|
|
450
483
|
// 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
484
|
template<typename T>
|
|
453
485
|
class From_Ruby<T*>
|
|
454
486
|
{
|
|
455
|
-
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
|
456
|
-
"Data_Object cannot be used with fundamental types");
|
|
457
|
-
|
|
458
487
|
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
|
459
488
|
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
|
460
489
|
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
|
@@ -463,6 +492,7 @@ namespace Rice::detail
|
|
|
463
492
|
"Please include rice/stl.hpp header for STL support");
|
|
464
493
|
|
|
465
494
|
using Intrinsic_T = intrinsic_type<T>;
|
|
495
|
+
using Pointer_T = Pointer<remove_cv_recursive_t<T>>;
|
|
466
496
|
|
|
467
497
|
public:
|
|
468
498
|
From_Ruby() = default;
|
|
@@ -473,24 +503,23 @@ namespace Rice::detail
|
|
|
473
503
|
|
|
474
504
|
Convertible is_convertible(VALUE value)
|
|
475
505
|
{
|
|
506
|
+
bool isBuffer = this->arg_->isBuffer();
|
|
507
|
+
|
|
476
508
|
switch (rb_type(value))
|
|
477
509
|
{
|
|
510
|
+
case RUBY_T_NIL:
|
|
511
|
+
return Convertible::Exact;
|
|
512
|
+
break;
|
|
478
513
|
case RUBY_T_DATA:
|
|
479
|
-
if (
|
|
514
|
+
if (Data_Type<T>::is_descendant(value) && !isBuffer)
|
|
480
515
|
{
|
|
481
|
-
return
|
|
516
|
+
return Convertible::Exact;
|
|
482
517
|
}
|
|
483
|
-
else
|
|
518
|
+
else if (Data_Type<Pointer_T>::is_descendant(value))
|
|
484
519
|
{
|
|
485
|
-
return
|
|
520
|
+
return Convertible::Exact;
|
|
486
521
|
}
|
|
487
|
-
|
|
488
|
-
case RUBY_T_NIL:
|
|
489
|
-
return Convertible::Exact;
|
|
490
|
-
break;
|
|
491
|
-
case RUBY_T_ARRAY:
|
|
492
|
-
return Convertible::Exact;
|
|
493
|
-
break;
|
|
522
|
+
[[fallthrough]];
|
|
494
523
|
default:
|
|
495
524
|
return Convertible::None;
|
|
496
525
|
}
|
|
@@ -498,6 +527,9 @@ namespace Rice::detail
|
|
|
498
527
|
|
|
499
528
|
T* convert(VALUE value)
|
|
500
529
|
{
|
|
530
|
+
bool isOwner = this->arg_ && this->arg_->isOwner();
|
|
531
|
+
bool isBuffer = this->arg_ && this->arg_->isBuffer();
|
|
532
|
+
|
|
501
533
|
switch (rb_type(value))
|
|
502
534
|
{
|
|
503
535
|
case RUBY_T_NIL:
|
|
@@ -507,20 +539,26 @@ namespace Rice::detail
|
|
|
507
539
|
}
|
|
508
540
|
case RUBY_T_DATA:
|
|
509
541
|
{
|
|
510
|
-
if (
|
|
542
|
+
if (Data_Type<T>::is_descendant(value) && !isBuffer)
|
|
511
543
|
{
|
|
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();
|
|
544
|
+
return detail::unwrap<Intrinsic_T>(value, Data_Type<Intrinsic_T>::ruby_data_type(), isOwner);
|
|
515
545
|
}
|
|
516
|
-
else
|
|
546
|
+
else if (Data_Type<Pointer_T>::is_descendant(value))
|
|
517
547
|
{
|
|
518
|
-
return detail::unwrap<
|
|
548
|
+
return detail::unwrap<T>(value, Data_Type<Pointer_T>::ruby_data_type(), isOwner);
|
|
519
549
|
}
|
|
550
|
+
[[fallthrough]];
|
|
520
551
|
}
|
|
521
552
|
default:
|
|
522
553
|
{
|
|
523
|
-
|
|
554
|
+
if (isBuffer || std::is_fundamental_v<T>)
|
|
555
|
+
{
|
|
556
|
+
throw create_type_exception<Pointer_T>(value);
|
|
557
|
+
}
|
|
558
|
+
else
|
|
559
|
+
{
|
|
560
|
+
throw create_type_exception<T>(value);
|
|
561
|
+
}
|
|
524
562
|
}
|
|
525
563
|
}
|
|
526
564
|
}
|
|
@@ -532,9 +570,6 @@ namespace Rice::detail
|
|
|
532
570
|
template<typename T>
|
|
533
571
|
class From_Ruby<T*&>
|
|
534
572
|
{
|
|
535
|
-
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
|
536
|
-
"Data_Object cannot be used with fundamental types");
|
|
537
|
-
|
|
538
573
|
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
|
539
574
|
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
|
540
575
|
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
|
@@ -582,9 +617,6 @@ namespace Rice::detail
|
|
|
582
617
|
template<typename T>
|
|
583
618
|
class From_Ruby<T**>
|
|
584
619
|
{
|
|
585
|
-
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
|
586
|
-
"Data_Object cannot be used with fundamental types");
|
|
587
|
-
|
|
588
620
|
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
|
589
621
|
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
|
590
622
|
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
|
@@ -593,6 +625,7 @@ namespace Rice::detail
|
|
|
593
625
|
"Please include rice/stl.hpp header for STL support");
|
|
594
626
|
|
|
595
627
|
using Intrinsic_T = intrinsic_type<T>;
|
|
628
|
+
using Pointer_T = Pointer<remove_cv_recursive_t<T>*>;
|
|
596
629
|
public:
|
|
597
630
|
From_Ruby() = default;
|
|
598
631
|
|
|
@@ -602,17 +635,19 @@ namespace Rice::detail
|
|
|
602
635
|
|
|
603
636
|
Convertible is_convertible(VALUE value)
|
|
604
637
|
{
|
|
638
|
+
bool isBuffer = this->arg_ && this->arg_->isBuffer();
|
|
639
|
+
|
|
605
640
|
switch (rb_type(value))
|
|
606
641
|
{
|
|
607
|
-
case RUBY_T_DATA:
|
|
608
|
-
return Data_Type<Buffer<T*>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
|
|
609
|
-
break;
|
|
610
642
|
case RUBY_T_NIL:
|
|
611
643
|
return Convertible::Exact;
|
|
612
644
|
break;
|
|
613
|
-
case
|
|
614
|
-
|
|
615
|
-
|
|
645
|
+
case RUBY_T_DATA:
|
|
646
|
+
if (Data_Type<Pointer_T>::is_descendant(value) && isBuffer)
|
|
647
|
+
{
|
|
648
|
+
return Convertible::Exact;
|
|
649
|
+
}
|
|
650
|
+
[[fallthrough]];
|
|
616
651
|
default:
|
|
617
652
|
return Convertible::None;
|
|
618
653
|
}
|
|
@@ -620,22 +655,35 @@ namespace Rice::detail
|
|
|
620
655
|
|
|
621
656
|
T** convert(VALUE value)
|
|
622
657
|
{
|
|
658
|
+
bool isOwner = this->arg_ && this->arg_->isOwner();
|
|
659
|
+
bool isBuffer = this->arg_ && this->arg_->isBuffer();
|
|
660
|
+
|
|
623
661
|
switch (rb_type(value))
|
|
624
662
|
{
|
|
625
|
-
case RUBY_T_DATA:
|
|
626
|
-
{
|
|
627
|
-
Buffer<Intrinsic_T*>* buffer = detail::unwrap<Buffer<Intrinsic_T*>>(value, Data_Type<Buffer<Intrinsic_T*>>::ruby_data_type(), false);
|
|
628
|
-
return buffer->ptr();
|
|
629
|
-
break;
|
|
630
|
-
}
|
|
631
663
|
case RUBY_T_NIL:
|
|
632
664
|
{
|
|
633
665
|
return nullptr;
|
|
634
666
|
break;
|
|
635
667
|
}
|
|
668
|
+
case RUBY_T_DATA:
|
|
669
|
+
{
|
|
670
|
+
if (Data_Type<Pointer_T>::is_descendant(value) && isBuffer)
|
|
671
|
+
{
|
|
672
|
+
T** result = detail::unwrap<Intrinsic_T*>(value, Data_Type<Pointer_T>::ruby_data_type(), isOwner);
|
|
673
|
+
return result;
|
|
674
|
+
}
|
|
675
|
+
[[fallthrough]];
|
|
676
|
+
}
|
|
636
677
|
default:
|
|
637
678
|
{
|
|
638
|
-
|
|
679
|
+
if (isBuffer)
|
|
680
|
+
{
|
|
681
|
+
throw create_type_exception<Pointer_T>(value);
|
|
682
|
+
}
|
|
683
|
+
else
|
|
684
|
+
{
|
|
685
|
+
throw create_type_exception<T**>(value);
|
|
686
|
+
}
|
|
639
687
|
}
|
|
640
688
|
}
|
|
641
689
|
}
|
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
|
}
|