rice 4.8.0 → 4.9.1
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 +25 -1
- data/CMakePresets.json +77 -50
- data/FindRuby.cmake +1 -1
- data/bin/rice-doc.rb +2 -0
- data/include/rice/api.hpp +14 -1
- data/include/rice/rice.hpp +351 -132
- data/include/rice/stl.hpp +319 -256
- data/lib/rice/doc/config.rb +57 -57
- data/lib/rice/doc/cpp_reference.rb +158 -158
- data/lib/rice/doc/doxygen.rb +289 -289
- data/lib/rice/doc/mkdocs.rb +332 -332
- data/lib/rice/doc/rice.rb +48 -47
- data/lib/rice/doc/ruby.rb +26 -26
- data/lib/rice/native.rb +15 -15
- data/lib/rice/native_registry.rb +12 -17
- data/lib/rice/parameter.rb +5 -5
- data/lib/rice/rbs.rb +72 -72
- data/lib/rice/version.rb +1 -1
- data/lib/rubygems/builder.rb +9 -9
- data/lib/rubygems_plugin.rb +8 -8
- data/rice/Data_Type.ipp +12 -7
- 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/Native.ipp +2 -4
- data/rice/detail/NativeAttributeGet.ipp +1 -1
- data/rice/detail/NativeAttributeSet.hpp +5 -3
- data/rice/detail/NativeAttributeSet.ipp +41 -33
- data/rice/detail/NativeMethod.ipp +25 -22
- data/rice/detail/NativeRegistry.hpp +4 -2
- data/rice/detail/NativeRegistry.ipp +42 -9
- data/rice/detail/Parameter.ipp +3 -4
- data/rice/detail/Type.ipp +4 -0
- data/rice/detail/Wrapper.hpp +17 -12
- data/rice/detail/Wrapper.ipp +95 -36
- data/rice/rice.hpp +3 -0
- data/rice/rice_api/NativeRegistry.ipp +14 -1
- data/rice/stl/exception.ipp +1 -1
- data/rice/stl/filesystem.ipp +1 -1
- data/rice/stl/map.ipp +13 -11
- data/rice/stl/multimap.ipp +13 -11
- data/rice/stl/pair.ipp +14 -8
- data/rice/stl/set.ipp +16 -16
- data/rice/stl/shared_ptr.hpp +16 -0
- data/rice/stl/shared_ptr.ipp +74 -37
- data/rice/stl/type_index.ipp +1 -1
- data/rice/stl/unique_ptr.hpp +9 -3
- data/rice/stl/unique_ptr.ipp +80 -124
- data/rice/stl/unordered_map.ipp +14 -12
- data/rice/stl/vector.ipp +67 -31
- data/test/test_Attribute.cpp +72 -0
- data/test/test_Callback.cpp +3 -0
- data/test/test_Inheritance.cpp +14 -14
- data/test/test_Keep_Alive_No_Wrapper.cpp +6 -2
- data/test/test_Stl_Map.cpp +46 -0
- data/test/test_Stl_Multimap.cpp +46 -0
- data/test/test_Stl_Set.cpp +34 -0
- data/test/test_Stl_SharedPtr.cpp +160 -45
- data/test/test_Stl_UniquePtr.cpp +48 -3
- data/test/test_Stl_Unordered_Map.cpp +46 -0
- data/test/test_Stl_Variant.cpp +10 -14
- data/test/test_Stl_Vector.cpp +140 -13
- data/test/test_Tracking.cpp +3 -0
- metadata +3 -1
data/rice/detail/Wrapper.ipp
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Rice::detail
|
|
4
4
|
{
|
|
5
|
+
inline void WrapperBase::addKeepAlive(VALUE object, VALUE keepAlive)
|
|
6
|
+
{
|
|
7
|
+
WrapperBase* wrapper = getWrapper(object);
|
|
8
|
+
wrapper->addKeepAlive(keepAlive);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
inline bool WrapperBase::isConst(VALUE object)
|
|
12
|
+
{
|
|
13
|
+
WrapperBase* wrapper = getWrapper(object);
|
|
14
|
+
return wrapper->isConst();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
inline WrapperBase::WrapperBase(rb_data_type_t* rb_data_type) : rb_data_type_(rb_data_type)
|
|
18
|
+
{
|
|
19
|
+
}
|
|
20
|
+
|
|
5
21
|
inline bool WrapperBase::isConst()
|
|
6
22
|
{
|
|
7
23
|
return this->isConst_;
|
|
@@ -27,31 +43,40 @@ namespace Rice::detail
|
|
|
27
43
|
|
|
28
44
|
// ---- Wrapper -----
|
|
29
45
|
template <typename T>
|
|
30
|
-
inline Wrapper<T>::Wrapper(T& data): data_(data)
|
|
46
|
+
inline Wrapper<T>::Wrapper(rb_data_type_t* rb_data_type, T& data) : WrapperBase(rb_data_type), data_(data)
|
|
31
47
|
{
|
|
32
48
|
this->isConst_ = std::is_const_v<std::remove_reference_t<T>>;
|
|
33
49
|
}
|
|
34
50
|
|
|
35
51
|
template <typename T>
|
|
36
|
-
inline Wrapper<T>::Wrapper(T&& data) : data_(std::move(data))
|
|
52
|
+
inline Wrapper<T>::Wrapper(rb_data_type_t* rb_data_type, T&& data) : WrapperBase(rb_data_type), data_(std::move(data))
|
|
37
53
|
{
|
|
38
54
|
}
|
|
39
55
|
|
|
40
56
|
template <typename T>
|
|
41
57
|
inline Wrapper<T>::~Wrapper()
|
|
42
58
|
{
|
|
43
|
-
Registries::instance.instances.remove(this->get());
|
|
59
|
+
Registries::instance.instances.remove(this->get(this->rb_data_type_));
|
|
44
60
|
}
|
|
45
61
|
|
|
46
62
|
template <typename T>
|
|
47
|
-
inline void* Wrapper<T>::
|
|
63
|
+
inline void* Wrapper<T>::get(rb_data_type_t* requestedType)
|
|
48
64
|
{
|
|
49
|
-
|
|
65
|
+
if (rb_typeddata_inherited_p(this->rb_data_type_, requestedType))
|
|
66
|
+
{
|
|
67
|
+
return (void*)&this->data_;
|
|
68
|
+
}
|
|
69
|
+
else
|
|
70
|
+
{
|
|
71
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
|
|
72
|
+
this->rb_data_type_->wrap_struct_name,
|
|
73
|
+
requestedType->wrap_struct_name);
|
|
74
|
+
}
|
|
50
75
|
}
|
|
51
76
|
|
|
52
77
|
// ---- Wrapper& -----
|
|
53
78
|
template <typename T>
|
|
54
|
-
inline Wrapper<T&>::Wrapper(T& data): data_(data)
|
|
79
|
+
inline Wrapper<T&>::Wrapper(rb_data_type_t* rb_data_type, T& data) : WrapperBase(rb_data_type), data_(data)
|
|
55
80
|
{
|
|
56
81
|
this->isConst_ = std::is_const_v<std::remove_reference_t<T>>;
|
|
57
82
|
}
|
|
@@ -59,18 +84,27 @@ namespace Rice::detail
|
|
|
59
84
|
template <typename T>
|
|
60
85
|
inline Wrapper<T&>::~Wrapper()
|
|
61
86
|
{
|
|
62
|
-
Registries::instance.instances.remove(this->get());
|
|
87
|
+
Registries::instance.instances.remove(this->get(this->rb_data_type_));
|
|
63
88
|
}
|
|
64
89
|
|
|
65
90
|
template <typename T>
|
|
66
|
-
inline void* Wrapper<T&>::get()
|
|
91
|
+
inline void* Wrapper<T&>::get(rb_data_type_t* requestedType)
|
|
67
92
|
{
|
|
68
|
-
|
|
93
|
+
if (rb_typeddata_inherited_p(this->rb_data_type_, requestedType))
|
|
94
|
+
{
|
|
95
|
+
return (void*)&this->data_;
|
|
96
|
+
}
|
|
97
|
+
else
|
|
98
|
+
{
|
|
99
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
|
|
100
|
+
this->rb_data_type_->wrap_struct_name,
|
|
101
|
+
requestedType->wrap_struct_name);
|
|
102
|
+
}
|
|
69
103
|
}
|
|
70
104
|
|
|
71
105
|
// ---- Wrapper* -----
|
|
72
106
|
template <typename T>
|
|
73
|
-
inline Wrapper<T*>::Wrapper(T* data, bool isOwner) : data_(data)
|
|
107
|
+
inline Wrapper<T*>::Wrapper(rb_data_type_t* rb_data_type, T* data, bool isOwner) : WrapperBase(rb_data_type), data_(data)
|
|
74
108
|
{
|
|
75
109
|
this->isOwner_ = isOwner;
|
|
76
110
|
this->isConst_ = std::is_const_v<std::remove_pointer_t<T>>;
|
|
@@ -79,7 +113,8 @@ namespace Rice::detail
|
|
|
79
113
|
template <typename T>
|
|
80
114
|
inline Wrapper<T*>::~Wrapper()
|
|
81
115
|
{
|
|
82
|
-
Registries::instance.instances.remove(this->get());
|
|
116
|
+
Registries::instance.instances.remove(this->get(this->rb_data_type_));
|
|
117
|
+
|
|
83
118
|
if constexpr (std::is_destructible_v<T>)
|
|
84
119
|
{
|
|
85
120
|
if (this->isOwner_)
|
|
@@ -90,14 +125,23 @@ namespace Rice::detail
|
|
|
90
125
|
}
|
|
91
126
|
|
|
92
127
|
template <typename T>
|
|
93
|
-
inline void* Wrapper<T*>::get()
|
|
128
|
+
inline void* Wrapper<T*>::get(rb_data_type_t* requestedType)
|
|
94
129
|
{
|
|
95
|
-
|
|
130
|
+
if (rb_typeddata_inherited_p(this->rb_data_type_, requestedType))
|
|
131
|
+
{
|
|
132
|
+
return (void*)this->data_;
|
|
133
|
+
}
|
|
134
|
+
else
|
|
135
|
+
{
|
|
136
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
|
|
137
|
+
this->rb_data_type_->wrap_struct_name,
|
|
138
|
+
requestedType->wrap_struct_name);
|
|
139
|
+
}
|
|
96
140
|
}
|
|
97
141
|
|
|
98
142
|
// ---- Wrapper** -----
|
|
99
143
|
template <typename T>
|
|
100
|
-
inline Wrapper<T**>::Wrapper(T** data, bool isOwner) : data_(data)
|
|
144
|
+
inline Wrapper<T**>::Wrapper(rb_data_type_t* rb_data_type, T** data, bool isOwner) : WrapperBase(rb_data_type), data_(data)
|
|
101
145
|
{
|
|
102
146
|
this->isOwner_ = isOwner;
|
|
103
147
|
this->isConst_ = std::is_const_v<std::remove_pointer_t<std::remove_pointer_t<T>>>;
|
|
@@ -106,7 +150,8 @@ namespace Rice::detail
|
|
|
106
150
|
template <typename T>
|
|
107
151
|
inline Wrapper<T**>::~Wrapper()
|
|
108
152
|
{
|
|
109
|
-
Registries::instance.instances.remove(this->get());
|
|
153
|
+
Registries::instance.instances.remove(this->get(this->rb_data_type_));
|
|
154
|
+
|
|
110
155
|
if constexpr (std::is_destructible_v<T>)
|
|
111
156
|
{
|
|
112
157
|
if (this->isOwner_)
|
|
@@ -117,9 +162,18 @@ namespace Rice::detail
|
|
|
117
162
|
}
|
|
118
163
|
|
|
119
164
|
template <typename T>
|
|
120
|
-
inline void* Wrapper<T**>::get()
|
|
165
|
+
inline void* Wrapper<T**>::get(rb_data_type_t* requestedType)
|
|
121
166
|
{
|
|
122
|
-
|
|
167
|
+
if (rb_typeddata_inherited_p(this->rb_data_type_, requestedType))
|
|
168
|
+
{
|
|
169
|
+
return (void*)this->data_;
|
|
170
|
+
}
|
|
171
|
+
else
|
|
172
|
+
{
|
|
173
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
|
|
174
|
+
this->rb_data_type_->wrap_struct_name,
|
|
175
|
+
requestedType->wrap_struct_name);
|
|
176
|
+
}
|
|
123
177
|
}
|
|
124
178
|
|
|
125
179
|
// ---- Helper Functions -------
|
|
@@ -136,7 +190,7 @@ namespace Rice::detail
|
|
|
136
190
|
// If Ruby is not the owner then wrap the reference
|
|
137
191
|
if (!isOwner)
|
|
138
192
|
{
|
|
139
|
-
wrapper = new Wrapper<T&>(data);
|
|
193
|
+
wrapper = new Wrapper<T&>(rb_data_type, data);
|
|
140
194
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
141
195
|
}
|
|
142
196
|
|
|
@@ -145,12 +199,12 @@ namespace Rice::detail
|
|
|
145
199
|
{
|
|
146
200
|
if constexpr (std::is_copy_constructible_v<typename T::value_type>)
|
|
147
201
|
{
|
|
148
|
-
wrapper = new Wrapper<T>(data);
|
|
202
|
+
wrapper = new Wrapper<T>(rb_data_type, data);
|
|
149
203
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
150
204
|
}
|
|
151
205
|
else
|
|
152
206
|
{
|
|
153
|
-
wrapper = new Wrapper<T>(std::move(data));
|
|
207
|
+
wrapper = new Wrapper<T>(rb_data_type, std::move(data));
|
|
154
208
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
155
209
|
}
|
|
156
210
|
}
|
|
@@ -158,14 +212,14 @@ namespace Rice::detail
|
|
|
158
212
|
// Ruby is the owner so copy data
|
|
159
213
|
else if constexpr (std::is_copy_constructible_v<T>)
|
|
160
214
|
{
|
|
161
|
-
wrapper = new Wrapper<T>(data);
|
|
215
|
+
wrapper = new Wrapper<T>(rb_data_type, data);
|
|
162
216
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
163
217
|
}
|
|
164
218
|
|
|
165
219
|
// Ruby is the owner so move data
|
|
166
220
|
else if constexpr (std::is_move_constructible_v<T>)
|
|
167
221
|
{
|
|
168
|
-
wrapper = new Wrapper<T>(std::move(data));
|
|
222
|
+
wrapper = new Wrapper<T>(rb_data_type, std::move(data));
|
|
169
223
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
170
224
|
}
|
|
171
225
|
|
|
@@ -177,7 +231,7 @@ namespace Rice::detail
|
|
|
177
231
|
throw std::runtime_error(message);
|
|
178
232
|
}
|
|
179
233
|
|
|
180
|
-
Registries::instance.instances.add(wrapper->get(), result);
|
|
234
|
+
Registries::instance.instances.add(wrapper->get(rb_data_type), result);
|
|
181
235
|
|
|
182
236
|
return result;
|
|
183
237
|
};
|
|
@@ -190,38 +244,40 @@ namespace Rice::detail
|
|
|
190
244
|
if (result != Qnil)
|
|
191
245
|
return result;
|
|
192
246
|
|
|
193
|
-
WrapperBase* wrapper = new Wrapper<T*>(data, isOwner);
|
|
247
|
+
WrapperBase* wrapper = new Wrapper<T*>(rb_data_type, data, isOwner);
|
|
194
248
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
195
249
|
|
|
196
|
-
Registries::instance.instances.add(wrapper->get(), result);
|
|
250
|
+
Registries::instance.instances.add(wrapper->get(rb_data_type), result);
|
|
197
251
|
return result;
|
|
198
252
|
};
|
|
199
253
|
|
|
200
254
|
template <typename T>
|
|
201
255
|
inline T* unwrap(VALUE value, rb_data_type_t* rb_data_type, bool takeOwnership)
|
|
202
256
|
{
|
|
203
|
-
if (
|
|
257
|
+
if (!RTYPEDDATA_P(value))
|
|
204
258
|
{
|
|
205
259
|
std::string message = "The Ruby object does not wrap a C++ object. It is actually a " +
|
|
206
260
|
std::string(detail::protect(rb_obj_classname, value)) + ".";
|
|
207
261
|
throw std::runtime_error(message);
|
|
208
262
|
}
|
|
209
263
|
|
|
210
|
-
WrapperBase* wrapper =
|
|
264
|
+
WrapperBase* wrapper = static_cast<WrapperBase*>(RTYPEDDATA_DATA(value));
|
|
211
265
|
|
|
212
266
|
if (wrapper == nullptr)
|
|
213
267
|
{
|
|
214
|
-
std::string message = "Wrapped C++ object is nil. Did you override " +
|
|
215
|
-
std::string(detail::protect(rb_obj_classname, value)) +
|
|
268
|
+
std::string message = "Wrapped C++ object is nil. Did you override " +
|
|
269
|
+
std::string(detail::protect(rb_obj_classname, value)) +
|
|
216
270
|
"#initialize and forget to call super?";
|
|
217
271
|
|
|
218
272
|
throw std::runtime_error(message);
|
|
219
273
|
}
|
|
220
274
|
|
|
221
275
|
if (takeOwnership)
|
|
276
|
+
{
|
|
222
277
|
wrapper->setOwner(false);
|
|
278
|
+
}
|
|
223
279
|
|
|
224
|
-
return static_cast<T*>(wrapper->get());
|
|
280
|
+
return static_cast<T*>(wrapper->get(rb_data_type));
|
|
225
281
|
}
|
|
226
282
|
|
|
227
283
|
template <typename Wrapper_T>
|
|
@@ -243,7 +299,8 @@ namespace Rice::detail
|
|
|
243
299
|
if (!RTYPEDDATA_P(value))
|
|
244
300
|
{
|
|
245
301
|
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
|
|
246
|
-
|
|
302
|
+
detail::protect(rb_obj_classname, value),
|
|
303
|
+
"wrapped C++ object");
|
|
247
304
|
}
|
|
248
305
|
|
|
249
306
|
return static_cast<WrapperBase*>(RTYPEDDATA_DATA(value));
|
|
@@ -254,21 +311,23 @@ namespace Rice::detail
|
|
|
254
311
|
}
|
|
255
312
|
|
|
256
313
|
template <typename T>
|
|
257
|
-
inline
|
|
314
|
+
inline Wrapper<T*>* wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data)
|
|
258
315
|
{
|
|
259
316
|
using Wrapper_T = Wrapper<T*>;
|
|
260
|
-
|
|
317
|
+
|
|
261
318
|
Wrapper_T* wrapper = nullptr;
|
|
262
319
|
TypedData_Get_Struct(value, Wrapper_T, rb_data_type, wrapper);
|
|
263
320
|
if (wrapper)
|
|
264
321
|
{
|
|
265
|
-
Registries::instance.instances.remove(wrapper->get());
|
|
322
|
+
Registries::instance.instances.remove(wrapper->get(rb_data_type));
|
|
266
323
|
delete wrapper;
|
|
267
324
|
}
|
|
268
325
|
|
|
269
|
-
wrapper = new Wrapper_T(data, true);
|
|
326
|
+
wrapper = new Wrapper_T(rb_data_type, data, true);
|
|
270
327
|
RTYPEDDATA_DATA(value) = wrapper;
|
|
271
328
|
|
|
272
329
|
Registries::instance.instances.add(data, value);
|
|
330
|
+
|
|
331
|
+
return wrapper;
|
|
273
332
|
}
|
|
274
|
-
}
|
|
333
|
+
}
|
data/rice/rice.hpp
CHANGED
|
@@ -156,6 +156,9 @@
|
|
|
156
156
|
// Dependent on Module, Class, Array and String
|
|
157
157
|
#include "forward_declares.ipp"
|
|
158
158
|
|
|
159
|
+
// Dependent on Module, Array, Symbol - used by stl smart pointers
|
|
160
|
+
#include "detail/Forwards.hpp"
|
|
161
|
+
|
|
159
162
|
// For now include libc support - maybe should be separate header file someday
|
|
160
163
|
#include "libc/file.hpp"
|
|
161
164
|
|
|
@@ -17,5 +17,18 @@ inline void Init_Native_Registry()
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
return result;
|
|
20
|
-
}, Arg("klass").setValue())
|
|
20
|
+
}, Arg("klass").setValue()).
|
|
21
|
+
|
|
22
|
+
define_method("lookup_by_kind", [](detail::NativeRegistry& self, VALUE klass, detail::NativeKind kind) -> Array
|
|
23
|
+
{
|
|
24
|
+
Array result;
|
|
25
|
+
|
|
26
|
+
const std::vector<detail::Native*> natives = self.lookup(klass, kind);
|
|
27
|
+
for (detail::Native* native : natives)
|
|
28
|
+
{
|
|
29
|
+
result.push(native, false);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return result;
|
|
33
|
+
}, Arg("klass").setValue(), Arg("kind"));
|
|
21
34
|
}
|
data/rice/stl/exception.ipp
CHANGED
|
@@ -13,7 +13,7 @@ namespace Rice::stl
|
|
|
13
13
|
define_method("message", &std::exception::what);
|
|
14
14
|
|
|
15
15
|
define_class_under<std::runtime_error>(rb_mStd, "RuntimeError", rb_eRuntimeError).
|
|
16
|
-
define_constructor(Constructor<std::runtime_error, const char*>()).
|
|
16
|
+
define_constructor(Constructor<std::runtime_error, const char*>(), Arg("what")).
|
|
17
17
|
define_method("message", &std::runtime_error::what);
|
|
18
18
|
}
|
|
19
19
|
}
|
data/rice/stl/filesystem.ipp
CHANGED
|
@@ -11,7 +11,7 @@ namespace Rice
|
|
|
11
11
|
|
|
12
12
|
define_class_under<std::filesystem::path>(rb_mFileSystem, "Path").
|
|
13
13
|
define_constructor(Constructor<std::filesystem::path>()).
|
|
14
|
-
define_constructor(Constructor<std::filesystem::path, std::string>());
|
|
14
|
+
define_constructor(Constructor<std::filesystem::path, std::string>(), Arg("source"));
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
}
|
data/rice/stl/map.ipp
CHANGED
|
@@ -14,6 +14,8 @@ namespace Rice
|
|
|
14
14
|
using Size_T = typename T::size_type;
|
|
15
15
|
using Difference_T = typename T::difference_type;
|
|
16
16
|
using To_Ruby_T = typename detail::remove_cv_recursive_t<Mapped_T>;
|
|
17
|
+
// For pointer types, use the pointer directly; for non-pointer types, use a reference
|
|
18
|
+
using Mapped_Parameter_T = std::conditional_t<std::is_pointer_v<Mapped_T>, Mapped_T, Mapped_T&>;
|
|
17
19
|
|
|
18
20
|
public:
|
|
19
21
|
MapHelper(Data_Type<T> klass) : klass_(klass)
|
|
@@ -42,7 +44,7 @@ namespace Rice
|
|
|
42
44
|
|
|
43
45
|
if constexpr (std::is_copy_constructible_v<Key_T> && std::is_copy_constructible_v<Value_T>)
|
|
44
46
|
{
|
|
45
|
-
klass_.define_constructor(Constructor<T, const T&>());
|
|
47
|
+
klass_.define_constructor(Constructor<T, const T&>(), Arg("other"));
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
|
|
@@ -71,11 +73,11 @@ namespace Rice
|
|
|
71
73
|
{
|
|
72
74
|
return std::nullopt;
|
|
73
75
|
}
|
|
74
|
-
})
|
|
76
|
+
}, Arg("key"))
|
|
75
77
|
.define_method("include?", [](T& map, Key_T& key) -> bool
|
|
76
78
|
{
|
|
77
79
|
return map.find(key) != map.end();
|
|
78
|
-
})
|
|
80
|
+
}, Arg("key"))
|
|
79
81
|
.define_method("keys", [](T& map) -> std::vector<Key_T>
|
|
80
82
|
{
|
|
81
83
|
std::vector<Key_T> result;
|
|
@@ -110,8 +112,8 @@ namespace Rice
|
|
|
110
112
|
klass_.define_method("==", [](T& map, T& other)->bool
|
|
111
113
|
{
|
|
112
114
|
return map == other;
|
|
113
|
-
})
|
|
114
|
-
.define_method("value?", [](T& map,
|
|
115
|
+
}, Arg("other"))
|
|
116
|
+
.define_method("value?", [](T& map, Mapped_Parameter_T value) -> bool
|
|
115
117
|
{
|
|
116
118
|
auto it = std::find_if(map.begin(), map.end(),
|
|
117
119
|
[&value](auto& pair)
|
|
@@ -120,15 +122,15 @@ namespace Rice
|
|
|
120
122
|
});
|
|
121
123
|
|
|
122
124
|
return it != map.end();
|
|
123
|
-
});
|
|
125
|
+
}, Arg("value"));
|
|
124
126
|
rb_define_alias(klass_, "eql?", "==");
|
|
125
127
|
}
|
|
126
128
|
else
|
|
127
129
|
{
|
|
128
|
-
klass_.define_method("value?", [](T&,
|
|
130
|
+
klass_.define_method("value?", [](T&, Mapped_Parameter_T) -> bool
|
|
129
131
|
{
|
|
130
132
|
return false;
|
|
131
|
-
});
|
|
133
|
+
}, Arg("value"));
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
rb_define_alias(klass_, "has_value", "value?");
|
|
@@ -151,12 +153,12 @@ namespace Rice
|
|
|
151
153
|
{
|
|
152
154
|
return std::nullopt;
|
|
153
155
|
}
|
|
154
|
-
})
|
|
155
|
-
.define_method("[]=", [](T& map, Key_T key,
|
|
156
|
+
}, Arg("key"))
|
|
157
|
+
.define_method("[]=", [](T& map, Key_T key, Mapped_Parameter_T value) -> Mapped_T
|
|
156
158
|
{
|
|
157
159
|
map[key] = value;
|
|
158
160
|
return value;
|
|
159
|
-
});
|
|
161
|
+
}, Arg("key").keepAlive(), Arg("value").keepAlive());
|
|
160
162
|
|
|
161
163
|
rb_define_alias(klass_, "store", "[]=");
|
|
162
164
|
}
|
data/rice/stl/multimap.ipp
CHANGED
|
@@ -14,6 +14,8 @@ namespace Rice
|
|
|
14
14
|
using Size_T = typename T::size_type;
|
|
15
15
|
using Difference_T = typename T::difference_type;
|
|
16
16
|
using To_Ruby_T = typename detail::remove_cv_recursive_t<Mapped_T>;
|
|
17
|
+
// For pointer types, use the pointer directly; for non-pointer types, use a reference
|
|
18
|
+
using Mapped_Parameter_T = std::conditional_t<std::is_pointer_v<Mapped_T>, Mapped_T, Mapped_T&>;
|
|
17
19
|
|
|
18
20
|
public:
|
|
19
21
|
MultimapHelper(Data_Type<T> klass) : klass_(klass)
|
|
@@ -41,7 +43,7 @@ namespace Rice
|
|
|
41
43
|
|
|
42
44
|
if constexpr (std::is_copy_constructible_v<Key_T> && std::is_copy_constructible_v<Value_T>)
|
|
43
45
|
{
|
|
44
|
-
klass_.define_constructor(Constructor<T, const T&>());
|
|
46
|
+
klass_.define_constructor(Constructor<T, const T&>(), Arg("other"));
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
49
|
|
|
@@ -70,11 +72,11 @@ namespace Rice
|
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
return result;
|
|
73
|
-
})
|
|
75
|
+
}, Arg("key"))
|
|
74
76
|
.define_method("include?", [](T& multimap, Key_T& key) -> bool
|
|
75
77
|
{
|
|
76
78
|
return multimap.find(key) != multimap.end();
|
|
77
|
-
})
|
|
79
|
+
}, Arg("key"))
|
|
78
80
|
.define_method("keys", [](T& multimap) -> std::vector<Key_T>
|
|
79
81
|
{
|
|
80
82
|
std::vector<Key_T> result;
|
|
@@ -109,8 +111,8 @@ namespace Rice
|
|
|
109
111
|
klass_.define_method("==", [](T& multimap, T& other)->bool
|
|
110
112
|
{
|
|
111
113
|
return multimap == other;
|
|
112
|
-
})
|
|
113
|
-
.define_method("value?", [](T& multimap,
|
|
114
|
+
}, Arg("other"))
|
|
115
|
+
.define_method("value?", [](T& multimap, Mapped_Parameter_T value) -> bool
|
|
114
116
|
{
|
|
115
117
|
auto it = std::find_if(multimap.begin(), multimap.end(),
|
|
116
118
|
[&value](auto& pair)
|
|
@@ -119,15 +121,15 @@ namespace Rice
|
|
|
119
121
|
});
|
|
120
122
|
|
|
121
123
|
return it != multimap.end();
|
|
122
|
-
});
|
|
124
|
+
}, Arg("value"));
|
|
123
125
|
rb_define_alias(klass_, "eql?", "==");
|
|
124
126
|
}
|
|
125
127
|
else
|
|
126
128
|
{
|
|
127
|
-
klass_.define_method("value?", [](T&,
|
|
129
|
+
klass_.define_method("value?", [](T&, Mapped_Parameter_T) -> bool
|
|
128
130
|
{
|
|
129
131
|
return false;
|
|
130
|
-
});
|
|
132
|
+
}, Arg("value"));
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
rb_define_alias(klass_, "has_value", "value?");
|
|
@@ -150,13 +152,13 @@ namespace Rice
|
|
|
150
152
|
{
|
|
151
153
|
return std::nullopt;
|
|
152
154
|
}
|
|
153
|
-
})
|
|
154
|
-
.define_method("insert", [](T& map, Key_T key,
|
|
155
|
+
}, Arg("key"))
|
|
156
|
+
.define_method("insert", [](T& map, Key_T key, Mapped_Parameter_T value) -> Mapped_T
|
|
155
157
|
{
|
|
156
158
|
Value_T element{ key, value };
|
|
157
159
|
map.insert(element);
|
|
158
160
|
return value;
|
|
159
|
-
});
|
|
161
|
+
}, Arg("key").keepAlive(), Arg("value").keepAlive());
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
void define_enumerable()
|
data/rice/stl/pair.ipp
CHANGED
|
@@ -7,6 +7,12 @@ namespace Rice
|
|
|
7
7
|
template<typename T>
|
|
8
8
|
class PairHelper
|
|
9
9
|
{
|
|
10
|
+
using First_T = typename T::first_type;
|
|
11
|
+
using Second_T = typename T::second_type;
|
|
12
|
+
// For pointer types, use the pointer directly; for non-pointer types, use a reference
|
|
13
|
+
using First_Parameter_T = std::conditional_t<std::is_pointer_v<First_T>, First_T, First_T&>;
|
|
14
|
+
using Second_Parameter_T = std::conditional_t<std::is_pointer_v<Second_T>, Second_T, Second_T&>;
|
|
15
|
+
|
|
10
16
|
public:
|
|
11
17
|
PairHelper(Data_Type<T> klass) : klass_(klass)
|
|
12
18
|
{
|
|
@@ -19,33 +25,33 @@ namespace Rice
|
|
|
19
25
|
void define_constructors()
|
|
20
26
|
{
|
|
21
27
|
klass_.define_constructor(Constructor<T>())
|
|
22
|
-
.define_constructor(Constructor<T,
|
|
23
|
-
|
|
24
|
-
if constexpr (std::is_copy_constructible_v<
|
|
28
|
+
.define_constructor(Constructor<T, First_Parameter_T, Second_Parameter_T>(), Arg("x").keepAlive(), Arg("y").keepAlive());
|
|
29
|
+
|
|
30
|
+
if constexpr (std::is_copy_constructible_v<First_T> && std::is_copy_constructible_v<Second_T>)
|
|
25
31
|
{
|
|
26
|
-
klass_.define_constructor(Constructor<T, const T&>());
|
|
32
|
+
klass_.define_constructor(Constructor<T, const T&>(), Arg("other"));
|
|
27
33
|
}
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
void define_attributes()
|
|
31
37
|
{
|
|
32
38
|
// Access methods
|
|
33
|
-
if constexpr (std::is_const_v<std::remove_reference_t<std::remove_pointer_t<
|
|
39
|
+
if constexpr (std::is_const_v<std::remove_reference_t<std::remove_pointer_t<First_T>>>)
|
|
34
40
|
{
|
|
35
41
|
klass_.define_attr("first", &T::first, Rice::AttrAccess::Read);
|
|
36
42
|
}
|
|
37
43
|
else
|
|
38
44
|
{
|
|
39
|
-
klass_.define_attr("first", &T::first, Rice::AttrAccess::ReadWrite);
|
|
45
|
+
klass_.define_attr("first", &T::first, Rice::AttrAccess::ReadWrite, Arg("value").keepAlive());
|
|
40
46
|
}
|
|
41
47
|
|
|
42
|
-
if constexpr (std::is_const_v<std::remove_reference_t<std::remove_pointer_t<
|
|
48
|
+
if constexpr (std::is_const_v<std::remove_reference_t<std::remove_pointer_t<Second_T>>>)
|
|
43
49
|
{
|
|
44
50
|
klass_.define_attr("second", &T::second, Rice::AttrAccess::Read);
|
|
45
51
|
}
|
|
46
52
|
else
|
|
47
53
|
{
|
|
48
|
-
klass_.define_attr("second", &T::second, Rice::AttrAccess::ReadWrite);
|
|
54
|
+
klass_.define_attr("second", &T::second, Rice::AttrAccess::ReadWrite, Arg("value").keepAlive());
|
|
49
55
|
}
|
|
50
56
|
}
|
|
51
57
|
|
data/rice/stl/set.ipp
CHANGED
|
@@ -38,7 +38,7 @@ namespace Rice
|
|
|
38
38
|
void define_constructors()
|
|
39
39
|
{
|
|
40
40
|
klass_.define_constructor(Constructor<T>())
|
|
41
|
-
.define_constructor(Constructor<T, const T&>());
|
|
41
|
+
.define_constructor(Constructor<T, const T&>(), Arg("other"));
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
void define_capacity_methods()
|
|
@@ -58,11 +58,11 @@ namespace Rice
|
|
|
58
58
|
{
|
|
59
59
|
auto iter = self.find(element);
|
|
60
60
|
return iter != self.end();
|
|
61
|
-
})
|
|
61
|
+
}, Arg("key"))
|
|
62
62
|
.define_method("count", [](T& self, const Key_T element) -> Size_T
|
|
63
63
|
{
|
|
64
64
|
return self.count(element);
|
|
65
|
-
});
|
|
65
|
+
}, Arg("key"));
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
void define_modify_methods()
|
|
@@ -73,17 +73,17 @@ namespace Rice
|
|
|
73
73
|
{
|
|
74
74
|
self.erase(key);
|
|
75
75
|
return self;
|
|
76
|
-
})
|
|
77
|
-
.define_method("insert", [](T& self,
|
|
76
|
+
}, Arg("key"))
|
|
77
|
+
.define_method("insert", [](T& self, Parameter_T value) -> T&
|
|
78
78
|
{
|
|
79
79
|
self.insert(value);
|
|
80
80
|
return self;
|
|
81
|
-
})
|
|
81
|
+
}, Arg("value").keepAlive())
|
|
82
82
|
.define_method("merge", [](T& self, T& other) -> T&
|
|
83
83
|
{
|
|
84
84
|
self.merge(other);
|
|
85
85
|
return self;
|
|
86
|
-
});
|
|
86
|
+
}, Arg("source"));
|
|
87
87
|
|
|
88
88
|
rb_define_alias(klass_, "erase", "delete");
|
|
89
89
|
}
|
|
@@ -91,11 +91,11 @@ namespace Rice
|
|
|
91
91
|
void define_operators()
|
|
92
92
|
{
|
|
93
93
|
klass_
|
|
94
|
-
.define_method("<<", [](T& self,
|
|
94
|
+
.define_method("<<", [](T& self, Parameter_T value) -> T&
|
|
95
95
|
{
|
|
96
96
|
self.insert(value);
|
|
97
97
|
return self;
|
|
98
|
-
})
|
|
98
|
+
}, Arg("value").keepAlive())
|
|
99
99
|
.define_method("==", [](const T& self, const T& other) -> bool
|
|
100
100
|
{
|
|
101
101
|
if constexpr (detail::is_comparable_v<Value_T>)
|
|
@@ -106,7 +106,7 @@ namespace Rice
|
|
|
106
106
|
{
|
|
107
107
|
return false;
|
|
108
108
|
}
|
|
109
|
-
})
|
|
109
|
+
}, Arg("other"))
|
|
110
110
|
.define_method("&", [](const T& self, const T& other) -> T
|
|
111
111
|
{
|
|
112
112
|
T result;
|
|
@@ -115,7 +115,7 @@ namespace Rice
|
|
|
115
115
|
std::inserter(result, result.begin()));
|
|
116
116
|
|
|
117
117
|
return result;
|
|
118
|
-
})
|
|
118
|
+
}, Arg("other"))
|
|
119
119
|
.define_method("|", [](const T& self, const T& other) -> T
|
|
120
120
|
{
|
|
121
121
|
T result;
|
|
@@ -124,7 +124,7 @@ namespace Rice
|
|
|
124
124
|
std::inserter(result, result.begin()));
|
|
125
125
|
|
|
126
126
|
return result;
|
|
127
|
-
})
|
|
127
|
+
}, Arg("other"))
|
|
128
128
|
.define_method("-", [](const T& self, const T& other) -> T
|
|
129
129
|
{
|
|
130
130
|
T result;
|
|
@@ -133,7 +133,7 @@ namespace Rice
|
|
|
133
133
|
std::inserter(result, result.begin()));
|
|
134
134
|
|
|
135
135
|
return result;
|
|
136
|
-
})
|
|
136
|
+
}, Arg("other"))
|
|
137
137
|
.define_method("^", [](const T& self, const T& other) -> T
|
|
138
138
|
{
|
|
139
139
|
T result;
|
|
@@ -142,17 +142,17 @@ namespace Rice
|
|
|
142
142
|
std::inserter(result, result.begin()));
|
|
143
143
|
|
|
144
144
|
return result;
|
|
145
|
-
})
|
|
145
|
+
}, Arg("other"))
|
|
146
146
|
.define_method("<", [](const T& self, const T& other) -> bool
|
|
147
147
|
{
|
|
148
148
|
return std::includes(other.begin(), other.end(),
|
|
149
149
|
self.begin(), self.end());
|
|
150
|
-
})
|
|
150
|
+
}, Arg("other"))
|
|
151
151
|
.define_method(">", [](const T& self, const T& other) -> bool
|
|
152
152
|
{
|
|
153
153
|
return std::includes(self.begin(), self.end(),
|
|
154
154
|
other.begin(), other.end());
|
|
155
|
-
});
|
|
155
|
+
}, Arg("other"));
|
|
156
156
|
|
|
157
157
|
rb_define_alias(klass_, "eql?", "==");
|
|
158
158
|
rb_define_alias(klass_, "intersection", "&");
|