rice 4.3.3 → 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 +86 -26
- data/CMakeLists.txt +31 -0
- data/CMakePresets.json +75 -0
- data/COPYING +3 -2
- data/FindRuby.cmake +437 -0
- data/README.md +7 -2
- data/Rakefile +12 -5
- data/include/rice/rice.hpp +9522 -4426
- data/include/rice/stl.hpp +2831 -1198
- data/lib/make_rice_headers.rb +79 -0
- data/lib/mkmf-rice.rb +40 -94
- 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/Address_Registration_Guard.hpp +72 -3
- data/rice/Arg.hpp +26 -6
- data/rice/Arg.ipp +35 -2
- data/rice/Buffer.hpp +123 -0
- data/rice/Buffer.ipp +599 -0
- data/rice/Callback.hpp +21 -0
- data/rice/Callback.ipp +13 -0
- data/rice/Constructor.hpp +4 -27
- data/rice/Constructor.ipp +79 -0
- data/rice/Data_Object.hpp +73 -3
- data/rice/Data_Object.ipp +388 -96
- data/rice/Data_Type.hpp +214 -3
- data/rice/Data_Type.ipp +144 -67
- data/rice/Director.hpp +0 -2
- data/rice/Enum.hpp +4 -7
- data/rice/Enum.ipp +102 -55
- data/rice/Exception.hpp +62 -2
- data/rice/Exception.ipp +7 -12
- data/rice/Init.hpp +8 -0
- data/rice/Init.ipp +8 -0
- data/rice/JumpException.hpp +44 -0
- data/rice/JumpException.ipp +48 -0
- data/rice/MemoryView.hpp +11 -0
- data/rice/MemoryView.ipp +3 -0
- data/rice/Return.hpp +7 -27
- data/rice/Return.ipp +13 -13
- 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/{Identifier.hpp → cpp_api/Identifier.hpp} +2 -6
- data/rice/{Identifier.ipp → cpp_api/Identifier.ipp} +4 -2
- 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/DefaultHandler.hpp +12 -0
- data/rice/detail/DefaultHandler.ipp +8 -0
- data/rice/detail/HandlerRegistry.hpp +5 -35
- data/rice/detail/HandlerRegistry.ipp +7 -11
- data/rice/detail/InstanceRegistry.hpp +1 -4
- data/rice/detail/MethodInfo.hpp +12 -10
- data/rice/detail/MethodInfo.ipp +26 -21
- data/rice/detail/Native.hpp +33 -0
- data/rice/detail/Native.ipp +157 -0
- data/rice/detail/NativeAttributeGet.hpp +52 -0
- data/rice/detail/NativeAttributeGet.ipp +57 -0
- data/rice/detail/NativeAttributeSet.hpp +44 -0
- data/rice/detail/NativeAttributeSet.ipp +88 -0
- data/rice/detail/NativeCallbackFFI.hpp +55 -0
- data/rice/detail/NativeCallbackFFI.ipp +151 -0
- data/rice/detail/NativeCallbackSimple.hpp +30 -0
- data/rice/detail/NativeCallbackSimple.ipp +29 -0
- data/rice/detail/NativeFunction.hpp +33 -23
- data/rice/detail/NativeFunction.ipp +309 -70
- data/rice/detail/NativeIterator.hpp +9 -11
- data/rice/detail/NativeIterator.ipp +33 -31
- data/rice/detail/NativeRegistry.hpp +24 -15
- data/rice/detail/NativeRegistry.ipp +23 -48
- data/rice/detail/Proc.hpp +4 -0
- data/rice/detail/Proc.ipp +85 -0
- data/rice/detail/Registries.hpp +0 -7
- data/rice/detail/Registries.ipp +0 -18
- data/rice/detail/RubyFunction.hpp +0 -3
- data/rice/detail/RubyFunction.ipp +4 -8
- data/rice/detail/RubyType.hpp +16 -0
- data/rice/detail/RubyType.ipp +232 -0
- data/rice/detail/Type.hpp +7 -6
- data/rice/detail/Type.ipp +192 -45
- data/rice/detail/TypeRegistry.hpp +15 -7
- data/rice/detail/TypeRegistry.ipp +105 -12
- data/rice/detail/Wrapper.hpp +68 -32
- data/rice/detail/Wrapper.ipp +121 -109
- data/rice/detail/cpp_protect.hpp +5 -6
- data/rice/detail/default_allocation_func.ipp +0 -2
- data/rice/detail/from_ruby.hpp +38 -3
- data/rice/detail/from_ruby.ipp +1321 -492
- data/rice/detail/ruby.hpp +18 -0
- data/rice/detail/to_ruby.hpp +41 -3
- data/rice/detail/to_ruby.ipp +1424 -194
- data/rice/global_function.hpp +0 -4
- data/rice/global_function.ipp +0 -1
- data/rice/libc/file.hpp +11 -0
- data/rice/libc/file.ipp +32 -0
- data/rice/rice.hpp +116 -26
- data/rice/ruby_mark.hpp +4 -3
- 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 +11 -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 +7 -1
- data/test/extconf.rb +2 -0
- data/test/test_Address_Registration_Guard.cpp +5 -0
- data/test/test_Array.cpp +18 -4
- data/test/test_Attribute.cpp +136 -21
- data/test/test_Buffer.cpp +285 -0
- data/test/test_Builtin_Object.cpp +5 -0
- data/test/test_Callback.cpp +230 -0
- data/test/test_Class.cpp +5 -31
- data/test/test_Constructor.cpp +69 -6
- data/test/test_Data_Object.cpp +97 -38
- data/test/test_Data_Type.cpp +470 -65
- data/test/test_Director.cpp +17 -8
- data/test/test_Enum.cpp +155 -40
- data/test/test_Exception.cpp +235 -0
- data/test/test_File.cpp +70 -0
- data/test/test_From_Ruby.cpp +609 -0
- data/test/test_Hash.cpp +5 -0
- data/test/test_Identifier.cpp +5 -0
- data/test/test_Inheritance.cpp +6 -1
- data/test/test_Iterator.cpp +6 -1
- data/test/test_Jump_Exception.cpp +23 -0
- data/test/test_Keep_Alive.cpp +13 -19
- data/test/test_Keep_Alive_No_Wrapper.cpp +5 -1
- data/test/test_Memory_Management.cpp +5 -0
- data/test/test_Module.cpp +128 -67
- data/test/test_Native_Registry.cpp +2 -34
- data/test/test_Object.cpp +5 -0
- data/test/test_Overloads.cpp +806 -0
- data/test/test_Ownership.cpp +160 -54
- data/test/test_Proc.cpp +44 -0
- data/test/test_Self.cpp +9 -4
- data/test/test_Stl_Exception.cpp +109 -0
- data/test/test_Stl_Map.cpp +54 -42
- data/test/test_Stl_Multimap.cpp +693 -0
- data/test/test_Stl_Optional.cpp +5 -0
- data/test/test_Stl_Pair.cpp +14 -9
- data/test/test_Stl_Reference_Wrapper.cpp +9 -2
- data/test/test_Stl_Set.cpp +790 -0
- data/test/test_Stl_SharedPtr.cpp +458 -0
- data/test/test_Stl_String.cpp +5 -0
- data/test/test_Stl_String_View.cpp +5 -0
- data/test/test_Stl_Tuple.cpp +116 -0
- data/test/test_Stl_Type.cpp +147 -0
- data/test/test_Stl_UniquePtr.cpp +202 -0
- data/test/test_Stl_Unordered_Map.cpp +43 -38
- data/test/test_Stl_Variant.cpp +217 -84
- data/test/test_Stl_Vector.cpp +306 -58
- data/test/test_String.cpp +5 -0
- data/test/test_Struct.cpp +5 -0
- data/test/test_Symbol.cpp +5 -0
- data/test/test_Template.cpp +192 -0
- data/test/test_To_Ruby.cpp +524 -0
- data/test/test_Tracking.cpp +1 -0
- data/test/test_Type.cpp +171 -0
- data/test/test_global_functions.cpp +67 -7
- data/test/unittest.cpp +8 -0
- metadata +127 -26
- data/lib/version.rb +0 -3
- data/rice/Address_Registration_Guard_defn.hpp +0 -79
- data/rice/Data_Object_defn.hpp +0 -84
- data/rice/Data_Type_defn.hpp +0 -190
- data/rice/Exception_defn.hpp +0 -68
- data/rice/HandlerRegistration.hpp +0 -15
- data/rice/detail/ExceptionHandler.hpp +0 -8
- data/rice/detail/ExceptionHandler.ipp +0 -28
- data/rice/detail/ExceptionHandler_defn.hpp +0 -77
- data/rice/detail/Jump_Tag.hpp +0 -21
- data/rice/detail/NativeAttribute.hpp +0 -64
- data/rice/detail/NativeAttribute.ipp +0 -112
- data/rice/detail/from_ruby_defn.hpp +0 -38
- data/rice/detail/to_ruby_defn.hpp +0 -48
- data/test/test_Jump_Tag.cpp +0 -17
- data/test/test_Stl_SmartPointer.cpp +0 -283
- data/test/test_To_From_Ruby.cpp +0 -399
@@ -1,8 +1,8 @@
|
|
1
|
+
#include <iostream>
|
1
2
|
#include <stdexcept>
|
3
|
+
#include <sstream>
|
4
|
+
#include <typeindex>
|
2
5
|
|
3
|
-
#include "ruby.hpp"
|
4
|
-
#include "../traits/rice_traits.hpp"
|
5
|
-
#include "Type.hpp"
|
6
6
|
|
7
7
|
namespace Rice::detail
|
8
8
|
{
|
@@ -13,6 +13,22 @@ namespace Rice::detail
|
|
13
13
|
registry_[key] = std::pair(klass, rbType);
|
14
14
|
}
|
15
15
|
|
16
|
+
/* Special case void. Rice defines classes using the class name not a pointer to the
|
17
|
+
class. Thus define_class<void> is more consistent with Rice then
|
18
|
+
define_class<void*>. However, the types of void and void* are different so we need
|
19
|
+
this special case.
|
20
|
+
|
21
|
+
It is possible to support define_class<void*>, but it requires changing the static
|
22
|
+
assertions on Data_Type and Data_Object and thus seems less desirable (and less
|
23
|
+
consistent as mentioned above).*/
|
24
|
+
template <>
|
25
|
+
inline void TypeRegistry::add<void>(VALUE klass, rb_data_type_t* rbType)
|
26
|
+
{
|
27
|
+
// The special case, use void*
|
28
|
+
std::type_index key(typeid(void*));
|
29
|
+
registry_[key] = std::pair(klass, rbType);
|
30
|
+
}
|
31
|
+
|
16
32
|
template <typename T>
|
17
33
|
inline void TypeRegistry::remove()
|
18
34
|
{
|
@@ -29,14 +45,45 @@ namespace Rice::detail
|
|
29
45
|
}
|
30
46
|
|
31
47
|
template <typename T>
|
32
|
-
|
48
|
+
std::pair<VALUE, rb_data_type_t*> TypeRegistry::getType()
|
33
49
|
{
|
34
|
-
|
50
|
+
std::type_index key(typeid(T));
|
51
|
+
auto iter = registry_.find(key);
|
52
|
+
if (iter != registry_.end())
|
35
53
|
{
|
36
|
-
|
37
|
-
|
54
|
+
return iter->second;
|
55
|
+
}
|
56
|
+
else
|
57
|
+
{
|
58
|
+
this->raiseUnverifiedType(typeid(T).name());
|
59
|
+
// Make compiler happy
|
60
|
+
return std::make_pair(Qnil, nullptr);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
// Special case void. See comment for add above.
|
65
|
+
template <>
|
66
|
+
inline bool TypeRegistry::isDefined<void>()
|
67
|
+
{
|
68
|
+
std::type_index key(typeid(void*));
|
69
|
+
auto iter = registry_.find(key);
|
70
|
+
return iter != registry_.end();
|
71
|
+
}
|
72
|
+
|
73
|
+
template <typename T>
|
74
|
+
inline bool TypeRegistry::verify()
|
75
|
+
{
|
76
|
+
if (isDefined<T>())
|
77
|
+
{
|
78
|
+
return true;
|
79
|
+
}
|
80
|
+
else
|
81
|
+
{
|
82
|
+
const std::type_info& typeInfo = typeid(T);
|
83
|
+
std::type_index key(typeInfo);
|
84
|
+
this->unverified_.insert(key);
|
85
|
+
return false;
|
38
86
|
}
|
39
|
-
return true;
|
40
87
|
}
|
41
88
|
|
42
89
|
inline std::optional<std::pair<VALUE, rb_data_type_t*>> TypeRegistry::lookup(const std::type_info& typeInfo)
|
@@ -68,14 +115,60 @@ namespace Rice::detail
|
|
68
115
|
// If not, then we are willing to accept an ancestor class specified by T. This is needed
|
69
116
|
// to support Directors. Classes inherited from Directors are never actually registered
|
70
117
|
// with Rice - and what we really want it to return the C++ class they inherit from.
|
71
|
-
|
118
|
+
const std::type_info& typeInfo = typeid(T);
|
119
|
+
result = lookup(typeInfo);
|
72
120
|
if (result)
|
73
121
|
{
|
74
122
|
return result.value();
|
75
123
|
}
|
76
124
|
|
77
|
-
|
78
|
-
|
79
|
-
|
125
|
+
raiseUnverifiedType(detail::typeName(typeInfo));
|
126
|
+
// Make the compiler happy
|
127
|
+
return std::pair<VALUE, rb_data_type_t*>(Qnil, nullptr);
|
128
|
+
}
|
129
|
+
|
130
|
+
inline void TypeRegistry::validateTypes()
|
131
|
+
{
|
132
|
+
// Loop over the unverified types and delete each on that is found in the registry
|
133
|
+
// the registry and raise an exception for the first one that is not
|
134
|
+
for (auto iter = this->unverified_.begin(); iter != this->unverified_.end(); )
|
135
|
+
{
|
136
|
+
const std::type_index& typeIndex = *iter;
|
137
|
+
bool isDefined = this->registry_.find(typeIndex) != this->registry_.end();
|
138
|
+
if (isDefined)
|
139
|
+
{
|
140
|
+
iter = this->unverified_.erase(iter);
|
141
|
+
}
|
142
|
+
else
|
143
|
+
{
|
144
|
+
iter++;
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
if (this->unverified_.empty())
|
149
|
+
{
|
150
|
+
return;
|
151
|
+
}
|
152
|
+
|
153
|
+
std::stringstream stream;
|
154
|
+
stream << "The following types are not registered with Rice:" << "\n";
|
155
|
+
|
156
|
+
for (const std::type_index& typeIndex : this->unverified_)
|
157
|
+
{
|
158
|
+
stream << " " << typeName(typeIndex) << "\n";
|
159
|
+
}
|
160
|
+
|
161
|
+
throw std::invalid_argument(stream.str());
|
162
|
+
}
|
163
|
+
|
164
|
+
inline void TypeRegistry::clearUnverifiedTypes()
|
165
|
+
{
|
166
|
+
this->unverified_.clear();
|
167
|
+
}
|
168
|
+
|
169
|
+
inline void TypeRegistry::raiseUnverifiedType(const std::string& typeName)
|
170
|
+
{
|
171
|
+
std::string message = "Type is not registered with Rice: " + typeName;
|
172
|
+
throw std::invalid_argument(message);
|
80
173
|
}
|
81
174
|
}
|
data/rice/detail/Wrapper.hpp
CHANGED
@@ -1,49 +1,85 @@
|
|
1
1
|
#ifndef Rice__detail__Wrapper__hpp_
|
2
2
|
#define Rice__detail__Wrapper__hpp_
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
namespace Rice
|
7
|
-
{
|
8
|
-
namespace detail
|
4
|
+
namespace Rice::detail
|
9
5
|
{
|
6
|
+
class WrapperBase
|
7
|
+
{
|
8
|
+
public:
|
9
|
+
WrapperBase() = default;
|
10
|
+
virtual ~WrapperBase() = default;
|
11
|
+
virtual void* get() = 0;
|
12
|
+
bool isConst();
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
virtual ~Wrapper() = default;
|
15
|
-
virtual void* get() = 0;
|
14
|
+
void ruby_mark();
|
15
|
+
void addKeepAlive(VALUE value);
|
16
|
+
void setOwner(bool value);
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
protected:
|
19
|
+
bool isOwner_ = false;
|
20
|
+
bool isConst_ = false;
|
19
21
|
|
20
|
-
private:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
};
|
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
|
+
};
|
26
28
|
|
27
|
-
template <typename T
|
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
|
-
T
|
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
|
-
|
50
|
+
private:
|
51
|
+
T& data_;
|
52
|
+
};
|
37
53
|
|
38
|
-
template <typename T>
|
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
|
-
|
62
|
+
private:
|
63
|
+
T* data_ = nullptr;
|
64
|
+
};
|
42
65
|
|
43
|
-
|
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
|
-
|
70
|
+
template <typename T>
|
71
|
+
VALUE wrap(VALUE klass, rb_data_type_t* rb_data_type, T& data, bool isOwner);
|
47
72
|
|
48
|
-
|
73
|
+
template <typename T>
|
74
|
+
VALUE wrap(VALUE klass, rb_data_type_t* rb_data_type, T* data, bool isOwner);
|
49
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
@@ -1,9 +1,13 @@
|
|
1
1
|
#include <memory>
|
2
|
-
#include "InstanceRegistry.hpp"
|
3
2
|
|
4
3
|
namespace Rice::detail
|
5
4
|
{
|
6
|
-
inline
|
5
|
+
inline bool WrapperBase::isConst()
|
6
|
+
{
|
7
|
+
return this->isConst_;
|
8
|
+
}
|
9
|
+
|
10
|
+
inline void WrapperBase::ruby_mark()
|
7
11
|
{
|
8
12
|
for (VALUE value : this->keepAlive_)
|
9
13
|
{
|
@@ -11,118 +15,122 @@ namespace Rice::detail
|
|
11
15
|
}
|
12
16
|
}
|
13
17
|
|
14
|
-
inline void
|
18
|
+
inline void WrapperBase::addKeepAlive(VALUE value)
|
15
19
|
{
|
16
20
|
this->keepAlive_.push_back(value);
|
17
21
|
}
|
18
22
|
|
19
|
-
|
20
|
-
class WrapperValue : public Wrapper
|
23
|
+
inline void WrapperBase::setOwner(bool value)
|
21
24
|
{
|
22
|
-
|
23
|
-
|
24
|
-
{
|
25
|
-
}
|
25
|
+
this->isOwner_ = value;
|
26
|
+
}
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
// ---- Wrapper -----
|
29
|
+
template <typename T>
|
30
|
+
inline Wrapper<T>::Wrapper(T& data): data_(data)
|
31
|
+
{
|
32
|
+
}
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
34
|
+
template <typename T>
|
35
|
+
inline Wrapper<T>::Wrapper(T&& data) : data_(std::move(data))
|
36
|
+
{
|
37
|
+
}
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
-
|
39
|
+
template <typename T>
|
40
|
+
inline Wrapper<T>::~Wrapper()
|
41
|
+
{
|
42
|
+
Registries::instance.instances.remove(this->get());
|
43
|
+
}
|
40
44
|
|
41
45
|
template <typename T>
|
42
|
-
|
46
|
+
inline void* Wrapper<T>::Wrapper::get()
|
43
47
|
{
|
44
|
-
|
45
|
-
|
46
|
-
{
|
47
|
-
}
|
48
|
+
return (void*)&this->data_;
|
49
|
+
}
|
48
50
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
+
}
|
53
57
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
+
template <typename T>
|
59
|
+
inline Wrapper<T&>::~Wrapper()
|
60
|
+
{
|
61
|
+
Registries::instance.instances.remove(this->get());
|
62
|
+
}
|
58
63
|
|
59
|
-
|
60
|
-
|
61
|
-
|
64
|
+
template <typename T>
|
65
|
+
inline void* Wrapper<T&>::get()
|
66
|
+
{
|
67
|
+
return (void*)&this->data_;
|
68
|
+
}
|
62
69
|
|
70
|
+
// ---- Wrapper* -----
|
63
71
|
template <typename T>
|
64
|
-
|
72
|
+
inline Wrapper<T*>::Wrapper(T* data, bool isOwner) : data_(data)
|
65
73
|
{
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
}
|
74
|
+
this->isOwner_ = isOwner;
|
75
|
+
this->isConst_ = std::is_const_v<std::remove_pointer_t<T>>;
|
76
|
+
}
|
70
77
|
|
71
|
-
|
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>)
|
72
83
|
{
|
73
|
-
Registries::instance.instances.remove(this->get());
|
74
|
-
|
75
84
|
if (this->isOwner_)
|
76
85
|
{
|
77
86
|
delete this->data_;
|
78
87
|
}
|
79
88
|
}
|
89
|
+
}
|
80
90
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
private:
|
87
|
-
T* data_ = nullptr;
|
88
|
-
bool isOwner_ = false;
|
89
|
-
};
|
91
|
+
template <typename T>
|
92
|
+
inline void* Wrapper<T*>::get()
|
93
|
+
{
|
94
|
+
return (void*)this->data_;
|
95
|
+
}
|
90
96
|
|
91
97
|
// ---- Helper Functions -------
|
92
|
-
template <typename T
|
93
|
-
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)
|
94
100
|
{
|
95
101
|
VALUE result = Registries::instance.instances.lookup(&data);
|
96
102
|
|
97
103
|
if (result != Qnil)
|
98
104
|
return result;
|
99
105
|
|
100
|
-
|
106
|
+
WrapperBase* wrapper = nullptr;
|
101
107
|
|
102
|
-
//
|
103
|
-
if
|
108
|
+
// If Ruby is not the owner then wrap the reference
|
109
|
+
if (!isOwner)
|
104
110
|
{
|
105
|
-
wrapper = new
|
106
|
-
result = TypedData_Wrap_Struct(klass,
|
111
|
+
wrapper = new Wrapper<T&>(data);
|
112
|
+
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
107
113
|
}
|
108
|
-
|
109
|
-
|
114
|
+
|
115
|
+
// Ruby is the owner so copy data
|
116
|
+
else if constexpr (std::is_copy_constructible_v<T>)
|
110
117
|
{
|
111
|
-
wrapper = new
|
112
|
-
result = TypedData_Wrap_Struct(klass,
|
118
|
+
wrapper = new Wrapper<T>(data);
|
119
|
+
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
113
120
|
}
|
114
|
-
|
115
|
-
//
|
116
|
-
else if (
|
121
|
+
|
122
|
+
// Ruby is the owner so move data
|
123
|
+
else if constexpr (std::is_move_constructible_v<T>)
|
117
124
|
{
|
118
|
-
wrapper = new
|
119
|
-
result = TypedData_Wrap_Struct(klass,
|
125
|
+
wrapper = new Wrapper<T>(std::forward<T>(data));
|
126
|
+
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
120
127
|
}
|
121
|
-
|
128
|
+
|
122
129
|
else
|
123
130
|
{
|
124
|
-
|
125
|
-
|
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);
|
126
134
|
}
|
127
135
|
|
128
136
|
Registries::instance.instances.add(wrapper->get(), result);
|
@@ -130,35 +138,31 @@ namespace Rice::detail
|
|
130
138
|
return result;
|
131
139
|
};
|
132
140
|
|
133
|
-
template <typename T
|
134
|
-
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)
|
135
143
|
{
|
136
144
|
VALUE result = Registries::instance.instances.lookup(data);
|
137
145
|
|
138
146
|
if (result != Qnil)
|
139
147
|
return result;
|
140
148
|
|
141
|
-
|
142
|
-
|
143
|
-
if constexpr (!std::is_void_v<Wrapper_T>)
|
144
|
-
{
|
145
|
-
wrapper = new Wrapper_T(data);
|
146
|
-
result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
|
147
|
-
}
|
148
|
-
else
|
149
|
-
{
|
150
|
-
wrapper = new WrapperPointer<T>(data, isOwner);
|
151
|
-
result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
|
152
|
-
}
|
149
|
+
WrapperBase* wrapper = new Wrapper<T*>(data, isOwner);
|
150
|
+
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
153
151
|
|
154
152
|
Registries::instance.instances.add(wrapper->get(), result);
|
155
153
|
return result;
|
156
154
|
};
|
157
155
|
|
158
156
|
template <typename T>
|
159
|
-
inline T* unwrap(VALUE value, rb_data_type_t*
|
157
|
+
inline T* unwrap(VALUE value, rb_data_type_t* rb_data_type, bool takeOwnership)
|
160
158
|
{
|
161
|
-
|
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);
|
162
166
|
|
163
167
|
if (wrapper == nullptr)
|
164
168
|
{
|
@@ -169,43 +173,51 @@ namespace Rice::detail
|
|
169
173
|
throw std::runtime_error(message);
|
170
174
|
}
|
171
175
|
|
176
|
+
if (takeOwnership)
|
177
|
+
wrapper->setOwner(false);
|
178
|
+
|
172
179
|
return static_cast<T*>(wrapper->get());
|
173
180
|
}
|
174
181
|
|
175
|
-
|
182
|
+
template <typename Wrapper_T>
|
183
|
+
inline Wrapper_T* getWrapper(VALUE value, rb_data_type_t* rb_data_type)
|
184
|
+
{
|
185
|
+
WrapperBase* wrapper = nullptr;
|
186
|
+
TypedData_Get_Struct(value, WrapperBase, rb_data_type, wrapper);
|
187
|
+
return dynamic_cast<Wrapper_T*>(wrapper);
|
188
|
+
}
|
189
|
+
|
190
|
+
inline WrapperBase* getWrapper(VALUE value)
|
176
191
|
{
|
177
|
-
|
178
|
-
|
179
|
-
|
192
|
+
// Turn off spurious warning on g++ 12
|
193
|
+
#if defined(__GNUC__) || defined(__clang__)
|
194
|
+
#pragma GCC diagnostic push
|
195
|
+
#pragma GCC diagnostic ignored "-Warray-bounds"
|
196
|
+
#endif
|
197
|
+
|
198
|
+
return RTYPEDDATA_P(value) ? static_cast<WrapperBase*>(RTYPEDDATA_DATA(value)) : nullptr;
|
199
|
+
|
200
|
+
#if defined(__GNUC__) || defined(__clang__)
|
201
|
+
#pragma GCC diagnostic pop
|
202
|
+
#endif
|
180
203
|
}
|
181
204
|
|
182
205
|
template <typename T>
|
183
|
-
inline void
|
206
|
+
inline void wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data, bool isOwner)
|
184
207
|
{
|
185
|
-
|
186
|
-
|
208
|
+
using Wrapper_T = Wrapper<T*>;
|
209
|
+
|
210
|
+
Wrapper_T* wrapper = nullptr;
|
211
|
+
TypedData_Get_Struct(value, Wrapper_T, rb_data_type, wrapper);
|
187
212
|
if (wrapper)
|
188
213
|
{
|
189
214
|
Registries::instance.instances.remove(wrapper->get());
|
190
215
|
delete wrapper;
|
191
216
|
}
|
192
217
|
|
193
|
-
wrapper = new
|
218
|
+
wrapper = new Wrapper_T(data, true);
|
194
219
|
RTYPEDDATA_DATA(value) = wrapper;
|
195
220
|
|
196
221
|
Registries::instance.instances.add(data, value);
|
197
222
|
}
|
198
|
-
|
199
|
-
inline Wrapper* getWrapper(VALUE value)
|
200
|
-
{
|
201
|
-
// Turn off spurious warning on g++ 12
|
202
|
-
#ifdef __GNUC__
|
203
|
-
#pragma GCC diagnostic push
|
204
|
-
#pragma GCC diagnostic ignored "-Warray-bounds"
|
205
|
-
#endif
|
206
|
-
return RTYPEDDATA_P(value) ? static_cast<Wrapper*>(RTYPEDDATA_DATA(value)) : nullptr;
|
207
|
-
#ifdef __GNUC__
|
208
|
-
#pragma GCC diagnostic pop
|
209
|
-
#endif
|
210
|
-
}
|
211
223
|
} // namespace
|
data/rice/detail/cpp_protect.hpp
CHANGED
@@ -14,8 +14,6 @@
|
|
14
14
|
#error "no filesystem include found :'("
|
15
15
|
#endif
|
16
16
|
|
17
|
-
#include "Jump_Tag.hpp"
|
18
|
-
#include "../Exception_defn.hpp"
|
19
17
|
|
20
18
|
namespace Rice::detail
|
21
19
|
{
|
@@ -30,13 +28,14 @@ namespace Rice::detail
|
|
30
28
|
{
|
31
29
|
try
|
32
30
|
{
|
33
|
-
detail::Registries::instance.handlers.handler()
|
31
|
+
std::function<void()> handler = detail::Registries::instance.handlers.handler();
|
32
|
+
handler();
|
34
33
|
}
|
35
34
|
catch (::Rice::Exception const& ex)
|
36
35
|
{
|
37
36
|
rb_exc_raise(ex.value());
|
38
37
|
}
|
39
|
-
catch (::Rice::
|
38
|
+
catch (::Rice::JumpException const& ex)
|
40
39
|
{
|
41
40
|
rb_jump_tag(ex.tag);
|
42
41
|
}
|
@@ -61,11 +60,11 @@ namespace Rice::detail
|
|
61
60
|
}
|
62
61
|
catch (std::length_error const& ex)
|
63
62
|
{
|
64
|
-
rb_exc_raise(rb_exc_new2(
|
63
|
+
rb_exc_raise(rb_exc_new2(rb_eIndexError, ex.what()));
|
65
64
|
}
|
66
65
|
catch (std::out_of_range const& ex)
|
67
66
|
{
|
68
|
-
rb_exc_raise(rb_exc_new2(
|
67
|
+
rb_exc_raise(rb_exc_new2(rb_eIndexError, ex.what()));
|
69
68
|
}
|
70
69
|
catch (std::overflow_error const& ex)
|
71
70
|
{
|
data/rice/detail/from_ruby.hpp
CHANGED
@@ -1,8 +1,43 @@
|
|
1
1
|
#ifndef Rice__detail__from_ruby__hpp_
|
2
2
|
#define Rice__detail__from_ruby__hpp_
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
namespace Rice::detail
|
5
|
+
{
|
6
|
+
//! Convert a Ruby object to C++.
|
7
|
+
/*! If the Ruby object can be converted to an immediate value, returns a
|
8
|
+
* copy of the Ruby object. If the Ruby object is holding a C++
|
9
|
+
* object and the type specified is a pointer to that type, returns a
|
10
|
+
* pointer to that object.
|
11
|
+
*
|
12
|
+
* Conversions from ruby to a pointer type are automatically generated
|
13
|
+
* when a type is bound using Data_Type. If no conversion exists an
|
14
|
+
* exception is thrown.
|
15
|
+
*
|
16
|
+
* \param T the C++ type to which to convert.
|
17
|
+
* \param x the Ruby object to convert.
|
18
|
+
* \return a C++ representation of the Ruby object.
|
19
|
+
*
|
20
|
+
* Example:
|
21
|
+
* \code
|
22
|
+
* Object x = INT2NUM(42);
|
23
|
+
* std::cout << From_Ruby<int>::convert(x);
|
24
|
+
*
|
25
|
+
* Data_Object<Foo> foo(new Foo);
|
26
|
+
* std::cout << *From_Ruby<Foo *>(foo) << std::endl;
|
27
|
+
* \endcode
|
28
|
+
*/
|
6
29
|
|
7
|
-
|
30
|
+
template <typename T>
|
31
|
+
class From_Ruby;
|
8
32
|
|
33
|
+
enum class Convertible: uint8_t
|
34
|
+
{
|
35
|
+
None = 0b0000,
|
36
|
+
Narrow = 0b0001,
|
37
|
+
Cast = 0b0011,
|
38
|
+
Const = 0b0111,
|
39
|
+
Exact = 0b1111
|
40
|
+
};
|
41
|
+
}
|
42
|
+
|
43
|
+
#endif // Rice__detail__From_Ruby2__hpp_
|