rice 2.1.3 → 4.0.2
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 +121 -0
- data/CONTRIBUTORS.md +19 -0
- data/COPYING +2 -2
- data/Gemfile +3 -0
- data/README.md +45 -1028
- data/Rakefile +95 -12
- data/include/rice/rice.hpp +7766 -0
- data/include/rice/stl.hpp +1113 -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 -50
- 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 -276
- 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 +121 -136
- data/Doxyfile +0 -2268
- data/Makefile.am +0 -26
- data/Makefile.in +0 -923
- data/README.mingw +0 -8
- data/aclocal.m4 +0 -1088
- data/bootstrap +0 -8
- data/check_stdcxx_11.ac +0 -103
- data/config.guess +0 -1421
- data/config.sub +0 -1807
- data/configure +0 -7367
- 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 -125
- data/rice/Makefile.in +0 -888
- 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 -628
- data/ruby/lib/Makefile.am +0 -3
- data/ruby/lib/Makefile.in +0 -506
- 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 -489
- data/test/Makefile.am +0 -72
- data/test/Makefile.in +0 -1213
- data/test/ext/Makefile.am +0 -41
- data/test/ext/Makefile.in +0 -483
- data/test/test_rice.rb +0 -41
@@ -0,0 +1,1113 @@
|
|
1
|
+
#ifndef Rice__stl__hpp_
|
2
|
+
#define Rice__stl__hpp_
|
3
|
+
|
4
|
+
|
5
|
+
// ========= string.hpp =========
|
6
|
+
|
7
|
+
|
8
|
+
// --------- string.ipp ---------
|
9
|
+
#include <string>
|
10
|
+
|
11
|
+
namespace Rice::detail
|
12
|
+
{
|
13
|
+
template<>
|
14
|
+
struct Type<std::string>
|
15
|
+
{
|
16
|
+
static bool verify()
|
17
|
+
{
|
18
|
+
return true;
|
19
|
+
}
|
20
|
+
};
|
21
|
+
|
22
|
+
template<>
|
23
|
+
class To_Ruby<std::string>
|
24
|
+
{
|
25
|
+
public:
|
26
|
+
VALUE convert(std::string const& x)
|
27
|
+
{
|
28
|
+
return detail::protect(rb_external_str_new, x.data(), (long)x.size());
|
29
|
+
}
|
30
|
+
};
|
31
|
+
|
32
|
+
template<>
|
33
|
+
class To_Ruby<std::string&>
|
34
|
+
{
|
35
|
+
public:
|
36
|
+
VALUE convert(std::string const& x)
|
37
|
+
{
|
38
|
+
return detail::protect(rb_external_str_new, x.data(), (long)x.size());
|
39
|
+
}
|
40
|
+
};
|
41
|
+
|
42
|
+
template<>
|
43
|
+
class From_Ruby<std::string>
|
44
|
+
{
|
45
|
+
public:
|
46
|
+
From_Ruby() = default;
|
47
|
+
|
48
|
+
explicit From_Ruby(Arg* arg) : arg_(arg)
|
49
|
+
{
|
50
|
+
}
|
51
|
+
|
52
|
+
std::string convert(VALUE value)
|
53
|
+
{
|
54
|
+
if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
|
55
|
+
{
|
56
|
+
return this->arg_->defaultValue<std::string>();
|
57
|
+
}
|
58
|
+
else
|
59
|
+
{
|
60
|
+
detail::protect(rb_check_type, value, (int)T_STRING);
|
61
|
+
return std::string(RSTRING_PTR(value), RSTRING_LEN(value));
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
private:
|
66
|
+
Arg* arg_ = nullptr;
|
67
|
+
};
|
68
|
+
|
69
|
+
template<>
|
70
|
+
class From_Ruby<std::string*>
|
71
|
+
{
|
72
|
+
public:
|
73
|
+
std::string* convert(VALUE value)
|
74
|
+
{
|
75
|
+
detail::protect(rb_check_type, value, (int)T_STRING);
|
76
|
+
this->converted_ = std::string(RSTRING_PTR(value), RSTRING_LEN(value));
|
77
|
+
return &this->converted_;
|
78
|
+
}
|
79
|
+
|
80
|
+
private:
|
81
|
+
std::string converted_;
|
82
|
+
};
|
83
|
+
|
84
|
+
template<>
|
85
|
+
class From_Ruby<std::string&>
|
86
|
+
{
|
87
|
+
public:
|
88
|
+
From_Ruby() = default;
|
89
|
+
|
90
|
+
explicit From_Ruby(Arg* arg) : arg_(arg)
|
91
|
+
{
|
92
|
+
}
|
93
|
+
|
94
|
+
std::string& convert(VALUE value)
|
95
|
+
{
|
96
|
+
if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
|
97
|
+
{
|
98
|
+
return this->arg_->defaultValue<std::string>();
|
99
|
+
}
|
100
|
+
else
|
101
|
+
{
|
102
|
+
detail::protect(rb_check_type, value, (int)T_STRING);
|
103
|
+
this->converted_ = std::string(RSTRING_PTR(value), RSTRING_LEN(value));
|
104
|
+
return this->converted_;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
private:
|
109
|
+
Arg* arg_ = nullptr;
|
110
|
+
std::string converted_;
|
111
|
+
};
|
112
|
+
}
|
113
|
+
|
114
|
+
// ========= complex.hpp =========
|
115
|
+
|
116
|
+
|
117
|
+
// --------- complex.ipp ---------
|
118
|
+
#include <complex>
|
119
|
+
|
120
|
+
|
121
|
+
namespace Rice::detail
|
122
|
+
{
|
123
|
+
template<typename T>
|
124
|
+
struct Type<std::complex<T>>
|
125
|
+
{
|
126
|
+
static bool verify()
|
127
|
+
{
|
128
|
+
return true;
|
129
|
+
}
|
130
|
+
};
|
131
|
+
|
132
|
+
template<typename T>
|
133
|
+
class To_Ruby<std::complex<T>>
|
134
|
+
{
|
135
|
+
public:
|
136
|
+
VALUE convert(const std::complex<T>& data)
|
137
|
+
{
|
138
|
+
std::vector<VALUE> args(2);
|
139
|
+
args[0] = To_Ruby<T>().convert(data.real());
|
140
|
+
args[1] = To_Ruby<T>().convert(data.imag());
|
141
|
+
return protect(rb_funcall2, rb_mKernel, rb_intern("Complex"), (int)args.size(), (const VALUE*)args.data());
|
142
|
+
}
|
143
|
+
};
|
144
|
+
|
145
|
+
template<typename T>
|
146
|
+
class From_Ruby<std::complex<T>>
|
147
|
+
{
|
148
|
+
public:
|
149
|
+
std::complex<T> convert(VALUE value)
|
150
|
+
{
|
151
|
+
VALUE real = protect(rb_funcall2, value, rb_intern("real"), 0, (const VALUE*)nullptr);
|
152
|
+
VALUE imaginary = protect(rb_funcall2, value, rb_intern("imaginary"), 0, (const VALUE*)nullptr);
|
153
|
+
|
154
|
+
return std::complex<T>(From_Ruby<T>().convert(real), From_Ruby<T>().convert(imaginary));
|
155
|
+
}
|
156
|
+
};
|
157
|
+
|
158
|
+
template<typename T>
|
159
|
+
class From_Ruby<std::complex<T>&>
|
160
|
+
{
|
161
|
+
public:
|
162
|
+
std::complex<T>& convert(VALUE value)
|
163
|
+
{
|
164
|
+
VALUE real = protect(rb_funcall2, value, rb_intern("real"), 0, (const VALUE*)nullptr);
|
165
|
+
VALUE imaginary = protect(rb_funcall2, value, rb_intern("imaginary"), 0, (const VALUE*)nullptr);
|
166
|
+
this->converted_ = std::complex<T>(From_Ruby<T>().convert(real), From_Ruby<T>().convert(imaginary));
|
167
|
+
|
168
|
+
return this->converted_;
|
169
|
+
}
|
170
|
+
|
171
|
+
private:
|
172
|
+
std::complex<T> converted_;
|
173
|
+
};
|
174
|
+
}
|
175
|
+
|
176
|
+
// ========= optional.hpp =========
|
177
|
+
|
178
|
+
|
179
|
+
// --------- optional.ipp ---------
|
180
|
+
#include <optional>
|
181
|
+
|
182
|
+
namespace Rice::detail
|
183
|
+
{
|
184
|
+
template<typename T>
|
185
|
+
struct Type<std::optional<T>>
|
186
|
+
{
|
187
|
+
constexpr static bool verify()
|
188
|
+
{
|
189
|
+
return Type<T>::verify();
|
190
|
+
}
|
191
|
+
};
|
192
|
+
|
193
|
+
template<>
|
194
|
+
class To_Ruby<std::nullopt_t>
|
195
|
+
{
|
196
|
+
public:
|
197
|
+
VALUE convert(std::nullopt_t& _)
|
198
|
+
{
|
199
|
+
return Qnil;
|
200
|
+
}
|
201
|
+
};
|
202
|
+
|
203
|
+
template<typename T>
|
204
|
+
class To_Ruby<std::optional<T>>
|
205
|
+
{
|
206
|
+
public:
|
207
|
+
static VALUE convert(std::optional<T>& data, bool takeOwnership = false)
|
208
|
+
{
|
209
|
+
if (data.has_value())
|
210
|
+
{
|
211
|
+
return To_Ruby<T>().convert(data.value());
|
212
|
+
}
|
213
|
+
else
|
214
|
+
{
|
215
|
+
return Qnil;
|
216
|
+
}
|
217
|
+
}
|
218
|
+
};
|
219
|
+
|
220
|
+
template<typename T>
|
221
|
+
class To_Ruby<std::optional<T>&>
|
222
|
+
{
|
223
|
+
public:
|
224
|
+
static VALUE convert(std::optional<T>& data, bool takeOwnership = false)
|
225
|
+
{
|
226
|
+
if (data.has_value())
|
227
|
+
{
|
228
|
+
return To_Ruby<T>().convert(data.value());
|
229
|
+
}
|
230
|
+
else
|
231
|
+
{
|
232
|
+
return Qnil;
|
233
|
+
}
|
234
|
+
}
|
235
|
+
};
|
236
|
+
|
237
|
+
template<typename T>
|
238
|
+
class From_Ruby<std::optional<T>>
|
239
|
+
{
|
240
|
+
public:
|
241
|
+
std::optional<T> convert(VALUE value)
|
242
|
+
{
|
243
|
+
if (value == Qnil)
|
244
|
+
{
|
245
|
+
return std::nullopt;
|
246
|
+
}
|
247
|
+
else
|
248
|
+
{
|
249
|
+
return From_Ruby<T>().convert(value);
|
250
|
+
}
|
251
|
+
}
|
252
|
+
};
|
253
|
+
|
254
|
+
template<typename T>
|
255
|
+
class From_Ruby<std::optional<T>&>
|
256
|
+
{
|
257
|
+
public:
|
258
|
+
std::optional<T>& convert(VALUE value)
|
259
|
+
{
|
260
|
+
if (value == Qnil)
|
261
|
+
{
|
262
|
+
this->converted_ = std::nullopt;
|
263
|
+
}
|
264
|
+
else
|
265
|
+
{
|
266
|
+
this->converted_ = From_Ruby<T>().convert(value);
|
267
|
+
}
|
268
|
+
return this->converted_;
|
269
|
+
}
|
270
|
+
|
271
|
+
private:
|
272
|
+
std::optional<T> converted_;
|
273
|
+
};
|
274
|
+
}
|
275
|
+
|
276
|
+
// ========= pair.hpp =========
|
277
|
+
|
278
|
+
|
279
|
+
namespace Rice
|
280
|
+
{
|
281
|
+
template<typename T>
|
282
|
+
Data_Type<T> define_pair(std::string name);
|
283
|
+
|
284
|
+
template<typename T>
|
285
|
+
Data_Type<T> define_pair_under(Object module, std::string name);
|
286
|
+
}
|
287
|
+
|
288
|
+
|
289
|
+
// --------- pair.ipp ---------
|
290
|
+
|
291
|
+
#include <sstream>
|
292
|
+
#include <stdexcept>
|
293
|
+
#include <utility>
|
294
|
+
|
295
|
+
namespace Rice
|
296
|
+
{
|
297
|
+
namespace stl
|
298
|
+
{
|
299
|
+
template<typename T>
|
300
|
+
class PairHelper
|
301
|
+
{
|
302
|
+
public:
|
303
|
+
PairHelper(Data_Type<T> klass) : klass_(klass)
|
304
|
+
{
|
305
|
+
this->define_constructor();
|
306
|
+
this->define_copyable_methods();
|
307
|
+
this->define_access_methods();
|
308
|
+
this->define_modify_methods();
|
309
|
+
this->define_to_s();
|
310
|
+
}
|
311
|
+
|
312
|
+
private:
|
313
|
+
void define_constructor()
|
314
|
+
{
|
315
|
+
klass_.define_constructor(Constructor<T, typename T::first_type&, typename T::second_type&>());
|
316
|
+
}
|
317
|
+
|
318
|
+
void define_copyable_methods()
|
319
|
+
{
|
320
|
+
if constexpr (std::is_copy_constructible_v<typename T::first_type> && std::is_copy_constructible_v<typename T::second_type>)
|
321
|
+
{
|
322
|
+
klass_.define_method("copy", [](T& self) -> T
|
323
|
+
{
|
324
|
+
return self;
|
325
|
+
});
|
326
|
+
}
|
327
|
+
else
|
328
|
+
{
|
329
|
+
klass_.define_method("copy", [](T& self) -> T
|
330
|
+
{
|
331
|
+
throw std::runtime_error("Cannot copy pair with non-copy constructible types");
|
332
|
+
return self;
|
333
|
+
});
|
334
|
+
}
|
335
|
+
}
|
336
|
+
|
337
|
+
void define_access_methods()
|
338
|
+
{
|
339
|
+
// Access methods
|
340
|
+
klass_.define_method("first", [](T& self) -> typename T::first_type&
|
341
|
+
{
|
342
|
+
return self.first;
|
343
|
+
})
|
344
|
+
.define_method("second", [](T& self) -> typename T::second_type&
|
345
|
+
{
|
346
|
+
return self.second;
|
347
|
+
});
|
348
|
+
}
|
349
|
+
|
350
|
+
void define_modify_methods()
|
351
|
+
{
|
352
|
+
// Access methods
|
353
|
+
klass_.define_method("first=", [](T& self, typename T::first_type& value) -> typename T::first_type&
|
354
|
+
{
|
355
|
+
self.first = value;
|
356
|
+
return self.first;
|
357
|
+
})
|
358
|
+
.define_method("second=", [](T& self, typename T::second_type& value) -> typename T::second_type&
|
359
|
+
{
|
360
|
+
self.second = value;
|
361
|
+
return self.second;
|
362
|
+
});
|
363
|
+
}
|
364
|
+
|
365
|
+
void define_to_s()
|
366
|
+
{
|
367
|
+
if constexpr (detail::is_ostreamable_v<typename T::first_type> && detail::is_ostreamable_v<typename T::second_type>)
|
368
|
+
{
|
369
|
+
klass_.define_method("to_s", [](const T& self)
|
370
|
+
{
|
371
|
+
std::stringstream stream;
|
372
|
+
stream << "[" << self.first << ", " << self.second << "]";
|
373
|
+
return stream.str();
|
374
|
+
});
|
375
|
+
}
|
376
|
+
else
|
377
|
+
{
|
378
|
+
klass_.define_method("to_s", [](const T& self)
|
379
|
+
{
|
380
|
+
return "[Not printable]";
|
381
|
+
});
|
382
|
+
}
|
383
|
+
}
|
384
|
+
|
385
|
+
private:
|
386
|
+
Data_Type<T> klass_;
|
387
|
+
};
|
388
|
+
} // namespace
|
389
|
+
|
390
|
+
template<typename T>
|
391
|
+
Data_Type<T> define_pair_under(Object module, std::string name)
|
392
|
+
{
|
393
|
+
if (detail::TypeRegistry::isDefined<T>())
|
394
|
+
{
|
395
|
+
return Data_Type<T>(Data_Type<T>());
|
396
|
+
}
|
397
|
+
|
398
|
+
Data_Type<T> result = define_class_under<detail::intrinsic_type<T>>(module, name.c_str());
|
399
|
+
stl::PairHelper helper(result);
|
400
|
+
return result;
|
401
|
+
}
|
402
|
+
|
403
|
+
template<typename T>
|
404
|
+
Data_Type<T> define_pair(std::string name)
|
405
|
+
{
|
406
|
+
if (detail::TypeRegistry::isDefined<T>())
|
407
|
+
{
|
408
|
+
return Data_Type<T>(Data_Type<T>());
|
409
|
+
}
|
410
|
+
|
411
|
+
Data_Type<T> result = define_class<detail::intrinsic_type<T>>(name.c_str());
|
412
|
+
stl::PairHelper<T> helper(result);
|
413
|
+
return result;
|
414
|
+
}
|
415
|
+
|
416
|
+
template<typename T>
|
417
|
+
Data_Type<T> define_pair_auto()
|
418
|
+
{
|
419
|
+
std::string klassName = detail::makeClassName(typeid(T));
|
420
|
+
Module rb_mRice = define_module("Rice");
|
421
|
+
Module rb_mpair = define_module_under(rb_mRice, "Std");
|
422
|
+
return define_pair_under<T>(rb_mpair, klassName);
|
423
|
+
}
|
424
|
+
|
425
|
+
namespace detail
|
426
|
+
{
|
427
|
+
template<typename T1, typename T2>
|
428
|
+
struct Type<std::pair<T1, T2>>
|
429
|
+
{
|
430
|
+
static bool verify()
|
431
|
+
{
|
432
|
+
Type<T1>::verify();
|
433
|
+
Type<T2>::verify();
|
434
|
+
|
435
|
+
if (!detail::TypeRegistry::isDefined<std::pair<T1, T2>>())
|
436
|
+
{
|
437
|
+
define_pair_auto<std::pair<T1, T2>>();
|
438
|
+
}
|
439
|
+
|
440
|
+
return true;
|
441
|
+
}
|
442
|
+
};
|
443
|
+
}
|
444
|
+
}
|
445
|
+
|
446
|
+
|
447
|
+
|
448
|
+
// ========= smart_ptr.hpp =========
|
449
|
+
|
450
|
+
|
451
|
+
namespace Rice::detail
|
452
|
+
{
|
453
|
+
template <template <typename, typename...> typename SmartPointer_T, typename...Arg_Ts>
|
454
|
+
class WrapperSmartPointer : public Wrapper
|
455
|
+
{
|
456
|
+
public:
|
457
|
+
WrapperSmartPointer(SmartPointer_T<Arg_Ts...>& data);
|
458
|
+
void* get() override;
|
459
|
+
SmartPointer_T<Arg_Ts...>& data();
|
460
|
+
|
461
|
+
private:
|
462
|
+
SmartPointer_T<Arg_Ts...> data_;
|
463
|
+
};
|
464
|
+
}
|
465
|
+
|
466
|
+
|
467
|
+
// --------- smart_ptr.ipp ---------
|
468
|
+
|
469
|
+
#include <assert.h>
|
470
|
+
#include <memory>
|
471
|
+
|
472
|
+
namespace Rice::detail
|
473
|
+
{
|
474
|
+
// ---- WrapperSmartPointer ------
|
475
|
+
template <template <typename, typename...> typename SmartPointer_T, typename...Arg_Ts>
|
476
|
+
inline WrapperSmartPointer<SmartPointer_T, Arg_Ts...>::WrapperSmartPointer(SmartPointer_T<Arg_Ts...>& data)
|
477
|
+
: data_(std::move(data))
|
478
|
+
{
|
479
|
+
}
|
480
|
+
|
481
|
+
template <template <typename, typename...> typename SmartPointer_T, typename...Arg_Ts>
|
482
|
+
inline void* WrapperSmartPointer<SmartPointer_T, Arg_Ts...>::get()
|
483
|
+
{
|
484
|
+
return (void*)this->data_.get();
|
485
|
+
}
|
486
|
+
|
487
|
+
template <template <typename, typename...> typename SmartPointer_T, typename...Arg_Ts>
|
488
|
+
inline SmartPointer_T<Arg_Ts...>& WrapperSmartPointer<SmartPointer_T, Arg_Ts...>::data()
|
489
|
+
{
|
490
|
+
return data_;
|
491
|
+
}
|
492
|
+
|
493
|
+
// ---- unique_ptr ------
|
494
|
+
template <typename T>
|
495
|
+
class To_Ruby<std::unique_ptr<T>>
|
496
|
+
{
|
497
|
+
public:
|
498
|
+
VALUE convert(std::unique_ptr<T>& data)
|
499
|
+
{
|
500
|
+
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::TypeRegistry::figureType<T>(*data);
|
501
|
+
|
502
|
+
// Use custom wrapper type
|
503
|
+
using Wrapper_T = WrapperSmartPointer<std::unique_ptr, T>;
|
504
|
+
return detail::wrap<std::unique_ptr<T>, Wrapper_T>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
505
|
+
}
|
506
|
+
};
|
507
|
+
|
508
|
+
template <typename T>
|
509
|
+
class From_Ruby<std::unique_ptr<T>&>
|
510
|
+
{
|
511
|
+
public:
|
512
|
+
std::unique_ptr<T>& convert(VALUE value)
|
513
|
+
{
|
514
|
+
Wrapper* wrapper = detail::getWrapper(value, Data_Type<T>::rb_type());
|
515
|
+
|
516
|
+
using Wrapper_T = WrapperSmartPointer<std::unique_ptr, T>;
|
517
|
+
Wrapper_T* smartWrapper = dynamic_cast<Wrapper_T*>(wrapper);
|
518
|
+
if (!smartWrapper)
|
519
|
+
{
|
520
|
+
std::string message = "Invalid smart pointer wrapper";
|
521
|
+
throw std::runtime_error(message.c_str());
|
522
|
+
}
|
523
|
+
return smartWrapper->data();
|
524
|
+
}
|
525
|
+
};
|
526
|
+
|
527
|
+
template<typename T>
|
528
|
+
struct Type<std::unique_ptr<T>>
|
529
|
+
{
|
530
|
+
static bool verify()
|
531
|
+
{
|
532
|
+
return Type<T>::verify();
|
533
|
+
}
|
534
|
+
};
|
535
|
+
|
536
|
+
// ----- shared_ptr -------------
|
537
|
+
template <typename T>
|
538
|
+
class To_Ruby<std::shared_ptr<T>>
|
539
|
+
{
|
540
|
+
public:
|
541
|
+
VALUE convert(std::shared_ptr<T>& data)
|
542
|
+
{
|
543
|
+
std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::TypeRegistry::figureType<T>(*data);
|
544
|
+
|
545
|
+
// Use custom wrapper type
|
546
|
+
using Wrapper_T = WrapperSmartPointer<std::shared_ptr, T>;
|
547
|
+
return detail::wrap<std::shared_ptr<T>, Wrapper_T>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
|
548
|
+
}
|
549
|
+
};
|
550
|
+
|
551
|
+
template <typename T>
|
552
|
+
class From_Ruby<std::shared_ptr<T>>
|
553
|
+
{
|
554
|
+
public:
|
555
|
+
std::shared_ptr<T> convert(VALUE value)
|
556
|
+
{
|
557
|
+
Wrapper* wrapper = detail::getWrapper(value, Data_Type<T>::rb_type());
|
558
|
+
|
559
|
+
using Wrapper_T = WrapperSmartPointer<std::shared_ptr, T>;
|
560
|
+
Wrapper_T* smartWrapper = dynamic_cast<Wrapper_T*>(wrapper);
|
561
|
+
if (!smartWrapper)
|
562
|
+
{
|
563
|
+
std::string message = "Invalid smart pointer wrapper";
|
564
|
+
throw std::runtime_error(message.c_str());
|
565
|
+
}
|
566
|
+
return smartWrapper->data();
|
567
|
+
}
|
568
|
+
};
|
569
|
+
|
570
|
+
template <typename T>
|
571
|
+
class From_Ruby<std::shared_ptr<T>&>
|
572
|
+
{
|
573
|
+
public:
|
574
|
+
std::shared_ptr<T>& convert(VALUE value)
|
575
|
+
{
|
576
|
+
Wrapper* wrapper = detail::getWrapper(value, Data_Type<T>::rb_type());
|
577
|
+
|
578
|
+
using Wrapper_T = WrapperSmartPointer<std::shared_ptr, T>;
|
579
|
+
Wrapper_T* smartWrapper = dynamic_cast<Wrapper_T*>(wrapper);
|
580
|
+
if (!smartWrapper)
|
581
|
+
{
|
582
|
+
std::string message = "Invalid smart pointer wrapper";
|
583
|
+
throw std::runtime_error(message.c_str());
|
584
|
+
}
|
585
|
+
return smartWrapper->data();
|
586
|
+
}
|
587
|
+
};
|
588
|
+
|
589
|
+
template<typename T>
|
590
|
+
struct Type<std::shared_ptr<T>>
|
591
|
+
{
|
592
|
+
static bool verify()
|
593
|
+
{
|
594
|
+
return Type<T>::verify();
|
595
|
+
}
|
596
|
+
};
|
597
|
+
}
|
598
|
+
|
599
|
+
// ========= vector.hpp =========
|
600
|
+
|
601
|
+
|
602
|
+
namespace Rice
|
603
|
+
{
|
604
|
+
template<typename T>
|
605
|
+
Data_Type<T> define_vector(std::string name);
|
606
|
+
|
607
|
+
template<typename T>
|
608
|
+
Data_Type<T> define_vector_under(Object module, std::string name);
|
609
|
+
}
|
610
|
+
|
611
|
+
|
612
|
+
// --------- vector.ipp ---------
|
613
|
+
|
614
|
+
#include <sstream>
|
615
|
+
#include <stdexcept>
|
616
|
+
#include <vector>
|
617
|
+
|
618
|
+
namespace Rice
|
619
|
+
{
|
620
|
+
namespace stl
|
621
|
+
{
|
622
|
+
template<typename T>
|
623
|
+
class VectorHelper
|
624
|
+
{
|
625
|
+
using Value_T = typename T::value_type;
|
626
|
+
using Size_T = typename T::size_type;
|
627
|
+
using Difference_T = typename T::difference_type;
|
628
|
+
|
629
|
+
public:
|
630
|
+
VectorHelper(Data_Type<T> klass) : klass_(klass)
|
631
|
+
{
|
632
|
+
this->define_constructor();
|
633
|
+
this->define_copyable_methods();
|
634
|
+
this->define_constructable_methods();
|
635
|
+
this->define_capacity_methods();
|
636
|
+
this->define_access_methods();
|
637
|
+
this->define_comparable_methods();
|
638
|
+
this->define_modify_methods();
|
639
|
+
this->define_to_s();
|
640
|
+
this->define_enumerable();
|
641
|
+
}
|
642
|
+
|
643
|
+
private:
|
644
|
+
|
645
|
+
// Helper method to translate Ruby indices to vector indices
|
646
|
+
Difference_T normalizeIndex(Size_T size, Difference_T index, bool enforceBounds = false)
|
647
|
+
{
|
648
|
+
// Negative indices mean count from the right. Note that negative indices
|
649
|
+
// wrap around!
|
650
|
+
if (index < 0)
|
651
|
+
{
|
652
|
+
index = ((-index) % size);
|
653
|
+
index = index > 0 ? size - index : index;
|
654
|
+
}
|
655
|
+
|
656
|
+
if (enforceBounds && (index < 0 || index >= (Difference_T)size))
|
657
|
+
{
|
658
|
+
throw std::out_of_range("Invalid index: " + std::to_string(index));
|
659
|
+
}
|
660
|
+
|
661
|
+
return index;
|
662
|
+
};
|
663
|
+
|
664
|
+
void define_constructor()
|
665
|
+
{
|
666
|
+
klass_.define_constructor(Constructor<T>());
|
667
|
+
}
|
668
|
+
|
669
|
+
void define_copyable_methods()
|
670
|
+
{
|
671
|
+
if constexpr (std::is_copy_constructible_v<Value_T>)
|
672
|
+
{
|
673
|
+
klass_.define_method("copy", [](T& self) -> T
|
674
|
+
{
|
675
|
+
return self;
|
676
|
+
});
|
677
|
+
}
|
678
|
+
else
|
679
|
+
{
|
680
|
+
klass_.define_method("copy", [](T& self) -> T
|
681
|
+
{
|
682
|
+
throw std::runtime_error("Cannot copy vectors with non-copy constructible types");
|
683
|
+
return self;
|
684
|
+
});
|
685
|
+
}
|
686
|
+
}
|
687
|
+
|
688
|
+
void define_constructable_methods()
|
689
|
+
{
|
690
|
+
if constexpr (std::is_default_constructible_v<Value_T>)
|
691
|
+
{
|
692
|
+
klass_.define_method("resize", static_cast<void (T::*)(const size_t)>(&T::resize));
|
693
|
+
}
|
694
|
+
else
|
695
|
+
{
|
696
|
+
klass_.define_method("resize", [](const T& self, Size_T newSize)
|
697
|
+
{
|
698
|
+
// Do nothing
|
699
|
+
});
|
700
|
+
}
|
701
|
+
}
|
702
|
+
|
703
|
+
void define_capacity_methods()
|
704
|
+
{
|
705
|
+
klass_.define_method("empty?", &T::empty)
|
706
|
+
.define_method("capacity", &T::capacity)
|
707
|
+
.define_method("max_size", &T::max_size)
|
708
|
+
.define_method("reserve", &T::reserve)
|
709
|
+
.define_method("size", &T::size);
|
710
|
+
|
711
|
+
rb_define_alias(klass_, "count", "size");
|
712
|
+
rb_define_alias(klass_, "length", "size");
|
713
|
+
//detail::protect(rb_define_alias, klass_, "count", "size");
|
714
|
+
//detail::protect(rb_define_alias, klass_, "length", "size");
|
715
|
+
}
|
716
|
+
|
717
|
+
void define_access_methods()
|
718
|
+
{
|
719
|
+
// Access methods
|
720
|
+
klass_.define_method("first", [](const T& self) -> std::optional<Value_T>
|
721
|
+
{
|
722
|
+
if (self.size() > 0)
|
723
|
+
{
|
724
|
+
return self.front();
|
725
|
+
}
|
726
|
+
else
|
727
|
+
{
|
728
|
+
return std::nullopt;
|
729
|
+
}
|
730
|
+
})
|
731
|
+
.define_method("last", [](const T& self) -> std::optional<Value_T>
|
732
|
+
{
|
733
|
+
if (self.size() > 0)
|
734
|
+
{
|
735
|
+
return self.back();
|
736
|
+
}
|
737
|
+
else
|
738
|
+
{
|
739
|
+
return std::nullopt;
|
740
|
+
}
|
741
|
+
})
|
742
|
+
.define_method("[]", [this](const T& self, Difference_T index) -> std::optional<Value_T>
|
743
|
+
{
|
744
|
+
index = normalizeIndex(self.size(), index);
|
745
|
+
if (index < 0 || index >= (Difference_T)self.size())
|
746
|
+
{
|
747
|
+
return std::nullopt;
|
748
|
+
}
|
749
|
+
else
|
750
|
+
{
|
751
|
+
return self[index];
|
752
|
+
}
|
753
|
+
});
|
754
|
+
|
755
|
+
rb_define_alias(klass_, "at", "[]");
|
756
|
+
}
|
757
|
+
|
758
|
+
// Methods that require Value_T to support operator==
|
759
|
+
void define_comparable_methods()
|
760
|
+
{
|
761
|
+
if constexpr (detail::is_comparable_v<Value_T>)
|
762
|
+
{
|
763
|
+
klass_.define_method("delete", [](T& self, Value_T& element) -> std::optional<Value_T>
|
764
|
+
{
|
765
|
+
auto iter = std::find(self.begin(), self.end(), element);
|
766
|
+
if (iter == self.end())
|
767
|
+
{
|
768
|
+
return std::nullopt;
|
769
|
+
}
|
770
|
+
else
|
771
|
+
{
|
772
|
+
Value_T result = *iter;
|
773
|
+
self.erase(iter);
|
774
|
+
return result;
|
775
|
+
}
|
776
|
+
})
|
777
|
+
.define_method("include?", [](T& self, Value_T& element)
|
778
|
+
{
|
779
|
+
return std::find(self.begin(), self.end(), element) != self.end();
|
780
|
+
})
|
781
|
+
.define_method("index", [](T& self, Value_T& element) -> std::optional<Difference_T>
|
782
|
+
{
|
783
|
+
auto iter = std::find(self.begin(), self.end(), element);
|
784
|
+
if (iter == self.end())
|
785
|
+
{
|
786
|
+
return std::nullopt;
|
787
|
+
}
|
788
|
+
else
|
789
|
+
{
|
790
|
+
return iter - self.begin();
|
791
|
+
}
|
792
|
+
});
|
793
|
+
}
|
794
|
+
else
|
795
|
+
{
|
796
|
+
klass_.define_method("delete", [](T& self, Value_T& element) -> std::optional<Value_T>
|
797
|
+
{
|
798
|
+
return std::nullopt;
|
799
|
+
})
|
800
|
+
.define_method("include?", [](const T& self, Value_T& element)
|
801
|
+
{
|
802
|
+
return false;
|
803
|
+
})
|
804
|
+
.define_method("index", [](const T& self, Value_T& element) -> std::optional<Difference_T>
|
805
|
+
{
|
806
|
+
return std::nullopt;
|
807
|
+
});
|
808
|
+
}
|
809
|
+
}
|
810
|
+
|
811
|
+
void define_modify_methods()
|
812
|
+
{
|
813
|
+
klass_.define_method("clear", &T::clear)
|
814
|
+
.define_method("delete_at", [](T& self, const size_t& pos)
|
815
|
+
{
|
816
|
+
auto iter = self.begin() + pos;
|
817
|
+
Value_T result = *iter;
|
818
|
+
self.erase(iter);
|
819
|
+
return result;
|
820
|
+
})
|
821
|
+
.define_method("insert", [this](T& self, Difference_T index, Value_T& element) -> T&
|
822
|
+
{
|
823
|
+
index = normalizeIndex(self.size(), index, true);
|
824
|
+
auto iter = self.begin() + index;
|
825
|
+
self.insert(iter, element);
|
826
|
+
return self;
|
827
|
+
})
|
828
|
+
.define_method("pop", [](T& self) -> std::optional<Value_T>
|
829
|
+
{
|
830
|
+
if (self.size() > 0)
|
831
|
+
{
|
832
|
+
Value_T result = self.back();
|
833
|
+
self.pop_back();
|
834
|
+
return result;
|
835
|
+
}
|
836
|
+
else
|
837
|
+
{
|
838
|
+
return std::nullopt;
|
839
|
+
}
|
840
|
+
})
|
841
|
+
.define_method("push", [](T& self, Value_T& element) -> T&
|
842
|
+
{
|
843
|
+
self.push_back(element);
|
844
|
+
return self;
|
845
|
+
})
|
846
|
+
.define_method("shrink_to_fit", &T::shrink_to_fit)
|
847
|
+
.define_method("[]=", [this](T& self, Difference_T index, Value_T& element) -> Value_T&
|
848
|
+
{
|
849
|
+
index = normalizeIndex(self.size(), index, true);
|
850
|
+
self[index] = element;
|
851
|
+
return element;
|
852
|
+
});
|
853
|
+
|
854
|
+
rb_define_alias(klass_, "<<", "push");
|
855
|
+
rb_define_alias(klass_, "append", "push");
|
856
|
+
}
|
857
|
+
|
858
|
+
void define_enumerable()
|
859
|
+
{
|
860
|
+
// Add enumerable support
|
861
|
+
klass_.include_module(rb_mEnumerable)
|
862
|
+
.define_method("each", [](T& self) -> const T&
|
863
|
+
{
|
864
|
+
for (Value_T& item : self)
|
865
|
+
{
|
866
|
+
VALUE element = detail::To_Ruby<Value_T>().convert(item);
|
867
|
+
rb_yield(element);
|
868
|
+
}
|
869
|
+
return self;
|
870
|
+
});
|
871
|
+
}
|
872
|
+
|
873
|
+
void define_to_s()
|
874
|
+
{
|
875
|
+
if constexpr (detail::is_ostreamable_v<Value_T>)
|
876
|
+
{
|
877
|
+
klass_.define_method("to_s", [](const T& self)
|
878
|
+
{
|
879
|
+
auto iter = self.begin();
|
880
|
+
auto finish = self.size() > 1000 ? self.begin() + 1000 : self.end();
|
881
|
+
|
882
|
+
std::stringstream stream;
|
883
|
+
stream << "[";
|
884
|
+
|
885
|
+
for (; iter != finish; iter++)
|
886
|
+
{
|
887
|
+
if (iter == self.begin())
|
888
|
+
{
|
889
|
+
stream << *iter;
|
890
|
+
}
|
891
|
+
else
|
892
|
+
{
|
893
|
+
stream << ", " << *iter;
|
894
|
+
}
|
895
|
+
}
|
896
|
+
|
897
|
+
stream << "]";
|
898
|
+
return stream.str();
|
899
|
+
});
|
900
|
+
}
|
901
|
+
else
|
902
|
+
{
|
903
|
+
klass_.define_method("to_s", [](const T& self)
|
904
|
+
{
|
905
|
+
return "[Not printable]";
|
906
|
+
});
|
907
|
+
}
|
908
|
+
}
|
909
|
+
|
910
|
+
private:
|
911
|
+
Data_Type<T> klass_;
|
912
|
+
};
|
913
|
+
} // namespace
|
914
|
+
|
915
|
+
template<typename T>
|
916
|
+
Data_Type<T> define_vector_under(Object module, std::string name)
|
917
|
+
{
|
918
|
+
if (detail::TypeRegistry::isDefined<T>())
|
919
|
+
{
|
920
|
+
return Data_Type<T>(Data_Type<T>());
|
921
|
+
}
|
922
|
+
|
923
|
+
Data_Type<T> result = define_class_under<detail::intrinsic_type<T>>(module, name.c_str());
|
924
|
+
stl::VectorHelper helper(result);
|
925
|
+
return result;
|
926
|
+
}
|
927
|
+
|
928
|
+
template<typename T>
|
929
|
+
Data_Type<T> define_vector(std::string name)
|
930
|
+
{
|
931
|
+
if (detail::TypeRegistry::isDefined<T>())
|
932
|
+
{
|
933
|
+
return Data_Type<T>(Data_Type<T>());
|
934
|
+
}
|
935
|
+
|
936
|
+
Data_Type<T> result = define_class<detail::intrinsic_type<T>>(name.c_str());
|
937
|
+
stl::VectorHelper<T> helper(result);
|
938
|
+
return result;
|
939
|
+
}
|
940
|
+
|
941
|
+
template<typename T>
|
942
|
+
Data_Type<T> define_vector_auto()
|
943
|
+
{
|
944
|
+
std::string klassName = detail::makeClassName(typeid(T));
|
945
|
+
Module rb_mRice = define_module("Rice");
|
946
|
+
Module rb_mVector = define_module_under(rb_mRice, "Std");
|
947
|
+
return define_vector_under<T>(rb_mVector, klassName);
|
948
|
+
}
|
949
|
+
|
950
|
+
namespace detail
|
951
|
+
{
|
952
|
+
template<typename T>
|
953
|
+
struct Type<std::vector<T>>
|
954
|
+
{
|
955
|
+
static bool verify()
|
956
|
+
{
|
957
|
+
Type<T>::verify();
|
958
|
+
|
959
|
+
if (!detail::TypeRegistry::isDefined<std::vector<T>>())
|
960
|
+
{
|
961
|
+
define_vector_auto<std::vector<T>>();
|
962
|
+
}
|
963
|
+
|
964
|
+
return true;
|
965
|
+
}
|
966
|
+
};
|
967
|
+
|
968
|
+
template<typename T>
|
969
|
+
std::vector<T> vectorFromArray(VALUE value)
|
970
|
+
{
|
971
|
+
size_t length = protect(rb_array_len, value);
|
972
|
+
std::vector<T> result(length);
|
973
|
+
|
974
|
+
for (long i = 0; i < length; i++)
|
975
|
+
{
|
976
|
+
VALUE element = protect(rb_ary_entry, value, i);
|
977
|
+
result[i] = From_Ruby<T>().convert(element);
|
978
|
+
}
|
979
|
+
|
980
|
+
return result;
|
981
|
+
}
|
982
|
+
|
983
|
+
template<typename T>
|
984
|
+
class From_Ruby<std::vector<T>>
|
985
|
+
{
|
986
|
+
public:
|
987
|
+
From_Ruby() = default;
|
988
|
+
|
989
|
+
explicit From_Ruby(Arg * arg) : arg_(arg)
|
990
|
+
{
|
991
|
+
}
|
992
|
+
|
993
|
+
std::vector<T> convert(VALUE value)
|
994
|
+
{
|
995
|
+
switch (rb_type(value))
|
996
|
+
{
|
997
|
+
case T_DATA:
|
998
|
+
{
|
999
|
+
// This is a wrapped vector (hopefully!)
|
1000
|
+
return *Data_Object<std::vector<T>>::from_ruby(value);
|
1001
|
+
}
|
1002
|
+
case T_ARRAY:
|
1003
|
+
{
|
1004
|
+
// If this an Ruby array and the vector type is copyable
|
1005
|
+
if constexpr (std::is_default_constructible_v<T>)
|
1006
|
+
{
|
1007
|
+
return vectorFromArray<T>(value);
|
1008
|
+
}
|
1009
|
+
}
|
1010
|
+
case T_NIL:
|
1011
|
+
{
|
1012
|
+
if (this->arg_ && this->arg_->hasDefaultValue())
|
1013
|
+
{
|
1014
|
+
return this->arg_->template defaultValue<std::vector<T>>();
|
1015
|
+
}
|
1016
|
+
}
|
1017
|
+
default:
|
1018
|
+
{
|
1019
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
|
1020
|
+
detail::protect(rb_obj_classname, value), "std::vector");
|
1021
|
+
}
|
1022
|
+
}
|
1023
|
+
}
|
1024
|
+
|
1025
|
+
private:
|
1026
|
+
Arg* arg_ = nullptr;
|
1027
|
+
};
|
1028
|
+
|
1029
|
+
template<typename T>
|
1030
|
+
class From_Ruby<std::vector<T>&>
|
1031
|
+
{
|
1032
|
+
public:
|
1033
|
+
From_Ruby() = default;
|
1034
|
+
|
1035
|
+
explicit From_Ruby(Arg * arg) : arg_(arg)
|
1036
|
+
{
|
1037
|
+
}
|
1038
|
+
|
1039
|
+
std::vector<T>& convert(VALUE value)
|
1040
|
+
{
|
1041
|
+
switch (rb_type(value))
|
1042
|
+
{
|
1043
|
+
case T_DATA:
|
1044
|
+
{
|
1045
|
+
// This is a wrapped vector (hopefully!)
|
1046
|
+
return *Data_Object<std::vector<T>>::from_ruby(value);
|
1047
|
+
}
|
1048
|
+
case T_ARRAY:
|
1049
|
+
{
|
1050
|
+
// If this an Ruby array and the vector type is copyable
|
1051
|
+
if constexpr (std::is_default_constructible_v<T>)
|
1052
|
+
{
|
1053
|
+
this->converted_ = vectorFromArray<T>(value);
|
1054
|
+
return this->converted_;
|
1055
|
+
}
|
1056
|
+
}
|
1057
|
+
case T_NIL:
|
1058
|
+
{
|
1059
|
+
if (this->arg_ && this->arg_->hasDefaultValue())
|
1060
|
+
{
|
1061
|
+
return this->arg_->template defaultValue<std::vector<T>>();
|
1062
|
+
}
|
1063
|
+
}
|
1064
|
+
default:
|
1065
|
+
{
|
1066
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
|
1067
|
+
detail::protect(rb_obj_classname, value), "std::vector");
|
1068
|
+
}
|
1069
|
+
}
|
1070
|
+
}
|
1071
|
+
|
1072
|
+
private:
|
1073
|
+
Arg* arg_ = nullptr;
|
1074
|
+
std::vector<T> converted_;
|
1075
|
+
};
|
1076
|
+
|
1077
|
+
template<typename T>
|
1078
|
+
class From_Ruby<std::vector<T>*>
|
1079
|
+
{
|
1080
|
+
public:
|
1081
|
+
std::vector<T>* convert(VALUE value)
|
1082
|
+
{
|
1083
|
+
switch (rb_type(value))
|
1084
|
+
{
|
1085
|
+
case T_DATA:
|
1086
|
+
{
|
1087
|
+
// This is a wrapped vector (hopefully!)
|
1088
|
+
return Data_Object<std::vector<T>>::from_ruby(value);
|
1089
|
+
}
|
1090
|
+
case T_ARRAY:
|
1091
|
+
{
|
1092
|
+
// If this an Ruby array and the vector type is copyable
|
1093
|
+
if constexpr (std::is_default_constructible_v<T>)
|
1094
|
+
{
|
1095
|
+
this->converted_ = vectorFromArray<T>(value);
|
1096
|
+
return &this->converted_;
|
1097
|
+
}
|
1098
|
+
}
|
1099
|
+
default:
|
1100
|
+
{
|
1101
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
|
1102
|
+
detail::protect(rb_obj_classname, value), "std::vector");
|
1103
|
+
}
|
1104
|
+
}
|
1105
|
+
}
|
1106
|
+
|
1107
|
+
private:
|
1108
|
+
std::vector<T> converted_;
|
1109
|
+
};
|
1110
|
+
}
|
1111
|
+
}
|
1112
|
+
|
1113
|
+
#endif // Rice__stl__hpp_
|