rice 4.5.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/CMakeLists.txt +31 -0
- data/CMakePresets.json +75 -0
- data/COPYING +3 -2
- data/FindRuby.cmake +437 -0
- data/Rakefile +5 -4
- data/include/rice/rice.hpp +5436 -3201
- data/include/rice/stl.hpp +2355 -1269
- data/lib/make_rice_headers.rb +79 -0
- data/lib/mkmf-rice.rb +4 -0
- data/lib/rice/version.rb +3 -0
- data/lib/rice.rb +1 -0
- data/lib/rubygems/builder.rb +11 -0
- data/lib/rubygems/cmake_builder.rb +113 -0
- data/lib/rubygems_plugin.rb +9 -0
- data/rice/Arg.hpp +7 -1
- data/rice/Arg.ipp +11 -2
- data/rice/Buffer.hpp +123 -0
- data/rice/Buffer.ipp +599 -0
- data/rice/Constructor.ipp +3 -3
- data/rice/Data_Object.hpp +2 -3
- data/rice/Data_Object.ipp +188 -188
- data/rice/Data_Type.hpp +4 -5
- data/rice/Data_Type.ipp +42 -26
- data/rice/Enum.hpp +0 -1
- data/rice/Enum.ipp +26 -23
- data/rice/Init.hpp +8 -0
- data/rice/Init.ipp +8 -0
- data/rice/MemoryView.ipp +1 -41
- data/rice/Return.hpp +1 -1
- data/rice/Return.ipp +6 -0
- data/rice/cpp_api/Array.hpp +209 -0
- data/rice/cpp_api/Array.ipp +304 -0
- data/rice/cpp_api/Builtin_Object.hpp +31 -0
- data/rice/cpp_api/Builtin_Object.ipp +37 -0
- data/rice/cpp_api/Class.hpp +70 -0
- data/rice/cpp_api/Class.ipp +97 -0
- data/rice/cpp_api/Encoding.hpp +32 -0
- data/rice/cpp_api/Encoding.ipp +59 -0
- data/rice/cpp_api/Hash.hpp +194 -0
- data/rice/cpp_api/Hash.ipp +257 -0
- data/rice/cpp_api/Identifier.hpp +46 -0
- data/rice/cpp_api/Identifier.ipp +31 -0
- data/rice/cpp_api/Module.hpp +72 -0
- data/rice/cpp_api/Module.ipp +101 -0
- data/rice/cpp_api/Object.hpp +272 -0
- data/rice/cpp_api/Object.ipp +235 -0
- data/rice/cpp_api/String.hpp +74 -0
- data/rice/cpp_api/String.ipp +120 -0
- data/rice/cpp_api/Struct.hpp +113 -0
- data/rice/cpp_api/Struct.ipp +92 -0
- data/rice/cpp_api/Symbol.hpp +46 -0
- data/rice/cpp_api/Symbol.ipp +93 -0
- data/rice/cpp_api/shared_methods.hpp +134 -0
- data/rice/detail/MethodInfo.hpp +1 -9
- data/rice/detail/MethodInfo.ipp +5 -72
- data/rice/detail/Native.hpp +3 -2
- data/rice/detail/Native.ipp +32 -4
- data/rice/detail/NativeAttributeGet.hpp +3 -2
- data/rice/detail/NativeAttributeGet.ipp +8 -2
- data/rice/detail/NativeAttributeSet.hpp +3 -2
- data/rice/detail/NativeAttributeSet.ipp +8 -2
- data/rice/detail/NativeCallbackFFI.ipp +1 -1
- data/rice/detail/NativeFunction.hpp +17 -6
- data/rice/detail/NativeFunction.ipp +168 -64
- data/rice/detail/NativeIterator.hpp +3 -2
- data/rice/detail/NativeIterator.ipp +8 -2
- data/rice/detail/RubyType.hpp +2 -5
- data/rice/detail/RubyType.ipp +50 -5
- data/rice/detail/Type.hpp +3 -1
- data/rice/detail/Type.ipp +61 -31
- data/rice/detail/Wrapper.hpp +68 -33
- data/rice/detail/Wrapper.ipp +103 -113
- data/rice/detail/from_ruby.hpp +5 -4
- data/rice/detail/from_ruby.ipp +737 -365
- data/rice/detail/to_ruby.ipp +1092 -186
- data/rice/global_function.ipp +1 -1
- data/rice/libc/file.hpp +11 -0
- data/rice/libc/file.ipp +32 -0
- data/rice/rice.hpp +23 -16
- data/rice/stl/complex.hpp +6 -0
- data/rice/stl/complex.ipp +93 -0
- data/rice/stl/exception.hpp +11 -0
- data/rice/stl/exception.ipp +29 -0
- data/rice/stl/exception_ptr.hpp +6 -0
- data/rice/stl/exception_ptr.ipp +27 -0
- data/rice/stl/map.hpp +12 -0
- data/rice/stl/map.ipp +469 -0
- data/rice/stl/monostate.hpp +6 -0
- data/rice/stl/monostate.ipp +80 -0
- data/rice/stl/multimap.hpp +14 -0
- data/rice/stl/multimap.ipp +448 -0
- data/rice/stl/optional.hpp +6 -0
- data/rice/stl/optional.ipp +118 -0
- data/rice/stl/pair.hpp +13 -0
- data/rice/stl/pair.ipp +155 -0
- data/rice/stl/reference_wrapper.hpp +6 -0
- data/rice/stl/reference_wrapper.ipp +41 -0
- data/rice/stl/set.hpp +12 -0
- data/rice/stl/set.ipp +495 -0
- data/rice/stl/shared_ptr.hpp +28 -0
- data/rice/stl/shared_ptr.ipp +224 -0
- data/rice/stl/string.hpp +6 -0
- data/rice/stl/string.ipp +158 -0
- data/rice/stl/string_view.hpp +6 -0
- data/rice/stl/string_view.ipp +65 -0
- data/rice/stl/tuple.hpp +6 -0
- data/rice/stl/tuple.ipp +128 -0
- data/rice/stl/type_index.hpp +6 -0
- data/rice/stl/type_index.ipp +30 -0
- data/rice/stl/type_info.hpp +6 -0
- data/rice/stl/type_info.ipp +29 -0
- data/rice/stl/unique_ptr.hpp +22 -0
- data/rice/stl/unique_ptr.ipp +139 -0
- data/rice/stl/unordered_map.hpp +12 -0
- data/rice/stl/unordered_map.ipp +469 -0
- data/rice/stl/variant.hpp +6 -0
- data/rice/stl/variant.ipp +242 -0
- data/rice/stl/vector.hpp +12 -0
- data/rice/stl/vector.ipp +590 -0
- data/rice/stl.hpp +7 -3
- data/rice/traits/attribute_traits.hpp +26 -0
- data/rice/traits/function_traits.hpp +95 -0
- data/rice/traits/method_traits.hpp +47 -0
- data/rice/traits/rice_traits.hpp +160 -0
- data/rice.gemspec +85 -0
- data/test/embed_ruby.cpp +3 -0
- data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
- data/test/test_Array.cpp +6 -3
- data/test/test_Attribute.cpp +34 -1
- data/test/test_Buffer.cpp +285 -0
- data/test/test_Callback.cpp +2 -3
- data/test/test_Data_Object.cpp +88 -34
- data/test/test_Data_Type.cpp +106 -65
- data/test/test_Director.cpp +7 -3
- data/test/test_Enum.cpp +5 -2
- data/test/test_File.cpp +1 -1
- data/test/test_From_Ruby.cpp +181 -114
- data/test/test_Iterator.cpp +1 -1
- data/test/{test_JumpException.cpp → test_Jump_Exception.cpp} +1 -0
- data/test/test_Keep_Alive.cpp +7 -18
- data/test/test_Keep_Alive_No_Wrapper.cpp +0 -1
- data/test/test_Module.cpp +13 -6
- data/test/test_Native_Registry.cpp +0 -1
- data/test/test_Overloads.cpp +180 -5
- data/test/test_Ownership.cpp +100 -57
- data/test/test_Proc.cpp +0 -1
- data/test/test_Self.cpp +4 -4
- data/test/test_Stl_Map.cpp +37 -39
- data/test/test_Stl_Multimap.cpp +693 -0
- data/test/test_Stl_Pair.cpp +8 -8
- data/test/test_Stl_Reference_Wrapper.cpp +4 -2
- data/test/test_Stl_Set.cpp +790 -0
- data/test/{test_Stl_SmartPointer.cpp → test_Stl_SharedPtr.cpp} +97 -127
- data/test/test_Stl_Tuple.cpp +116 -0
- data/test/test_Stl_Type.cpp +1 -1
- data/test/test_Stl_UniquePtr.cpp +202 -0
- data/test/test_Stl_Unordered_Map.cpp +28 -34
- data/test/test_Stl_Variant.cpp +217 -89
- data/test/test_Stl_Vector.cpp +209 -83
- data/test/test_To_Ruby.cpp +373 -1
- data/test/test_Type.cpp +85 -14
- data/test/test_global_functions.cpp +17 -4
- metadata +94 -10
- data/rice/detail/TupleIterator.hpp +0 -14
data/rice/Data_Object.ipp
CHANGED
@@ -18,6 +18,13 @@ namespace Rice
|
|
18
18
|
this->set_value(value);
|
19
19
|
}
|
20
20
|
|
21
|
+
template<typename T>
|
22
|
+
inline Data_Object<T>::Data_Object(T&& data, Class klass)
|
23
|
+
{
|
24
|
+
VALUE value = detail::wrap(klass, Data_Type<T>::ruby_data_type(), data, true);
|
25
|
+
this->set_value(value);
|
26
|
+
}
|
27
|
+
|
21
28
|
template<typename T>
|
22
29
|
inline Data_Object<T>::Data_Object(const T& data, bool isOwner, Class klass)
|
23
30
|
{
|
@@ -38,6 +45,12 @@ namespace Rice
|
|
38
45
|
check_ruby_type(value);
|
39
46
|
}
|
40
47
|
|
48
|
+
template<typename T>
|
49
|
+
inline Data_Object<T>::Data_Object(VALUE value) : Object(value)
|
50
|
+
{
|
51
|
+
check_ruby_type(value);
|
52
|
+
}
|
53
|
+
|
41
54
|
template<typename T>
|
42
55
|
inline void Data_Object<T>::check_ruby_type(VALUE value)
|
43
56
|
{
|
@@ -71,19 +84,6 @@ namespace Rice
|
|
71
84
|
return detail::unwrap<T>(this->value(), Data_Type<T>::ruby_data_type(), false);
|
72
85
|
}
|
73
86
|
}
|
74
|
-
|
75
|
-
template<typename T>
|
76
|
-
inline T* Data_Object<T>::from_ruby(VALUE value, bool takeOwnership)
|
77
|
-
{
|
78
|
-
if (Data_Type<T>::is_descendant(value))
|
79
|
-
{
|
80
|
-
return detail::unwrap<T>(value, Data_Type<T>::ruby_data_type(), takeOwnership);
|
81
|
-
}
|
82
|
-
else
|
83
|
-
{
|
84
|
-
throw create_type_exception<T>(value);
|
85
|
-
}
|
86
|
-
}
|
87
87
|
}
|
88
88
|
|
89
89
|
namespace Rice::detail
|
@@ -91,8 +91,19 @@ namespace Rice::detail
|
|
91
91
|
template<typename T>
|
92
92
|
class To_Ruby
|
93
93
|
{
|
94
|
+
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
95
|
+
"Data_Object cannot be used with fundamental types");
|
96
|
+
|
97
|
+
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
98
|
+
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
99
|
+
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
100
|
+
!std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
|
101
|
+
!std::is_same_v<T, std::vector<T>>,
|
102
|
+
"Please include rice/stl.hpp header for STL support");
|
103
|
+
|
94
104
|
public:
|
95
|
-
|
105
|
+
template<typename U>
|
106
|
+
VALUE convert(U& data)
|
96
107
|
{
|
97
108
|
// Get the ruby typeinfo
|
98
109
|
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(data);
|
@@ -102,7 +113,8 @@ namespace Rice::detail
|
|
102
113
|
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
103
114
|
}
|
104
115
|
|
105
|
-
|
116
|
+
template<typename U>
|
117
|
+
VALUE convert(U&& data)
|
106
118
|
{
|
107
119
|
// Get the ruby typeinfo
|
108
120
|
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(data);
|
@@ -116,6 +128,16 @@ namespace Rice::detail
|
|
116
128
|
template <typename T>
|
117
129
|
class To_Ruby<T&>
|
118
130
|
{
|
131
|
+
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
132
|
+
"Data_Object cannot be used with fundamental types");
|
133
|
+
|
134
|
+
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
135
|
+
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
136
|
+
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
137
|
+
!std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
|
138
|
+
!std::is_same_v<T, std::vector<T>>,
|
139
|
+
"Please include rice/stl.hpp header for STL support");
|
140
|
+
|
119
141
|
public:
|
120
142
|
To_Ruby() = default;
|
121
143
|
|
@@ -123,26 +145,16 @@ namespace Rice::detail
|
|
123
145
|
{
|
124
146
|
}
|
125
147
|
|
126
|
-
|
127
|
-
|
128
|
-
// Note that T could be a pointer or reference to a base class while data is in fact a
|
129
|
-
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
130
|
-
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(data);
|
131
|
-
|
132
|
-
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
133
|
-
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
134
|
-
}
|
135
|
-
|
136
|
-
VALUE convert(const T& data)
|
148
|
+
template<typename U>
|
149
|
+
VALUE convert(U& data)
|
137
150
|
{
|
138
151
|
// Note that T could be a pointer or reference to a base class while data is in fact a
|
139
152
|
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
140
153
|
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(data);
|
141
154
|
|
142
|
-
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
155
|
+
bool isOwner = (this->returnInfo_ && this->returnInfo_->isOwner());
|
143
156
|
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
144
157
|
}
|
145
|
-
|
146
158
|
private:
|
147
159
|
Return* returnInfo_ = nullptr;
|
148
160
|
};
|
@@ -150,6 +162,16 @@ namespace Rice::detail
|
|
150
162
|
template <typename T>
|
151
163
|
class To_Ruby<T*>
|
152
164
|
{
|
165
|
+
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
166
|
+
"Data_Object cannot be used with fundamental types");
|
167
|
+
|
168
|
+
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
169
|
+
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
170
|
+
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
171
|
+
!std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
|
172
|
+
!std::is_same_v<T, std::vector<T>>,
|
173
|
+
"Please include rice/stl.hpp header for STL support");
|
174
|
+
|
153
175
|
public:
|
154
176
|
To_Ruby() = default;
|
155
177
|
|
@@ -157,38 +179,31 @@ namespace Rice::detail
|
|
157
179
|
{
|
158
180
|
}
|
159
181
|
|
160
|
-
|
182
|
+
template<typename U>
|
183
|
+
VALUE convert(U* data)
|
161
184
|
{
|
162
|
-
|
185
|
+
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
186
|
+
|
187
|
+
if (data == nullptr)
|
163
188
|
{
|
164
|
-
|
165
|
-
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
166
|
-
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(*data);
|
167
|
-
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
168
|
-
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
189
|
+
return Qnil;
|
169
190
|
}
|
170
|
-
else
|
191
|
+
else if (this->returnInfo_ && this->returnInfo_->isArray())
|
171
192
|
{
|
172
|
-
|
193
|
+
using Buffer_T = Buffer<T>;
|
194
|
+
Buffer_T buffer((T*)data);
|
195
|
+
buffer.setOwner(isOwner);
|
196
|
+
return detail::wrap(Data_Type<Buffer_T>::klass(), Data_Type<Buffer_T>::ruby_data_type(), buffer, true);
|
173
197
|
}
|
174
|
-
|
175
|
-
|
176
|
-
VALUE convert(const T* data)
|
177
|
-
{
|
178
|
-
if (data)
|
198
|
+
else
|
179
199
|
{
|
180
200
|
// Note that T could be a pointer or reference to a base class while data is in fact a
|
181
201
|
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
182
202
|
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(*data);
|
183
|
-
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
184
203
|
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
185
204
|
}
|
186
|
-
else
|
187
|
-
{
|
188
|
-
return Qnil;
|
189
|
-
}
|
190
205
|
}
|
191
|
-
|
206
|
+
|
192
207
|
private:
|
193
208
|
Return* returnInfo_ = nullptr;
|
194
209
|
};
|
@@ -196,6 +211,16 @@ namespace Rice::detail
|
|
196
211
|
template <typename T>
|
197
212
|
class To_Ruby<T*&>
|
198
213
|
{
|
214
|
+
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
215
|
+
"Data_Object cannot be used with fundamental types");
|
216
|
+
|
217
|
+
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
218
|
+
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
219
|
+
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
220
|
+
!std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
|
221
|
+
!std::is_same_v<T, std::vector<T>>,
|
222
|
+
"Please include rice/stl.hpp header for STL support");
|
223
|
+
|
199
224
|
public:
|
200
225
|
To_Ruby() = default;
|
201
226
|
|
@@ -203,36 +228,29 @@ namespace Rice::detail
|
|
203
228
|
{
|
204
229
|
}
|
205
230
|
|
206
|
-
|
231
|
+
template<typename U>
|
232
|
+
VALUE convert(U* data)
|
207
233
|
{
|
208
|
-
|
234
|
+
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
235
|
+
|
236
|
+
if (data == nullptr)
|
209
237
|
{
|
210
|
-
|
211
|
-
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
212
|
-
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(*data);
|
213
|
-
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
214
|
-
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
238
|
+
return Qnil;
|
215
239
|
}
|
216
|
-
else
|
240
|
+
else if (this->returnInfo_ && this->returnInfo_->isArray())
|
217
241
|
{
|
218
|
-
|
242
|
+
using Buffer_T = Buffer<intrinsic_type<T>>;
|
243
|
+
Buffer_T buffer((T*)data);
|
244
|
+
buffer.setOwner(isOwner);
|
245
|
+
return detail::wrap(Data_Type<Buffer_T>::klass(), Data_Type<Buffer_T>::ruby_data_type(), buffer, true);
|
219
246
|
}
|
220
|
-
|
221
|
-
|
222
|
-
VALUE convert(const T* data)
|
223
|
-
{
|
224
|
-
if (data)
|
247
|
+
else
|
225
248
|
{
|
226
249
|
// Note that T could be a pointer or reference to a base class while data is in fact a
|
227
250
|
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
228
251
|
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(*data);
|
229
|
-
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
230
252
|
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
231
253
|
}
|
232
|
-
else
|
233
|
-
{
|
234
|
-
return Qnil;
|
235
|
-
}
|
236
254
|
}
|
237
255
|
|
238
256
|
private:
|
@@ -242,6 +260,16 @@ namespace Rice::detail
|
|
242
260
|
template <typename T>
|
243
261
|
class To_Ruby<T**>
|
244
262
|
{
|
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
|
+
|
245
273
|
public:
|
246
274
|
To_Ruby() = default;
|
247
275
|
|
@@ -249,31 +277,16 @@ namespace Rice::detail
|
|
249
277
|
{
|
250
278
|
}
|
251
279
|
|
252
|
-
|
280
|
+
template<typename U>
|
281
|
+
VALUE convert(U** data)
|
253
282
|
{
|
254
283
|
if (data)
|
255
284
|
{
|
256
|
-
// Note that T could be a pointer or reference to a base class while data is in fact a
|
257
|
-
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
258
|
-
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(**data);
|
259
285
|
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
return Qnil;
|
265
|
-
}
|
266
|
-
}
|
267
|
-
|
268
|
-
VALUE convert(const T** data)
|
269
|
-
{
|
270
|
-
if (data)
|
271
|
-
{
|
272
|
-
// Note that T could be a pointer or reference to a base class while data is in fact a
|
273
|
-
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
274
|
-
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(*data);
|
275
|
-
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
276
|
-
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
286
|
+
Buffer<T*> buffer((T**)data);
|
287
|
+
buffer.setOwner(isOwner);
|
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);
|
277
290
|
}
|
278
291
|
else
|
279
292
|
{
|
@@ -300,6 +313,14 @@ namespace Rice::detail
|
|
300
313
|
{
|
301
314
|
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
302
315
|
"Data_Object cannot be used with fundamental types");
|
316
|
+
|
317
|
+
static_assert(!std::is_same_v<T, std::map<T, T>> || !std::is_same_v<T, std::unordered_map<T, T>> ||
|
318
|
+
!std::is_same_v<T, std::monostate> || !std::is_same_v<T, std::multimap<T, T>> ||
|
319
|
+
!std::is_same_v<T, std::optional<T>> || !std::is_same_v<T, std::pair<T, T>> ||
|
320
|
+
!std::is_same_v<T, std::set<T>> || !std::is_same_v<T, std::string> ||
|
321
|
+
!std::is_same_v<T, std::vector<T>>,
|
322
|
+
"Please include rice/stl.hpp header for STL support");
|
323
|
+
|
303
324
|
public:
|
304
325
|
From_Ruby() = default;
|
305
326
|
|
@@ -321,34 +342,16 @@ namespace Rice::detail
|
|
321
342
|
|
322
343
|
T convert(VALUE value)
|
323
344
|
{
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
// std::is_constructible_v<T, T> && !std::is_convertible_v<T, T>
|
329
|
-
if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
|
345
|
+
using Intrinsic_T = intrinsic_type<T>;
|
346
|
+
Intrinsic_T* instance = detail::unwrap<Intrinsic_T>(value, Data_Type<Intrinsic_T>::ruby_data_type(), this->arg_ && this->arg_->isOwner());
|
347
|
+
|
348
|
+
if constexpr (std::is_constructible_v<T, T> && !std::is_convertible_v<T, T>)
|
330
349
|
{
|
331
|
-
|
332
|
-
{
|
333
|
-
return T(this->arg_->template defaultValue<T>());
|
334
|
-
}
|
335
|
-
else
|
336
|
-
{
|
337
|
-
return this->arg_->template defaultValue<T>();
|
338
|
-
}
|
350
|
+
return T(*instance);
|
339
351
|
}
|
340
352
|
else
|
341
353
|
{
|
342
|
-
|
343
|
-
{
|
344
|
-
using Intrinsic_T = intrinsic_type<T>;
|
345
|
-
return T(*Data_Object<Intrinsic_T>::from_ruby(value, this->arg_ && this->arg_->isOwner()));
|
346
|
-
}
|
347
|
-
else
|
348
|
-
{
|
349
|
-
using Intrinsic_T = intrinsic_type<T>;
|
350
|
-
return *Data_Object<Intrinsic_T>::from_ruby(value, this->arg_ && this->arg_->isOwner());
|
351
|
-
}
|
354
|
+
return *instance;
|
352
355
|
}
|
353
356
|
}
|
354
357
|
|
@@ -361,6 +364,14 @@ namespace Rice::detail
|
|
361
364
|
{
|
362
365
|
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
363
366
|
"Data_Object cannot be used with fundamental types");
|
367
|
+
|
368
|
+
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
369
|
+
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
370
|
+
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
371
|
+
!std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
|
372
|
+
!std::is_same_v<T, std::vector<T>>,
|
373
|
+
"Please include rice/stl.hpp header for STL support");
|
374
|
+
|
364
375
|
public:
|
365
376
|
From_Ruby() = default;
|
366
377
|
|
@@ -384,14 +395,7 @@ namespace Rice::detail
|
|
384
395
|
{
|
385
396
|
using Intrinsic_T = intrinsic_type<T>;
|
386
397
|
|
387
|
-
|
388
|
-
{
|
389
|
-
return this->arg_->template defaultValue<Intrinsic_T>();
|
390
|
-
}
|
391
|
-
else
|
392
|
-
{
|
393
|
-
return *Data_Object<Intrinsic_T>::from_ruby(value, this->arg_ && this->arg_->isOwner());
|
394
|
-
}
|
398
|
+
return *detail::unwrap<Intrinsic_T>(value, Data_Type<Intrinsic_T>::ruby_data_type(), this->arg_ && this->arg_->isOwner());
|
395
399
|
}
|
396
400
|
|
397
401
|
private:
|
@@ -403,6 +407,14 @@ namespace Rice::detail
|
|
403
407
|
{
|
404
408
|
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
405
409
|
"Data_Object cannot be used with fundamental types");
|
410
|
+
|
411
|
+
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
412
|
+
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
413
|
+
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
414
|
+
!std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
|
415
|
+
!std::is_same_v<T, std::vector<T>>,
|
416
|
+
"Please include rice/stl.hpp header for STL support");
|
417
|
+
|
406
418
|
public:
|
407
419
|
From_Ruby() = default;
|
408
420
|
|
@@ -426,55 +438,30 @@ namespace Rice::detail
|
|
426
438
|
{
|
427
439
|
using Intrinsic_T = intrinsic_type<T>;
|
428
440
|
|
429
|
-
|
430
|
-
|
431
|
-
return std::move(this->arg_->template defaultValue<Intrinsic_T>());
|
432
|
-
}
|
433
|
-
else
|
434
|
-
{
|
435
|
-
return std::move(*Data_Object<Intrinsic_T>::from_ruby(value, this->arg_ && this->arg_->isOwner()));
|
436
|
-
}
|
441
|
+
Intrinsic_T* object = detail::unwrap<Intrinsic_T>(value, Data_Type<Intrinsic_T>::ruby_data_type(), this->arg_ && this->arg_->isOwner());
|
442
|
+
return std::move(*object);
|
437
443
|
}
|
438
444
|
|
439
445
|
private:
|
440
446
|
Arg* arg_ = nullptr;
|
441
447
|
};
|
442
448
|
|
443
|
-
// Helper class to convert a Ruby array of T to a C++ array of T (this happens when an API take T* as parameter
|
444
|
-
// along with a second size parameter)
|
445
|
-
template<typename T>
|
446
|
-
class ArrayHelper
|
447
|
-
{
|
448
|
-
public:
|
449
|
-
using Intrinsic_T = intrinsic_type<T>;
|
450
|
-
|
451
|
-
T* convert(VALUE value)
|
452
|
-
{
|
453
|
-
this->vector_ = Array(value).to_vector<T>();
|
454
|
-
return this->vector_.data();
|
455
|
-
}
|
456
|
-
|
457
|
-
private:
|
458
|
-
std::vector<Intrinsic_T> vector_;
|
459
|
-
};
|
460
|
-
|
461
449
|
// 99% of the time a T* represents a wrapped C++ object that we want to call methods on. However, T*
|
462
450
|
// could also be a pointer to an array of T objects, so T[]. OpenCV for example has API calls like this.
|
463
|
-
//
|
464
|
-
// Therefore this From_Ruby implementation supports both uses cases which complicates the code. The problem
|
465
|
-
// is for T[] to compile, a class needs to be constructible, destructible and not abstract. A further wrinkle
|
466
|
-
// is if T has an explicit copy-constructor then that requires additional special handling in the code
|
467
|
-
// (see From_Ruby<T>). Whether this extra complication is worth it is debatable, but it does mean that
|
468
|
-
// a Ruby array can be passed to any C++ API that takes a * including fundamental types (unsigned char)
|
469
|
-
// and class types (T).
|
470
|
-
//
|
471
|
-
// Note that the From_Ruby<T[]> specialization never matches a parameter defined in function as T[] - the C++
|
472
|
-
// compiler always picks T* instead. Not sure why...
|
451
|
+
// In that case, the Ruby VALUE will be a Buffer<T> instance
|
473
452
|
template<typename T>
|
474
453
|
class From_Ruby<T*>
|
475
454
|
{
|
476
455
|
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
477
456
|
"Data_Object cannot be used with fundamental types");
|
457
|
+
|
458
|
+
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
459
|
+
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
460
|
+
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
461
|
+
!std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
|
462
|
+
!std::is_same_v<T, std::vector<T>>,
|
463
|
+
"Please include rice/stl.hpp header for STL support");
|
464
|
+
|
478
465
|
using Intrinsic_T = intrinsic_type<T>;
|
479
466
|
|
480
467
|
public:
|
@@ -484,20 +471,19 @@ namespace Rice::detail
|
|
484
471
|
{
|
485
472
|
}
|
486
473
|
|
487
|
-
~From_Ruby()
|
488
|
-
{
|
489
|
-
if constexpr (std::is_destructible_v<Intrinsic_T>)
|
490
|
-
{
|
491
|
-
delete this->arrayHelper_;
|
492
|
-
}
|
493
|
-
}
|
494
|
-
|
495
474
|
Convertible is_convertible(VALUE value)
|
496
475
|
{
|
497
476
|
switch (rb_type(value))
|
498
477
|
{
|
499
478
|
case RUBY_T_DATA:
|
500
|
-
|
479
|
+
if (this->arg_ && this->arg_->isArray())
|
480
|
+
{
|
481
|
+
return Data_Type<Buffer<T>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
|
482
|
+
}
|
483
|
+
else
|
484
|
+
{
|
485
|
+
return Data_Type<T>::is_descendant(value) ? Convertible::Exact : Convertible::None;
|
486
|
+
}
|
501
487
|
break;
|
502
488
|
case RUBY_T_NIL:
|
503
489
|
return Convertible::Exact;
|
@@ -514,28 +500,23 @@ namespace Rice::detail
|
|
514
500
|
{
|
515
501
|
switch (rb_type(value))
|
516
502
|
{
|
517
|
-
case RUBY_T_DATA:
|
518
|
-
{
|
519
|
-
return Data_Object<Intrinsic_T>::from_ruby(value, this->arg_ && this->arg_->isOwner());
|
520
|
-
break;
|
521
|
-
}
|
522
503
|
case RUBY_T_NIL:
|
523
504
|
{
|
524
505
|
return nullptr;
|
525
506
|
break;
|
526
507
|
}
|
527
|
-
case
|
508
|
+
case RUBY_T_DATA:
|
528
509
|
{
|
529
|
-
if
|
510
|
+
if (this->arg_ && this->arg_->isArray())
|
511
|
+
{
|
512
|
+
using Buffer_T = Buffer<Intrinsic_T>;
|
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();
|
515
|
+
}
|
516
|
+
else
|
530
517
|
{
|
531
|
-
|
532
|
-
{
|
533
|
-
this->arrayHelper_ = new ArrayHelper<T>();
|
534
|
-
}
|
535
|
-
return this->arrayHelper_->convert(value);
|
536
|
-
break;
|
518
|
+
return detail::unwrap<Intrinsic_T>(value, Data_Type<Intrinsic_T>::ruby_data_type(), this->arg_ && this->arg_->isOwner());
|
537
519
|
}
|
538
|
-
// Will fall through to the type exception if we get here
|
539
520
|
}
|
540
521
|
default:
|
541
522
|
{
|
@@ -546,7 +527,6 @@ namespace Rice::detail
|
|
546
527
|
|
547
528
|
private:
|
548
529
|
Arg* arg_ = nullptr;
|
549
|
-
ArrayHelper<T>* arrayHelper_ = nullptr;
|
550
530
|
};
|
551
531
|
|
552
532
|
template<typename T>
|
@@ -554,6 +534,14 @@ namespace Rice::detail
|
|
554
534
|
{
|
555
535
|
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
556
536
|
"Data_Object cannot be used with fundamental types");
|
537
|
+
|
538
|
+
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
539
|
+
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
540
|
+
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
541
|
+
!std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
|
542
|
+
!std::is_same_v<T, std::vector<T>>,
|
543
|
+
"Please include rice/stl.hpp header for STL support");
|
544
|
+
|
557
545
|
public:
|
558
546
|
From_Ruby() = default;
|
559
547
|
|
@@ -583,7 +571,7 @@ namespace Rice::detail
|
|
583
571
|
}
|
584
572
|
else
|
585
573
|
{
|
586
|
-
return
|
574
|
+
return detail::unwrap<Intrinsic_T>(value, Data_Type<Intrinsic_T>::ruby_data_type(), this->arg_ && this->arg_->isOwner());
|
587
575
|
}
|
588
576
|
}
|
589
577
|
|
@@ -596,6 +584,14 @@ namespace Rice::detail
|
|
596
584
|
{
|
597
585
|
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
598
586
|
"Data_Object cannot be used with fundamental types");
|
587
|
+
|
588
|
+
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
589
|
+
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
590
|
+
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
591
|
+
!std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
|
592
|
+
!std::is_same_v<T, std::vector<T>>,
|
593
|
+
"Please include rice/stl.hpp header for STL support");
|
594
|
+
|
599
595
|
using Intrinsic_T = intrinsic_type<T>;
|
600
596
|
public:
|
601
597
|
From_Ruby() = default;
|
@@ -609,7 +605,7 @@ namespace Rice::detail
|
|
609
605
|
switch (rb_type(value))
|
610
606
|
{
|
611
607
|
case RUBY_T_DATA:
|
612
|
-
return Data_Type<T
|
608
|
+
return Data_Type<Buffer<T*>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
|
613
609
|
break;
|
614
610
|
case RUBY_T_NIL:
|
615
611
|
return Convertible::Exact;
|
@@ -628,7 +624,8 @@ namespace Rice::detail
|
|
628
624
|
{
|
629
625
|
case RUBY_T_DATA:
|
630
626
|
{
|
631
|
-
|
627
|
+
Buffer<Intrinsic_T*>* buffer = detail::unwrap<Buffer<Intrinsic_T*>>(value, Data_Type<Buffer<Intrinsic_T*>>::ruby_data_type(), false);
|
628
|
+
return buffer->ptr();
|
632
629
|
break;
|
633
630
|
}
|
634
631
|
case RUBY_T_NIL:
|
@@ -636,11 +633,6 @@ namespace Rice::detail
|
|
636
633
|
return nullptr;
|
637
634
|
break;
|
638
635
|
}
|
639
|
-
case RUBY_T_ARRAY:
|
640
|
-
{
|
641
|
-
this->vector_ = Array(value).to_vector<Intrinsic_T*>();
|
642
|
-
return this->vector_.data();
|
643
|
-
}
|
644
636
|
default:
|
645
637
|
{
|
646
638
|
throw create_type_exception<Intrinsic_T>(value);
|
@@ -658,6 +650,14 @@ namespace Rice::detail
|
|
658
650
|
{
|
659
651
|
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
660
652
|
"Data_Object cannot be used with fundamental types");
|
653
|
+
|
654
|
+
static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
|
655
|
+
!std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
|
656
|
+
!std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
|
657
|
+
!std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
|
658
|
+
!std::is_same_v<T, std::vector<T>>,
|
659
|
+
"Please include rice/stl.hpp header for STL support");
|
660
|
+
|
661
661
|
public:
|
662
662
|
Convertible is_convertible(VALUE value)
|
663
663
|
{
|
data/rice/Data_Type.hpp
CHANGED
@@ -43,7 +43,7 @@ namespace Rice
|
|
43
43
|
* bound.
|
44
44
|
* \return *this
|
45
45
|
*/
|
46
|
-
|
46
|
+
Data_Type& operator=(Module const & klass);
|
47
47
|
|
48
48
|
/*! Creates a singleton method allocate and an instance method called
|
49
49
|
* initialize which together create a new instance of the class. The
|
@@ -114,7 +114,8 @@ namespace Rice
|
|
114
114
|
*/
|
115
115
|
static bool is_bound();
|
116
116
|
static void check_is_bound();
|
117
|
-
static bool is_defined(
|
117
|
+
static bool is_defined();
|
118
|
+
static bool check_defined(const std::string& name, Object parent = rb_cObject);
|
118
119
|
|
119
120
|
// This is only for testing - DO NOT USE!!!
|
120
121
|
static void unbind();
|
@@ -174,9 +175,7 @@ namespace Rice
|
|
174
175
|
// Typed Data support
|
175
176
|
static inline rb_data_type_t* rb_data_type_ = nullptr;
|
176
177
|
|
177
|
-
|
178
|
-
// before define_class is called)
|
179
|
-
static inline std::set<Data_Type<T>*>unbound_instances_;
|
178
|
+
static inline std::set<Data_Type<T>*>& unbound_instances();
|
180
179
|
};
|
181
180
|
|
182
181
|
//! Define a new data class in the namespace given by module.
|