rice 4.8.0 → 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 +8 -0
- data/bin/rice-doc.rb +2 -0
- data/include/rice/api.hpp +14 -1
- data/include/rice/rice.hpp +237 -51
- data/include/rice/stl.hpp +166 -165
- data/lib/rice/doc/rice.rb +2 -1
- data/lib/rice/native_registry.rb +4 -9
- data/lib/rice/rbs.rb +4 -4
- data/lib/rice/version.rb +1 -1
- data/rice/Data_Type.ipp +11 -6
- data/rice/cpp_api/Class.hpp +5 -0
- data/rice/cpp_api/Class.ipp +5 -0
- data/rice/cpp_api/Object.hpp +6 -0
- data/rice/cpp_api/Object.ipp +5 -0
- data/rice/detail/Forwards.hpp +18 -0
- data/rice/detail/Forwards.ipp +60 -0
- data/rice/detail/NativeRegistry.hpp +1 -0
- data/rice/detail/NativeRegistry.ipp +29 -0
- data/rice/detail/Type.ipp +4 -0
- data/rice/detail/Wrapper.hpp +12 -11
- data/rice/detail/Wrapper.ipp +80 -35
- data/rice/rice.hpp +3 -0
- data/rice/rice_api/NativeRegistry.ipp +14 -1
- data/rice/stl/shared_ptr.hpp +16 -0
- data/rice/stl/shared_ptr.ipp +61 -38
- data/rice/stl/unique_ptr.hpp +9 -3
- data/rice/stl/unique_ptr.ipp +80 -124
- data/test/test_Inheritance.cpp +14 -14
- data/test/test_Keep_Alive_No_Wrapper.cpp +6 -2
- data/test/test_Stl_SharedPtr.cpp +160 -45
- data/test/test_Stl_UniquePtr.cpp +48 -3
- metadata +3 -1
data/rice/stl/unique_ptr.hpp
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
#ifndef Rice__stl__unique_ptr__hpp_
|
|
2
2
|
#define Rice__stl__unique_ptr__hpp_
|
|
3
3
|
|
|
4
|
+
namespace Rice
|
|
5
|
+
{
|
|
6
|
+
template<typename T>
|
|
7
|
+
Data_Type<std::unique_ptr<T>> define_unique_ptr(std::string klassName = "");
|
|
8
|
+
}
|
|
9
|
+
|
|
4
10
|
namespace Rice::detail
|
|
5
11
|
{
|
|
6
12
|
template<typename T>
|
|
7
13
|
class Wrapper<std::unique_ptr<T>> : public WrapperBase
|
|
8
14
|
{
|
|
9
15
|
public:
|
|
10
|
-
Wrapper(std::unique_ptr<T>&& data);
|
|
16
|
+
Wrapper(rb_data_type_t* rb_data_type, std::unique_ptr<T>&& data);
|
|
11
17
|
~Wrapper();
|
|
12
|
-
void* get() override;
|
|
13
|
-
std::unique_ptr<T>& data();
|
|
18
|
+
void* get(rb_data_type_t* requestedType) override;
|
|
14
19
|
|
|
15
20
|
private:
|
|
16
21
|
std::unique_ptr<T> data_;
|
|
22
|
+
rb_data_type_t* inner_rb_data_type_;
|
|
17
23
|
};
|
|
18
24
|
}
|
|
19
25
|
|
data/rice/stl/unique_ptr.ipp
CHANGED
|
@@ -1,135 +1,123 @@
|
|
|
1
1
|
#include <memory>
|
|
2
2
|
|
|
3
|
-
namespace Rice
|
|
3
|
+
namespace Rice
|
|
4
4
|
{
|
|
5
5
|
template<typename T>
|
|
6
|
-
|
|
7
|
-
: data_(std::move(data))
|
|
8
|
-
{
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
template<typename T>
|
|
12
|
-
inline Wrapper<std::unique_ptr<T>>::~Wrapper()
|
|
13
|
-
{
|
|
14
|
-
Registries::instance.instances.remove(this->get());
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
template<typename T>
|
|
18
|
-
inline void* Wrapper<std::unique_ptr<T>>::get()
|
|
19
|
-
{
|
|
20
|
-
return (void*)this->data_.get();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
template<typename T>
|
|
24
|
-
inline std::unique_ptr<T>& Wrapper<std::unique_ptr<T>>::data()
|
|
6
|
+
Data_Type<std::unique_ptr<T>> define_unique_ptr(std::string klassName)
|
|
25
7
|
{
|
|
26
|
-
|
|
27
|
-
|
|
8
|
+
using UniquePtr_T = std::unique_ptr<T>;
|
|
9
|
+
using Data_Type_T = Data_Type<UniquePtr_T>;
|
|
28
10
|
|
|
29
|
-
|
|
30
|
-
class To_Ruby<std::unique_ptr<T>>
|
|
31
|
-
{
|
|
32
|
-
public:
|
|
33
|
-
To_Ruby() = default;
|
|
34
|
-
|
|
35
|
-
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
11
|
+
if (klassName.empty())
|
|
36
12
|
{
|
|
13
|
+
detail::TypeMapper<UniquePtr_T> typeMapper;
|
|
14
|
+
klassName = typeMapper.rubyName();
|
|
37
15
|
}
|
|
38
16
|
|
|
39
|
-
|
|
17
|
+
Module rb_mStd = define_module("Std");
|
|
18
|
+
if (Data_Type_T::check_defined(klassName, rb_mStd))
|
|
40
19
|
{
|
|
41
|
-
|
|
42
|
-
return detail::wrap<std::unique_ptr<T>>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
|
20
|
+
return Data_Type_T();
|
|
43
21
|
}
|
|
44
22
|
|
|
45
|
-
|
|
23
|
+
Identifier id(klassName);
|
|
24
|
+
Data_Type_T result = define_class_under<detail::intrinsic_type<UniquePtr_T>>(rb_mStd, id).
|
|
25
|
+
define_method("get", &UniquePtr_T::get).
|
|
26
|
+
define_method("release", &UniquePtr_T::release).
|
|
27
|
+
define_method("reset", &UniquePtr_T::reset).
|
|
28
|
+
define_method("swap", &UniquePtr_T::swap).
|
|
29
|
+
define_method("empty?", [](UniquePtr_T& self)->bool
|
|
30
|
+
{
|
|
31
|
+
return !self;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Setup delegation to forward T's methods via get (only for non-fundamental, non-void types)
|
|
35
|
+
if constexpr (!std::is_void_v<T> && !std::is_fundamental_v<T>)
|
|
46
36
|
{
|
|
47
|
-
|
|
48
|
-
return detail::wrap<std::unique_ptr<T>>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
|
37
|
+
detail::define_forwarding(result.klass(), Data_Type<T>::klass());
|
|
49
38
|
}
|
|
50
39
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
54
43
|
|
|
55
|
-
|
|
56
|
-
|
|
44
|
+
// --------- Wrapper ---------
|
|
45
|
+
namespace Rice::detail
|
|
46
|
+
{
|
|
47
|
+
template<typename T>
|
|
48
|
+
Wrapper<std::unique_ptr<T>>::Wrapper(rb_data_type_t* rb_data_type, std::unique_ptr<T>&& data)
|
|
49
|
+
: WrapperBase(rb_data_type), data_(std::move(data))
|
|
57
50
|
{
|
|
58
|
-
|
|
59
|
-
To_Ruby() = default;
|
|
51
|
+
using Intrinsic_T = intrinsic_type<T>;
|
|
60
52
|
|
|
61
|
-
|
|
53
|
+
if constexpr (std::is_fundamental_v<Intrinsic_T>)
|
|
62
54
|
{
|
|
55
|
+
inner_rb_data_type_ = Data_Type<Pointer<Intrinsic_T>>::ruby_data_type();
|
|
63
56
|
}
|
|
64
|
-
|
|
65
|
-
VALUE convert(std::unique_ptr<T>& data)
|
|
57
|
+
else
|
|
66
58
|
{
|
|
67
|
-
|
|
68
|
-
return detail::wrap<std::unique_ptr<T>>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
|
59
|
+
inner_rb_data_type_ = Data_Type<Intrinsic_T>::ruby_data_type();
|
|
69
60
|
}
|
|
61
|
+
}
|
|
70
62
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
63
|
+
template<typename T>
|
|
64
|
+
Wrapper<std::unique_ptr<T>>::~Wrapper()
|
|
65
|
+
{
|
|
66
|
+
Registries::instance.instances.remove(this->get(this->rb_data_type_));
|
|
67
|
+
}
|
|
74
68
|
|
|
75
|
-
template
|
|
76
|
-
|
|
69
|
+
template<typename T>
|
|
70
|
+
void* Wrapper<std::unique_ptr<T>>::get(rb_data_type_t* requestedType)
|
|
77
71
|
{
|
|
78
|
-
|
|
79
|
-
Wrapper<std::unique_ptr<T>>* is_same_smart_ptr(VALUE value)
|
|
72
|
+
if (rb_typeddata_inherited_p(this->rb_data_type_, requestedType))
|
|
80
73
|
{
|
|
81
|
-
|
|
82
|
-
return dynamic_cast<Wrapper<std::unique_ptr<T>>*>(wrapper);
|
|
74
|
+
return &this->data_;
|
|
83
75
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
76
|
+
else if (rb_typeddata_inherited_p(this->inner_rb_data_type_, requestedType))
|
|
77
|
+
{
|
|
78
|
+
return this->data_.get();
|
|
79
|
+
}
|
|
80
|
+
else
|
|
88
81
|
{
|
|
82
|
+
throw Exception(rb_eTypeError, "wrong argument type (expected %s)",
|
|
83
|
+
requestedType->wrap_struct_name);
|
|
89
84
|
}
|
|
85
|
+
}
|
|
90
86
|
|
|
91
|
-
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// --------- Type ---------
|
|
90
|
+
namespace Rice::detail
|
|
91
|
+
{
|
|
92
|
+
template<typename T>
|
|
93
|
+
struct Type<std::unique_ptr<T>>
|
|
94
|
+
{
|
|
95
|
+
static bool verify()
|
|
92
96
|
{
|
|
93
|
-
|
|
97
|
+
bool result = true;
|
|
98
|
+
if constexpr (std::is_fundamental_v<T>)
|
|
94
99
|
{
|
|
95
|
-
|
|
100
|
+
result = result && Type<Pointer<T>>::verify();
|
|
96
101
|
}
|
|
97
|
-
|
|
98
|
-
switch (rb_type(value))
|
|
102
|
+
else
|
|
99
103
|
{
|
|
100
|
-
|
|
101
|
-
return Convertible::Exact;
|
|
102
|
-
break;
|
|
103
|
-
default:
|
|
104
|
-
return Convertible::None;
|
|
104
|
+
result = result && Type<T>::verify();
|
|
105
105
|
}
|
|
106
|
-
}
|
|
107
106
|
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
Wrapper<std::unique_ptr<T>>* wrapper = is_same_smart_ptr(value);
|
|
111
|
-
if (!wrapper)
|
|
107
|
+
if (result)
|
|
112
108
|
{
|
|
113
|
-
|
|
114
|
-
throw std::runtime_error(message.c_str());
|
|
109
|
+
define_unique_ptr<T>();
|
|
115
110
|
}
|
|
116
|
-
return std::move(wrapper->data());
|
|
117
|
-
}
|
|
118
111
|
|
|
119
|
-
|
|
120
|
-
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
121
114
|
};
|
|
122
115
|
|
|
116
|
+
// --------- From_Ruby ---------
|
|
123
117
|
template <typename T>
|
|
124
|
-
class From_Ruby<std::unique_ptr<T
|
|
118
|
+
class From_Ruby<std::unique_ptr<T>>
|
|
125
119
|
{
|
|
126
120
|
public:
|
|
127
|
-
Wrapper<std::unique_ptr<T>>* is_same_smart_ptr(VALUE value)
|
|
128
|
-
{
|
|
129
|
-
WrapperBase* wrapper = detail::getWrapper(value, Data_Type<T>::ruby_data_type());
|
|
130
|
-
return dynamic_cast<Wrapper<std::unique_ptr<T>>*>(wrapper);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
121
|
From_Ruby() = default;
|
|
134
122
|
|
|
135
123
|
explicit From_Ruby(Arg* arg) : arg_(arg)
|
|
@@ -138,11 +126,6 @@ namespace Rice::detail
|
|
|
138
126
|
|
|
139
127
|
double is_convertible(VALUE value)
|
|
140
128
|
{
|
|
141
|
-
if (!is_same_smart_ptr(value))
|
|
142
|
-
{
|
|
143
|
-
return Convertible::None;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
129
|
switch (rb_type(value))
|
|
147
130
|
{
|
|
148
131
|
case RUBY_T_DATA:
|
|
@@ -153,41 +136,14 @@ namespace Rice::detail
|
|
|
153
136
|
}
|
|
154
137
|
}
|
|
155
138
|
|
|
156
|
-
std::unique_ptr<T
|
|
139
|
+
std::unique_ptr<T> convert(VALUE value)
|
|
157
140
|
{
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
std::string message = "Invalid smart pointer wrapper";
|
|
162
|
-
throw std::runtime_error(message.c_str());
|
|
163
|
-
}
|
|
164
|
-
return wrapper->data();
|
|
141
|
+
std::unique_ptr<T>* result = detail::unwrap<std::unique_ptr<T>>(value, Data_Type<std::unique_ptr<T>>::ruby_data_type(), this->arg_ && this->arg_->isOwner());
|
|
142
|
+
// The reason we need this overriden From_Ruby is to do this std::move.
|
|
143
|
+
return std::move(*result);
|
|
165
144
|
}
|
|
166
145
|
|
|
167
146
|
private:
|
|
168
147
|
Arg* arg_ = nullptr;
|
|
169
148
|
};
|
|
170
|
-
|
|
171
|
-
template<typename T>
|
|
172
|
-
struct Type<std::unique_ptr<T>>
|
|
173
|
-
{
|
|
174
|
-
static bool verify()
|
|
175
|
-
{
|
|
176
|
-
if constexpr (std::is_fundamental_v<T>)
|
|
177
|
-
{
|
|
178
|
-
return Type<Pointer<T>>::verify();
|
|
179
|
-
return Type<Buffer<T>>::verify();
|
|
180
|
-
}
|
|
181
|
-
else
|
|
182
|
-
{
|
|
183
|
-
return Type<T>::verify();
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
static VALUE rubyKlass()
|
|
188
|
-
{
|
|
189
|
-
TypeMapper<T> typeMapper;
|
|
190
|
-
return typeMapper.rubyKlass();
|
|
191
|
-
}
|
|
192
|
-
};
|
|
193
149
|
}
|
data/test/test_Inheritance.cpp
CHANGED
|
@@ -128,12 +128,12 @@ TESTCASE(base_pointer_method_call)
|
|
|
128
128
|
|
|
129
129
|
Module m = define_module("Testing");
|
|
130
130
|
|
|
131
|
-
Object message = m.module_eval(R"
|
|
132
|
-
|
|
131
|
+
Object message = m.module_eval(R"(notification = EmailNotification.new
|
|
132
|
+
notification.message)");
|
|
133
133
|
ASSERT_EQUAL("Email", detail::From_Ruby<std::string>().convert(message));
|
|
134
134
|
|
|
135
|
-
message = m.module_eval(R"
|
|
136
|
-
|
|
135
|
+
message = m.module_eval(R"(notification = PushNotification.new
|
|
136
|
+
notification.message)");
|
|
137
137
|
ASSERT_EQUAL("Push", detail::From_Ruby<std::string>().convert(message));
|
|
138
138
|
}
|
|
139
139
|
|
|
@@ -151,12 +151,12 @@ TESTCASE(base_pointer_function_argument)
|
|
|
151
151
|
define_global_function("process_notification", &processNotification);
|
|
152
152
|
|
|
153
153
|
Module m = define_module("Testing");
|
|
154
|
-
Object message = m.module_eval(R"
|
|
155
|
-
|
|
154
|
+
Object message = m.module_eval(R"(notification = EmailNotification.new
|
|
155
|
+
process_notification(notification))");
|
|
156
156
|
ASSERT_EQUAL("Email", detail::From_Ruby<std::string>().convert(message));
|
|
157
157
|
|
|
158
|
-
message = m.module_eval(R"
|
|
159
|
-
|
|
158
|
+
message = m.module_eval(R"(notification = PushNotification.new
|
|
159
|
+
process_notification(notification))");
|
|
160
160
|
ASSERT_EQUAL("Push", detail::From_Ruby<std::string>().convert(message));
|
|
161
161
|
}
|
|
162
162
|
|
|
@@ -175,12 +175,12 @@ TESTCASE(module_base_pointer_method_call)
|
|
|
175
175
|
|
|
176
176
|
Module m = define_module("Testing");
|
|
177
177
|
|
|
178
|
-
Object message = m.module_eval(R"
|
|
179
|
-
|
|
178
|
+
Object message = m.module_eval(R"(notification = Inheritance::EmailNotification.new
|
|
179
|
+
notification.message)");
|
|
180
180
|
ASSERT_EQUAL("Email", detail::From_Ruby<std::string>().convert(message));
|
|
181
181
|
|
|
182
|
-
message = m.module_eval(R"
|
|
183
|
-
|
|
182
|
+
message = m.module_eval(R"(notification = Inheritance::PushNotification.new
|
|
183
|
+
notification.message)");
|
|
184
184
|
ASSERT_EQUAL("Push", detail::From_Ruby<std::string>().convert(message));
|
|
185
185
|
}
|
|
186
186
|
|
|
@@ -219,8 +219,8 @@ TESTCASE(base_pointer_constructor)
|
|
|
219
219
|
|
|
220
220
|
Module m = define_module("Testing");
|
|
221
221
|
|
|
222
|
-
Object result = m.module_eval(R"
|
|
222
|
+
Object result = m.module_eval(R"(notification = PushNotification.new
|
|
223
223
|
processor = Processor.new(notification)
|
|
224
|
-
processor.process)
|
|
224
|
+
processor.process)");
|
|
225
225
|
ASSERT_EQUAL("Push", detail::From_Ruby<std::string>().convert(result));
|
|
226
226
|
}
|
|
@@ -75,11 +75,15 @@ TESTCASE(test_keep_alive_no_wrapper)
|
|
|
75
75
|
Module m = define_module("TestingModule");
|
|
76
76
|
Object zoo = m.module_eval("@zoo = Zoo.new");
|
|
77
77
|
|
|
78
|
+
std::string code = R"(@zoo.get_pets.each do |pet|
|
|
79
|
+
puts pet.get_name
|
|
80
|
+
end)";
|
|
81
|
+
|
|
78
82
|
// get_pets returns an Array (builtin type) so Return().keepAlive()
|
|
79
|
-
//
|
|
83
|
+
// should result in std::runtime_error
|
|
80
84
|
ASSERT_EXCEPTION_CHECK(
|
|
81
85
|
Exception,
|
|
82
|
-
m.module_eval(
|
|
86
|
+
m.module_eval(code),
|
|
83
87
|
ASSERT_EQUAL("wrong argument type Array (expected wrapped C++ object)",
|
|
84
88
|
ex.what())
|
|
85
89
|
);
|