rice 4.7.1 → 4.9.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 +37 -1
- data/CMakeLists.txt +14 -22
- data/CMakePresets.json +203 -75
- data/FindRuby.cmake +358 -123
- data/bin/rice-doc.rb +58 -141
- data/include/rice/api.hpp +261 -0
- data/include/rice/rice.hpp +2459 -1693
- data/include/rice/stl.hpp +450 -546
- data/lib/rice/doc/config.rb +70 -0
- data/lib/rice/doc/cpp_reference.rb +1 -4
- data/lib/rice/doc/mkdocs.rb +58 -20
- data/lib/rice/doc/rice.rb +21 -0
- data/lib/rice/doc.rb +1 -0
- data/lib/rice/make_rice_headers.rb +7 -0
- data/lib/rice/native_registry.rb +5 -10
- data/lib/rice/rbs.rb +6 -6
- data/lib/rice/version.rb +1 -1
- data/lib/rubygems_plugin.rb +12 -9
- data/rice/Arg.hpp +12 -6
- data/rice/Arg.ipp +14 -7
- data/rice/Buffer.ipp +44 -40
- data/rice/Callback.hpp +1 -1
- data/rice/Callback.ipp +2 -7
- data/rice/Constructor.hpp +1 -1
- data/rice/Constructor.ipp +11 -11
- data/rice/Data_Object.ipp +15 -15
- data/rice/Data_Type.hpp +9 -10
- data/rice/Data_Type.ipp +33 -31
- data/rice/Director.hpp +1 -0
- data/rice/Enum.ipp +58 -39
- data/rice/Exception.hpp +4 -4
- data/rice/Exception.ipp +7 -7
- data/rice/NoGVL.hpp +13 -0
- data/rice/Reference.hpp +56 -0
- data/rice/Reference.ipp +96 -0
- data/rice/Return.hpp +4 -1
- data/rice/Return.ipp +0 -6
- data/rice/cpp_api/Array.hpp +41 -4
- data/rice/cpp_api/Array.ipp +105 -9
- data/rice/cpp_api/Class.hpp +7 -2
- data/rice/cpp_api/Class.ipp +9 -4
- data/rice/cpp_api/Hash.ipp +7 -4
- data/rice/cpp_api/Module.hpp +4 -4
- data/rice/cpp_api/Module.ipp +12 -10
- data/rice/cpp_api/Object.hpp +10 -4
- data/rice/cpp_api/Object.ipp +20 -12
- data/rice/cpp_api/String.hpp +2 -2
- data/rice/cpp_api/String.ipp +11 -8
- data/rice/cpp_api/Symbol.ipp +7 -7
- data/rice/cpp_api/shared_methods.hpp +5 -9
- data/rice/detail/Forwards.hpp +18 -0
- data/rice/detail/Forwards.ipp +60 -0
- data/rice/detail/InstanceRegistry.hpp +0 -2
- data/rice/detail/Native.hpp +31 -21
- data/rice/detail/Native.ipp +282 -130
- data/rice/detail/NativeAttributeGet.hpp +5 -7
- data/rice/detail/NativeAttributeGet.ipp +26 -26
- data/rice/detail/NativeAttributeSet.hpp +2 -4
- data/rice/detail/NativeAttributeSet.ipp +20 -16
- data/rice/detail/NativeCallback.hpp +77 -0
- data/rice/detail/NativeCallback.ipp +280 -0
- data/rice/detail/NativeFunction.hpp +11 -21
- data/rice/detail/NativeFunction.ipp +58 -119
- data/rice/detail/NativeInvoker.hpp +4 -4
- data/rice/detail/NativeInvoker.ipp +7 -7
- data/rice/detail/NativeIterator.hpp +2 -4
- data/rice/detail/NativeIterator.ipp +18 -14
- data/rice/detail/NativeMethod.hpp +10 -20
- data/rice/detail/NativeMethod.ipp +54 -114
- data/rice/detail/NativeProc.hpp +5 -7
- data/rice/detail/NativeProc.ipp +39 -28
- data/rice/detail/NativeRegistry.hpp +1 -1
- data/rice/detail/NativeRegistry.ipp +29 -0
- data/rice/detail/Parameter.hpp +15 -8
- data/rice/detail/Parameter.ipp +102 -43
- data/rice/detail/Proc.ipp +14 -28
- data/rice/detail/RubyType.ipp +2 -53
- data/rice/detail/Type.hpp +23 -7
- data/rice/detail/Type.ipp +77 -93
- data/rice/detail/TypeRegistry.ipp +5 -4
- data/rice/detail/Wrapper.hpp +13 -12
- data/rice/detail/Wrapper.ipp +97 -44
- data/rice/detail/from_ruby.hpp +8 -6
- data/rice/detail/from_ruby.ipp +306 -173
- data/rice/detail/ruby.hpp +23 -0
- data/rice/libc/file.hpp +4 -4
- data/rice/rice.hpp +9 -8
- data/rice/rice_api/Native.ipp +5 -1
- data/rice/rice_api/NativeRegistry.ipp +14 -1
- data/rice/rice_api/Parameter.ipp +1 -1
- data/rice/ruby_mark.hpp +2 -1
- data/rice/stl/complex.ipp +12 -8
- data/rice/stl/map.ipp +27 -22
- data/rice/stl/monostate.ipp +16 -12
- data/rice/stl/multimap.hpp +0 -2
- data/rice/stl/multimap.ipp +27 -22
- data/rice/stl/optional.ipp +27 -11
- data/rice/stl/pair.ipp +5 -5
- data/rice/stl/reference_wrapper.ipp +5 -4
- data/rice/stl/set.ipp +16 -16
- data/rice/stl/shared_ptr.hpp +9 -9
- data/rice/stl/shared_ptr.ipp +52 -185
- data/rice/stl/string.ipp +18 -18
- data/rice/stl/string_view.ipp +1 -1
- data/rice/stl/tuple.ipp +15 -36
- data/rice/stl/unique_ptr.hpp +9 -3
- data/rice/stl/unique_ptr.ipp +86 -120
- data/rice/stl/unordered_map.ipp +20 -15
- data/rice/stl/variant.ipp +37 -21
- data/rice/stl/vector.ipp +41 -36
- data/rice/traits/function_traits.hpp +19 -19
- data/rice/traits/method_traits.hpp +4 -4
- data/rice/traits/rice_traits.hpp +162 -39
- data/rice.gemspec +1 -3
- data/test/test_Array.cpp +261 -3
- data/test/test_Attribute.cpp +6 -3
- data/test/test_Buffer.cpp +6 -42
- data/test/test_Callback.cpp +77 -23
- data/test/test_Data_Object.cpp +1 -1
- data/test/test_Data_Type.cpp +21 -22
- data/test/test_Director.cpp +2 -4
- data/test/test_Enum.cpp +34 -5
- data/test/test_File.cpp +9 -5
- data/test/test_From_Ruby.cpp +4 -3
- data/test/test_GVL.cpp +3 -3
- data/test/test_Hash.cpp +1 -1
- data/test/test_Inheritance.cpp +14 -14
- data/test/test_Iterator.cpp +54 -22
- data/test/test_Keep_Alive.cpp +1 -1
- data/test/test_Keep_Alive_No_Wrapper.cpp +7 -3
- data/test/test_Module.cpp +5 -5
- data/test/test_Overloads.cpp +345 -48
- data/test/test_Proc.cpp +54 -0
- data/test/test_Reference.cpp +181 -0
- data/test/test_Self.cpp +2 -2
- data/test/test_Stl_Set.cpp +6 -6
- data/test/test_Stl_SharedPtr.cpp +172 -33
- data/test/test_Stl_String_View.cpp +4 -2
- data/test/test_Stl_Tuple.cpp +1 -1
- data/test/test_Stl_UniquePtr.cpp +48 -3
- data/test/test_Stl_Variant.cpp +6 -14
- data/test/test_Stl_Vector.cpp +61 -30
- data/test/test_String.cpp +4 -2
- data/test/test_Struct.cpp +1 -1
- data/test/test_Symbol.cpp +1 -1
- data/test/test_To_Ruby.cpp +1 -0
- data/test/test_Type.cpp +36 -35
- data/test/test_global_functions.cpp +1 -1
- data/test/unittest.cpp +1 -1
- data/test/unittest.hpp +5 -5
- metadata +12 -10
- data/rice/Function.hpp +0 -17
- data/rice/Function.ipp +0 -13
- data/rice/detail/MethodInfo.hpp +0 -48
- data/rice/detail/MethodInfo.ipp +0 -99
- data/rice/detail/NativeCallbackFFI.hpp +0 -55
- data/rice/detail/NativeCallbackFFI.ipp +0 -152
- data/rice/detail/NativeCallbackSimple.hpp +0 -30
- data/rice/detail/NativeCallbackSimple.ipp +0 -29
data/rice/detail/Type.ipp
CHANGED
|
@@ -71,37 +71,20 @@ namespace Rice::detail
|
|
|
71
71
|
{
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
-
// ----------
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
// ---------- TypeIndexParser ------------
|
|
75
|
+
inline TypeIndexParser::TypeIndexParser(const std::type_index& typeIndex, bool isFundamental) :
|
|
76
|
+
typeIndex_(typeIndex), isFundamental_(isFundamental)
|
|
77
77
|
{
|
|
78
|
-
|
|
79
|
-
struct Helper
|
|
80
|
-
{
|
|
81
|
-
Helper(
|
|
82
|
-
char const* mangled_name)
|
|
83
|
-
: name_(0)
|
|
84
|
-
{
|
|
85
|
-
int status = 0;
|
|
86
|
-
name_ = abi::__cxa_demangle(mangled_name, 0, 0, &status);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
~Helper()
|
|
90
|
-
{
|
|
91
|
-
std::free(name_);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
char* name_;
|
|
95
|
-
|
|
96
|
-
private:
|
|
97
|
-
Helper(Helper const&);
|
|
98
|
-
void operator=(Helper const&);
|
|
99
|
-
};
|
|
78
|
+
}
|
|
100
79
|
|
|
101
|
-
|
|
102
|
-
|
|
80
|
+
inline std::string TypeIndexParser::demangle(char const* mangled_name)
|
|
81
|
+
{
|
|
82
|
+
#ifdef __GNUC__
|
|
83
|
+
int status = 0;
|
|
84
|
+
char* name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
|
|
85
|
+
if (name)
|
|
103
86
|
{
|
|
104
|
-
return
|
|
87
|
+
return name;
|
|
105
88
|
}
|
|
106
89
|
else
|
|
107
90
|
{
|
|
@@ -112,17 +95,9 @@ namespace Rice::detail
|
|
|
112
95
|
#endif
|
|
113
96
|
}
|
|
114
97
|
|
|
115
|
-
|
|
116
|
-
inline std::string TypeMapper<T>::name()
|
|
98
|
+
inline std::string TypeIndexParser::name()
|
|
117
99
|
{
|
|
118
|
-
|
|
119
|
-
return demangle(typeIndex.name());
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
template<typename T>
|
|
123
|
-
inline std::string TypeMapper<T>::name(const std::type_index& typeIndex)
|
|
124
|
-
{
|
|
125
|
-
return demangle(typeIndex.name());
|
|
100
|
+
return this->demangle(this->typeIndex_.name());
|
|
126
101
|
}
|
|
127
102
|
|
|
128
103
|
// Find text inside of < > taking into account nested groups.
|
|
@@ -130,8 +105,7 @@ namespace Rice::detail
|
|
|
130
105
|
// Example:
|
|
131
106
|
//
|
|
132
107
|
// std::vector<std::vector<int>, std::allocator<std::vector, std::allocator<int>>>
|
|
133
|
-
|
|
134
|
-
inline std::string TypeMapper<T>::findGroup(std::string& string, size_t offset)
|
|
108
|
+
inline std::string TypeIndexParser::findGroup(std::string& string, size_t offset)
|
|
135
109
|
{
|
|
136
110
|
int depth = 0;
|
|
137
111
|
|
|
@@ -164,8 +138,7 @@ namespace Rice::detail
|
|
|
164
138
|
throw std::runtime_error("Unbalanced Group");
|
|
165
139
|
}
|
|
166
140
|
|
|
167
|
-
|
|
168
|
-
inline void TypeMapper<T>::replaceAll(std::string& string, std::regex regex, std::string replacement)
|
|
141
|
+
inline void TypeIndexParser::replaceAll(std::string& string, std::regex regex, std::string replacement)
|
|
169
142
|
{
|
|
170
143
|
std::smatch match;
|
|
171
144
|
while (std::regex_search(string, match, regex))
|
|
@@ -174,8 +147,7 @@ namespace Rice::detail
|
|
|
174
147
|
}
|
|
175
148
|
}
|
|
176
149
|
|
|
177
|
-
|
|
178
|
-
inline void TypeMapper<T>::removeGroup(std::string& string, std::regex regex)
|
|
150
|
+
inline void TypeIndexParser::removeGroup(std::string& string, std::regex regex)
|
|
179
151
|
{
|
|
180
152
|
std::smatch match;
|
|
181
153
|
while (std::regex_search(string, match, regex))
|
|
@@ -186,8 +158,7 @@ namespace Rice::detail
|
|
|
186
158
|
}
|
|
187
159
|
}
|
|
188
160
|
|
|
189
|
-
|
|
190
|
-
inline void TypeMapper<T>::replaceGroup(std::string& string, std::regex regex, std::string replacement)
|
|
161
|
+
inline void TypeIndexParser::replaceGroup(std::string& string, std::regex regex, std::string replacement)
|
|
191
162
|
{
|
|
192
163
|
std::smatch match;
|
|
193
164
|
while (std::regex_search(string, match, regex))
|
|
@@ -198,8 +169,7 @@ namespace Rice::detail
|
|
|
198
169
|
}
|
|
199
170
|
}
|
|
200
171
|
|
|
201
|
-
|
|
202
|
-
inline std::string TypeMapper<T>::simplifiedName()
|
|
172
|
+
inline std::string TypeIndexParser::simplifiedName()
|
|
203
173
|
{
|
|
204
174
|
std::string base = this->name();
|
|
205
175
|
|
|
@@ -239,6 +209,10 @@ namespace Rice::detail
|
|
|
239
209
|
std::regex equalRegex(R"(,\s*std::equal_to)");
|
|
240
210
|
removeGroup(base, equalRegex);
|
|
241
211
|
|
|
212
|
+
// Remove default_delete (std::unique_ptr)
|
|
213
|
+
std::regex defaultDeleteRegex(R"(,\s*std::default_delete)");
|
|
214
|
+
removeGroup(base, defaultDeleteRegex);
|
|
215
|
+
|
|
242
216
|
// Remove spaces before pointers
|
|
243
217
|
std::regex ptrRegex = std::regex(R"(\s+\*)");
|
|
244
218
|
base = std::regex_replace(base, ptrRegex, "*");
|
|
@@ -271,42 +245,9 @@ namespace Rice::detail
|
|
|
271
245
|
return base;
|
|
272
246
|
}
|
|
273
247
|
|
|
274
|
-
|
|
275
|
-
inline void TypeMapper<T>::capitalizeHelper(std::string& content, std::regex& regex)
|
|
248
|
+
inline std::string TypeIndexParser::rubyName(std::string rubyTypeName)
|
|
276
249
|
{
|
|
277
|
-
std::
|
|
278
|
-
while (std::regex_search(content, match, regex))
|
|
279
|
-
{
|
|
280
|
-
std::string replacement = match[1];
|
|
281
|
-
std::transform(replacement.begin(), replacement.end(), replacement.begin(), ::toupper);
|
|
282
|
-
content.replace(match.position(), match.length(), replacement);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
template<typename T>
|
|
287
|
-
inline std::string TypeMapper<T>::rubyTypeName()
|
|
288
|
-
{
|
|
289
|
-
using Intrinsic_T = detail::intrinsic_type<T>;
|
|
290
|
-
|
|
291
|
-
if constexpr (std::is_fundamental_v<T>)
|
|
292
|
-
{
|
|
293
|
-
return RubyType<Intrinsic_T>::name;
|
|
294
|
-
}
|
|
295
|
-
else if constexpr (std::is_same_v<std::remove_cv_t<T>, char*>)
|
|
296
|
-
{
|
|
297
|
-
return "String";
|
|
298
|
-
}
|
|
299
|
-
else
|
|
300
|
-
{
|
|
301
|
-
detail::TypeMapper<Intrinsic_T> typeIntrinsicMapper;
|
|
302
|
-
return typeIntrinsicMapper.simplifiedName();
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
template<typename T>
|
|
307
|
-
inline std::string TypeMapper<T>::rubyName()
|
|
308
|
-
{
|
|
309
|
-
std::string base = this->rubyTypeName();
|
|
250
|
+
std::string base = rubyTypeName;
|
|
310
251
|
|
|
311
252
|
// Remove std:: these could be embedded in template types
|
|
312
253
|
auto stdRegex = std::regex("std::");
|
|
@@ -318,50 +259,93 @@ namespace Rice::detail
|
|
|
318
259
|
base = std::regex_replace(base, leadingNamespacesRegex, "");
|
|
319
260
|
|
|
320
261
|
// Capitalize first letter
|
|
321
|
-
base[0] = std::toupper(base[0]);
|
|
262
|
+
base[0] = (char)std::toupper(base[0]);
|
|
322
263
|
|
|
323
264
|
// Replace :: with unicode U+u02F8 (Modified Letter raised colon)
|
|
324
265
|
auto colonRegex = std::regex(R"(:)");
|
|
325
|
-
replaceAll(base, colonRegex, "\uA789");
|
|
266
|
+
this->replaceAll(base, colonRegex, "\uA789");
|
|
326
267
|
|
|
327
268
|
// Replace _ and capitalize the next letter
|
|
328
269
|
std::regex underscoreRegex(R"(_(\w))");
|
|
329
|
-
capitalizeHelper(base, underscoreRegex);
|
|
270
|
+
this->capitalizeHelper(base, underscoreRegex);
|
|
330
271
|
|
|
331
|
-
if
|
|
272
|
+
if (this->isFundamental_)
|
|
332
273
|
{
|
|
333
274
|
// Replace space and capitalize the next letter
|
|
334
275
|
std::regex spaceRegex(R"(\s+(\w))");
|
|
335
|
-
capitalizeHelper(base, spaceRegex);
|
|
276
|
+
this->capitalizeHelper(base, spaceRegex);
|
|
336
277
|
}
|
|
337
278
|
else
|
|
338
279
|
{
|
|
339
280
|
// Replace spaces with unicode U+u00A0 (Non breaking Space)
|
|
340
281
|
std::regex spaceRegex = std::regex(R"(\s+)");
|
|
341
|
-
replaceAll(base, spaceRegex, "\u00A0");
|
|
282
|
+
this->replaceAll(base, spaceRegex, "\u00A0");
|
|
342
283
|
}
|
|
343
284
|
|
|
344
285
|
// Replace < with unicode U+227A (Precedes)
|
|
345
286
|
auto lessThanRegex = std::regex("<");
|
|
346
287
|
//replaceAll(base, lessThanRegex, "≺");
|
|
347
|
-
replaceAll(base, lessThanRegex, "\u227A");
|
|
288
|
+
this->replaceAll(base, lessThanRegex, "\u227A");
|
|
348
289
|
|
|
349
290
|
// Replace > with unicode U+227B (Succeeds)
|
|
350
291
|
auto greaterThanRegex = std::regex(">");
|
|
351
292
|
//replaceAll(base, greaterThanRegex, "≻");
|
|
352
|
-
replaceAll(base, greaterThanRegex, "\u227B");
|
|
293
|
+
this->replaceAll(base, greaterThanRegex, "\u227B");
|
|
353
294
|
|
|
354
295
|
// Replace , with Unicode Character (U+066C) - Arabic Thousands Separator
|
|
355
296
|
auto commaRegex = std::regex(R"(,\s*)");
|
|
356
|
-
replaceAll(base, commaRegex, "\u201A");
|
|
297
|
+
this->replaceAll(base, commaRegex, "\u201A");
|
|
357
298
|
|
|
358
299
|
// Replace * with Unicode Character (U+2217) - Asterisk Operator
|
|
359
300
|
auto asteriskRegex = std::regex(R"(\*)");
|
|
360
|
-
replaceAll(base, asteriskRegex, "\u2217");
|
|
301
|
+
this->replaceAll(base, asteriskRegex, "\u2217");
|
|
361
302
|
|
|
362
303
|
return base;
|
|
363
304
|
}
|
|
364
305
|
|
|
306
|
+
inline void TypeIndexParser::capitalizeHelper(std::string& content, std::regex& regex)
|
|
307
|
+
{
|
|
308
|
+
std::smatch match;
|
|
309
|
+
while (std::regex_search(content, match, regex))
|
|
310
|
+
{
|
|
311
|
+
std::string replacement = match[1];
|
|
312
|
+
std::transform(replacement.begin(), replacement.end(), replacement.begin(),
|
|
313
|
+
[](unsigned char c) -> char
|
|
314
|
+
{
|
|
315
|
+
return static_cast<char>(std::toupper(c));
|
|
316
|
+
});
|
|
317
|
+
content.replace(match.position(), match.length(), replacement);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// ---------- TypeMapper ------------
|
|
322
|
+
template<typename T>
|
|
323
|
+
inline std::string TypeMapper<T>::rubyTypeName()
|
|
324
|
+
{
|
|
325
|
+
using Intrinsic_T = detail::intrinsic_type<T>;
|
|
326
|
+
|
|
327
|
+
if constexpr (std::is_fundamental_v<T>)
|
|
328
|
+
{
|
|
329
|
+
return RubyType<Intrinsic_T>::name;
|
|
330
|
+
}
|
|
331
|
+
else if constexpr (std::is_same_v<std::remove_cv_t<T>, char*>)
|
|
332
|
+
{
|
|
333
|
+
return "String";
|
|
334
|
+
}
|
|
335
|
+
else
|
|
336
|
+
{
|
|
337
|
+
detail::TypeIndexParser typeIndexParser(typeid(Intrinsic_T), std::is_fundamental_v<detail::intrinsic_type<Intrinsic_T>>);
|
|
338
|
+
return typeIndexParser.simplifiedName();
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
template<typename T>
|
|
343
|
+
inline std::string TypeMapper<T>::rubyName()
|
|
344
|
+
{
|
|
345
|
+
std::string base = this->rubyTypeName();
|
|
346
|
+
return this->typeIndexParser_.rubyName(base);
|
|
347
|
+
}
|
|
348
|
+
|
|
365
349
|
template<typename T>
|
|
366
350
|
inline VALUE TypeMapper<T>::rubyKlass()
|
|
367
351
|
{
|
|
@@ -97,8 +97,9 @@ namespace Rice::detail
|
|
|
97
97
|
return result.value();
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
detail::
|
|
101
|
-
raiseUnverifiedType(
|
|
100
|
+
detail::TypeIndexParser typeIndexParser(typeid(T), std::is_fundamental_v<detail::intrinsic_type<T>>);
|
|
101
|
+
raiseUnverifiedType(typeIndexParser.name());
|
|
102
|
+
|
|
102
103
|
// Make the compiler happy
|
|
103
104
|
return std::pair<VALUE, rb_data_type_t*>(Qnil, nullptr);
|
|
104
105
|
}
|
|
@@ -131,8 +132,8 @@ namespace Rice::detail
|
|
|
131
132
|
|
|
132
133
|
for (const std::type_index& typeIndex : this->unverified_)
|
|
133
134
|
{
|
|
134
|
-
detail::
|
|
135
|
-
stream << " " <<
|
|
135
|
+
detail::TypeIndexParser typeIndexParser(typeIndex);
|
|
136
|
+
stream << " " << typeIndexParser.name() << "\n";
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
throw std::invalid_argument(stream.str());
|
data/rice/detail/Wrapper.hpp
CHANGED
|
@@ -6,9 +6,9 @@ namespace Rice::detail
|
|
|
6
6
|
class WrapperBase
|
|
7
7
|
{
|
|
8
8
|
public:
|
|
9
|
-
WrapperBase()
|
|
9
|
+
WrapperBase(rb_data_type_t* rb_data_type);
|
|
10
10
|
virtual ~WrapperBase() = default;
|
|
11
|
-
virtual void* get() = 0;
|
|
11
|
+
virtual void* get(rb_data_type_t* requestedType) = 0;
|
|
12
12
|
bool isConst();
|
|
13
13
|
|
|
14
14
|
void ruby_mark();
|
|
@@ -16,6 +16,7 @@ namespace Rice::detail
|
|
|
16
16
|
void setOwner(bool value);
|
|
17
17
|
|
|
18
18
|
protected:
|
|
19
|
+
rb_data_type_t* rb_data_type_;
|
|
19
20
|
bool isOwner_ = false;
|
|
20
21
|
bool isConst_ = false;
|
|
21
22
|
|
|
@@ -30,10 +31,10 @@ namespace Rice::detail
|
|
|
30
31
|
class Wrapper : public WrapperBase
|
|
31
32
|
{
|
|
32
33
|
public:
|
|
33
|
-
Wrapper(T& data);
|
|
34
|
-
Wrapper(T&& data);
|
|
34
|
+
Wrapper(rb_data_type_t* rb_data_type, T& data);
|
|
35
|
+
Wrapper(rb_data_type_t* rb_data_type, T&& data);
|
|
35
36
|
~Wrapper();
|
|
36
|
-
void* get() override;
|
|
37
|
+
void* get(rb_data_type_t* requestedType) override;
|
|
37
38
|
|
|
38
39
|
private:
|
|
39
40
|
T data_;
|
|
@@ -43,9 +44,9 @@ namespace Rice::detail
|
|
|
43
44
|
class Wrapper<T&> : public WrapperBase
|
|
44
45
|
{
|
|
45
46
|
public:
|
|
46
|
-
Wrapper(T& data);
|
|
47
|
+
Wrapper(rb_data_type_t* rb_data_type, T& data);
|
|
47
48
|
~Wrapper();
|
|
48
|
-
void* get() override;
|
|
49
|
+
void* get(rb_data_type_t* requestedType) override;
|
|
49
50
|
|
|
50
51
|
private:
|
|
51
52
|
T& data_;
|
|
@@ -55,9 +56,9 @@ namespace Rice::detail
|
|
|
55
56
|
class Wrapper<T*> : public WrapperBase
|
|
56
57
|
{
|
|
57
58
|
public:
|
|
58
|
-
Wrapper(T* data, bool isOwner);
|
|
59
|
+
Wrapper(rb_data_type_t* rb_data_type, T* data, bool isOwner);
|
|
59
60
|
~Wrapper();
|
|
60
|
-
void* get() override;
|
|
61
|
+
void* get(rb_data_type_t* requestedType) override;
|
|
61
62
|
|
|
62
63
|
private:
|
|
63
64
|
T* data_ = nullptr;
|
|
@@ -67,9 +68,9 @@ namespace Rice::detail
|
|
|
67
68
|
class Wrapper<T**> : public WrapperBase
|
|
68
69
|
{
|
|
69
70
|
public:
|
|
70
|
-
Wrapper(T** data, bool isOwner);
|
|
71
|
+
Wrapper(rb_data_type_t* rb_data_type, T** data, bool isOwner);
|
|
71
72
|
~Wrapper();
|
|
72
|
-
void* get() override;
|
|
73
|
+
void* get(rb_data_type_t* requestedType) override;
|
|
73
74
|
|
|
74
75
|
private:
|
|
75
76
|
T** data_ = nullptr;
|
|
@@ -77,7 +78,7 @@ namespace Rice::detail
|
|
|
77
78
|
|
|
78
79
|
// ---- Helper Functions ---------
|
|
79
80
|
template <typename T>
|
|
80
|
-
void wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data
|
|
81
|
+
void wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data);
|
|
81
82
|
|
|
82
83
|
template <typename T>
|
|
83
84
|
VALUE wrap(VALUE klass, rb_data_type_t* rb_data_type, T& data, bool isOwner);
|
data/rice/detail/Wrapper.ipp
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Rice::detail
|
|
4
4
|
{
|
|
5
|
+
inline WrapperBase::WrapperBase(rb_data_type_t* rb_data_type) : rb_data_type_(rb_data_type)
|
|
6
|
+
{
|
|
7
|
+
}
|
|
8
|
+
|
|
5
9
|
inline bool WrapperBase::isConst()
|
|
6
10
|
{
|
|
7
11
|
return this->isConst_;
|
|
@@ -27,30 +31,40 @@ namespace Rice::detail
|
|
|
27
31
|
|
|
28
32
|
// ---- Wrapper -----
|
|
29
33
|
template <typename T>
|
|
30
|
-
inline Wrapper<T>::Wrapper(T& data): data_(data)
|
|
34
|
+
inline Wrapper<T>::Wrapper(rb_data_type_t* rb_data_type, T& data) : WrapperBase(rb_data_type), data_(data)
|
|
31
35
|
{
|
|
36
|
+
this->isConst_ = std::is_const_v<std::remove_reference_t<T>>;
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
template <typename T>
|
|
35
|
-
inline Wrapper<T>::Wrapper(T&& data) : data_(std::move(data))
|
|
40
|
+
inline Wrapper<T>::Wrapper(rb_data_type_t* rb_data_type, T&& data) : WrapperBase(rb_data_type), data_(std::move(data))
|
|
36
41
|
{
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
template <typename T>
|
|
40
45
|
inline Wrapper<T>::~Wrapper()
|
|
41
46
|
{
|
|
42
|
-
Registries::instance.instances.remove(this->get());
|
|
47
|
+
Registries::instance.instances.remove(this->get(this->rb_data_type_));
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
template <typename T>
|
|
46
|
-
inline void* Wrapper<T>::
|
|
51
|
+
inline void* Wrapper<T>::get(rb_data_type_t* requestedType)
|
|
47
52
|
{
|
|
48
|
-
|
|
53
|
+
if (rb_typeddata_inherited_p(this->rb_data_type_, requestedType))
|
|
54
|
+
{
|
|
55
|
+
return (void*)&this->data_;
|
|
56
|
+
}
|
|
57
|
+
else
|
|
58
|
+
{
|
|
59
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
|
|
60
|
+
this->rb_data_type_->wrap_struct_name,
|
|
61
|
+
requestedType->wrap_struct_name);
|
|
62
|
+
}
|
|
49
63
|
}
|
|
50
64
|
|
|
51
65
|
// ---- Wrapper& -----
|
|
52
66
|
template <typename T>
|
|
53
|
-
inline Wrapper<T&>::Wrapper(T& data): data_(data)
|
|
67
|
+
inline Wrapper<T&>::Wrapper(rb_data_type_t* rb_data_type, T& data) : WrapperBase(rb_data_type), data_(data)
|
|
54
68
|
{
|
|
55
69
|
this->isConst_ = std::is_const_v<std::remove_reference_t<T>>;
|
|
56
70
|
}
|
|
@@ -58,18 +72,27 @@ namespace Rice::detail
|
|
|
58
72
|
template <typename T>
|
|
59
73
|
inline Wrapper<T&>::~Wrapper()
|
|
60
74
|
{
|
|
61
|
-
Registries::instance.instances.remove(this->get());
|
|
75
|
+
Registries::instance.instances.remove(this->get(this->rb_data_type_));
|
|
62
76
|
}
|
|
63
77
|
|
|
64
78
|
template <typename T>
|
|
65
|
-
inline void* Wrapper<T&>::get()
|
|
79
|
+
inline void* Wrapper<T&>::get(rb_data_type_t* requestedType)
|
|
66
80
|
{
|
|
67
|
-
|
|
81
|
+
if (rb_typeddata_inherited_p(this->rb_data_type_, requestedType))
|
|
82
|
+
{
|
|
83
|
+
return (void*)&this->data_;
|
|
84
|
+
}
|
|
85
|
+
else
|
|
86
|
+
{
|
|
87
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
|
|
88
|
+
this->rb_data_type_->wrap_struct_name,
|
|
89
|
+
requestedType->wrap_struct_name);
|
|
90
|
+
}
|
|
68
91
|
}
|
|
69
92
|
|
|
70
93
|
// ---- Wrapper* -----
|
|
71
94
|
template <typename T>
|
|
72
|
-
inline Wrapper<T*>::Wrapper(T* data, bool isOwner) : data_(data)
|
|
95
|
+
inline Wrapper<T*>::Wrapper(rb_data_type_t* rb_data_type, T* data, bool isOwner) : WrapperBase(rb_data_type), data_(data)
|
|
73
96
|
{
|
|
74
97
|
this->isOwner_ = isOwner;
|
|
75
98
|
this->isConst_ = std::is_const_v<std::remove_pointer_t<T>>;
|
|
@@ -78,7 +101,8 @@ namespace Rice::detail
|
|
|
78
101
|
template <typename T>
|
|
79
102
|
inline Wrapper<T*>::~Wrapper()
|
|
80
103
|
{
|
|
81
|
-
Registries::instance.instances.remove(this->get());
|
|
104
|
+
Registries::instance.instances.remove(this->get(this->rb_data_type_));
|
|
105
|
+
|
|
82
106
|
if constexpr (std::is_destructible_v<T>)
|
|
83
107
|
{
|
|
84
108
|
if (this->isOwner_)
|
|
@@ -89,14 +113,23 @@ namespace Rice::detail
|
|
|
89
113
|
}
|
|
90
114
|
|
|
91
115
|
template <typename T>
|
|
92
|
-
inline void* Wrapper<T*>::get()
|
|
116
|
+
inline void* Wrapper<T*>::get(rb_data_type_t* requestedType)
|
|
93
117
|
{
|
|
94
|
-
|
|
118
|
+
if (rb_typeddata_inherited_p(this->rb_data_type_, requestedType))
|
|
119
|
+
{
|
|
120
|
+
return (void*)this->data_;
|
|
121
|
+
}
|
|
122
|
+
else
|
|
123
|
+
{
|
|
124
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
|
|
125
|
+
this->rb_data_type_->wrap_struct_name,
|
|
126
|
+
requestedType->wrap_struct_name);
|
|
127
|
+
}
|
|
95
128
|
}
|
|
96
129
|
|
|
97
130
|
// ---- Wrapper** -----
|
|
98
131
|
template <typename T>
|
|
99
|
-
inline Wrapper<T**>::Wrapper(T** data, bool isOwner) : data_(data)
|
|
132
|
+
inline Wrapper<T**>::Wrapper(rb_data_type_t* rb_data_type, T** data, bool isOwner) : WrapperBase(rb_data_type), data_(data)
|
|
100
133
|
{
|
|
101
134
|
this->isOwner_ = isOwner;
|
|
102
135
|
this->isConst_ = std::is_const_v<std::remove_pointer_t<std::remove_pointer_t<T>>>;
|
|
@@ -105,7 +138,8 @@ namespace Rice::detail
|
|
|
105
138
|
template <typename T>
|
|
106
139
|
inline Wrapper<T**>::~Wrapper()
|
|
107
140
|
{
|
|
108
|
-
Registries::instance.instances.remove(this->get());
|
|
141
|
+
Registries::instance.instances.remove(this->get(this->rb_data_type_));
|
|
142
|
+
|
|
109
143
|
if constexpr (std::is_destructible_v<T>)
|
|
110
144
|
{
|
|
111
145
|
if (this->isOwner_)
|
|
@@ -116,9 +150,18 @@ namespace Rice::detail
|
|
|
116
150
|
}
|
|
117
151
|
|
|
118
152
|
template <typename T>
|
|
119
|
-
inline void* Wrapper<T**>::get()
|
|
153
|
+
inline void* Wrapper<T**>::get(rb_data_type_t* requestedType)
|
|
120
154
|
{
|
|
121
|
-
|
|
155
|
+
if (rb_typeddata_inherited_p(this->rb_data_type_, requestedType))
|
|
156
|
+
{
|
|
157
|
+
return (void*)this->data_;
|
|
158
|
+
}
|
|
159
|
+
else
|
|
160
|
+
{
|
|
161
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
|
|
162
|
+
this->rb_data_type_->wrap_struct_name,
|
|
163
|
+
requestedType->wrap_struct_name);
|
|
164
|
+
}
|
|
122
165
|
}
|
|
123
166
|
|
|
124
167
|
// ---- Helper Functions -------
|
|
@@ -135,21 +178,21 @@ namespace Rice::detail
|
|
|
135
178
|
// If Ruby is not the owner then wrap the reference
|
|
136
179
|
if (!isOwner)
|
|
137
180
|
{
|
|
138
|
-
wrapper = new Wrapper<T&>(data);
|
|
181
|
+
wrapper = new Wrapper<T&>(rb_data_type, data);
|
|
139
182
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
140
183
|
}
|
|
141
184
|
|
|
142
|
-
// std::is_copy_constructible_v<std::vector<std::unique_ptr<T>>>>
|
|
185
|
+
// std::is_copy_constructible_v<std::vector<std::unique_ptr<T>>>> returns true. Sigh.
|
|
143
186
|
else if constexpr (detail::is_std_vector_v<T>)
|
|
144
187
|
{
|
|
145
188
|
if constexpr (std::is_copy_constructible_v<typename T::value_type>)
|
|
146
189
|
{
|
|
147
|
-
wrapper = new Wrapper<T>(data);
|
|
190
|
+
wrapper = new Wrapper<T>(rb_data_type, data);
|
|
148
191
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
149
192
|
}
|
|
150
193
|
else
|
|
151
194
|
{
|
|
152
|
-
wrapper = new Wrapper<T>(std::move(data));
|
|
195
|
+
wrapper = new Wrapper<T>(rb_data_type, std::move(data));
|
|
153
196
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
154
197
|
}
|
|
155
198
|
}
|
|
@@ -157,26 +200,26 @@ namespace Rice::detail
|
|
|
157
200
|
// Ruby is the owner so copy data
|
|
158
201
|
else if constexpr (std::is_copy_constructible_v<T>)
|
|
159
202
|
{
|
|
160
|
-
wrapper = new Wrapper<T>(data);
|
|
203
|
+
wrapper = new Wrapper<T>(rb_data_type, data);
|
|
161
204
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
162
205
|
}
|
|
163
206
|
|
|
164
207
|
// Ruby is the owner so move data
|
|
165
208
|
else if constexpr (std::is_move_constructible_v<T>)
|
|
166
209
|
{
|
|
167
|
-
wrapper = new Wrapper<T>(std::move(data));
|
|
210
|
+
wrapper = new Wrapper<T>(rb_data_type, std::move(data));
|
|
168
211
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
169
212
|
}
|
|
170
213
|
|
|
171
214
|
else
|
|
172
215
|
{
|
|
173
|
-
detail::
|
|
216
|
+
detail::TypeIndexParser typeIndexParser(typeid(T), std::is_fundamental_v<detail::intrinsic_type<T>>);
|
|
174
217
|
std::string message = "Rice was directed to take ownership of a C++ object but it does not have an accessible copy or move constructor. Type: " +
|
|
175
|
-
|
|
218
|
+
typeIndexParser.name();
|
|
176
219
|
throw std::runtime_error(message);
|
|
177
220
|
}
|
|
178
221
|
|
|
179
|
-
Registries::instance.instances.add(wrapper->get(), result);
|
|
222
|
+
Registries::instance.instances.add(wrapper->get(rb_data_type), result);
|
|
180
223
|
|
|
181
224
|
return result;
|
|
182
225
|
};
|
|
@@ -189,37 +232,40 @@ namespace Rice::detail
|
|
|
189
232
|
if (result != Qnil)
|
|
190
233
|
return result;
|
|
191
234
|
|
|
192
|
-
WrapperBase* wrapper = new Wrapper<T*>(data, isOwner);
|
|
235
|
+
WrapperBase* wrapper = new Wrapper<T*>(rb_data_type, data, isOwner);
|
|
193
236
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
194
237
|
|
|
195
|
-
Registries::instance.instances.add(wrapper->get(), result);
|
|
238
|
+
Registries::instance.instances.add(wrapper->get(rb_data_type), result);
|
|
196
239
|
return result;
|
|
197
240
|
};
|
|
198
241
|
|
|
199
242
|
template <typename T>
|
|
200
243
|
inline T* unwrap(VALUE value, rb_data_type_t* rb_data_type, bool takeOwnership)
|
|
201
244
|
{
|
|
202
|
-
if (
|
|
245
|
+
if (!RTYPEDDATA_P(value))
|
|
203
246
|
{
|
|
204
|
-
std::string message = "The
|
|
247
|
+
std::string message = "The Ruby object does not wrap a C++ object. It is actually a " +
|
|
248
|
+
std::string(detail::protect(rb_obj_classname, value)) + ".";
|
|
205
249
|
throw std::runtime_error(message);
|
|
206
250
|
}
|
|
207
251
|
|
|
208
|
-
WrapperBase* wrapper =
|
|
252
|
+
WrapperBase* wrapper = static_cast<WrapperBase*>(RTYPEDDATA_DATA(value));
|
|
209
253
|
|
|
210
254
|
if (wrapper == nullptr)
|
|
211
255
|
{
|
|
212
|
-
std::string message = "Wrapped C++ object is nil. Did you override " +
|
|
213
|
-
std::string(detail::protect(rb_obj_classname, value)) +
|
|
256
|
+
std::string message = "Wrapped C++ object is nil. Did you override " +
|
|
257
|
+
std::string(detail::protect(rb_obj_classname, value)) +
|
|
214
258
|
"#initialize and forget to call super?";
|
|
215
259
|
|
|
216
260
|
throw std::runtime_error(message);
|
|
217
261
|
}
|
|
218
262
|
|
|
219
263
|
if (takeOwnership)
|
|
264
|
+
{
|
|
220
265
|
wrapper->setOwner(false);
|
|
266
|
+
}
|
|
221
267
|
|
|
222
|
-
return static_cast<T*>(wrapper->get());
|
|
268
|
+
return static_cast<T*>(wrapper->get(rb_data_type));
|
|
223
269
|
}
|
|
224
270
|
|
|
225
271
|
template <typename Wrapper_T>
|
|
@@ -233,12 +279,19 @@ namespace Rice::detail
|
|
|
233
279
|
inline WrapperBase* getWrapper(VALUE value)
|
|
234
280
|
{
|
|
235
281
|
// Turn off spurious warning on g++ 12
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
282
|
+
#if defined(__GNUC__) || defined(__clang__)
|
|
283
|
+
#pragma GCC diagnostic push
|
|
284
|
+
#pragma GCC diagnostic ignored "-Warray-bounds"
|
|
285
|
+
#endif
|
|
286
|
+
|
|
287
|
+
if (!RTYPEDDATA_P(value))
|
|
288
|
+
{
|
|
289
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
|
|
290
|
+
detail::protect(rb_obj_classname, value),
|
|
291
|
+
"wrapped C++ object");
|
|
292
|
+
}
|
|
240
293
|
|
|
241
|
-
return
|
|
294
|
+
return static_cast<WrapperBase*>(RTYPEDDATA_DATA(value));
|
|
242
295
|
|
|
243
296
|
#if defined(__GNUC__) || defined(__clang__)
|
|
244
297
|
#pragma GCC diagnostic pop
|
|
@@ -246,21 +299,21 @@ namespace Rice::detail
|
|
|
246
299
|
}
|
|
247
300
|
|
|
248
301
|
template <typename T>
|
|
249
|
-
inline void wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data
|
|
302
|
+
inline void wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data)
|
|
250
303
|
{
|
|
251
304
|
using Wrapper_T = Wrapper<T*>;
|
|
252
|
-
|
|
305
|
+
|
|
253
306
|
Wrapper_T* wrapper = nullptr;
|
|
254
307
|
TypedData_Get_Struct(value, Wrapper_T, rb_data_type, wrapper);
|
|
255
308
|
if (wrapper)
|
|
256
309
|
{
|
|
257
|
-
Registries::instance.instances.remove(wrapper->get());
|
|
310
|
+
Registries::instance.instances.remove(wrapper->get(rb_data_type));
|
|
258
311
|
delete wrapper;
|
|
259
312
|
}
|
|
260
313
|
|
|
261
|
-
wrapper = new Wrapper_T(data, true);
|
|
314
|
+
wrapper = new Wrapper_T(rb_data_type, data, true);
|
|
262
315
|
RTYPEDDATA_DATA(value) = wrapper;
|
|
263
316
|
|
|
264
317
|
Registries::instance.instances.add(data, value);
|
|
265
318
|
}
|
|
266
|
-
}
|
|
319
|
+
}
|