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/lib/mkmf-rice.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
|
3
3
|
IS_MSWIN = !RbConfig::CONFIG['host_os'].match(/mswin/).nil?
|
4
|
+
IS_MINGW = !RbConfig::CONFIG['host_os'].match(/mingw/).nil?
|
4
5
|
IS_DARWIN = !RbConfig::CONFIG['host_os'].match(/darwin/).nil?
|
5
6
|
|
6
7
|
# If we are on versions of Ruby before 2.7 then we need to copy in the experimental C++ support
|
@@ -106,8 +107,10 @@ include MakeMakefile['C++']
|
|
106
107
|
|
107
108
|
# Rice needs c++17.
|
108
109
|
if IS_MSWIN
|
109
|
-
$CXXFLAGS += " /std:c++17 /EHsc /permissive-"
|
110
|
-
$CPPFLAGS += " -D_ALLOW_KEYWORD_MACROS"
|
110
|
+
$CXXFLAGS += " /std:c++17 /EHsc /permissive- /bigobj"
|
111
|
+
$CPPFLAGS += " -D_ALLOW_KEYWORD_MACROS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE"
|
112
|
+
elsif IS_MINGW
|
113
|
+
$CXXFLAGS += " -std=c++17 -Wa,-mbig-obj"
|
111
114
|
else
|
112
115
|
$CXXFLAGS += " -std=c++17"
|
113
116
|
end
|
data/lib/version.rb
CHANGED
data/rice/Arg.hpp
CHANGED
@@ -57,18 +57,17 @@ namespace Rice
|
|
57
57
|
//! Tell the receiving object to keep this argument alive
|
58
58
|
//! until the receiving object is freed.
|
59
59
|
Arg& keepAlive();
|
60
|
+
|
61
|
+
//! Returns if the argument should be kept alive
|
62
|
+
bool isKeepAlive() const;
|
60
63
|
|
61
64
|
//! Specifies if the argument should be treated as a value
|
62
|
-
Arg&
|
65
|
+
Arg& setValue();
|
63
66
|
|
64
67
|
//! Returns if the argument should be treated as a value
|
65
|
-
bool
|
66
|
-
|
67
|
-
// No longer supported - implemented to raise error
|
68
|
-
Arg operator,(const Arg& other);
|
68
|
+
bool isValue() const;
|
69
69
|
|
70
70
|
public:
|
71
|
-
bool isKeepAlive = false;
|
72
71
|
const std::string name;
|
73
72
|
int32_t position = -1;
|
74
73
|
|
@@ -76,6 +75,7 @@ namespace Rice
|
|
76
75
|
//! Our saved default value
|
77
76
|
std::any defaultValue_;
|
78
77
|
bool isValue_ = false;
|
78
|
+
bool isKeepAlive_ = false;
|
79
79
|
};
|
80
80
|
} // Rice
|
81
81
|
|
data/rice/Arg.ipp
CHANGED
@@ -28,24 +28,23 @@ namespace Rice
|
|
28
28
|
|
29
29
|
inline Arg& Arg::keepAlive()
|
30
30
|
{
|
31
|
-
this->
|
31
|
+
this->isKeepAlive_ = true;
|
32
32
|
return *this;
|
33
33
|
}
|
34
34
|
|
35
|
-
inline
|
35
|
+
inline bool Arg::isKeepAlive() const
|
36
36
|
{
|
37
|
-
|
38
|
-
return *this;
|
37
|
+
return this->isKeepAlive_;
|
39
38
|
}
|
40
39
|
|
41
|
-
inline
|
40
|
+
inline Arg& Arg::setValue()
|
42
41
|
{
|
43
|
-
|
42
|
+
isValue_ = true;
|
43
|
+
return *this;
|
44
44
|
}
|
45
45
|
|
46
|
-
|
47
|
-
inline Arg Arg::operator,(const Arg& other)
|
46
|
+
inline bool Arg::isValue() const
|
48
47
|
{
|
49
|
-
|
48
|
+
return isValue_;
|
50
49
|
}
|
51
50
|
} // Rice
|
data/rice/Constructor.hpp
CHANGED
@@ -26,7 +26,7 @@ namespace Rice
|
|
26
26
|
static void construct(VALUE self, Arg_Ts...args)
|
27
27
|
{
|
28
28
|
T* data = new T(args...);
|
29
|
-
detail::replace<T>(self, Data_Type<T>::
|
29
|
+
detail::replace<T>(self, Data_Type<T>::ruby_data_type(), data, true);
|
30
30
|
}
|
31
31
|
};
|
32
32
|
|
@@ -38,7 +38,7 @@ namespace Rice
|
|
38
38
|
static void construct(Object self, Arg_Ts...args)
|
39
39
|
{
|
40
40
|
T* data = new T(self, args...);
|
41
|
-
detail::replace<T>(self.value(), Data_Type<T>::
|
41
|
+
detail::replace<T>(self.value(), Data_Type<T>::ruby_data_type(), data, true);
|
42
42
|
}
|
43
43
|
};
|
44
44
|
}
|
data/rice/Data_Object.ipp
CHANGED
@@ -18,27 +18,19 @@ namespace Rice
|
|
18
18
|
template<typename T>
|
19
19
|
inline Data_Object<T>::Data_Object(T& data, bool isOwner, Class klass)
|
20
20
|
{
|
21
|
-
VALUE value = detail::wrap(klass, Data_Type<T>::
|
21
|
+
VALUE value = detail::wrap(klass, Data_Type<T>::ruby_data_type(), data, isOwner);
|
22
22
|
this->set_value(value);
|
23
23
|
}
|
24
24
|
|
25
25
|
template<typename T>
|
26
26
|
inline Data_Object<T>::Data_Object(T* data, bool isOwner, Class klass)
|
27
27
|
{
|
28
|
-
VALUE value = detail::wrap(klass, Data_Type<T>::
|
28
|
+
VALUE value = detail::wrap(klass, Data_Type<T>::ruby_data_type(), data, isOwner);
|
29
29
|
this->set_value(value);
|
30
30
|
}
|
31
31
|
|
32
32
|
template<typename T>
|
33
33
|
inline Data_Object<T>::Data_Object(Object value) : Object(value)
|
34
|
-
{
|
35
|
-
Data_Type<T> klass;
|
36
|
-
check_ruby_type(value);
|
37
|
-
}
|
38
|
-
|
39
|
-
template<typename T>
|
40
|
-
template<typename U>
|
41
|
-
inline Data_Object<T>::Data_Object(Object value) : Object(value)
|
42
34
|
{
|
43
35
|
check_ruby_type(value);
|
44
36
|
}
|
@@ -73,7 +65,7 @@ namespace Rice
|
|
73
65
|
}
|
74
66
|
else
|
75
67
|
{
|
76
|
-
return detail::unwrap<T>(this->value(), Data_Type<T>::
|
68
|
+
return detail::unwrap<T>(this->value(), Data_Type<T>::ruby_data_type());
|
77
69
|
}
|
78
70
|
}
|
79
71
|
|
@@ -82,7 +74,7 @@ namespace Rice
|
|
82
74
|
{
|
83
75
|
if (Data_Type<T>::is_descendant(value))
|
84
76
|
{
|
85
|
-
return detail::unwrap<T>(value, Data_Type<T>::
|
77
|
+
return detail::unwrap<T>(value, Data_Type<T>::ruby_data_type());
|
86
78
|
}
|
87
79
|
else
|
88
80
|
{
|
@@ -100,7 +92,17 @@ namespace Rice::detail
|
|
100
92
|
VALUE convert(T& data)
|
101
93
|
{
|
102
94
|
// Get the ruby typeinfo
|
103
|
-
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::
|
95
|
+
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(data);
|
96
|
+
|
97
|
+
// We always take ownership of data passed by value (yes the parameter is T& but the template
|
98
|
+
// matched <typename T> thus we have to tell wrap to copy the reference we are sending to it
|
99
|
+
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
100
|
+
}
|
101
|
+
|
102
|
+
VALUE convert(const T& data)
|
103
|
+
{
|
104
|
+
// Get the ruby typeinfo
|
105
|
+
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(data);
|
104
106
|
|
105
107
|
// We always take ownership of data passed by value (yes the parameter is T& but the template
|
106
108
|
// matched <typename T> thus we have to tell wrap to copy the reference we are sending to it
|
@@ -122,7 +124,17 @@ namespace Rice::detail
|
|
122
124
|
{
|
123
125
|
// Note that T could be a pointer or reference to a base class while data is in fact a
|
124
126
|
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
125
|
-
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::
|
127
|
+
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(data);
|
128
|
+
|
129
|
+
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
130
|
+
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
131
|
+
}
|
132
|
+
|
133
|
+
VALUE convert(const T& data)
|
134
|
+
{
|
135
|
+
// Note that T could be a pointer or reference to a base class while data is in fact a
|
136
|
+
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
137
|
+
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(data);
|
126
138
|
|
127
139
|
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
128
140
|
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
@@ -142,13 +154,29 @@ namespace Rice::detail
|
|
142
154
|
{
|
143
155
|
}
|
144
156
|
|
157
|
+
VALUE convert(T* data)
|
158
|
+
{
|
159
|
+
if (data)
|
160
|
+
{
|
161
|
+
// Note that T could be a pointer or reference to a base class while data is in fact a
|
162
|
+
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
163
|
+
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(*data);
|
164
|
+
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
165
|
+
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
166
|
+
}
|
167
|
+
else
|
168
|
+
{
|
169
|
+
return Qnil;
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
145
173
|
VALUE convert(const T* data)
|
146
174
|
{
|
147
175
|
if (data)
|
148
176
|
{
|
149
177
|
// Note that T could be a pointer or reference to a base class while data is in fact a
|
150
178
|
// child class. Lookup the correct type so we return an instance of the correct Ruby class
|
151
|
-
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::
|
179
|
+
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType(*data);
|
152
180
|
bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
|
153
181
|
return detail::wrap(rubyTypeInfo.first, rubyTypeInfo.second, data, isOwner);
|
154
182
|
}
|
@@ -175,6 +203,8 @@ namespace Rice::detail
|
|
175
203
|
template <typename T>
|
176
204
|
class From_Ruby
|
177
205
|
{
|
206
|
+
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
207
|
+
"Data_Object cannot be used with fundamental types");
|
178
208
|
public:
|
179
209
|
From_Ruby() = default;
|
180
210
|
|
@@ -182,6 +212,12 @@ namespace Rice::detail
|
|
182
212
|
{
|
183
213
|
}
|
184
214
|
|
215
|
+
bool is_convertible(VALUE value)
|
216
|
+
{
|
217
|
+
return rb_type(value) == RUBY_T_DATA &&
|
218
|
+
Data_Type<T>::is_descendant(value);
|
219
|
+
}
|
220
|
+
|
185
221
|
T convert(VALUE value)
|
186
222
|
{
|
187
223
|
using Intrinsic_T = intrinsic_type<T>;
|
@@ -203,6 +239,8 @@ namespace Rice::detail
|
|
203
239
|
template<typename T>
|
204
240
|
class From_Ruby<T&>
|
205
241
|
{
|
242
|
+
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
243
|
+
"Data_Object cannot be used with fundamental types");
|
206
244
|
public:
|
207
245
|
From_Ruby() = default;
|
208
246
|
|
@@ -210,6 +248,12 @@ namespace Rice::detail
|
|
210
248
|
{
|
211
249
|
}
|
212
250
|
|
251
|
+
bool is_convertible(VALUE value)
|
252
|
+
{
|
253
|
+
return rb_type(value) == RUBY_T_DATA &&
|
254
|
+
Data_Type<T>::is_descendant(value);
|
255
|
+
}
|
256
|
+
|
213
257
|
T& convert(VALUE value)
|
214
258
|
{
|
215
259
|
using Intrinsic_T = intrinsic_type<T>;
|
@@ -231,7 +275,15 @@ namespace Rice::detail
|
|
231
275
|
template<typename T>
|
232
276
|
class From_Ruby<T*>
|
233
277
|
{
|
278
|
+
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
279
|
+
"Data_Object cannot be used with fundamental types");
|
234
280
|
public:
|
281
|
+
bool is_convertible(VALUE value)
|
282
|
+
{
|
283
|
+
return rb_type(value) == RUBY_T_DATA &&
|
284
|
+
Data_Type<T>::is_descendant(value);
|
285
|
+
}
|
286
|
+
|
235
287
|
T* convert(VALUE value)
|
236
288
|
{
|
237
289
|
using Intrinsic_T = intrinsic_type<T>;
|
@@ -250,6 +302,8 @@ namespace Rice::detail
|
|
250
302
|
template<typename T>
|
251
303
|
class From_Ruby<Data_Object<T>>
|
252
304
|
{
|
305
|
+
static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
|
306
|
+
"Data_Object cannot be used with fundamental types");
|
253
307
|
public:
|
254
308
|
static Data_Object<T> convert(VALUE value)
|
255
309
|
{
|
data/rice/Data_Object_defn.hpp
CHANGED
@@ -48,7 +48,6 @@ namespace Rice
|
|
48
48
|
|
49
49
|
public:
|
50
50
|
static T* from_ruby(VALUE value);
|
51
|
-
static std::optional<T> implicit_from_ruby(VALUE value);
|
52
51
|
|
53
52
|
public:
|
54
53
|
//! Wrap a C++ object.
|
@@ -58,12 +57,9 @@ namespace Rice
|
|
58
57
|
* constructed objects that need to be managed by Ruby's garbage
|
59
58
|
* collector).
|
60
59
|
* \param obj the object to wrap.
|
60
|
+
* \param isOwner Should the Data_Object take ownership of the object?
|
61
61
|
* \param klass the Ruby class to use for the newly created Ruby
|
62
62
|
* object.
|
63
|
-
* \param mark_func a function that gets called by the garbage
|
64
|
-
* collector to mark the object's children.
|
65
|
-
* \param free_func a function that gets called by the garbage
|
66
|
-
* collector to free the object.
|
67
63
|
*/
|
68
64
|
Data_Object(T* obj, bool isOwner = false, Class klass = Data_Type<T>::klass());
|
69
65
|
Data_Object(T& obj, bool isOwner = false, Class klass = Data_Type<T>::klass());
|
@@ -75,16 +71,6 @@ namespace Rice
|
|
75
71
|
*/
|
76
72
|
Data_Object(Object value);
|
77
73
|
|
78
|
-
//! Unwrap a Ruby object.
|
79
|
-
/*! This constructor is analogous to calling Data_Get_Struct. Will
|
80
|
-
* throw an exception if the class of the object differs from the
|
81
|
-
* specified class.
|
82
|
-
* \param value the Ruby object to unwrap.
|
83
|
-
* \param klass the expected class of the object.
|
84
|
-
*/
|
85
|
-
template<typename U>
|
86
|
-
Data_Object(Object value);
|
87
|
-
|
88
74
|
T& operator*() const; //!< Return a reference to obj_
|
89
75
|
T* operator->() const; //!< Return a pointer to obj_
|
90
76
|
T* get() const; //!< Return a pointer to obj_
|
data/rice/Data_Type.ipp
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
#ifndef Rice__Data_Type__ipp_
|
2
2
|
#define Rice__Data_Type__ipp_
|
3
3
|
|
4
|
-
#include "
|
4
|
+
#include "traits/attribute_traits.hpp"
|
5
|
+
#include "traits/method_traits.hpp"
|
6
|
+
#include "detail/NativeRegistry.hpp"
|
5
7
|
#include "detail/NativeAttribute.hpp"
|
6
8
|
#include "detail/default_allocation_func.hpp"
|
7
9
|
#include "detail/TypeRegistry.hpp"
|
8
10
|
#include "detail/Wrapper.hpp"
|
9
|
-
#include "detail/
|
10
|
-
#include "Class.hpp"
|
11
|
-
#include "String.hpp"
|
11
|
+
#include "detail/NativeIterator.hpp"
|
12
|
+
#include "cpp_api/Class.hpp"
|
13
|
+
#include "cpp_api/String.hpp"
|
12
14
|
|
13
15
|
#include <stdexcept>
|
14
16
|
|
@@ -39,7 +41,7 @@ namespace Rice
|
|
39
41
|
|
40
42
|
template<typename T>
|
41
43
|
template <typename Base_T>
|
42
|
-
inline Data_Type<T> Data_Type<T>::bind(Module
|
44
|
+
inline Data_Type<T> Data_Type<T>::bind(const Module& klass)
|
43
45
|
{
|
44
46
|
if (is_bound())
|
45
47
|
{
|
@@ -49,21 +51,21 @@ namespace Rice
|
|
49
51
|
|
50
52
|
klass_ = klass;
|
51
53
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
rb_data_type_ = new rb_data_type_t();
|
55
|
+
rb_data_type_->wrap_struct_name = strdup(Rice::detail::protect(rb_class2name, klass_));
|
56
|
+
rb_data_type_->function.dmark = reinterpret_cast<void(*)(void*)>(&Rice::ruby_mark_internal<T>);
|
57
|
+
rb_data_type_->function.dfree = reinterpret_cast<void(*)(void*)>(&Rice::ruby_free_internal<T>);
|
58
|
+
rb_data_type_->function.dsize = reinterpret_cast<size_t(*)(const void*)>(&Rice::ruby_size_internal<T>);
|
59
|
+
rb_data_type_->data = nullptr;
|
60
|
+
rb_data_type_->flags = RUBY_TYPED_FREE_IMMEDIATELY;
|
59
61
|
|
60
62
|
if constexpr (!std::is_void_v<Base_T>)
|
61
63
|
{
|
62
|
-
|
64
|
+
rb_data_type_->parent = Data_Type<Base_T>::ruby_data_type();
|
63
65
|
}
|
64
66
|
|
65
67
|
// Now register with the type registry
|
66
|
-
detail::
|
68
|
+
detail::Registries::instance.types.add<T>(klass_, rb_data_type_);
|
67
69
|
|
68
70
|
for (typename Instances::iterator it = unbound_instances().begin(),
|
69
71
|
end = unbound_instances().end();
|
@@ -79,7 +81,7 @@ namespace Rice
|
|
79
81
|
template<typename T>
|
80
82
|
inline void Data_Type<T>::unbind()
|
81
83
|
{
|
82
|
-
detail::
|
84
|
+
detail::Registries::instance.types.remove<T>();
|
83
85
|
|
84
86
|
if (klass_ != Qnil)
|
85
87
|
{
|
@@ -88,7 +90,7 @@ namespace Rice
|
|
88
90
|
|
89
91
|
// There could be objects floating around using the existing rb_type so
|
90
92
|
// do not delete it. This is of course a memory leak.
|
91
|
-
|
93
|
+
rb_data_type_ = nullptr;
|
92
94
|
}
|
93
95
|
|
94
96
|
template<typename T>
|
@@ -113,10 +115,10 @@ namespace Rice
|
|
113
115
|
}
|
114
116
|
|
115
117
|
template<typename T>
|
116
|
-
inline rb_data_type_t* Data_Type<T>::
|
118
|
+
inline rb_data_type_t* Data_Type<T>::ruby_data_type()
|
117
119
|
{
|
118
120
|
check_is_bound();
|
119
|
-
return
|
121
|
+
return rb_data_type_;
|
120
122
|
}
|
121
123
|
|
122
124
|
template<typename T>
|
@@ -133,19 +135,6 @@ namespace Rice
|
|
133
135
|
return *this;
|
134
136
|
}
|
135
137
|
|
136
|
-
template<typename T>
|
137
|
-
template<typename Constructor_T>
|
138
|
-
inline Data_Type<T>& Data_Type<T>::define_constructor(Constructor_T, MethodInfo* methodInfo)
|
139
|
-
{
|
140
|
-
check_is_bound();
|
141
|
-
|
142
|
-
// Normal constructor pattern with new/initialize
|
143
|
-
detail::protect(rb_define_alloc_func, static_cast<VALUE>(*this), detail::default_allocation_func<T>);
|
144
|
-
this->define_method("initialize", &Constructor_T::construct, methodInfo);
|
145
|
-
|
146
|
-
return *this;
|
147
|
-
}
|
148
|
-
|
149
138
|
template<typename T>
|
150
139
|
template<typename Constructor_T, typename...Arg_Ts>
|
151
140
|
inline Data_Type<T>& Data_Type<T>::define_constructor(Constructor_T constructor, Arg_Ts const& ...args)
|
@@ -165,14 +154,14 @@ namespace Rice
|
|
165
154
|
template<typename Director_T>
|
166
155
|
inline Data_Type<T>& Data_Type<T>::define_director()
|
167
156
|
{
|
168
|
-
if (!detail::
|
157
|
+
if (!detail::Registries::instance.types.isDefined<Director_T>())
|
169
158
|
{
|
170
159
|
Data_Type<Director_T>::bind(*this);
|
171
160
|
}
|
172
161
|
|
173
162
|
// TODO - hack to fake Ruby into thinking that a Director is
|
174
163
|
// the same as the base data type
|
175
|
-
Data_Type<Director_T>::
|
164
|
+
Data_Type<Director_T>::rb_data_type_ = Data_Type<T>::rb_data_type_;
|
176
165
|
return *this;
|
177
166
|
}
|
178
167
|
|
@@ -202,7 +191,7 @@ namespace Rice
|
|
202
191
|
template<typename T, typename Base_T>
|
203
192
|
inline Data_Type<T> define_class_under(Object module, char const* name)
|
204
193
|
{
|
205
|
-
if (detail::
|
194
|
+
if (detail::Registries::instance.types.isDefined<T>())
|
206
195
|
{
|
207
196
|
return Data_Type<T>();
|
208
197
|
}
|
@@ -226,7 +215,7 @@ namespace Rice
|
|
226
215
|
template<typename T, typename Base_T>
|
227
216
|
inline Data_Type<T> define_class(char const* name)
|
228
217
|
{
|
229
|
-
if (detail::
|
218
|
+
if (detail::Registries::instance.types.isDefined<T>())
|
230
219
|
{
|
231
220
|
return Data_Type<T>();
|
232
221
|
}
|
@@ -247,75 +236,56 @@ namespace Rice
|
|
247
236
|
}
|
248
237
|
|
249
238
|
template<typename T>
|
250
|
-
template<typename
|
251
|
-
inline Data_Type<T>& Data_Type<T>::define_iterator(
|
239
|
+
template<typename Iterator_Func_T>
|
240
|
+
inline Data_Type<T>& Data_Type<T>::define_iterator(Iterator_Func_T begin, Iterator_Func_T end, std::string name)
|
252
241
|
{
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
242
|
+
// Define a NativeIterator to bridge Ruby to C++
|
243
|
+
detail::NativeIterator<T, Iterator_Func_T>::define(Data_Type<T>::klass(), name, begin, end);
|
244
|
+
|
245
|
+
// Include enumerable support
|
246
|
+
this->klass().include_module(rb_mEnumerable);
|
257
247
|
|
258
248
|
return *this;
|
259
249
|
}
|
260
250
|
|
261
251
|
template <typename T>
|
262
|
-
template <typename
|
263
|
-
inline Data_Type<T>& Data_Type<T>::define_attr(std::string name,
|
252
|
+
template <typename Attribute_T>
|
253
|
+
inline Data_Type<T>& Data_Type<T>::define_attr(std::string name, Attribute_T attribute, AttrAccess access)
|
264
254
|
{
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
detail::verifyType<typename Native_T::Native_Return_T>();
|
269
|
-
|
270
|
-
if (access == AttrAccess::ReadWrite || access == AttrAccess::Read)
|
271
|
-
{
|
272
|
-
detail::MethodData::define_method( klass_, Identifier(name).id(),
|
273
|
-
RUBY_METHOD_FUNC(&Native_T::get), 0, native);
|
274
|
-
}
|
275
|
-
|
276
|
-
if (access == AttrAccess::ReadWrite || access == AttrAccess::Write)
|
277
|
-
{
|
278
|
-
if (std::is_const_v<std::remove_pointer_t<Attr_T>>)
|
279
|
-
{
|
280
|
-
throw std::runtime_error(name + " is readonly");
|
281
|
-
}
|
255
|
+
// Make sure the Attribute type has been previously seen by Rice
|
256
|
+
detail::verifyType<typename detail::attribute_traits<Attribute_T>::attr_type>();
|
282
257
|
|
283
|
-
|
284
|
-
|
285
|
-
}
|
258
|
+
// Define native attribute
|
259
|
+
detail::NativeAttribute<Attribute_T>::define(klass_, name, std::forward<Attribute_T>(attribute), access);
|
286
260
|
|
287
261
|
return *this;
|
288
262
|
}
|
289
263
|
|
290
264
|
template <typename T>
|
291
|
-
template <typename
|
292
|
-
inline Data_Type<T>& Data_Type<T>::define_singleton_attr(std::string name,
|
265
|
+
template <typename Attribute_T>
|
266
|
+
inline Data_Type<T>& Data_Type<T>::define_singleton_attr(std::string name, Attribute_T attribute, AttrAccess access)
|
293
267
|
{
|
294
|
-
|
295
|
-
|
268
|
+
// Make sure the Attribute type has been previously seen by Rice
|
269
|
+
detail::verifyType<typename detail::attribute_traits<Attribute_T>::attr_type>();
|
296
270
|
|
297
|
-
|
271
|
+
// Define native attribute
|
272
|
+
VALUE singleton = detail::protect(rb_singleton_class, this->value());
|
273
|
+
detail::NativeAttribute<Attribute_T>::define(singleton, name, std::forward<Attribute_T>(attribute), access);
|
298
274
|
|
299
|
-
|
300
|
-
|
301
|
-
VALUE singleton = detail::protect(rb_singleton_class, this->value());
|
302
|
-
detail::MethodData::define_method(singleton, Identifier(name).id(),
|
303
|
-
RUBY_METHOD_FUNC(&Native_T::get), 0, native);
|
304
|
-
}
|
275
|
+
return *this;
|
276
|
+
}
|
305
277
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
detail::MethodData::define_method(singleton, Identifier(name + "=").id(),
|
315
|
-
RUBY_METHOD_FUNC(&Native_T::set), 1, native);
|
316
|
-
}
|
278
|
+
template <typename T>
|
279
|
+
template<bool IsMethod, typename Function_T>
|
280
|
+
inline void Data_Type<T>::wrap_native_call(VALUE klass, std::string name, Function_T&& function, MethodInfo* methodInfo)
|
281
|
+
{
|
282
|
+
// Make sure the return type and arguments have been previously seen by Rice
|
283
|
+
using traits = detail::method_traits<Function_T, IsMethod>;
|
284
|
+
detail::verifyType<typename traits::Return_T>();
|
285
|
+
detail::verifyTypes<typename traits::Arg_Ts>();
|
317
286
|
|
318
|
-
|
287
|
+
// Define a NativeFunction to bridge Ruby to C++
|
288
|
+
detail::NativeFunction<T, Function_T, IsMethod>::define(klass, name, std::forward<Function_T>(function), methodInfo);
|
319
289
|
}
|
320
290
|
}
|
321
291
|
#endif
|
data/rice/Data_Type_defn.hpp
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#ifndef Rice__Data_Type_defn__hpp_
|
2
2
|
#define Rice__Data_Type_defn__hpp_
|
3
3
|
|
4
|
-
#include "Class_defn.hpp"
|
4
|
+
#include "cpp_api/Class_defn.hpp"
|
5
5
|
#include "detail/ruby.hpp"
|
6
6
|
#include <set>
|
7
7
|
|
@@ -38,8 +38,8 @@ namespace Rice
|
|
38
38
|
*/
|
39
39
|
static Class klass();
|
40
40
|
|
41
|
-
//! Return the Ruby type.
|
42
|
-
static rb_data_type_t*
|
41
|
+
//! Return the Ruby data type.
|
42
|
+
static rb_data_type_t* ruby_data_type();
|
43
43
|
|
44
44
|
//! Assignment operator which takes a Module
|
45
45
|
/*! \param klass must be the class to which this data type is already
|
@@ -48,11 +48,6 @@ namespace Rice
|
|
48
48
|
*/
|
49
49
|
virtual Data_Type & operator=(Module const & klass);
|
50
50
|
|
51
|
-
//! Define a constructor for the class.
|
52
|
-
template<typename Constructor_T>
|
53
|
-
[[deprecated("Please call define_constructor with Arg parameters")]]
|
54
|
-
Data_Type<T> & define_constructor(Constructor_T constructor, MethodInfo * methodInfo);
|
55
|
-
|
56
51
|
/*! Creates a singleton method allocate and an instance method called
|
57
52
|
* initialize which together create a new instance of the class. The
|
58
53
|
* allocate method allocates memory for the object reference and the
|
@@ -118,14 +113,14 @@ namespace Rice
|
|
118
113
|
* \return *this
|
119
114
|
*/
|
120
115
|
|
121
|
-
template<typename
|
122
|
-
Data_Type<T>& define_iterator(
|
116
|
+
template<typename Iterator_Func_T>
|
117
|
+
Data_Type<T>& define_iterator(Iterator_Func_T begin, Iterator_Func_T end, std::string name = "each");
|
123
118
|
|
124
|
-
template <typename
|
125
|
-
Data_Type<T>& define_attr(std::string name,
|
119
|
+
template <typename Attribute_T>
|
120
|
+
Data_Type<T>& define_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite);
|
126
121
|
|
127
|
-
template <typename
|
128
|
-
Data_Type<T>& define_singleton_attr(std::string name,
|
122
|
+
template <typename Attribute_T>
|
123
|
+
Data_Type<T>& define_singleton_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite);
|
129
124
|
|
130
125
|
#include "cpp_api/shared_methods.hpp"
|
131
126
|
|
@@ -138,7 +133,7 @@ namespace Rice
|
|
138
133
|
* \return *this
|
139
134
|
*/
|
140
135
|
template <typename Base_T = void>
|
141
|
-
static Data_Type bind(
|
136
|
+
static Data_Type bind(const Module& klass);
|
142
137
|
|
143
138
|
template<typename T_, typename Base_T_>
|
144
139
|
friend Rice::Data_Type<T_> define_class_under(Object module, char const * name);
|
@@ -146,6 +141,9 @@ namespace Rice
|
|
146
141
|
template<typename T_, typename Base_T_>
|
147
142
|
friend Rice::Data_Type<T_> define_class(char const * name);
|
148
143
|
|
144
|
+
template<bool IsMethod, typename Function_T>
|
145
|
+
void wrap_native_call(VALUE klass, std::string name, Function_T&& function, MethodInfo* methodInfo);
|
146
|
+
|
149
147
|
private:
|
150
148
|
template<typename T_>
|
151
149
|
friend class Data_Type;
|
@@ -153,7 +151,7 @@ namespace Rice
|
|
153
151
|
static inline VALUE klass_ = Qnil;
|
154
152
|
|
155
153
|
// Typed Data support
|
156
|
-
static inline rb_data_type_t*
|
154
|
+
static inline rb_data_type_t* rb_data_type_ = nullptr;
|
157
155
|
|
158
156
|
typedef std::set<Data_Type<T> *> Instances;
|
159
157
|
|
@@ -185,7 +183,6 @@ namespace Rice
|
|
185
183
|
*/
|
186
184
|
template<typename T, typename Base_T = void>
|
187
185
|
Data_Type<T> define_class(char const* name);
|
188
|
-
|
189
186
|
} // namespace Rice
|
190
187
|
|
191
188
|
#include "Data_Type.ipp"
|