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/detail/Type.hpp
CHANGED
@@ -14,8 +14,10 @@ namespace Rice::detail
|
|
14
14
|
// Return the name of a type
|
15
15
|
std::string typeName(const std::type_info& typeInfo);
|
16
16
|
std::string typeName(const std::type_index& typeIndex);
|
17
|
-
std::string
|
17
|
+
std::string cppClassName(const std::string& typeInfoName);
|
18
|
+
std::string rubyClassName(const std::string& typeInfoName);
|
18
19
|
std::string findGroup(std::string& string, size_t start = 0);
|
20
|
+
void replaceGroup(std::string& string, std::regex regex, std::string replacement);
|
19
21
|
void replaceAll(std::string& string, std::regex regex, std::string replacement);
|
20
22
|
|
21
23
|
template<typename T>
|
data/rice/detail/Type.ipp
CHANGED
@@ -13,21 +13,16 @@ namespace Rice::detail
|
|
13
13
|
{
|
14
14
|
return true;
|
15
15
|
}
|
16
|
+
else if constexpr (std::is_array_v<T> && std::is_fundamental_v<std::remove_extent_t<T>>)
|
17
|
+
{
|
18
|
+
return true;
|
19
|
+
}
|
16
20
|
else
|
17
21
|
{
|
18
22
|
return Registries::instance.types.verify<T>();
|
19
23
|
}
|
20
24
|
}
|
21
25
|
|
22
|
-
template<>
|
23
|
-
struct Type<void>
|
24
|
-
{
|
25
|
-
static bool verify()
|
26
|
-
{
|
27
|
-
return true;
|
28
|
-
}
|
29
|
-
};
|
30
|
-
|
31
26
|
template<typename T>
|
32
27
|
void verifyType()
|
33
28
|
{
|
@@ -35,7 +30,7 @@ namespace Rice::detail
|
|
35
30
|
}
|
36
31
|
|
37
32
|
template<typename Tuple_T, size_t...Is>
|
38
|
-
void verifyTypesImpl()
|
33
|
+
void verifyTypesImpl(std::index_sequence<Is...> indexes)
|
39
34
|
{
|
40
35
|
(verifyType<typename std::tuple_element<Is, Tuple_T>::type>(), ...);
|
41
36
|
}
|
@@ -43,10 +38,8 @@ namespace Rice::detail
|
|
43
38
|
template<typename Tuple_T>
|
44
39
|
void verifyTypes()
|
45
40
|
{
|
46
|
-
|
47
|
-
|
48
|
-
verifyTypesImpl<Tuple_T, std::tuple_size<Tuple_T>::value - 1>();
|
49
|
-
}
|
41
|
+
std::make_index_sequence<std::tuple_size_v<Tuple_T>> indexes;
|
42
|
+
verifyTypesImpl<Tuple_T>(indexes);
|
50
43
|
}
|
51
44
|
|
52
45
|
inline std::string demangle(char const* mangled_name)
|
@@ -156,7 +149,18 @@ namespace Rice::detail
|
|
156
149
|
}
|
157
150
|
}
|
158
151
|
|
159
|
-
inline std::string
|
152
|
+
inline void replaceGroup(std::string& string, std::regex regex, std::string replacement)
|
153
|
+
{
|
154
|
+
std::smatch match;
|
155
|
+
while (std::regex_search(string, match, regex))
|
156
|
+
{
|
157
|
+
std::string group = findGroup(string, match.position());
|
158
|
+
group = match.str() + group;
|
159
|
+
string.replace(match.position(), group.length(), replacement);
|
160
|
+
}
|
161
|
+
}
|
162
|
+
|
163
|
+
inline std::string cppClassName(const std::string& typeInfoName)
|
160
164
|
{
|
161
165
|
std::string base = typeInfoName;
|
162
166
|
|
@@ -170,34 +174,26 @@ namespace Rice::detail
|
|
170
174
|
|
171
175
|
// Remove std::__[^:]*::
|
172
176
|
auto stdClangRegex = std::regex("std::__[^:]+::");
|
173
|
-
base = std::regex_replace(base, stdClangRegex, "");
|
174
|
-
|
175
|
-
// Remove std::
|
176
|
-
auto stdRegex = std::regex("std::");
|
177
|
-
base = std::regex_replace(base, stdRegex, "");
|
177
|
+
base = std::regex_replace(base, stdClangRegex, "std::");
|
178
178
|
|
179
|
-
// Replace basic_string with string
|
180
|
-
auto basicStringRegex = std::regex(R"(basic_string)");
|
181
|
-
replaceAll(base, basicStringRegex, "string");
|
182
|
-
|
183
179
|
// Remove allocators
|
184
|
-
std::regex allocatorRegex(R"(,\s*allocator)");
|
180
|
+
std::regex allocatorRegex(R"(,\s*std::allocator)");
|
185
181
|
removeGroup(base, allocatorRegex);
|
186
182
|
|
187
183
|
// Remove char_traits
|
188
|
-
std::regex charTraitsRegex(R"(,\s*char_traits)");
|
184
|
+
std::regex charTraitsRegex(R"(,\s*std::char_traits)");
|
189
185
|
removeGroup(base, charTraitsRegex);
|
190
186
|
|
191
187
|
// Remove less (std::map)
|
192
|
-
std::regex lessRegex(R"(,\s*less)");
|
188
|
+
std::regex lessRegex(R"(,\s*std::less)");
|
193
189
|
removeGroup(base, lessRegex);
|
194
190
|
|
195
191
|
// Remove hash (std::unordered_map)
|
196
|
-
std::regex hashRegex(R"(,\s*hash)");
|
192
|
+
std::regex hashRegex(R"(,\s*std::hash)");
|
197
193
|
removeGroup(base, hashRegex);
|
198
194
|
|
199
195
|
// Remove equal_to (std::unordered_map)
|
200
|
-
std::regex equalRegex(R"(,\s*equal_to)");
|
196
|
+
std::regex equalRegex(R"(,\s*std::equal_to)");
|
201
197
|
removeGroup(base, equalRegex);
|
202
198
|
|
203
199
|
// Remove spaces before pointers
|
@@ -216,6 +212,36 @@ namespace Rice::detail
|
|
216
212
|
auto commaSpaceRegex = std::regex(R"(,(\S))");
|
217
213
|
replaceAll(base, commaSpaceRegex, ", $1");
|
218
214
|
|
215
|
+
// Fix strings
|
216
|
+
auto stringRegex = std::regex(R"(basic_string<char>)");
|
217
|
+
replaceAll(base, stringRegex, "string");
|
218
|
+
|
219
|
+
auto wstringRegex = std::regex(R"(basic_string<wchar_t>)");
|
220
|
+
replaceAll(base, wstringRegex, "wstring");
|
221
|
+
|
222
|
+
// Normalize Anonymous namespace
|
223
|
+
auto anonymousNamespaceGcc = std::regex(R"(\(anonymous namespace\))");
|
224
|
+
replaceAll(base, anonymousNamespaceGcc, "AnonymousNamespace");
|
225
|
+
auto anonymousNamespaceMsvc = std::regex(R"(`anonymous namespace')");
|
226
|
+
replaceAll(base, anonymousNamespaceMsvc, "AnonymousNamespace");
|
227
|
+
|
228
|
+
return base;
|
229
|
+
}
|
230
|
+
|
231
|
+
|
232
|
+
inline std::string rubyClassName(const std::string& typeInfoName)
|
233
|
+
{
|
234
|
+
std::string base = cppClassName(typeInfoName);
|
235
|
+
|
236
|
+
// Remove std:: these could be embedded in template types
|
237
|
+
auto stdRegex = std::regex("std::");
|
238
|
+
base = std::regex_replace(base, stdRegex, "");
|
239
|
+
|
240
|
+
// Remove leading namespaces. This will not remove namespaces
|
241
|
+
// embedded in template types like std::vector<mynamespace::foo>
|
242
|
+
auto leadingNamespacesRegex = std::regex("^[^<]*::");
|
243
|
+
base = std::regex_replace(base, leadingNamespacesRegex, "");
|
244
|
+
|
219
245
|
// Capitalize first letter
|
220
246
|
base[0] = std::toupper(base[0]);
|
221
247
|
|
@@ -239,18 +265,22 @@ namespace Rice::detail
|
|
239
265
|
|
240
266
|
// Replace < with unicode U+227A (Precedes)
|
241
267
|
auto lessThanRegex = std::regex("<");
|
242
|
-
//replaceAll(base, lessThanRegex,
|
268
|
+
//replaceAll(base, lessThanRegex, "≺");
|
243
269
|
replaceAll(base, lessThanRegex, "\u227A");
|
244
270
|
|
245
271
|
// Replace > with unicode U+227B (Succeeds)
|
246
272
|
auto greaterThanRegex = std::regex(">");
|
247
|
-
//replaceAll(base, greaterThanRegex,
|
273
|
+
//replaceAll(base, greaterThanRegex, "≻");
|
248
274
|
replaceAll(base, greaterThanRegex, "\u227B");
|
249
275
|
|
250
276
|
// Replace , with Unicode Character (U+066C) - Arabic Thousands Separator
|
251
277
|
auto commaRegex = std::regex(R"(,\s*)");
|
252
278
|
replaceAll(base, commaRegex, "\u201A");
|
253
279
|
|
280
|
+
// Replace * with Unicode Character (U+2217) - Asterisk Operator
|
281
|
+
auto asteriskRegex = std::regex(R"(\*)");
|
282
|
+
replaceAll(base, asteriskRegex, "\u2217");
|
283
|
+
|
254
284
|
return base;
|
255
285
|
}
|
256
286
|
}
|
data/rice/detail/Wrapper.hpp
CHANGED
@@ -1,50 +1,85 @@
|
|
1
1
|
#ifndef Rice__detail__Wrapper__hpp_
|
2
2
|
#define Rice__detail__Wrapper__hpp_
|
3
3
|
|
4
|
-
namespace Rice
|
5
|
-
{
|
6
|
-
namespace detail
|
4
|
+
namespace Rice::detail
|
7
5
|
{
|
6
|
+
class WrapperBase
|
7
|
+
{
|
8
|
+
public:
|
9
|
+
WrapperBase() = default;
|
10
|
+
virtual ~WrapperBase() = default;
|
11
|
+
virtual void* get() = 0;
|
12
|
+
bool isConst();
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
Wrapper(bool isOwner = false);
|
13
|
-
virtual ~Wrapper() = default;
|
14
|
-
virtual void* get() = 0;
|
14
|
+
void ruby_mark();
|
15
|
+
void addKeepAlive(VALUE value);
|
16
|
+
void setOwner(bool value);
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
18
|
+
protected:
|
19
|
+
bool isOwner_ = false;
|
20
|
+
bool isConst_ = false;
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
+
private:
|
23
|
+
// We use a vector for speed and memory locality versus a set which does
|
24
|
+
// not scale well when getting to tens of thousands of objects (not expecting
|
25
|
+
// that to happen...but just in case)
|
26
|
+
std::vector<VALUE> keepAlive_;
|
27
|
+
};
|
22
28
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
template <typename T>
|
30
|
+
class Wrapper : public WrapperBase
|
31
|
+
{
|
32
|
+
public:
|
33
|
+
Wrapper(T& data);
|
34
|
+
Wrapper(T&& data);
|
35
|
+
~Wrapper();
|
36
|
+
void* get() override;
|
29
37
|
|
30
|
-
|
31
|
-
|
38
|
+
private:
|
39
|
+
T data_;
|
40
|
+
};
|
32
41
|
|
33
|
-
template
|
34
|
-
|
42
|
+
template<typename T>
|
43
|
+
class Wrapper<T&> : public WrapperBase
|
44
|
+
{
|
45
|
+
public:
|
46
|
+
Wrapper(T& data);
|
47
|
+
~Wrapper();
|
48
|
+
void* get() override;
|
35
49
|
|
36
|
-
|
37
|
-
T
|
50
|
+
private:
|
51
|
+
T& data_;
|
52
|
+
};
|
38
53
|
|
39
|
-
|
54
|
+
template <typename T>
|
55
|
+
class Wrapper<T*> : public WrapperBase
|
56
|
+
{
|
57
|
+
public:
|
58
|
+
Wrapper(T* data, bool isOwner);
|
59
|
+
~Wrapper();
|
60
|
+
void* get() override;
|
40
61
|
|
41
|
-
|
42
|
-
|
62
|
+
private:
|
63
|
+
T* data_ = nullptr;
|
64
|
+
};
|
43
65
|
|
44
|
-
|
66
|
+
// ---- Helper Functions ---------
|
67
|
+
template <typename T>
|
68
|
+
void wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data, bool isOwner);
|
45
69
|
|
46
|
-
|
47
|
-
|
70
|
+
template <typename T>
|
71
|
+
VALUE wrap(VALUE klass, rb_data_type_t* rb_data_type, T& data, bool isOwner);
|
48
72
|
|
49
|
-
|
73
|
+
template <typename T>
|
74
|
+
VALUE wrap(VALUE klass, rb_data_type_t* rb_data_type, T* data, bool isOwner);
|
50
75
|
|
76
|
+
template <typename T>
|
77
|
+
T* unwrap(VALUE value, rb_data_type_t* rb_data_type, bool takeOwnership);
|
78
|
+
|
79
|
+
template <typename Wrapper_T = WrapperBase>
|
80
|
+
Wrapper_T* getWrapper(VALUE value, rb_data_type_t* rb_data_type);
|
81
|
+
|
82
|
+
WrapperBase* getWrapper(VALUE value);
|
83
|
+
}
|
84
|
+
#endif // Rice__detail__Wrapper__hpp_
|
85
|
+
|
data/rice/detail/Wrapper.ipp
CHANGED
@@ -2,11 +2,12 @@
|
|
2
2
|
|
3
3
|
namespace Rice::detail
|
4
4
|
{
|
5
|
-
inline
|
5
|
+
inline bool WrapperBase::isConst()
|
6
6
|
{
|
7
|
+
return this->isConst_;
|
7
8
|
}
|
8
9
|
|
9
|
-
inline void
|
10
|
+
inline void WrapperBase::ruby_mark()
|
10
11
|
{
|
11
12
|
for (VALUE value : this->keepAlive_)
|
12
13
|
{
|
@@ -14,133 +15,122 @@ namespace Rice::detail
|
|
14
15
|
}
|
15
16
|
}
|
16
17
|
|
17
|
-
inline void
|
18
|
+
inline void WrapperBase::addKeepAlive(VALUE value)
|
18
19
|
{
|
19
20
|
this->keepAlive_.push_back(value);
|
20
21
|
}
|
21
22
|
|
22
|
-
inline void
|
23
|
+
inline void WrapperBase::setOwner(bool value)
|
23
24
|
{
|
24
25
|
this->isOwner_ = value;
|
25
26
|
}
|
26
27
|
|
28
|
+
// ---- Wrapper -----
|
27
29
|
template <typename T>
|
28
|
-
|
30
|
+
inline Wrapper<T>::Wrapper(T& data): data_(data)
|
29
31
|
{
|
30
|
-
|
31
|
-
WrapperValue(T& data): data_(std::move(data))
|
32
|
-
{
|
33
|
-
}
|
34
|
-
|
35
|
-
~WrapperValue()
|
36
|
-
{
|
37
|
-
Registries::instance.instances.remove(this->get());
|
38
|
-
}
|
32
|
+
}
|
39
33
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
34
|
+
template <typename T>
|
35
|
+
inline Wrapper<T>::Wrapper(T&& data) : data_(std::move(data))
|
36
|
+
{
|
37
|
+
}
|
44
38
|
|
45
|
-
|
46
|
-
|
47
|
-
|
39
|
+
template <typename T>
|
40
|
+
inline Wrapper<T>::~Wrapper()
|
41
|
+
{
|
42
|
+
Registries::instance.instances.remove(this->get());
|
43
|
+
}
|
48
44
|
|
49
45
|
template <typename T>
|
50
|
-
|
46
|
+
inline void* Wrapper<T>::Wrapper::get()
|
51
47
|
{
|
52
|
-
|
53
|
-
|
54
|
-
{
|
55
|
-
}
|
48
|
+
return (void*)&this->data_;
|
49
|
+
}
|
56
50
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
51
|
+
// ---- Wrapper& -----
|
52
|
+
template <typename T>
|
53
|
+
inline Wrapper<T&>::Wrapper(T& data): data_(data)
|
54
|
+
{
|
55
|
+
this->isConst_ = std::is_const_v<std::remove_reference_t<T>>;
|
56
|
+
}
|
61
57
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
58
|
+
template <typename T>
|
59
|
+
inline Wrapper<T&>::~Wrapper()
|
60
|
+
{
|
61
|
+
Registries::instance.instances.remove(this->get());
|
62
|
+
}
|
66
63
|
|
67
|
-
|
68
|
-
|
69
|
-
|
64
|
+
template <typename T>
|
65
|
+
inline void* Wrapper<T&>::get()
|
66
|
+
{
|
67
|
+
return (void*)&this->data_;
|
68
|
+
}
|
70
69
|
|
70
|
+
// ---- Wrapper* -----
|
71
71
|
template <typename T>
|
72
|
-
|
72
|
+
inline Wrapper<T*>::Wrapper(T* data, bool isOwner) : data_(data)
|
73
73
|
{
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
}
|
74
|
+
this->isOwner_ = isOwner;
|
75
|
+
this->isConst_ = std::is_const_v<std::remove_pointer_t<T>>;
|
76
|
+
}
|
78
77
|
|
79
|
-
|
78
|
+
template <typename T>
|
79
|
+
inline Wrapper<T*>::~Wrapper()
|
80
|
+
{
|
81
|
+
Registries::instance.instances.remove(this->get());
|
82
|
+
if constexpr (std::is_destructible_v<T>)
|
80
83
|
{
|
81
|
-
|
82
|
-
|
83
|
-
if constexpr (std::is_destructible_v<T>)
|
84
|
+
if (this->isOwner_)
|
84
85
|
{
|
85
|
-
|
86
|
-
{
|
87
|
-
delete this->data_;
|
88
|
-
}
|
86
|
+
delete this->data_;
|
89
87
|
}
|
90
88
|
}
|
89
|
+
}
|
91
90
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
private:
|
98
|
-
T* data_ = nullptr;
|
99
|
-
};
|
91
|
+
template <typename T>
|
92
|
+
inline void* Wrapper<T*>::get()
|
93
|
+
{
|
94
|
+
return (void*)this->data_;
|
95
|
+
}
|
100
96
|
|
101
97
|
// ---- Helper Functions -------
|
102
|
-
template <typename T
|
103
|
-
inline VALUE wrap(VALUE klass, rb_data_type_t*
|
98
|
+
template <typename T>
|
99
|
+
inline VALUE wrap(VALUE klass, rb_data_type_t* rb_data_type, T& data, bool isOwner)
|
104
100
|
{
|
105
101
|
VALUE result = Registries::instance.instances.lookup(&data);
|
106
102
|
|
107
103
|
if (result != Qnil)
|
108
104
|
return result;
|
109
105
|
|
110
|
-
|
106
|
+
WrapperBase* wrapper = nullptr;
|
111
107
|
|
112
|
-
//
|
113
|
-
if
|
108
|
+
// If Ruby is not the owner then wrap the reference
|
109
|
+
if (!isOwner)
|
114
110
|
{
|
115
|
-
wrapper = new
|
116
|
-
result = TypedData_Wrap_Struct(klass,
|
111
|
+
wrapper = new Wrapper<T&>(data);
|
112
|
+
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
117
113
|
}
|
118
|
-
|
119
|
-
|
114
|
+
|
115
|
+
// Ruby is the owner so copy data
|
116
|
+
else if constexpr (std::is_copy_constructible_v<T>)
|
120
117
|
{
|
121
|
-
wrapper = new
|
122
|
-
result = TypedData_Wrap_Struct(klass,
|
118
|
+
wrapper = new Wrapper<T>(data);
|
119
|
+
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
123
120
|
}
|
124
|
-
|
125
|
-
|
121
|
+
|
122
|
+
// Ruby is the owner so move data
|
123
|
+
else if constexpr (std::is_move_constructible_v<T>)
|
126
124
|
{
|
127
|
-
|
128
|
-
|
129
|
-
wrapper = new WrapperValue<T>(data);
|
130
|
-
result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
|
131
|
-
}
|
132
|
-
else
|
133
|
-
{
|
134
|
-
std::string message = "Ruby was directed to take ownership of a C++ object but it does not have an accessible copy or move constructor. Type: " +
|
135
|
-
typeName(typeid(T));
|
136
|
-
throw std::runtime_error(message);
|
137
|
-
}
|
125
|
+
wrapper = new Wrapper<T>(std::forward<T>(data));
|
126
|
+
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
138
127
|
}
|
139
|
-
|
128
|
+
|
140
129
|
else
|
141
130
|
{
|
142
|
-
|
143
|
-
|
131
|
+
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: " +
|
132
|
+
typeName(typeid(T));
|
133
|
+
throw std::runtime_error(message);
|
144
134
|
}
|
145
135
|
|
146
136
|
Registries::instance.instances.add(wrapper->get(), result);
|
@@ -148,37 +138,31 @@ namespace Rice::detail
|
|
148
138
|
return result;
|
149
139
|
};
|
150
140
|
|
151
|
-
template <typename T
|
152
|
-
inline VALUE wrap(VALUE klass, rb_data_type_t*
|
141
|
+
template <typename T>
|
142
|
+
inline VALUE wrap(VALUE klass, rb_data_type_t* rb_data_type, T* data, bool isOwner)
|
153
143
|
{
|
154
144
|
VALUE result = Registries::instance.instances.lookup(data);
|
155
145
|
|
156
146
|
if (result != Qnil)
|
157
147
|
return result;
|
158
148
|
|
159
|
-
|
160
|
-
|
161
|
-
if constexpr (!std::is_void_v<Wrapper_T>)
|
162
|
-
{
|
163
|
-
wrapper = new Wrapper_T(data);
|
164
|
-
result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
|
165
|
-
}
|
166
|
-
else
|
167
|
-
{
|
168
|
-
wrapper = new WrapperPointer<T>(data, isOwner);
|
169
|
-
result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
|
170
|
-
}
|
149
|
+
WrapperBase* wrapper = new Wrapper<T*>(data, isOwner);
|
150
|
+
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
171
151
|
|
172
152
|
Registries::instance.instances.add(wrapper->get(), result);
|
173
153
|
return result;
|
174
154
|
};
|
175
155
|
|
176
156
|
template <typename T>
|
177
|
-
inline T* unwrap(VALUE value, rb_data_type_t*
|
157
|
+
inline T* unwrap(VALUE value, rb_data_type_t* rb_data_type, bool takeOwnership)
|
178
158
|
{
|
179
|
-
|
180
|
-
|
181
|
-
|
159
|
+
if (rb_type(value) != RUBY_T_DATA)
|
160
|
+
{
|
161
|
+
std::string message = "The provided Ruby object does not wrap a C++ object";
|
162
|
+
throw std::runtime_error(message);
|
163
|
+
}
|
164
|
+
|
165
|
+
WrapperBase* wrapper = getWrapper(value, rb_data_type);
|
182
166
|
|
183
167
|
if (wrapper == nullptr)
|
184
168
|
{
|
@@ -189,17 +173,21 @@ namespace Rice::detail
|
|
189
173
|
throw std::runtime_error(message);
|
190
174
|
}
|
191
175
|
|
176
|
+
if (takeOwnership)
|
177
|
+
wrapper->setOwner(false);
|
178
|
+
|
192
179
|
return static_cast<T*>(wrapper->get());
|
193
180
|
}
|
194
181
|
|
195
|
-
|
182
|
+
template <typename Wrapper_T>
|
183
|
+
inline Wrapper_T* getWrapper(VALUE value, rb_data_type_t* rb_data_type)
|
196
184
|
{
|
197
|
-
|
198
|
-
TypedData_Get_Struct(value,
|
199
|
-
return wrapper;
|
185
|
+
WrapperBase* wrapper = nullptr;
|
186
|
+
TypedData_Get_Struct(value, WrapperBase, rb_data_type, wrapper);
|
187
|
+
return dynamic_cast<Wrapper_T*>(wrapper);
|
200
188
|
}
|
201
189
|
|
202
|
-
inline
|
190
|
+
inline WrapperBase* getWrapper(VALUE value)
|
203
191
|
{
|
204
192
|
// Turn off spurious warning on g++ 12
|
205
193
|
#if defined(__GNUC__) || defined(__clang__)
|
@@ -207,7 +195,7 @@ namespace Rice::detail
|
|
207
195
|
#pragma GCC diagnostic ignored "-Warray-bounds"
|
208
196
|
#endif
|
209
197
|
|
210
|
-
return RTYPEDDATA_P(value) ? static_cast<
|
198
|
+
return RTYPEDDATA_P(value) ? static_cast<WrapperBase*>(RTYPEDDATA_DATA(value)) : nullptr;
|
211
199
|
|
212
200
|
#if defined(__GNUC__) || defined(__clang__)
|
213
201
|
#pragma GCC diagnostic pop
|
@@ -215,17 +203,19 @@ namespace Rice::detail
|
|
215
203
|
}
|
216
204
|
|
217
205
|
template <typename T>
|
218
|
-
inline void
|
206
|
+
inline void wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data, bool isOwner)
|
219
207
|
{
|
220
|
-
|
221
|
-
|
208
|
+
using Wrapper_T = Wrapper<T*>;
|
209
|
+
|
210
|
+
Wrapper_T* wrapper = nullptr;
|
211
|
+
TypedData_Get_Struct(value, Wrapper_T, rb_data_type, wrapper);
|
222
212
|
if (wrapper)
|
223
213
|
{
|
224
214
|
Registries::instance.instances.remove(wrapper->get());
|
225
215
|
delete wrapper;
|
226
216
|
}
|
227
217
|
|
228
|
-
wrapper = new
|
218
|
+
wrapper = new Wrapper_T(data, true);
|
229
219
|
RTYPEDDATA_DATA(value) = wrapper;
|
230
220
|
|
231
221
|
Registries::instance.instances.add(data, value);
|
data/rice/detail/from_ruby.hpp
CHANGED
@@ -32,10 +32,11 @@ namespace Rice::detail
|
|
32
32
|
|
33
33
|
enum class Convertible: uint8_t
|
34
34
|
{
|
35
|
-
None
|
36
|
-
|
37
|
-
Cast
|
38
|
-
|
35
|
+
None = 0b0000,
|
36
|
+
Narrow = 0b0001,
|
37
|
+
Cast = 0b0011,
|
38
|
+
Const = 0b0111,
|
39
|
+
Exact = 0b1111
|
39
40
|
};
|
40
41
|
}
|
41
42
|
|