rice 4.0.4 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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"
|