rice 2.1.1 → 4.0.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 +5 -5
- data/CHANGELOG.md +121 -0
- data/CONTRIBUTORS.md +19 -0
- data/COPYING +2 -2
- data/Gemfile +3 -0
- data/README.md +69 -0
- data/Rakefile +95 -12
- data/include/rice/rice.hpp +7766 -0
- data/lib/mkmf-rice.rb +127 -0
- data/lib/version.rb +3 -0
- data/rice/Address_Registration_Guard.ipp +75 -32
- data/rice/Address_Registration_Guard_defn.hpp +60 -56
- data/rice/Arg.hpp +80 -4
- data/rice/Arg.ipp +51 -0
- data/rice/Constructor.hpp +30 -376
- data/rice/Data_Object.ipp +234 -107
- data/rice/Data_Object_defn.hpp +77 -117
- data/rice/Data_Type.hpp +1 -2
- data/rice/Data_Type.ipp +251 -295
- data/rice/Data_Type_defn.hpp +175 -243
- data/rice/Director.hpp +14 -9
- data/rice/Enum.hpp +54 -104
- data/rice/Enum.ipp +104 -230
- data/rice/Exception.hpp +2 -8
- data/rice/Exception.ipp +65 -0
- data/rice/Exception_defn.hpp +46 -47
- data/rice/Identifier.hpp +28 -28
- data/rice/Identifier.ipp +23 -27
- data/rice/Return.hpp +39 -0
- data/rice/Return.ipp +33 -0
- data/rice/detail/Exception_Handler.ipp +22 -62
- data/rice/detail/Exception_Handler_defn.hpp +76 -91
- data/rice/detail/Iterator.hpp +18 -88
- data/rice/detail/Iterator.ipp +47 -0
- data/rice/detail/Jump_Tag.hpp +21 -0
- data/rice/detail/MethodInfo.hpp +44 -0
- data/rice/detail/MethodInfo.ipp +78 -0
- data/rice/detail/NativeAttribute.hpp +53 -0
- data/rice/detail/NativeAttribute.ipp +83 -0
- data/rice/detail/NativeFunction.hpp +69 -0
- data/rice/detail/NativeFunction.ipp +248 -0
- data/rice/detail/RubyFunction.hpp +39 -0
- data/rice/detail/RubyFunction.ipp +92 -0
- data/rice/detail/Type.hpp +29 -0
- data/rice/detail/Type.ipp +138 -0
- data/rice/detail/TypeRegistry.hpp +50 -0
- data/rice/detail/TypeRegistry.ipp +106 -0
- data/rice/detail/Wrapper.hpp +51 -0
- data/rice/detail/Wrapper.ipp +151 -0
- data/rice/detail/default_allocation_func.hpp +8 -19
- data/rice/detail/default_allocation_func.ipp +9 -8
- data/rice/detail/from_ruby.hpp +2 -37
- data/rice/detail/from_ruby.ipp +1020 -46
- data/rice/detail/from_ruby_defn.hpp +38 -0
- data/rice/detail/function_traits.hpp +124 -0
- data/rice/detail/method_data.hpp +23 -15
- data/rice/detail/method_data.ipp +53 -0
- data/rice/detail/rice_traits.hpp +116 -0
- data/rice/detail/ruby.hpp +9 -49
- data/rice/detail/to_ruby.hpp +3 -17
- data/rice/detail/to_ruby.ipp +409 -31
- data/rice/detail/to_ruby_defn.hpp +48 -0
- data/rice/forward_declares.ipp +82 -0
- data/rice/global_function.hpp +16 -20
- data/rice/global_function.ipp +8 -17
- data/rice/rice.hpp +59 -0
- data/rice/ruby_mark.hpp +5 -3
- data/rice/ruby_try_catch.hpp +4 -4
- data/rice/stl.hpp +11 -0
- data/sample/callbacks/extconf.rb +6 -0
- data/sample/callbacks/sample_callbacks.cpp +35 -0
- data/sample/callbacks/test.rb +28 -0
- data/sample/enum/extconf.rb +3 -0
- data/sample/enum/sample_enum.cpp +3 -17
- data/sample/enum/test.rb +2 -2
- data/sample/inheritance/animals.cpp +8 -24
- data/sample/inheritance/extconf.rb +3 -0
- data/sample/inheritance/test.rb +1 -1
- data/sample/map/extconf.rb +3 -0
- data/sample/map/map.cpp +10 -18
- data/sample/map/test.rb +1 -1
- data/test/embed_ruby.cpp +34 -0
- data/test/embed_ruby.hpp +4 -0
- data/test/ext/t1/extconf.rb +3 -0
- data/test/ext/t1/t1.cpp +1 -3
- data/test/ext/t2/extconf.rb +3 -0
- data/test/ext/t2/t2.cpp +1 -1
- data/test/extconf.rb +23 -0
- data/test/ruby/test_callbacks_sample.rb +28 -0
- data/test/ruby/test_multiple_extensions.rb +18 -0
- data/test/ruby/test_multiple_extensions_same_class.rb +14 -0
- data/test/ruby/test_multiple_extensions_with_inheritance.rb +20 -0
- data/test/test_Address_Registration_Guard.cpp +25 -11
- data/test/test_Array.cpp +131 -74
- data/test/test_Attribute.cpp +147 -0
- data/test/test_Builtin_Object.cpp +36 -15
- data/test/test_Class.cpp +151 -274
- data/test/test_Constructor.cpp +10 -9
- data/test/test_Data_Object.cpp +135 -193
- data/test/test_Data_Type.cpp +323 -252
- data/test/test_Director.cpp +56 -42
- data/test/test_Enum.cpp +230 -104
- data/test/test_Exception.cpp +7 -7
- data/test/test_Hash.cpp +33 -31
- data/test/test_Identifier.cpp +6 -6
- data/test/test_Inheritance.cpp +221 -0
- data/test/test_Iterator.cpp +161 -0
- data/test/test_Jump_Tag.cpp +1 -1
- data/test/test_Keep_Alive.cpp +161 -0
- data/test/test_Memory_Management.cpp +4 -5
- data/test/test_Module.cpp +169 -111
- data/test/test_Object.cpp +51 -19
- data/test/test_Ownership.cpp +275 -0
- data/test/test_Self.cpp +205 -0
- data/test/test_Stl_Optional.cpp +90 -0
- data/test/test_Stl_Pair.cpp +144 -0
- data/test/test_Stl_SmartPointer.cpp +200 -0
- data/test/test_Stl_String.cpp +74 -0
- data/test/test_Stl_Vector.cpp +652 -0
- data/test/test_String.cpp +3 -3
- data/test/test_Struct.cpp +31 -40
- data/test/test_Symbol.cpp +3 -3
- data/test/test_To_From_Ruby.cpp +283 -218
- data/test/test_global_functions.cpp +41 -20
- data/test/unittest.cpp +34 -8
- data/test/unittest.hpp +0 -4
- metadata +117 -137
- data/Doxyfile +0 -2280
- data/Makefile.am +0 -26
- data/Makefile.in +0 -920
- data/README +0 -1055
- data/README.mingw +0 -8
- data/aclocal.m4 +0 -1088
- data/bootstrap +0 -8
- data/check_stdcxx_11.ac +0 -142
- data/config.guess +0 -1421
- data/config.sub +0 -1807
- data/configure +0 -7481
- data/configure.ac +0 -55
- data/depcomp +0 -791
- data/doxygen.ac +0 -314
- data/doxygen.am +0 -186
- data/extconf.rb +0 -69
- data/install-sh +0 -501
- data/missing +0 -215
- data/post-autoconf.rb +0 -22
- data/post-automake.rb +0 -28
- data/rice/Address_Registration_Guard.cpp +0 -22
- data/rice/Arg_impl.hpp +0 -129
- data/rice/Arg_operators.cpp +0 -21
- data/rice/Arg_operators.hpp +0 -19
- data/rice/Array.hpp +0 -214
- data/rice/Array.ipp +0 -256
- data/rice/Builtin_Object.hpp +0 -8
- data/rice/Builtin_Object.ipp +0 -50
- data/rice/Builtin_Object_defn.hpp +0 -50
- data/rice/Class.cpp +0 -57
- data/rice/Class.hpp +0 -8
- data/rice/Class.ipp +0 -6
- data/rice/Class_defn.hpp +0 -83
- data/rice/Data_Type.cpp +0 -54
- data/rice/Data_Type_fwd.hpp +0 -12
- data/rice/Director.cpp +0 -13
- data/rice/Exception.cpp +0 -59
- data/rice/Exception_Base.hpp +0 -8
- data/rice/Exception_Base.ipp +0 -13
- data/rice/Exception_Base_defn.hpp +0 -27
- data/rice/Hash.hpp +0 -227
- data/rice/Hash.ipp +0 -329
- data/rice/Identifier.cpp +0 -8
- data/rice/Jump_Tag.hpp +0 -24
- data/rice/Makefile.am +0 -124
- data/rice/Makefile.in +0 -839
- data/rice/Module.cpp +0 -84
- data/rice/Module.hpp +0 -8
- data/rice/Module.ipp +0 -6
- data/rice/Module_defn.hpp +0 -88
- data/rice/Module_impl.hpp +0 -281
- data/rice/Module_impl.ipp +0 -345
- data/rice/Object.cpp +0 -169
- data/rice/Object.hpp +0 -8
- data/rice/Object.ipp +0 -19
- data/rice/Object_defn.hpp +0 -191
- data/rice/Require_Guard.hpp +0 -21
- data/rice/String.cpp +0 -94
- data/rice/String.hpp +0 -91
- data/rice/Struct.cpp +0 -117
- data/rice/Struct.hpp +0 -162
- data/rice/Struct.ipp +0 -26
- data/rice/Symbol.cpp +0 -25
- data/rice/Symbol.hpp +0 -66
- data/rice/Symbol.ipp +0 -44
- data/rice/config.hpp +0 -47
- data/rice/config.hpp.in +0 -46
- data/rice/detail/Arguments.hpp +0 -118
- data/rice/detail/Auto_Function_Wrapper.hpp +0 -898
- data/rice/detail/Auto_Function_Wrapper.ipp +0 -3694
- data/rice/detail/Auto_Member_Function_Wrapper.hpp +0 -897
- data/rice/detail/Auto_Member_Function_Wrapper.ipp +0 -2774
- data/rice/detail/Caster.hpp +0 -103
- data/rice/detail/Not_Copyable.hpp +0 -25
- data/rice/detail/Wrapped_Function.hpp +0 -33
- data/rice/detail/cfp.hpp +0 -24
- data/rice/detail/cfp.ipp +0 -51
- data/rice/detail/check_ruby_type.cpp +0 -27
- data/rice/detail/check_ruby_type.hpp +0 -23
- data/rice/detail/creation_funcs.hpp +0 -37
- data/rice/detail/creation_funcs.ipp +0 -36
- data/rice/detail/define_method_and_auto_wrap.hpp +0 -31
- data/rice/detail/define_method_and_auto_wrap.ipp +0 -30
- data/rice/detail/demangle.cpp +0 -56
- data/rice/detail/demangle.hpp +0 -19
- data/rice/detail/env.hpp +0 -11
- data/rice/detail/method_data.cpp +0 -86
- data/rice/detail/node.hpp +0 -13
- data/rice/detail/object_call.hpp +0 -69
- data/rice/detail/object_call.ipp +0 -131
- data/rice/detail/protect.cpp +0 -29
- data/rice/detail/protect.hpp +0 -34
- data/rice/detail/ruby_version_code.hpp +0 -6
- data/rice/detail/ruby_version_code.hpp.in +0 -6
- data/rice/detail/st.hpp +0 -22
- data/rice/detail/traits.hpp +0 -43
- data/rice/detail/win32.hpp +0 -16
- data/rice/detail/wrap_function.hpp +0 -341
- data/rice/detail/wrap_function.ipp +0 -514
- data/rice/protect.hpp +0 -92
- data/rice/protect.ipp +0 -1134
- data/rice/rubypp.rb +0 -97
- data/rice/to_from_ruby.hpp +0 -8
- data/rice/to_from_ruby.ipp +0 -294
- data/rice/to_from_ruby_defn.hpp +0 -70
- data/ruby.ac +0 -135
- data/ruby/Makefile.am +0 -1
- data/ruby/Makefile.in +0 -625
- data/ruby/lib/Makefile.am +0 -3
- data/ruby/lib/Makefile.in +0 -503
- data/ruby/lib/mkmf-rice.rb.in +0 -217
- data/ruby/lib/version.rb +0 -3
- data/sample/Makefile.am +0 -47
- data/sample/Makefile.in +0 -486
- data/test/Makefile.am +0 -72
- data/test/Makefile.in +0 -1150
- data/test/ext/Makefile.am +0 -41
- data/test/ext/Makefile.in +0 -480
- data/test/test_rice.rb +0 -41
data/rice/Data_Type.hpp
CHANGED
data/rice/Data_Type.ipp
CHANGED
@@ -1,365 +1,321 @@
|
|
1
1
|
#ifndef Rice__Data_Type__ipp_
|
2
2
|
#define Rice__Data_Type__ipp_
|
3
3
|
|
4
|
+
#include "detail/method_data.hpp"
|
5
|
+
#include "detail/NativeAttribute.hpp"
|
6
|
+
#include "detail/default_allocation_func.hpp"
|
7
|
+
#include "detail/TypeRegistry.hpp"
|
8
|
+
#include "detail/Wrapper.hpp"
|
9
|
+
#include "detail/Iterator.hpp"
|
4
10
|
#include "Class.hpp"
|
5
11
|
#include "String.hpp"
|
6
|
-
#include "Data_Object.hpp"
|
7
|
-
#include "detail/default_allocation_func.hpp"
|
8
|
-
#include "detail/creation_funcs.hpp"
|
9
|
-
#include "detail/method_data.hpp"
|
10
|
-
#include "detail/Caster.hpp"
|
11
|
-
#include "detail/demangle.hpp"
|
12
12
|
|
13
13
|
#include <stdexcept>
|
14
|
-
#include <typeinfo>
|
15
14
|
|
16
|
-
|
17
|
-
|
15
|
+
namespace Rice
|
16
|
+
{
|
17
|
+
template<typename T>
|
18
|
+
void ruby_mark_internal(detail::Wrapper* wrapper)
|
19
|
+
{
|
20
|
+
// Tell the wrapper to mark the objects its keeping alive
|
21
|
+
wrapper->ruby_mark();
|
18
22
|
|
19
|
-
|
20
|
-
|
23
|
+
// Get the underlying data and call custom mark function (if any)
|
24
|
+
T* data = static_cast<T*>(wrapper->get());
|
25
|
+
ruby_mark<T>(data);
|
26
|
+
}
|
21
27
|
|
22
|
-
template<typename T>
|
23
|
-
|
24
|
-
inline Rice::Data_Type<T> Rice::Data_Type<T>::
|
25
|
-
bind(Module const & klass)
|
26
|
-
{
|
27
|
-
if(klass.value() == klass_)
|
28
|
+
template<typename T>
|
29
|
+
void ruby_free_internal(detail::Wrapper* wrapper)
|
28
30
|
{
|
29
|
-
|
31
|
+
delete wrapper;
|
30
32
|
}
|
31
33
|
|
32
|
-
|
34
|
+
template<typename T>
|
35
|
+
size_t ruby_size_internal(const T* data)
|
33
36
|
{
|
34
|
-
|
35
|
-
s = "Data type ";
|
36
|
-
s += detail::demangle(typeid(T).name());
|
37
|
-
s += " is already bound to a different type";
|
38
|
-
throw std::runtime_error(s.c_str());
|
37
|
+
return sizeof(T);
|
39
38
|
}
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
template<typename T>
|
41
|
+
template <typename Base_T>
|
42
|
+
inline Data_Type<T> Data_Type<T>::bind(Module const& klass)
|
43
|
+
{
|
44
|
+
if (is_bound())
|
45
|
+
{
|
46
|
+
std::string message = "Type " + detail::typeName(typeid(T)) + " is already bound to a different type";
|
47
|
+
throw std::runtime_error(message.c_str());
|
48
|
+
}
|
49
|
+
|
50
|
+
klass_ = klass;
|
45
51
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
+
rb_type_ = new rb_data_type_t();
|
53
|
+
rb_type_->wrap_struct_name = strdup(Rice::detail::protect(rb_class2name, klass_));
|
54
|
+
rb_type_->function.dmark = reinterpret_cast<void(*)(void*)>(&Rice::ruby_mark_internal<T>);
|
55
|
+
rb_type_->function.dfree = reinterpret_cast<void(*)(void*)>(&Rice::ruby_free_internal<T>);
|
56
|
+
rb_type_->function.dsize = reinterpret_cast<size_t(*)(const void*)>(&Rice::ruby_size_internal<T>);
|
57
|
+
rb_type_->data = nullptr;
|
58
|
+
rb_type_->flags = RUBY_TYPED_FREE_IMMEDIATELY;
|
52
59
|
|
53
|
-
|
60
|
+
if constexpr (!std::is_void_v<Base_T>)
|
61
|
+
{
|
62
|
+
rb_type_->parent = Data_Type<Base_T>::rb_type();
|
63
|
+
}
|
64
|
+
|
65
|
+
// Now register with the type registry
|
66
|
+
detail::TypeRegistry::add<T>(klass_, rb_type_);
|
67
|
+
|
68
|
+
for (typename Instances::iterator it = unbound_instances().begin(),
|
54
69
|
end = unbound_instances().end();
|
55
70
|
it != end;
|
56
71
|
unbound_instances().erase(it++))
|
72
|
+
{
|
73
|
+
(*it)->set_value(klass);
|
74
|
+
}
|
75
|
+
|
76
|
+
return Data_Type<T>();
|
77
|
+
}
|
78
|
+
|
79
|
+
template<typename T>
|
80
|
+
inline void Data_Type<T>::unbind()
|
57
81
|
{
|
58
|
-
(
|
82
|
+
detail::TypeRegistry::remove<T>();
|
83
|
+
|
84
|
+
if (klass_ != Qnil)
|
85
|
+
{
|
86
|
+
klass_ = Qnil;
|
87
|
+
}
|
88
|
+
|
89
|
+
// There could be objects floating around using the existing rb_type so
|
90
|
+
// do not delete it. This is of course a memory leak.
|
91
|
+
rb_type_ = nullptr;
|
59
92
|
}
|
60
93
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
94
|
+
template<typename T>
|
95
|
+
inline Data_Type<T>::Data_Type() : Class(klass_ == Qnil ? rb_cObject : klass_)
|
96
|
+
{
|
97
|
+
if (!is_bound())
|
98
|
+
{
|
99
|
+
unbound_instances().insert(this);
|
100
|
+
}
|
101
|
+
}
|
66
102
|
|
67
|
-
template<typename T>
|
68
|
-
inline
|
69
|
-
Data_Type()
|
70
|
-
: Module_impl<Data_Type_Base, Data_Type<T> >(
|
71
|
-
klass_ == Qnil ? rb_cObject : klass_)
|
72
|
-
{
|
73
|
-
if(!is_bound())
|
103
|
+
template<typename T>
|
104
|
+
inline Data_Type<T>::Data_Type(Module const& klass) : Class(klass)
|
74
105
|
{
|
75
|
-
|
106
|
+
this->bind(klass);
|
76
107
|
}
|
77
|
-
}
|
78
108
|
|
79
|
-
template<typename T>
|
80
|
-
inline
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
{
|
85
|
-
this->bind<void>(klass);
|
86
|
-
}
|
109
|
+
template<typename T>
|
110
|
+
inline Data_Type<T>::~Data_Type()
|
111
|
+
{
|
112
|
+
unbound_instances().erase(this);
|
113
|
+
}
|
87
114
|
|
88
|
-
template<typename T>
|
89
|
-
inline
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
}
|
115
|
+
template<typename T>
|
116
|
+
inline rb_data_type_t* Data_Type<T>::rb_type()
|
117
|
+
{
|
118
|
+
check_is_bound();
|
119
|
+
return rb_type_;
|
120
|
+
}
|
94
121
|
|
95
|
-
template<typename T>
|
96
|
-
|
97
|
-
Rice::Data_Type<T>::
|
98
|
-
klass() {
|
99
|
-
if(is_bound())
|
122
|
+
template<typename T>
|
123
|
+
inline Class Data_Type<T>::klass()
|
100
124
|
{
|
125
|
+
check_is_bound();
|
101
126
|
return klass_;
|
102
127
|
}
|
103
|
-
|
128
|
+
|
129
|
+
template<typename T>
|
130
|
+
inline Data_Type<T>& Data_Type<T>::operator=(Module const& klass)
|
104
131
|
{
|
105
|
-
|
106
|
-
|
107
|
-
s += " is unbound";
|
108
|
-
throw std::runtime_error(s.c_str());
|
132
|
+
this->bind(klass);
|
133
|
+
return *this;
|
109
134
|
}
|
110
|
-
}
|
111
135
|
|
112
|
-
template<typename T>
|
113
|
-
|
114
|
-
|
115
|
-
{
|
116
|
-
|
117
|
-
return *this;
|
118
|
-
}
|
119
|
-
|
120
|
-
template<typename T>
|
121
|
-
template<typename Constructor_T>
|
122
|
-
inline Rice::Data_Type<T> & Rice::Data_Type<T>::
|
123
|
-
define_constructor(
|
124
|
-
Constructor_T /* constructor */,
|
125
|
-
Arguments* arguments)
|
126
|
-
{
|
127
|
-
check_is_bound();
|
128
|
-
|
129
|
-
// Normal constructor pattern with new/initialize
|
130
|
-
rb_define_alloc_func(
|
131
|
-
static_cast<VALUE>(*this),
|
132
|
-
detail::default_allocation_func<T>);
|
133
|
-
this->define_method(
|
134
|
-
"initialize",
|
135
|
-
&Constructor_T::construct,
|
136
|
-
arguments
|
137
|
-
);
|
138
|
-
|
139
|
-
return *this;
|
140
|
-
}
|
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
141
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
define_constructor(
|
146
|
-
Constructor_T constructor,
|
147
|
-
Arg const& arg)
|
148
|
-
{
|
149
|
-
Arguments* args = new Arguments();
|
150
|
-
args->add(arg);
|
151
|
-
return define_constructor(constructor, args);
|
152
|
-
}
|
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);
|
153
145
|
|
146
|
+
return *this;
|
147
|
+
}
|
154
148
|
|
155
|
-
template<typename T>
|
156
|
-
template<typename
|
157
|
-
inline
|
158
|
-
|
159
|
-
|
160
|
-
Rice::Data_Type<Director_T>::template bind<T>(*this);
|
161
|
-
return *this;
|
162
|
-
}
|
149
|
+
template<typename T>
|
150
|
+
template<typename Constructor_T, typename...Arg_Ts>
|
151
|
+
inline Data_Type<T>& Data_Type<T>::define_constructor(Constructor_T constructor, Arg_Ts const& ...args)
|
152
|
+
{
|
153
|
+
check_is_bound();
|
163
154
|
|
164
|
-
|
165
|
-
|
166
|
-
from_ruby(Object x)
|
167
|
-
{
|
168
|
-
check_is_bound();
|
155
|
+
// Define a Ruby allocator which creates the Ruby object
|
156
|
+
detail::protect(rb_define_alloc_func, static_cast<VALUE>(*this), detail::default_allocation_func<T>);
|
169
157
|
|
170
|
-
|
171
|
-
|
158
|
+
// Define an initialize function that will create the C++ object
|
159
|
+
this->define_method("initialize", &Constructor_T::construct, args...);
|
172
160
|
|
173
|
-
|
174
|
-
{
|
175
|
-
// Great, not converting to a base/derived type
|
176
|
-
Data_Type<T> data_klass;
|
177
|
-
Data_Object<T> obj(x, data_klass);
|
178
|
-
return obj.get();
|
161
|
+
return *this;
|
179
162
|
}
|
180
163
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
// 1) casters that handle this direct type
|
189
|
-
// 2) casters that handle types that are ancestors of klass
|
190
|
-
//
|
191
|
-
// Step 2 allows us to handle the case where a Rice-wrapped class
|
192
|
-
// is subclassed in Ruby but then an instance of that class is passed
|
193
|
-
// back into C++ (say, in a Listener / callback construction)
|
194
|
-
//
|
195
|
-
|
196
|
-
VALUE ancestors = rb_mod_ancestors(klass.value());
|
197
|
-
|
198
|
-
long earliest = RARRAY_LEN(ancestors) + 1;
|
199
|
-
|
200
|
-
int index;
|
201
|
-
VALUE indexFound;
|
202
|
-
Data_Type_Base::Casters::const_iterator toUse = end;
|
203
|
-
|
204
|
-
for(; it != end; it++) {
|
205
|
-
// Do we match directly?
|
206
|
-
if(klass.value() == it->first) {
|
207
|
-
toUse = it;
|
208
|
-
break;
|
164
|
+
template<typename T>
|
165
|
+
template<typename Director_T>
|
166
|
+
inline Data_Type<T>& Data_Type<T>::define_director()
|
167
|
+
{
|
168
|
+
if (!detail::TypeRegistry::isDefined<Director_T>())
|
169
|
+
{
|
170
|
+
Data_Type<Director_T>::bind(*this);
|
209
171
|
}
|
210
172
|
|
211
|
-
//
|
212
|
-
//
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
indexFound = rb_funcall(ancestors, rb_intern("index"), 1, it->first);
|
173
|
+
// TODO - hack to fake Ruby into thinking that a Director is
|
174
|
+
// the same as the base data type
|
175
|
+
Data_Type<Director_T>::rb_type_ = Data_Type<T>::rb_type_;
|
176
|
+
return *this;
|
177
|
+
}
|
217
178
|
|
218
|
-
|
219
|
-
|
179
|
+
template<typename T>
|
180
|
+
inline bool Data_Type<T>::is_bound()
|
181
|
+
{
|
182
|
+
return klass_ != Qnil;
|
183
|
+
}
|
220
184
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
185
|
+
template<typename T>
|
186
|
+
inline bool Data_Type<T>::is_descendant(VALUE value)
|
187
|
+
{
|
188
|
+
check_is_bound();
|
189
|
+
return detail::protect(rb_obj_is_kind_of, value, klass_) == Qtrue;
|
190
|
+
}
|
191
|
+
|
192
|
+
template<typename T>
|
193
|
+
inline void Data_Type<T>::check_is_bound()
|
194
|
+
{
|
195
|
+
if (!is_bound())
|
196
|
+
{
|
197
|
+
std::string message = "Type " + detail::typeName(typeid(T)) + " is not bound";
|
198
|
+
throw std::runtime_error(message.c_str());
|
225
199
|
}
|
226
200
|
}
|
227
|
-
|
228
|
-
|
201
|
+
|
202
|
+
template<typename T, typename Base_T>
|
203
|
+
inline Data_Type<T> define_class_under(Object module, char const* name)
|
229
204
|
{
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
205
|
+
if (detail::TypeRegistry::isDefined<T>())
|
206
|
+
{
|
207
|
+
return Data_Type<T>();
|
208
|
+
}
|
209
|
+
|
210
|
+
Class superKlass;
|
211
|
+
|
212
|
+
if constexpr (std::is_void_v<Base_T>)
|
213
|
+
{
|
214
|
+
superKlass = rb_cObject;
|
215
|
+
}
|
216
|
+
else
|
217
|
+
{
|
218
|
+
superKlass = Data_Type<Base_T>::klass();
|
219
|
+
}
|
220
|
+
|
221
|
+
Class c = define_class_under(module, name, superKlass);
|
222
|
+
c.undef_creation_funcs();
|
223
|
+
return Data_Type<T>::template bind<Base_T>(c);
|
234
224
|
}
|
235
225
|
|
236
|
-
|
237
|
-
|
226
|
+
template<typename T, typename Base_T>
|
227
|
+
inline Data_Type<T> define_class(char const* name)
|
238
228
|
{
|
239
|
-
|
240
|
-
|
229
|
+
if (detail::TypeRegistry::isDefined<T>())
|
230
|
+
{
|
231
|
+
return Data_Type<T>();
|
232
|
+
}
|
233
|
+
|
234
|
+
Class superKlass;
|
235
|
+
if constexpr (std::is_void_v<Base_T>)
|
236
|
+
{
|
237
|
+
superKlass = rb_cObject;
|
238
|
+
}
|
239
|
+
else
|
240
|
+
{
|
241
|
+
superKlass = Data_Type<Base_T>::klass();
|
242
|
+
}
|
243
|
+
|
244
|
+
Class c = define_class(name, superKlass);
|
245
|
+
c.undef_creation_funcs();
|
246
|
+
return Data_Type<T>::template bind<Base_T>(c);
|
241
247
|
}
|
242
|
-
|
248
|
+
|
249
|
+
template<typename T>
|
250
|
+
template<typename U, typename Iterator_T>
|
251
|
+
inline Data_Type<T>& Data_Type<T>::define_iterator(Iterator_T(U::* begin)(), Iterator_T(U::* end)(), Identifier name)
|
243
252
|
{
|
244
|
-
|
253
|
+
using Iter_T = detail::Iterator<U, Iterator_T>;
|
254
|
+
Iter_T* iterator = new Iter_T(begin, end);
|
255
|
+
detail::MethodData::define_method(Data_Type<T>::klass(), name,
|
256
|
+
(RUBY_METHOD_FUNC)iterator->call, 0, iterator);
|
257
|
+
|
258
|
+
return *this;
|
245
259
|
}
|
246
|
-
}
|
247
260
|
|
248
|
-
template<typename T>
|
249
|
-
|
250
|
-
|
251
|
-
{
|
252
|
-
|
253
|
-
|
261
|
+
template <typename T>
|
262
|
+
template <typename Attr_T>
|
263
|
+
inline Data_Type<T>& Data_Type<T>::define_attr(std::string name, Attr_T attr, AttrAccess access)
|
264
|
+
{
|
265
|
+
auto* native = detail::Make_Native_Attribute(attr, access);
|
266
|
+
using Native_T = typename std::remove_pointer_t<decltype(native)>;
|
254
267
|
|
255
|
-
|
256
|
-
inline Rice::detail::Abstract_Caster * Rice::Data_Type<T>::
|
257
|
-
caster() const
|
258
|
-
{
|
259
|
-
check_is_bound();
|
260
|
-
return caster_.get();
|
261
|
-
}
|
268
|
+
detail::verifyType<typename Native_T::Native_Return_T>();
|
262
269
|
|
263
|
-
|
264
|
-
{
|
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
|
+
}
|
265
275
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
{
|
270
|
-
|
271
|
-
}
|
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
|
+
}
|
272
282
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
{
|
279
|
-
std::string s;
|
280
|
-
s = "Data type ";
|
281
|
-
s += detail::demangle(typeid(T).name());
|
282
|
-
s += " is not bound";
|
283
|
-
throw std::runtime_error(s.c_str());
|
283
|
+
detail::MethodData::define_method( klass_, Identifier(name + "=").id(),
|
284
|
+
RUBY_METHOD_FUNC(&Native_T::set), 1, native);
|
285
|
+
}
|
286
|
+
|
287
|
+
return *this;
|
284
288
|
}
|
285
|
-
}
|
286
289
|
|
287
|
-
|
290
|
+
template <typename T>
|
291
|
+
template <typename Attr_T>
|
292
|
+
inline Data_Type<T>& Data_Type<T>::define_singleton_attr(std::string name, Attr_T attr, AttrAccess access)
|
293
|
+
{
|
294
|
+
auto* native = detail::Make_Native_Attribute(attr, access);
|
295
|
+
using Native_T = typename std::remove_pointer_t<decltype(native)>;
|
288
296
|
|
289
|
-
|
290
|
-
inline Rice::Data_Type<T> Rice::
|
291
|
-
define_class_under(
|
292
|
-
Object module,
|
293
|
-
char const * name)
|
294
|
-
{
|
295
|
-
Class c(define_class_under(module, name, rb_cObject));
|
296
|
-
c.undef_creation_funcs();
|
297
|
-
return Data_Type<T>::template bind<void>(c);
|
298
|
-
}
|
297
|
+
detail::verifyType<typename Native_T::Native_Return_T>();
|
299
298
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
Data_Type<Base_T> base_dt;
|
307
|
-
Class c(define_class_under(module, name, base_dt));
|
308
|
-
c.undef_creation_funcs();
|
309
|
-
return Data_Type<T>::template bind<Base_T>(c);
|
310
|
-
}
|
299
|
+
if (access == AttrAccess::ReadWrite || access == AttrAccess::Read)
|
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
|
+
}
|
311
305
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
c.undef_creation_funcs();
|
319
|
-
return Data_Type<T>::template bind<void>(c);
|
320
|
-
}
|
306
|
+
if (access == AttrAccess::ReadWrite || access == AttrAccess::Write)
|
307
|
+
{
|
308
|
+
if (std::is_const_v<std::remove_pointer_t<Attr_T>>)
|
309
|
+
{
|
310
|
+
throw std::runtime_error(name + " is readonly");
|
311
|
+
}
|
321
312
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
{
|
327
|
-
Data_Type<Base_T> base_dt;
|
328
|
-
Class c(define_class(name, base_dt));
|
329
|
-
c.undef_creation_funcs();
|
330
|
-
return Data_Type<T>::template bind<Base_T>(c);
|
331
|
-
}
|
313
|
+
VALUE singleton = detail::protect(rb_singleton_class, this->value());
|
314
|
+
detail::MethodData::define_method(singleton, Identifier(name + "=").id(),
|
315
|
+
RUBY_METHOD_FUNC(&Native_T::set), 1, native);
|
316
|
+
}
|
332
317
|
|
333
|
-
|
334
|
-
|
335
|
-
Rice::define_implicit_cast()
|
336
|
-
{
|
337
|
-
// As Rice currently expects only one entry into
|
338
|
-
// this list for a given klass VALUE, we need to get
|
339
|
-
// the current caster for From_T and insert in our
|
340
|
-
// new caster as the head of the caster list
|
341
|
-
|
342
|
-
Class from_class = Data_Type<From_T>::klass().value();
|
343
|
-
Class to_class = Data_Type<To_T>::klass().value();
|
344
|
-
|
345
|
-
detail::Abstract_Caster* from_caster =
|
346
|
-
Data_Type<From_T>::caster_.release();
|
347
|
-
|
348
|
-
detail::Abstract_Caster* new_caster =
|
349
|
-
new detail::Implicit_Caster<To_T, From_T>(from_caster, to_class);
|
350
|
-
|
351
|
-
// Insert our new caster into the list for the from class
|
352
|
-
Data_Type_Base::casters().erase(from_class);
|
353
|
-
Data_Type_Base::casters().insert(
|
354
|
-
std::make_pair(
|
355
|
-
from_class,
|
356
|
-
new_caster
|
357
|
-
)
|
358
|
-
);
|
359
|
-
|
360
|
-
// And make sure the from_class has direct access to the
|
361
|
-
// updated caster list
|
362
|
-
Data_Type<From_T>::caster_.reset(new_caster);
|
318
|
+
return *this;
|
319
|
+
}
|
363
320
|
}
|
364
|
-
|
365
|
-
#endif // Rice__Data_Type__ipp_
|
321
|
+
#endif
|