rice 4.0.4 → 4.2.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 -0
- data/CONTRIBUTORS.md +2 -0
- data/Rakefile +1 -1
- data/include/rice/rice.hpp +2851 -1955
- data/include/rice/stl.hpp +1654 -287
- data/lib/mkmf-rice.rb +5 -2
- data/lib/version.rb +1 -1
- data/rice/Arg.hpp +6 -6
- data/rice/Arg.ipp +8 -9
- data/rice/Constructor.hpp +2 -2
- data/rice/Data_Object.ipp +69 -15
- data/rice/Data_Object_defn.hpp +1 -15
- data/rice/Data_Type.ipp +56 -86
- data/rice/Data_Type_defn.hpp +14 -17
- data/rice/Director.hpp +0 -1
- data/rice/Enum.ipp +31 -22
- data/rice/Exception.ipp +2 -3
- data/rice/Exception_defn.hpp +5 -5
- data/rice/HandlerRegistration.hpp +15 -0
- data/rice/Return.hpp +5 -4
- data/rice/Return.ipp +8 -3
- data/rice/detail/ExceptionHandler.hpp +8 -0
- data/rice/detail/ExceptionHandler.ipp +28 -0
- data/rice/detail/{Exception_Handler_defn.hpp → ExceptionHandler_defn.hpp} +17 -21
- data/rice/detail/HandlerRegistry.hpp +51 -0
- data/rice/detail/HandlerRegistry.ipp +20 -0
- data/rice/detail/InstanceRegistry.hpp +34 -0
- data/rice/detail/InstanceRegistry.ipp +50 -0
- data/rice/detail/MethodInfo.ipp +1 -1
- data/rice/detail/NativeAttribute.hpp +26 -15
- data/rice/detail/NativeAttribute.ipp +76 -47
- data/rice/detail/NativeFunction.hpp +64 -14
- data/rice/detail/NativeFunction.ipp +138 -86
- data/rice/detail/NativeIterator.hpp +49 -0
- data/rice/detail/NativeIterator.ipp +102 -0
- data/rice/detail/NativeRegistry.hpp +31 -0
- data/rice/detail/{method_data.ipp → NativeRegistry.ipp} +20 -16
- data/rice/detail/Registries.hpp +26 -0
- data/rice/detail/Registries.ipp +23 -0
- data/rice/detail/RubyFunction.hpp +6 -11
- data/rice/detail/RubyFunction.ipp +10 -22
- data/rice/detail/Type.hpp +1 -1
- data/rice/detail/Type.ipp +2 -2
- data/rice/detail/TypeRegistry.hpp +8 -11
- data/rice/detail/TypeRegistry.ipp +3 -28
- data/rice/detail/Wrapper.hpp +0 -2
- data/rice/detail/Wrapper.ipp +74 -24
- data/rice/detail/cpp_protect.hpp +93 -0
- data/rice/detail/default_allocation_func.ipp +1 -1
- data/rice/detail/from_ruby.ipp +206 -2
- data/rice/detail/to_ruby.ipp +39 -5
- data/rice/detail/to_ruby_defn.hpp +1 -1
- data/rice/forward_declares.ipp +6 -0
- data/rice/global_function.hpp +0 -4
- data/rice/global_function.ipp +0 -6
- data/rice/rice.hpp +29 -24
- data/rice/stl.hpp +6 -1
- data/sample/callbacks/extconf.rb +0 -1
- data/sample/enum/extconf.rb +0 -1
- data/sample/inheritance/extconf.rb +0 -1
- data/sample/map/extconf.rb +0 -1
- data/test/embed_ruby.cpp +6 -15
- data/test/ext/t1/extconf.rb +0 -1
- data/test/ext/t2/extconf.rb +0 -1
- data/test/extconf.rb +0 -1
- data/test/test_Array.cpp +20 -24
- data/test/test_Attribute.cpp +6 -6
- data/test/test_Class.cpp +8 -47
- data/test/test_Constructor.cpp +0 -2
- data/test/test_Data_Object.cpp +25 -11
- data/test/test_Data_Type.cpp +124 -28
- data/test/test_Director.cpp +12 -13
- data/test/test_Enum.cpp +65 -26
- data/test/test_Inheritance.cpp +9 -9
- data/test/test_Iterator.cpp +134 -5
- data/test/test_Keep_Alive.cpp +7 -7
- data/test/test_Keep_Alive_No_Wrapper.cpp +80 -0
- data/test/test_Memory_Management.cpp +1 -1
- data/test/test_Module.cpp +25 -62
- data/test/test_Object.cpp +75 -3
- data/test/test_Ownership.cpp +12 -13
- data/test/test_Self.cpp +12 -13
- data/test/test_Stl_Map.cpp +696 -0
- data/test/test_Stl_Optional.cpp +3 -3
- data/test/test_Stl_Pair.cpp +38 -2
- data/test/test_Stl_Reference_Wrapper.cpp +102 -0
- data/test/test_Stl_SmartPointer.cpp +49 -9
- data/test/test_Stl_String.cpp +5 -2
- data/test/test_Stl_Unordered_Map.cpp +697 -0
- data/test/test_Stl_Variant.cpp +346 -0
- data/test/test_Stl_Vector.cpp +200 -41
- data/test/test_Struct.cpp +3 -3
- data/test/test_To_From_Ruby.cpp +8 -2
- data/test/test_Tracking.cpp +239 -0
- data/test/unittest.hpp +21 -4
- metadata +24 -13
- data/rice/detail/Exception_Handler.hpp +0 -8
- data/rice/detail/Exception_Handler.ipp +0 -28
- data/rice/detail/Iterator.hpp +0 -23
- data/rice/detail/Iterator.ipp +0 -47
- data/rice/detail/function_traits.hpp +0 -124
- data/rice/detail/method_data.hpp +0 -29
- data/rice/detail/rice_traits.hpp +0 -116
- data/rice/ruby_try_catch.hpp +0 -86
data/rice/detail/Wrapper.ipp
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#include <memory>
|
2
|
+
#include "InstanceRegistry.hpp"
|
2
3
|
|
3
4
|
namespace Rice::detail
|
4
5
|
{
|
@@ -23,6 +24,11 @@ namespace Rice::detail
|
|
23
24
|
{
|
24
25
|
}
|
25
26
|
|
27
|
+
~WrapperValue()
|
28
|
+
{
|
29
|
+
Registries::instance.instances.remove(this->get());
|
30
|
+
}
|
31
|
+
|
26
32
|
void* get() override
|
27
33
|
{
|
28
34
|
return (void*)&this->data_;
|
@@ -36,8 +42,13 @@ namespace Rice::detail
|
|
36
42
|
class WrapperReference : public Wrapper
|
37
43
|
{
|
38
44
|
public:
|
39
|
-
WrapperReference(
|
45
|
+
WrapperReference(T& data): data_(data)
|
46
|
+
{
|
47
|
+
}
|
48
|
+
|
49
|
+
~WrapperReference()
|
40
50
|
{
|
51
|
+
Registries::instance.instances.remove(this->get());
|
41
52
|
}
|
42
53
|
|
43
54
|
void* get() override
|
@@ -46,7 +57,7 @@ namespace Rice::detail
|
|
46
57
|
}
|
47
58
|
|
48
59
|
private:
|
49
|
-
|
60
|
+
T& data_;
|
50
61
|
};
|
51
62
|
|
52
63
|
template <typename T>
|
@@ -59,6 +70,8 @@ namespace Rice::detail
|
|
59
70
|
|
60
71
|
~WrapperPointer()
|
61
72
|
{
|
73
|
+
Registries::instance.instances.remove(this->get());
|
74
|
+
|
62
75
|
if (this->isOwner_)
|
63
76
|
{
|
64
77
|
delete this->data_;
|
@@ -79,53 +92,76 @@ namespace Rice::detail
|
|
79
92
|
template <typename T, typename Wrapper_T>
|
80
93
|
inline VALUE wrap(VALUE klass, rb_data_type_t* rb_type, T& data, bool isOwner)
|
81
94
|
{
|
95
|
+
VALUE result = Registries::instance.instances.lookup(&data);
|
96
|
+
|
97
|
+
if (result != Qnil)
|
98
|
+
return result;
|
99
|
+
|
100
|
+
Wrapper* wrapper = nullptr;
|
101
|
+
|
82
102
|
if constexpr (!std::is_void_v<Wrapper_T>)
|
83
103
|
{
|
84
|
-
|
85
|
-
|
104
|
+
wrapper = new Wrapper_T(data);
|
105
|
+
result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
|
86
106
|
}
|
87
107
|
else if (isOwner)
|
88
108
|
{
|
89
|
-
|
90
|
-
|
109
|
+
wrapper = new WrapperValue<T>(data);
|
110
|
+
result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
|
91
111
|
}
|
92
112
|
else
|
93
113
|
{
|
94
|
-
|
95
|
-
|
114
|
+
wrapper = new WrapperReference<T>(data);
|
115
|
+
result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
|
96
116
|
}
|
117
|
+
|
118
|
+
Registries::instance.instances.add(wrapper->get(), result);
|
119
|
+
|
120
|
+
return result;
|
97
121
|
};
|
98
122
|
|
99
123
|
template <typename T, typename Wrapper_T>
|
100
124
|
inline VALUE wrap(VALUE klass, rb_data_type_t* rb_type, T* data, bool isOwner)
|
101
125
|
{
|
126
|
+
VALUE result = Registries::instance.instances.lookup(data);
|
127
|
+
|
128
|
+
if (result != Qnil)
|
129
|
+
return result;
|
130
|
+
|
131
|
+
Wrapper* wrapper = nullptr;
|
132
|
+
|
102
133
|
if constexpr (!std::is_void_v<Wrapper_T>)
|
103
134
|
{
|
104
|
-
|
105
|
-
|
135
|
+
wrapper = new Wrapper_T(data);
|
136
|
+
result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
|
106
137
|
}
|
107
138
|
else
|
108
139
|
{
|
109
|
-
|
110
|
-
|
140
|
+
wrapper = new WrapperPointer<T>(data, isOwner);
|
141
|
+
result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
|
111
142
|
}
|
143
|
+
|
144
|
+
Registries::instance.instances.add(wrapper->get(), result);
|
145
|
+
return result;
|
112
146
|
};
|
113
147
|
|
114
148
|
template <typename T>
|
115
149
|
inline T* unwrap(VALUE value, rb_data_type_t* rb_type)
|
116
150
|
{
|
117
151
|
Wrapper* wrapper = getWrapper(value, rb_type);
|
118
|
-
TypedData_Get_Struct(value, Wrapper, rb_type, wrapper);
|
119
|
-
return static_cast<T*>(wrapper->get());
|
120
|
-
}
|
121
152
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
}
|
153
|
+
if (wrapper == nullptr)
|
154
|
+
{
|
155
|
+
std::string message = "Wrapped C++ object is nil. Did you override " +
|
156
|
+
std::string(detail::protect(rb_obj_classname, value)) +
|
157
|
+
"#initialize and forget to call super?";
|
128
158
|
|
159
|
+
throw std::runtime_error(message);
|
160
|
+
}
|
161
|
+
|
162
|
+
return static_cast<T*>(wrapper->get());
|
163
|
+
}
|
164
|
+
|
129
165
|
inline Wrapper* getWrapper(VALUE value, rb_data_type_t* rb_type)
|
130
166
|
{
|
131
167
|
Wrapper* wrapper = nullptr;
|
@@ -138,14 +174,28 @@ namespace Rice::detail
|
|
138
174
|
{
|
139
175
|
WrapperPointer<T>* wrapper = nullptr;
|
140
176
|
TypedData_Get_Struct(value, WrapperPointer<T>, rb_type, wrapper);
|
141
|
-
|
177
|
+
if (wrapper)
|
178
|
+
{
|
179
|
+
Registries::instance.instances.remove(wrapper->get());
|
180
|
+
delete wrapper;
|
181
|
+
}
|
142
182
|
|
143
|
-
wrapper = new WrapperPointer<T>(data,
|
183
|
+
wrapper = new WrapperPointer<T>(data, isOwner);
|
144
184
|
RTYPEDDATA_DATA(value) = wrapper;
|
185
|
+
|
186
|
+
Registries::instance.instances.add(data, value);
|
145
187
|
}
|
146
188
|
|
147
189
|
inline Wrapper* getWrapper(VALUE value)
|
148
190
|
{
|
149
|
-
|
191
|
+
// Turn off spurious warning on g++ 12
|
192
|
+
#ifdef __GNUC__
|
193
|
+
#pragma GCC diagnostic push
|
194
|
+
#pragma GCC diagnostic ignored "-Warray-bounds"
|
195
|
+
#endif
|
196
|
+
return RTYPEDDATA_P(value) ? static_cast<Wrapper*>(RTYPEDDATA_DATA(value)) : nullptr;
|
197
|
+
#ifdef __GNUC__
|
198
|
+
#pragma GCC diagnostic pop
|
199
|
+
#endif
|
150
200
|
}
|
151
201
|
} // namespace
|
@@ -0,0 +1,93 @@
|
|
1
|
+
#ifndef Rice__detail__cpp_protect__hpp_
|
2
|
+
#define Rice__detail__cpp_protect__hpp_
|
3
|
+
|
4
|
+
#include <regex>
|
5
|
+
#include <filesystem>
|
6
|
+
#include <stdexcept>
|
7
|
+
|
8
|
+
#include "Jump_Tag.hpp"
|
9
|
+
#include "../Exception_defn.hpp"
|
10
|
+
|
11
|
+
namespace Rice::detail
|
12
|
+
{
|
13
|
+
template <typename Callable_T>
|
14
|
+
auto cpp_protect(Callable_T&& func)
|
15
|
+
{
|
16
|
+
try
|
17
|
+
{
|
18
|
+
return func();
|
19
|
+
}
|
20
|
+
catch (...)
|
21
|
+
{
|
22
|
+
try
|
23
|
+
{
|
24
|
+
detail::Registries::instance.handlers.handler()->handle();
|
25
|
+
}
|
26
|
+
catch (::Rice::Exception const& ex)
|
27
|
+
{
|
28
|
+
rb_exc_raise(ex.value());
|
29
|
+
}
|
30
|
+
catch (::Rice::Jump_Tag const& ex)
|
31
|
+
{
|
32
|
+
rb_jump_tag(ex.tag);
|
33
|
+
}
|
34
|
+
catch (std::bad_alloc const& ex)
|
35
|
+
{
|
36
|
+
/* This won't work quite right if the rb_exc_new2 fails; not
|
37
|
+
much we can do about that, since Ruby doesn't give us access
|
38
|
+
to a pre-allocated NoMemoryError object */
|
39
|
+
rb_exc_raise(rb_exc_new2(rb_eNoMemError, ex.what()));
|
40
|
+
}
|
41
|
+
catch (std::domain_error const& ex)
|
42
|
+
{
|
43
|
+
rb_exc_raise(rb_exc_new2(rb_eFloatDomainError, ex.what()));
|
44
|
+
}
|
45
|
+
catch (std::invalid_argument const& ex)
|
46
|
+
{
|
47
|
+
rb_exc_raise(rb_exc_new2(rb_eArgError, ex.what()));
|
48
|
+
}
|
49
|
+
catch (std::filesystem::filesystem_error const& ex)
|
50
|
+
{
|
51
|
+
rb_exc_raise(rb_exc_new2(rb_eIOError, ex.what()));
|
52
|
+
}
|
53
|
+
catch (std::length_error const& ex)
|
54
|
+
{
|
55
|
+
rb_exc_raise(rb_exc_new2(rb_eRuntimeError, ex.what()));
|
56
|
+
}
|
57
|
+
catch (std::out_of_range const& ex)
|
58
|
+
{
|
59
|
+
rb_exc_raise(rb_exc_new2(rb_eRangeError, ex.what()));
|
60
|
+
}
|
61
|
+
catch (std::overflow_error const& ex)
|
62
|
+
{
|
63
|
+
rb_exc_raise(rb_exc_new2(rb_eRangeError, ex.what()));
|
64
|
+
}
|
65
|
+
catch (std::range_error const& ex)
|
66
|
+
{
|
67
|
+
rb_exc_raise(rb_exc_new2(rb_eRangeError, ex.what()));
|
68
|
+
}
|
69
|
+
catch (std::regex_error const& ex)
|
70
|
+
{
|
71
|
+
rb_exc_raise(rb_exc_new2(rb_eRegexpError, ex.what()));
|
72
|
+
}
|
73
|
+
catch (std::system_error const& ex)
|
74
|
+
{
|
75
|
+
rb_exc_raise(rb_exc_new2(rb_eSystemCallError, ex.what()));
|
76
|
+
}
|
77
|
+
catch (std::underflow_error const& ex)
|
78
|
+
{
|
79
|
+
rb_exc_raise(rb_exc_new2(rb_eRangeError, ex.what()));
|
80
|
+
}
|
81
|
+
catch (std::exception const& ex)
|
82
|
+
{
|
83
|
+
rb_exc_raise(rb_exc_new2(rb_eRuntimeError, ex.what()));
|
84
|
+
}
|
85
|
+
catch (...)
|
86
|
+
{
|
87
|
+
rb_exc_raise(rb_exc_new2(rb_eRuntimeError, "Unknown C++ exception thrown"));
|
88
|
+
}
|
89
|
+
throw std::runtime_error("Should never get here - just making compilers happy");
|
90
|
+
}
|
91
|
+
}
|
92
|
+
}
|
93
|
+
#endif // Rice__detail__cpp_protect__hpp_
|
@@ -7,6 +7,6 @@ namespace Rice::detail
|
|
7
7
|
{
|
8
8
|
// Create a new Ruby object but since we do not yet have a C++ object
|
9
9
|
// just pass a nullptr. It will be set via the Constructor call
|
10
|
-
return TypedData_Wrap_Struct(klass, Data_Type<T>::
|
10
|
+
return TypedData_Wrap_Struct(klass, Data_Type<T>::ruby_data_type(), nullptr);
|
11
11
|
}
|
12
12
|
}
|