rice 1.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.
- data/COPYING +23 -0
- data/Doxyfile +1253 -0
- data/Makefile.am +26 -0
- data/Makefile.in +736 -0
- data/README +881 -0
- data/README.mingw +8 -0
- data/bootstrap +8 -0
- data/config.guess +1535 -0
- data/config.sub +1644 -0
- data/configure +7310 -0
- data/configure.ac +48 -0
- data/depcomp +584 -0
- data/doxygen.ac +314 -0
- data/doxygen.am +186 -0
- data/install-sh +507 -0
- data/missing +367 -0
- data/post-autoconf.rb +22 -0
- data/post-automake.rb +28 -0
- data/rice/Address_Registration_Guard.hpp +7 -0
- data/rice/Address_Registration_Guard.ipp +34 -0
- data/rice/Address_Registration_Guard_defn.hpp +65 -0
- data/rice/Allocation_Strategies.hpp +37 -0
- data/rice/Array.hpp +220 -0
- data/rice/Array.ipp +262 -0
- data/rice/Builtin_Object.hpp +8 -0
- data/rice/Builtin_Object.ipp +50 -0
- data/rice/Builtin_Object_defn.hpp +51 -0
- data/rice/Class.cpp +57 -0
- data/rice/Class.hpp +8 -0
- data/rice/Class.ipp +4 -0
- data/rice/Class_defn.hpp +83 -0
- data/rice/Constructor.hpp +189 -0
- data/rice/Critical_Guard.hpp +34 -0
- data/rice/Critical_Guard.ipp +20 -0
- data/rice/Data_Object.hpp +127 -0
- data/rice/Data_Object.ipp +129 -0
- data/rice/Data_Type.cpp +21 -0
- data/rice/Data_Type.hpp +8 -0
- data/rice/Data_Type.ipp +227 -0
- data/rice/Data_Type_defn.hpp +219 -0
- data/rice/Data_Type_fwd.hpp +12 -0
- data/rice/Enum.hpp +118 -0
- data/rice/Enum.ipp +246 -0
- data/rice/Exception.cpp +59 -0
- data/rice/Exception.hpp +69 -0
- data/rice/Exception_Base.hpp +30 -0
- data/rice/Exception_Base.ipp +11 -0
- data/rice/Hash.hpp +206 -0
- data/rice/Hash.ipp +336 -0
- data/rice/Identifier.cpp +8 -0
- data/rice/Identifier.hpp +50 -0
- data/rice/Identifier.ipp +33 -0
- data/rice/Jump_Tag.hpp +24 -0
- data/rice/Makefile.am +112 -0
- data/rice/Makefile.in +675 -0
- data/rice/Module.cpp +75 -0
- data/rice/Module.hpp +8 -0
- data/rice/Module.ipp +6 -0
- data/rice/Module_defn.hpp +87 -0
- data/rice/Module_impl.hpp +237 -0
- data/rice/Module_impl.ipp +302 -0
- data/rice/Object.cpp +153 -0
- data/rice/Object.hpp +8 -0
- data/rice/Object.ipp +19 -0
- data/rice/Object_defn.hpp +183 -0
- data/rice/Require_Guard.hpp +21 -0
- data/rice/String.cpp +93 -0
- data/rice/String.hpp +88 -0
- data/rice/Struct.cpp +117 -0
- data/rice/Struct.hpp +162 -0
- data/rice/Struct.ipp +26 -0
- data/rice/Symbol.cpp +25 -0
- data/rice/Symbol.hpp +66 -0
- data/rice/Symbol.ipp +44 -0
- data/rice/VM.cpp +79 -0
- data/rice/VM.hpp +27 -0
- data/rice/config.hpp +23 -0
- data/rice/config.hpp.in +22 -0
- data/rice/detail/Auto_Function_Wrapper.hpp +719 -0
- data/rice/detail/Auto_Function_Wrapper.ipp +1354 -0
- data/rice/detail/Auto_Member_Function_Wrapper.hpp +685 -0
- data/rice/detail/Auto_Member_Function_Wrapper.ipp +1435 -0
- data/rice/detail/Caster.hpp +61 -0
- data/rice/detail/Exception_Handler.hpp +118 -0
- data/rice/detail/Iterator_Definer.hpp +98 -0
- data/rice/detail/Not_Copyable.hpp +25 -0
- data/rice/detail/Wrapped_Function.hpp +33 -0
- data/rice/detail/check_ruby_type.cpp +21 -0
- data/rice/detail/check_ruby_type.hpp +23 -0
- data/rice/detail/creation_funcs.hpp +45 -0
- data/rice/detail/creation_funcs.ipp +62 -0
- data/rice/detail/default_allocation_func.hpp +23 -0
- data/rice/detail/default_allocation_func.ipp +11 -0
- data/rice/detail/define_method_and_auto_wrap.hpp +27 -0
- data/rice/detail/define_method_and_auto_wrap.ipp +20 -0
- data/rice/detail/env.hpp +13 -0
- data/rice/detail/from_ruby.hpp +43 -0
- data/rice/detail/from_ruby.ipp +74 -0
- data/rice/detail/method_data.cpp +105 -0
- data/rice/detail/method_data.hpp +33 -0
- data/rice/detail/node.hpp +13 -0
- data/rice/detail/object_call.hpp +85 -0
- data/rice/detail/object_call.ipp +147 -0
- data/rice/detail/protect.cpp +27 -0
- data/rice/detail/protect.hpp +34 -0
- data/rice/detail/remove_const.hpp +21 -0
- data/rice/detail/ruby.hpp +85 -0
- data/rice/detail/rubysig.hpp +13 -0
- data/rice/detail/st.hpp +56 -0
- data/rice/detail/to_ruby.hpp +16 -0
- data/rice/detail/to_ruby.ipp +10 -0
- data/rice/detail/win32.hpp +16 -0
- data/rice/detail/wrap_function.hpp +288 -0
- data/rice/detail/wrap_function.ipp +473 -0
- data/rice/generate_code.rb +1092 -0
- data/rice/global_function.hpp +16 -0
- data/rice/global_function.ipp +11 -0
- data/rice/protect.hpp +91 -0
- data/rice/protect.ipp +803 -0
- data/rice/ruby_try_catch.hpp +86 -0
- data/rice/to_from_ruby.hpp +8 -0
- data/rice/to_from_ruby.ipp +299 -0
- data/rice/to_from_ruby_defn.hpp +71 -0
- data/ruby.ac +105 -0
- data/ruby/Makefile.am +1 -0
- data/ruby/Makefile.in +493 -0
- data/ruby/lib/Makefile.am +3 -0
- data/ruby/lib/Makefile.in +369 -0
- data/ruby/lib/mkmf-rice.rb.in +199 -0
- data/sample/Makefile.am +47 -0
- data/sample/Makefile.in +375 -0
- data/sample/enum/extconf.rb +3 -0
- data/sample/enum/sample_enum.cpp +54 -0
- data/sample/enum/test.rb +8 -0
- data/sample/inheritance/animals.cpp +98 -0
- data/sample/inheritance/extconf.rb +3 -0
- data/sample/inheritance/test.rb +7 -0
- data/sample/map/extconf.rb +3 -0
- data/sample/map/map.cpp +81 -0
- data/sample/map/test.rb +7 -0
- data/test/Makefile.am +44 -0
- data/test/Makefile.in +575 -0
- data/test/test_Address_Registration_Guard.cpp +43 -0
- data/test/test_Allocation_Strategies.cpp +77 -0
- data/test/test_Array.cpp +241 -0
- data/test/test_Builtin_Object.cpp +72 -0
- data/test/test_Class.cpp +350 -0
- data/test/test_Constructor.cpp +30 -0
- data/test/test_Critical_Guard.cpp +47 -0
- data/test/test_Data_Object.cpp +235 -0
- data/test/test_Enum.cpp +162 -0
- data/test/test_Exception.cpp +46 -0
- data/test/test_Hash.cpp +195 -0
- data/test/test_Identifier.cpp +70 -0
- data/test/test_Jump_Tag.cpp +17 -0
- data/test/test_Module.cpp +253 -0
- data/test/test_Object.cpp +148 -0
- data/test/test_String.cpp +94 -0
- data/test/test_Struct.cpp +192 -0
- data/test/test_Symbol.cpp +63 -0
- data/test/test_To_From_Ruby.cpp +281 -0
- data/test/test_VM.cpp +26 -0
- data/test/test_rice.rb +30 -0
- data/test/unittest.cpp +136 -0
- data/test/unittest.hpp +292 -0
- metadata +209 -0
|
@@ -0,0 +1,1092 @@
|
|
|
1
|
+
require 'ftools'
|
|
2
|
+
|
|
3
|
+
MAX_ARGS = 15
|
|
4
|
+
|
|
5
|
+
# ======================================================================
|
|
6
|
+
# TODO: This doesn't properly handle escaped %'s
|
|
7
|
+
def fill_template(template_str, args)
|
|
8
|
+
result = template_str.dup
|
|
9
|
+
args_not_found = args.dup
|
|
10
|
+
result.gsub!(/%\(-(\w+)\)/) do |match|
|
|
11
|
+
args_not_found.delete($1.intern)
|
|
12
|
+
''
|
|
13
|
+
end
|
|
14
|
+
result.gsub!(/%\((\w+)\)/) do |match|
|
|
15
|
+
value = args[$1.intern]
|
|
16
|
+
raise ArgumentError, "#{match} not found in argument hash" if value.nil?
|
|
17
|
+
args_not_found.delete($1.intern)
|
|
18
|
+
value
|
|
19
|
+
end
|
|
20
|
+
if args_not_found.size != 0 then
|
|
21
|
+
args_not_found.each do |name, value|
|
|
22
|
+
raise "#{name} not found in template"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
return result
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
GENERATED_FILE_WARNING = <<END
|
|
29
|
+
// This is a generated file. DO NOT EDIT!!%(-macro_name)
|
|
30
|
+
END
|
|
31
|
+
|
|
32
|
+
# TODO: shouldn't include ruby.h directly
|
|
33
|
+
HEADER_TOP = <<END
|
|
34
|
+
#ifndef %(macro_name)
|
|
35
|
+
#define %(macro_name)
|
|
36
|
+
|
|
37
|
+
#{GENERATED_FILE_WARNING}
|
|
38
|
+
|
|
39
|
+
// This causes problems with certain C++ libraries
|
|
40
|
+
#undef TYPE
|
|
41
|
+
|
|
42
|
+
END
|
|
43
|
+
HEADER_BOTTOM = <<END
|
|
44
|
+
|
|
45
|
+
#endif // %(macro_name)
|
|
46
|
+
|
|
47
|
+
END
|
|
48
|
+
|
|
49
|
+
$filenames = []
|
|
50
|
+
|
|
51
|
+
def wrap_header(
|
|
52
|
+
filename,
|
|
53
|
+
namespace=nil,
|
|
54
|
+
docstring=nil,
|
|
55
|
+
include_ipp=false,
|
|
56
|
+
head=nil,
|
|
57
|
+
tail=nil,
|
|
58
|
+
header_top=HEADER_TOP,
|
|
59
|
+
header_bottom=HEADER_BOTTOM,
|
|
60
|
+
&block)
|
|
61
|
+
$filenames << filename
|
|
62
|
+
File.open(filename, 'w') do |out|
|
|
63
|
+
namespace_str = namespace.nil? ? '' : "#{namespace}__"
|
|
64
|
+
trailer = File.basename(filename)
|
|
65
|
+
macro_name = namespace_str + trailer + '_'
|
|
66
|
+
macro_name.gsub!(/[.]/, '__')
|
|
67
|
+
macro_name.tr!(':', '_')
|
|
68
|
+
if header_top then
|
|
69
|
+
out.puts fill_template(header_top, { :macro_name => macro_name })
|
|
70
|
+
end
|
|
71
|
+
out.puts head if head
|
|
72
|
+
namespace_wrapper = namespace ? method(:wrap_namespace) : method(:null_wrap)
|
|
73
|
+
docstring_wrapper = docstring ? method(:wrap_docstring) : method(:null_wrap)
|
|
74
|
+
namespace_wrapper.call(out, namespace) do
|
|
75
|
+
docstring_wrapper.call(out, docstring) do
|
|
76
|
+
yield out
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
out.puts tail if tail
|
|
80
|
+
out.puts "#include \"#{File.basename(filename, '.hpp')}.ipp\"" if include_ipp
|
|
81
|
+
if header_bottom then
|
|
82
|
+
out.puts fill_template(header_bottom, { :macro_name => macro_name })
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def null_wrap(*args)
|
|
88
|
+
yield *args
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def wrap_docstring(out, docstring)
|
|
92
|
+
out.puts "#ifdef DOXYGEN"
|
|
93
|
+
out.puts docstring
|
|
94
|
+
out.puts "#else"
|
|
95
|
+
out.puts ""
|
|
96
|
+
yield out
|
|
97
|
+
out.puts "#endif // DOXYGEN"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def wrap_namespace(out, namespace)
|
|
101
|
+
namespaces = namespace.split('::')
|
|
102
|
+
namespaces.each do |namespace|
|
|
103
|
+
out.print "namespace #{namespace}\n{\n\n"
|
|
104
|
+
end
|
|
105
|
+
yield out
|
|
106
|
+
namespaces.reverse.each do |namespace|
|
|
107
|
+
out.print "\n} // namespace #{namespace}\n"
|
|
108
|
+
end
|
|
109
|
+
out.print "\n"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
if __FILE__ == $0 then
|
|
113
|
+
|
|
114
|
+
# ======================================================================
|
|
115
|
+
# TODO: Can I make protect accept a function or functor that
|
|
116
|
+
# doesn't return a VALUE?
|
|
117
|
+
docstring = <<END
|
|
118
|
+
/*! \\file
|
|
119
|
+
* \\brief A collection of functions (overloaded on number of
|
|
120
|
+
* arguments) for calling C functions that might raise Ruby exceptions.
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
//! Call the C function f with arguments (arg1, arg2, ...).
|
|
124
|
+
/*! E.g.:
|
|
125
|
+
* \\code
|
|
126
|
+
* VALUE x = protect(rb_ary_new);
|
|
127
|
+
* protect(rb_ary_push(x, INT2NUM(42));
|
|
128
|
+
* \\endcode
|
|
129
|
+
*
|
|
130
|
+
* Note that this function makes copies of all of its arguments; it
|
|
131
|
+
* does not take anything by reference. All of the copies are const so
|
|
132
|
+
* that protect will not work if f takes a non-const
|
|
133
|
+
* reference to any of its arguments (though you can use non-const
|
|
134
|
+
* pointers).
|
|
135
|
+
*/
|
|
136
|
+
VALUE protect(Function f, T1 arg1, T2 arg2, ...);
|
|
137
|
+
END
|
|
138
|
+
ipp_template = <<END
|
|
139
|
+
namespace detail
|
|
140
|
+
{
|
|
141
|
+
|
|
142
|
+
template<typename Fun%(typenames)>
|
|
143
|
+
class Ruby_Function_%(j)
|
|
144
|
+
{
|
|
145
|
+
public:
|
|
146
|
+
Ruby_Function_%(j)(Fun f%(member_args));
|
|
147
|
+
inline VALUE operator()();
|
|
148
|
+
static inline VALUE call(Ruby_Function_%(j) * f);
|
|
149
|
+
private:
|
|
150
|
+
Fun f_;
|
|
151
|
+
%(member_decls)
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
template<typename Fun%(typenames)>
|
|
155
|
+
inline Ruby_Function_%(j)<Fun%(types)>::
|
|
156
|
+
Ruby_Function_%(j)(Fun f%(member_args))
|
|
157
|
+
: f_(f)%(initializers)
|
|
158
|
+
{ }
|
|
159
|
+
|
|
160
|
+
template<typename Fun%(typenames)>
|
|
161
|
+
inline VALUE Ruby_Function_%(j)<Fun%(types)>::
|
|
162
|
+
operator()()
|
|
163
|
+
{
|
|
164
|
+
return f_(%(member_params));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
template<typename Fun%(typenames)>
|
|
168
|
+
inline VALUE Ruby_Function_%(j)<Fun%(types)>::
|
|
169
|
+
call(Ruby_Function_%(j) * f)
|
|
170
|
+
{
|
|
171
|
+
return (*f)();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
} // namespace detail
|
|
175
|
+
|
|
176
|
+
template<typename Fun%(typenames)>
|
|
177
|
+
inline VALUE protect(Fun fun%(args))
|
|
178
|
+
{
|
|
179
|
+
typedef detail::Ruby_Function_%(j)<Fun%(types)> RF;
|
|
180
|
+
RF f(fun%(params));
|
|
181
|
+
return detail::protect(
|
|
182
|
+
RUBY_VALUE_FUNC(RF::call),
|
|
183
|
+
reinterpret_cast<VALUE>(&f));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ---------------------------------------------------------------------
|
|
187
|
+
END
|
|
188
|
+
hpp_template = <<END
|
|
189
|
+
template<typename Fun%(typenames)>
|
|
190
|
+
VALUE protect(Fun fun%(args));
|
|
191
|
+
END
|
|
192
|
+
ipp_head = <<END
|
|
193
|
+
#include "detail/protect.hpp"
|
|
194
|
+
END
|
|
195
|
+
hpp_head = <<END
|
|
196
|
+
#include "Object_defn.hpp"
|
|
197
|
+
END
|
|
198
|
+
ipp_filename = 'protect.ipp'
|
|
199
|
+
hpp_filename = 'protect.hpp'
|
|
200
|
+
wrap_header(ipp_filename, 'Rice', nil, false, ipp_head) do |ipp|
|
|
201
|
+
wrap_header(hpp_filename, 'Rice', docstring, true, hpp_head) do |hpp|
|
|
202
|
+
for j in 0..MAX_ARGS do
|
|
203
|
+
t_array = (1..j).to_a
|
|
204
|
+
type_list = t_array.map { |x| "T#{x}" }.join(', ')
|
|
205
|
+
init_list = t_array.map { |x| "t#{x}_(t#{x})" }.join(', ')
|
|
206
|
+
param_list = t_array.map { |x| "t#{x}" }.join(', ')
|
|
207
|
+
# arg_list = t_array.map { |x| "T#{x} t#{x}" }.join(', ')
|
|
208
|
+
arg_list = t_array.map { |x| "T#{x} const & t#{x}" }.join(', ')
|
|
209
|
+
member_param_list = t_array.map { |x| "t#{x}_" }.join(', ')
|
|
210
|
+
member_decl_list =
|
|
211
|
+
# t_array.map { |x| "typename detail::Copy_Type<T#{x}>::Type const t#{x}_; " }
|
|
212
|
+
t_array.map { |x| "T#{x} const & t#{x}_; " }
|
|
213
|
+
add_comma = (j == 0) ? '' : ', '
|
|
214
|
+
typename_list =
|
|
215
|
+
(j == 0) ? '' : t_array.map { |x| "typename T#{x}" }.join(', ')
|
|
216
|
+
member_arg_list =
|
|
217
|
+
# t_array.map { |x| "typename detail::Copy_Type<T#{x}>::Type t#{x}" }.join(', ')
|
|
218
|
+
t_array.map { |x| "T#{x} const & t#{x}" }.join(', ')
|
|
219
|
+
ipp.puts fill_template(ipp_template, {
|
|
220
|
+
:j => j,
|
|
221
|
+
:typenames => add_comma + typename_list,
|
|
222
|
+
:args => add_comma + arg_list,
|
|
223
|
+
:member_args => add_comma + member_arg_list,
|
|
224
|
+
:initializers => add_comma + init_list,
|
|
225
|
+
:member_params => member_param_list,
|
|
226
|
+
:member_decls => member_decl_list,
|
|
227
|
+
:types => add_comma + type_list,
|
|
228
|
+
:params => add_comma + param_list
|
|
229
|
+
})
|
|
230
|
+
ipp.puts ''
|
|
231
|
+
hpp.puts fill_template(hpp_template, {
|
|
232
|
+
:typenames => add_comma + typename_list,
|
|
233
|
+
:args => add_comma + arg_list,
|
|
234
|
+
})
|
|
235
|
+
hpp.puts ''
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# ======================================================================
|
|
241
|
+
docstring = <<END
|
|
242
|
+
|
|
243
|
+
//! Call the Ruby method specified by 'id' on object 'obj'.
|
|
244
|
+
/*! Pass in arguments (arg1, arg2, ...). The arguments will be converted to
|
|
245
|
+
* Ruby objects with to_ruby<>. The return value will automatically be
|
|
246
|
+
* converted to type Retval_T with from_ruby<>.
|
|
247
|
+
*
|
|
248
|
+
* E.g.:
|
|
249
|
+
* \\code
|
|
250
|
+
* float y = x.call<float>("foo", z, 42);
|
|
251
|
+
* \\endcode
|
|
252
|
+
*/
|
|
253
|
+
template<typename Retval_T>
|
|
254
|
+
Retval_T call(Identifier id, T1 arg1, T2 arg2, ...) const;
|
|
255
|
+
|
|
256
|
+
//! Version of call which defaults to Object return type.
|
|
257
|
+
Object call(Identifier id, T1 arg1, T2 arg2, ...) const;
|
|
258
|
+
END
|
|
259
|
+
ipp_template = <<END
|
|
260
|
+
|
|
261
|
+
%(template)
|
|
262
|
+
inline Rice::Object Rice::Object::
|
|
263
|
+
call(Identifier id%(args)) const
|
|
264
|
+
{
|
|
265
|
+
VALUE args[] = { %(convert_list) };
|
|
266
|
+
return protect(rb_funcall2, value(), id, %(j), args);
|
|
267
|
+
}
|
|
268
|
+
END
|
|
269
|
+
hpp_template = <<END
|
|
270
|
+
%(template)
|
|
271
|
+
Object call(Identifier id%(args)) const;
|
|
272
|
+
|
|
273
|
+
END
|
|
274
|
+
ipp_head = <<END
|
|
275
|
+
#include "../protect.hpp"
|
|
276
|
+
#include "../to_from_ruby.hpp"
|
|
277
|
+
END
|
|
278
|
+
ipp_filename = 'detail/object_call.ipp'
|
|
279
|
+
hpp_filename = 'detail/object_call.hpp'
|
|
280
|
+
wrap_header(hpp_filename, nil, docstring, false, nil, nil, GENERATED_FILE_WARNING, nil) do |hpp|
|
|
281
|
+
wrap_header(ipp_filename, nil, nil, false, ipp_head, nil, GENERATED_FILE_WARNING, nil) do |ipp|
|
|
282
|
+
for j in 0..MAX_ARGS do
|
|
283
|
+
t_array = (1..j).to_a
|
|
284
|
+
arg_list = t_array.map { |x| ", T#{x} arg#{x}" }
|
|
285
|
+
if j == 0 then
|
|
286
|
+
template = ''
|
|
287
|
+
convert_list = 'Qnil';
|
|
288
|
+
else
|
|
289
|
+
template = 'template<' + t_array.map { |x| "typename T#{x}" }.join(', ') + '>'
|
|
290
|
+
convert_list = t_array.map { |x| "to_ruby(arg#{x})" }.join(', ')
|
|
291
|
+
end
|
|
292
|
+
ipp.puts fill_template(ipp_template, {
|
|
293
|
+
:args => arg_list,
|
|
294
|
+
:convert_list => convert_list,
|
|
295
|
+
:j => j,
|
|
296
|
+
:template => template,
|
|
297
|
+
})
|
|
298
|
+
ipp.puts
|
|
299
|
+
hpp.puts fill_template(hpp_template, {
|
|
300
|
+
:args => arg_list,
|
|
301
|
+
:template => template,
|
|
302
|
+
})
|
|
303
|
+
hpp.puts
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
#
|
|
308
|
+
# # ======================================================================
|
|
309
|
+
# method_types = [
|
|
310
|
+
# 'method', 'module_function', 'protected_method',
|
|
311
|
+
# 'private_method', 'singleton_method'
|
|
312
|
+
# ]
|
|
313
|
+
# method_docstring = <<END
|
|
314
|
+
# //! Define a %s method. Like rb_define_%s, but automatically calculates
|
|
315
|
+
# //! the number of arguments based on the prototype of the supplied
|
|
316
|
+
# //! function f.
|
|
317
|
+
# VALUE define_%s(
|
|
318
|
+
# VALUE klass,
|
|
319
|
+
# char const * name,
|
|
320
|
+
# VALUE (*f)(VALUE arg1, VALUE arg2, ...));
|
|
321
|
+
# END
|
|
322
|
+
# docstring = <<END
|
|
323
|
+
# /*! \\file
|
|
324
|
+
# * \\brief Helpers for defining ruby methods, overloaded on the
|
|
325
|
+
# * signature of the function being wrapped.
|
|
326
|
+
# */
|
|
327
|
+
# #{method_types.map do |t| method_docstring % [ t, t, t ] end}
|
|
328
|
+
# //! Define a global function. Like rb_define_global_function, but
|
|
329
|
+
# //! automatically calculates the number of arguments based on the
|
|
330
|
+
# //! prototype of the supplied function f.
|
|
331
|
+
# void define_global_function(
|
|
332
|
+
# char const * name,
|
|
333
|
+
# VALUE (*f)(VALUE arg1, VALUE arg2, ...));
|
|
334
|
+
# END
|
|
335
|
+
# method_def = <<END
|
|
336
|
+
# inline void define_%s(
|
|
337
|
+
# VALUE klass,
|
|
338
|
+
# char const * name,
|
|
339
|
+
# VALUE(*f)(%%(args)))
|
|
340
|
+
# {
|
|
341
|
+
# rb_define_%s(klass, name, RUBY_METHOD_FUNC(f), %%(j));
|
|
342
|
+
# }
|
|
343
|
+
# END
|
|
344
|
+
# method_decl = <<END
|
|
345
|
+
# void define_%s(
|
|
346
|
+
# VALUE klass,
|
|
347
|
+
# char const * name,
|
|
348
|
+
# VALUE(*f)(%%(args)));
|
|
349
|
+
# END
|
|
350
|
+
# ipp_template = <<END
|
|
351
|
+
# #{method_types.map do |t| method_def % [ t, t ] end }\
|
|
352
|
+
# inline void define_global_function(
|
|
353
|
+
# char const * name,
|
|
354
|
+
# VALUE(*f)(%(args)))
|
|
355
|
+
# {
|
|
356
|
+
# rb_define_global_function(name, RUBY_METHOD_FUNC(f), %(j));
|
|
357
|
+
# }
|
|
358
|
+
#
|
|
359
|
+
# // ---------------------------------------------------------------------
|
|
360
|
+
# END
|
|
361
|
+
# hpp_template = <<END
|
|
362
|
+
# #{method_types.map do |t| method_decl % t end }\
|
|
363
|
+
# void define_global_function(
|
|
364
|
+
# char const * name,
|
|
365
|
+
# VALUE(*f)(%(args)));
|
|
366
|
+
#
|
|
367
|
+
# // ---------------------------------------------------------------------
|
|
368
|
+
# END
|
|
369
|
+
# ipp_filename = 'define_method.ipp'
|
|
370
|
+
# hpp_filename = 'define_method.hpp'
|
|
371
|
+
# wrap_header(ipp_filename, 'Rice') do |ipp|
|
|
372
|
+
# wrap_header(hpp_filename, 'Rice', docstring, true) do |hpp|
|
|
373
|
+
# for j in 0..MAX_ARGS do
|
|
374
|
+
# t_array = (0..j).to_a
|
|
375
|
+
# arg_list = t_array.map { |x| "VALUE" }.join(', ')
|
|
376
|
+
# ipp.puts fill_template(ipp_template, {
|
|
377
|
+
# :args => arg_list,
|
|
378
|
+
# :j => j
|
|
379
|
+
# })
|
|
380
|
+
# ipp.puts ""
|
|
381
|
+
# hpp.puts fill_template(hpp_template, {
|
|
382
|
+
# :args => arg_list
|
|
383
|
+
# })
|
|
384
|
+
# hpp.puts ""
|
|
385
|
+
# end
|
|
386
|
+
# arg_list = "int, VALUE*, VALUE";
|
|
387
|
+
# ipp.puts fill_template(ipp_template, {
|
|
388
|
+
# :args => arg_list,
|
|
389
|
+
# :j => -1
|
|
390
|
+
# })
|
|
391
|
+
# ipp.puts ""
|
|
392
|
+
# hpp.puts fill_template(hpp_template, {
|
|
393
|
+
# :args => arg_list
|
|
394
|
+
# })
|
|
395
|
+
# end
|
|
396
|
+
# end
|
|
397
|
+
#
|
|
398
|
+
# ======================================================================
|
|
399
|
+
docstring = <<END
|
|
400
|
+
END
|
|
401
|
+
ipp_template = <<END
|
|
402
|
+
template<typename Func_T, typename Ret_T, %(typename_list)>
|
|
403
|
+
Auto_Function_Wrapper<Func_T, Ret_T, %(typenames)>::
|
|
404
|
+
Auto_Function_Wrapper(
|
|
405
|
+
Func func,
|
|
406
|
+
Exception_Handler const * handler)
|
|
407
|
+
: Wrapped_Function(RUBY_METHOD_FUNC(call), Num_Args)
|
|
408
|
+
, func_(func)
|
|
409
|
+
, handler_(handler ? handler : new Default_Exception_Handler)
|
|
410
|
+
{
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
template<typename Func_T, typename Ret_T, %(typename_list)>
|
|
414
|
+
VALUE Auto_Function_Wrapper<Func_T, Ret_T, %(typenames)>::
|
|
415
|
+
call(%(value_args))
|
|
416
|
+
{
|
|
417
|
+
Auto_Function_Wrapper<Func_T, Ret_T, %(typenames)> * wrapper = 0;
|
|
418
|
+
try
|
|
419
|
+
{
|
|
420
|
+
void * data = detail::method_data();
|
|
421
|
+
wrapper = (Auto_Function_Wrapper<Func_T, Ret_T, %(typenames)> *)data;
|
|
422
|
+
%(arg_convert_list)
|
|
423
|
+
return to_ruby(wrapper->func_(%(arg_list)));
|
|
424
|
+
}
|
|
425
|
+
catch(...)
|
|
426
|
+
{
|
|
427
|
+
RUBY_TRY
|
|
428
|
+
{
|
|
429
|
+
if(wrapper)
|
|
430
|
+
{
|
|
431
|
+
return wrapper->handler_->handle_exception();
|
|
432
|
+
}
|
|
433
|
+
else
|
|
434
|
+
{
|
|
435
|
+
throw;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
RUBY_CATCH
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
template<typename Func_T, %(typename_list)>
|
|
443
|
+
Auto_Function_Wrapper<Func_T, void, %(typenames)>::
|
|
444
|
+
Auto_Function_Wrapper(
|
|
445
|
+
Func func,
|
|
446
|
+
Exception_Handler const * handler)
|
|
447
|
+
: Wrapped_Function(RUBY_METHOD_FUNC(call), Num_Args)
|
|
448
|
+
, func_(func)
|
|
449
|
+
, handler_(handler ? handler : new Default_Exception_Handler)
|
|
450
|
+
{
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
template<typename Func_T, %(typename_list)>
|
|
454
|
+
VALUE Auto_Function_Wrapper<Func_T, void, %(typenames)>::
|
|
455
|
+
call(%(value_args))
|
|
456
|
+
{
|
|
457
|
+
Auto_Function_Wrapper<Func_T, void, %(typenames)> * wrapper = 0;
|
|
458
|
+
try
|
|
459
|
+
{
|
|
460
|
+
void * data = detail::method_data();
|
|
461
|
+
wrapper =
|
|
462
|
+
(Auto_Function_Wrapper<Func_T, void, %(typenames)> *)data;
|
|
463
|
+
%(arg_convert_list)
|
|
464
|
+
wrapper->func_(%(arg_list));
|
|
465
|
+
return Qnil;
|
|
466
|
+
}
|
|
467
|
+
catch(...)
|
|
468
|
+
{
|
|
469
|
+
RUBY_TRY
|
|
470
|
+
{
|
|
471
|
+
if(wrapper)
|
|
472
|
+
{
|
|
473
|
+
return wrapper->handler_->handle_exception();
|
|
474
|
+
}
|
|
475
|
+
else
|
|
476
|
+
{
|
|
477
|
+
throw;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
RUBY_CATCH
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// ---------------------------------------------------------------------
|
|
485
|
+
END
|
|
486
|
+
|
|
487
|
+
# ======================================================================
|
|
488
|
+
# TODO: Should the handler copy the exception handler or keep a pointer
|
|
489
|
+
# to it?
|
|
490
|
+
hpp_template = <<END
|
|
491
|
+
template<typename Func_T, typename Ret_T, %(typename_list_d)>
|
|
492
|
+
class Auto_Function_Wrapper%(specializations)
|
|
493
|
+
: public Wrapped_Function
|
|
494
|
+
{
|
|
495
|
+
public:
|
|
496
|
+
// typedef Ret_T (*Func)(%(typenames));
|
|
497
|
+
typedef Func_T Func;
|
|
498
|
+
|
|
499
|
+
static const int Num_Args = %(j);
|
|
500
|
+
|
|
501
|
+
Auto_Function_Wrapper(
|
|
502
|
+
Func func,
|
|
503
|
+
Exception_Handler const * handler = 0);
|
|
504
|
+
|
|
505
|
+
static VALUE call(%(value_args));
|
|
506
|
+
|
|
507
|
+
private:
|
|
508
|
+
Func func_;
|
|
509
|
+
Exception_Handler const * handler_;
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
template<typename Func_T, %(typename_list)>
|
|
513
|
+
class Auto_Function_Wrapper<Func_T, void, %(typenames)>
|
|
514
|
+
: public Wrapped_Function
|
|
515
|
+
{
|
|
516
|
+
public:
|
|
517
|
+
// typedef void (*Func)(%(typenames));
|
|
518
|
+
typedef Func_T Func;
|
|
519
|
+
|
|
520
|
+
static const int Num_Args = %(j);
|
|
521
|
+
|
|
522
|
+
Auto_Function_Wrapper(
|
|
523
|
+
Func func,
|
|
524
|
+
Exception_Handler const * handler = 0);
|
|
525
|
+
|
|
526
|
+
static VALUE call(%(value_args));
|
|
527
|
+
|
|
528
|
+
private:
|
|
529
|
+
Func func_;
|
|
530
|
+
Exception_Handler const * handler_;
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
// ---------------------------------------------------------------------
|
|
534
|
+
END
|
|
535
|
+
hpp_head = <<END
|
|
536
|
+
#include "Exception_Handler.hpp"
|
|
537
|
+
|
|
538
|
+
END
|
|
539
|
+
ipp_head = <<END
|
|
540
|
+
#include "method_data.hpp"
|
|
541
|
+
#include "../ruby_try_catch.hpp"
|
|
542
|
+
#include "../to_from_ruby.hpp"
|
|
543
|
+
END
|
|
544
|
+
ipp_filename = 'detail/Auto_Function_Wrapper.ipp'
|
|
545
|
+
hpp_filename = 'detail/Auto_Function_Wrapper.hpp'
|
|
546
|
+
wrap_header(hpp_filename, 'Rice::detail', docstring, true, hpp_head) do |hpp|
|
|
547
|
+
wrap_header(ipp_filename, 'Rice::detail', nil, false, ipp_head) do |ipp|
|
|
548
|
+
j = MAX_ARGS # TODO: what's the best way to iterate backward?
|
|
549
|
+
while j >= 0 do
|
|
550
|
+
t_array = (0..j).to_a
|
|
551
|
+
value_args = t_array.map { |x| "VALUE ruby_arg#{x}" }.join(', ')
|
|
552
|
+
arg_list = t_array.map { |x| "arg#{x}" }.join(', ')
|
|
553
|
+
typenames = t_array.map { |x| "Arg#{x}_T" }.join(', ')
|
|
554
|
+
arg_convert_list = t_array.map do |x|
|
|
555
|
+
"Arg#{x}_T arg#{x}(from_ruby<Arg#{x}_T>(ruby_arg#{x})); "
|
|
556
|
+
end
|
|
557
|
+
if j == MAX_ARGS then
|
|
558
|
+
typename_list = t_array.map { |x| "typename Arg#{x}_T" }.join(', ')
|
|
559
|
+
typename_list_d = t_array.map { |x| "typename Arg#{x}_T = void" }.join(', ')
|
|
560
|
+
specializations = ''
|
|
561
|
+
else
|
|
562
|
+
typename_list = t_array.map { |x| "typename Arg#{x}_T" }.join(', ')
|
|
563
|
+
typename_list_d = typename_list
|
|
564
|
+
specializations = "<Func_T, Ret_T, #{typenames}>"
|
|
565
|
+
end
|
|
566
|
+
ipp.puts fill_template(ipp_template, {
|
|
567
|
+
:value_args => value_args,
|
|
568
|
+
:arg_list => arg_list,
|
|
569
|
+
:typenames => typenames,
|
|
570
|
+
:typename_list => typename_list,
|
|
571
|
+
:arg_convert_list => arg_convert_list,
|
|
572
|
+
})
|
|
573
|
+
hpp.puts fill_template(hpp_template, {
|
|
574
|
+
:value_args => value_args,
|
|
575
|
+
:typenames => typenames,
|
|
576
|
+
:typename_list_d => typename_list_d,
|
|
577
|
+
:typename_list => typename_list,
|
|
578
|
+
:j => j,
|
|
579
|
+
:specializations => specializations,
|
|
580
|
+
})
|
|
581
|
+
j -= 1
|
|
582
|
+
end
|
|
583
|
+
end
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
# ======================================================================
|
|
587
|
+
# TODO: Can I add another call() that works if from_ruby is defined
|
|
588
|
+
# for a reference to self instead of a pointer to self (and same for
|
|
589
|
+
# const reference and const pointer?)
|
|
590
|
+
docstring = <<END
|
|
591
|
+
END
|
|
592
|
+
ipp_template = <<END
|
|
593
|
+
template<typename Func_T, typename Ret_T, typename Self_T%(typename_list)>
|
|
594
|
+
Auto_Member_Function_Wrapper<Func_T, Ret_T, Self_T%(typenames)>::
|
|
595
|
+
Auto_Member_Function_Wrapper(
|
|
596
|
+
Func func,
|
|
597
|
+
Exception_Handler const * handler)
|
|
598
|
+
: Wrapped_Function(RUBY_METHOD_FUNC(call), Num_Args)
|
|
599
|
+
, func_(func)
|
|
600
|
+
, handler_(handler ? handler : new Default_Exception_Handler)
|
|
601
|
+
{
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
template<typename Func_T, typename Ret_T, typename Self_T%(typename_list)>
|
|
605
|
+
VALUE Auto_Member_Function_Wrapper<Func_T, Ret_T, Self_T%(typenames)>::
|
|
606
|
+
call(VALUE self%(value_args))
|
|
607
|
+
{
|
|
608
|
+
Auto_Member_Function_Wrapper<Func_T, Ret_T, Self_T%(typenames)> * wrapper = 0;
|
|
609
|
+
try
|
|
610
|
+
{
|
|
611
|
+
void * data = detail::method_data();
|
|
612
|
+
wrapper =
|
|
613
|
+
(Auto_Member_Function_Wrapper<Func_T, Ret_T, Self_T%(typenames)> *)data;
|
|
614
|
+
Self_T * obj = from_ruby<Self_T *>(self);
|
|
615
|
+
%(arg_convert_list)
|
|
616
|
+
Func func = wrapper->func_;
|
|
617
|
+
return to_ruby((*obj.*func)(%(arg_list)));
|
|
618
|
+
}
|
|
619
|
+
catch(...)
|
|
620
|
+
{
|
|
621
|
+
RUBY_TRY
|
|
622
|
+
{
|
|
623
|
+
if(wrapper)
|
|
624
|
+
{
|
|
625
|
+
return wrapper->handler_->handle_exception();
|
|
626
|
+
}
|
|
627
|
+
else
|
|
628
|
+
{
|
|
629
|
+
throw;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
RUBY_CATCH
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
template<typename Func_T, typename Self_T%(typename_list)>
|
|
637
|
+
Auto_Member_Function_Wrapper<Func_T, void, Self_T%(typenames)>::
|
|
638
|
+
Auto_Member_Function_Wrapper(
|
|
639
|
+
Func func,
|
|
640
|
+
Exception_Handler const * handler)
|
|
641
|
+
: Wrapped_Function(RUBY_METHOD_FUNC(call), Num_Args)
|
|
642
|
+
, func_(func)
|
|
643
|
+
, handler_(handler ? handler : new Default_Exception_Handler)
|
|
644
|
+
{
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
template<typename Func_T, typename Self_T%(typename_list)>
|
|
648
|
+
VALUE Auto_Member_Function_Wrapper<Func_T, void, Self_T%(typenames)>::
|
|
649
|
+
call(VALUE self%(value_args))
|
|
650
|
+
{
|
|
651
|
+
Auto_Member_Function_Wrapper<Func_T, void, Self_T%(typenames)> * wrapper = 0;
|
|
652
|
+
try
|
|
653
|
+
{
|
|
654
|
+
void * data = detail::method_data();
|
|
655
|
+
wrapper =
|
|
656
|
+
(Auto_Member_Function_Wrapper<Func_T, void, Self_T%(typenames)> *)data;
|
|
657
|
+
Self_T * obj = from_ruby<Self_T *>(self);
|
|
658
|
+
%(arg_convert_list)
|
|
659
|
+
Func func = wrapper->func_;
|
|
660
|
+
(*obj.*func)(%(arg_list));
|
|
661
|
+
return Qnil;
|
|
662
|
+
}
|
|
663
|
+
catch(...)
|
|
664
|
+
{
|
|
665
|
+
RUBY_TRY
|
|
666
|
+
{
|
|
667
|
+
if(wrapper)
|
|
668
|
+
{
|
|
669
|
+
return wrapper->handler_->handle_exception();
|
|
670
|
+
}
|
|
671
|
+
else
|
|
672
|
+
{
|
|
673
|
+
throw;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
RUBY_CATCH
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// ---------------------------------------------------------------------
|
|
681
|
+
END
|
|
682
|
+
hpp_template = <<END
|
|
683
|
+
template<typename Func_T, typename Ret_T, typename Self_T%(typename_list_d)>
|
|
684
|
+
class Auto_Member_Function_Wrapper%(specializations)
|
|
685
|
+
: public Wrapped_Function
|
|
686
|
+
{
|
|
687
|
+
public:
|
|
688
|
+
typedef Func_T Func;
|
|
689
|
+
|
|
690
|
+
static const int Num_Args = %(j);
|
|
691
|
+
|
|
692
|
+
Auto_Member_Function_Wrapper(
|
|
693
|
+
Func func,
|
|
694
|
+
Exception_Handler const * handler = 0);
|
|
695
|
+
|
|
696
|
+
static VALUE call(VALUE self%(value_args));
|
|
697
|
+
|
|
698
|
+
private:
|
|
699
|
+
Func func_;
|
|
700
|
+
Exception_Handler const * handler_;
|
|
701
|
+
};
|
|
702
|
+
|
|
703
|
+
template<typename Func_T, typename Self_T%(typename_list)>
|
|
704
|
+
class Auto_Member_Function_Wrapper<Func_T, void, Self_T%(typenames)>
|
|
705
|
+
: public Wrapped_Function
|
|
706
|
+
{
|
|
707
|
+
public:
|
|
708
|
+
typedef Func_T Func;
|
|
709
|
+
|
|
710
|
+
static const int Num_Args = %(j);
|
|
711
|
+
|
|
712
|
+
Auto_Member_Function_Wrapper(
|
|
713
|
+
Func func,
|
|
714
|
+
Exception_Handler const * handler = 0);
|
|
715
|
+
|
|
716
|
+
static VALUE call(VALUE self%(value_args));
|
|
717
|
+
|
|
718
|
+
private:
|
|
719
|
+
Func func_;
|
|
720
|
+
Exception_Handler const * handler_;
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
// ---------------------------------------------------------------------
|
|
724
|
+
END
|
|
725
|
+
ipp_head = <<END
|
|
726
|
+
#include "method_data.hpp"
|
|
727
|
+
#include "../ruby_try_catch.hpp"
|
|
728
|
+
#include "../to_from_ruby.hpp"
|
|
729
|
+
#include <typeinfo>
|
|
730
|
+
END
|
|
731
|
+
ipp_filename = 'detail/Auto_Member_Function_Wrapper.ipp'
|
|
732
|
+
hpp_filename = 'detail/Auto_Member_Function_Wrapper.hpp'
|
|
733
|
+
wrap_header(hpp_filename, 'Rice::detail', docstring, true) do |hpp|
|
|
734
|
+
wrap_header(ipp_filename, 'Rice::detail', nil, false, ipp_head) do |ipp|
|
|
735
|
+
j = MAX_ARGS # TODO: what's the best way to iterate backward?
|
|
736
|
+
while j >= 0 do
|
|
737
|
+
t_array = (1..j).to_a
|
|
738
|
+
value_args = t_array.map { |x| ", VALUE ruby_arg#{x}" }
|
|
739
|
+
arg_list = t_array.map { |x| "arg#{x}" }.join(', ')
|
|
740
|
+
typenames = t_array.map { |x| ", Arg#{x}_T" }
|
|
741
|
+
typenames_n = t_array.map { |x| "Arg#{x}_T" }.join(', ')
|
|
742
|
+
arg_convert_list = t_array.map do |x|
|
|
743
|
+
"Arg#{x}_T arg#{x}(from_ruby<Arg#{x}_T>(ruby_arg#{x})); "
|
|
744
|
+
end
|
|
745
|
+
if j == MAX_ARGS then
|
|
746
|
+
typename_list = t_array.map { |x| ", typename Arg#{x}_T" }.join
|
|
747
|
+
typename_list_d = t_array.map { |x| ", typename Arg#{x}_T = void" }.join
|
|
748
|
+
specializations = ''
|
|
749
|
+
else
|
|
750
|
+
typename_list = t_array.map { |x| ", typename Arg#{x}_T" }.join
|
|
751
|
+
typename_list_d = typename_list
|
|
752
|
+
specializations = "<Func_T, Ret_T, Self_T#{typenames}>"
|
|
753
|
+
end
|
|
754
|
+
ipp.puts fill_template(ipp_template, {
|
|
755
|
+
:value_args => value_args,
|
|
756
|
+
:arg_list => arg_list,
|
|
757
|
+
:typenames => typenames,
|
|
758
|
+
:typename_list => typename_list,
|
|
759
|
+
:arg_convert_list => arg_convert_list,
|
|
760
|
+
})
|
|
761
|
+
hpp.puts fill_template(hpp_template, {
|
|
762
|
+
:value_args => value_args,
|
|
763
|
+
:typenames => typenames,
|
|
764
|
+
# :typenames_n => typenames_n,
|
|
765
|
+
:typename_list => typename_list,
|
|
766
|
+
:typename_list_d => typename_list_d,
|
|
767
|
+
:j => j,
|
|
768
|
+
:specializations => specializations,
|
|
769
|
+
})
|
|
770
|
+
j -= 1
|
|
771
|
+
end
|
|
772
|
+
end
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
=begin
|
|
776
|
+
# ======================================================================
|
|
777
|
+
docstring = <<END
|
|
778
|
+
END
|
|
779
|
+
ipp_template = <<END
|
|
780
|
+
template<typename Ret_T, %(typename_list)>
|
|
781
|
+
void define_method_and_auto_wrap(
|
|
782
|
+
VALUE klass,
|
|
783
|
+
char const * name,
|
|
784
|
+
Ret_T (*func)(%(typenames)),
|
|
785
|
+
Exception_Handler const * handler)
|
|
786
|
+
{
|
|
787
|
+
// TODO: Register this wrapper with the GC?
|
|
788
|
+
Auto_Function_Wrapper<Ret_T, %(typenames)> * wrapper = new
|
|
789
|
+
Auto_Function_Wrapper<Ret_T, %(typenames)>(func, handler);
|
|
790
|
+
define_method_with_data(
|
|
791
|
+
klass,
|
|
792
|
+
name,
|
|
793
|
+
(RUBY_METHOD_FUNC)Auto_Function_Wrapper<Ret_T, %(typenames)>::call,
|
|
794
|
+
(RUBY_METHOD_FUNC)Auto_Function_Wrapper<Ret_T, %(typenames)>::Num_Args,
|
|
795
|
+
wrapper);
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
template<typename Ret_T, typename Self_T%(typename_list_no_self)>
|
|
799
|
+
void define_method_and_auto_wrap(
|
|
800
|
+
VALUE klass,
|
|
801
|
+
char const * name,
|
|
802
|
+
Ret_T (Self_T::*func)(%(typenames_no_self_no_comma)),
|
|
803
|
+
Exception_Handler const * handler)
|
|
804
|
+
{
|
|
805
|
+
// TODO: Register this wrapper with the GC?
|
|
806
|
+
Auto_Member_Function_Wrapper<Ret_T, Self_T%(typenames_no_self)> * wrapper = new
|
|
807
|
+
Auto_Member_Function_Wrapper<Ret_T, Self_T%(typenames_no_self)>(func, handler);
|
|
808
|
+
define_method_with_data(
|
|
809
|
+
klass,
|
|
810
|
+
name,
|
|
811
|
+
(RUBY_METHOD_FUNC)Auto_Member_Function_Wrapper<Ret_T, Self_T%(typenames_no_self)>::call,
|
|
812
|
+
%(j),
|
|
813
|
+
wrapper);
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// ---------------------------------------------------------------------
|
|
817
|
+
END
|
|
818
|
+
hpp_template = <<END
|
|
819
|
+
template<typename Ret_T, %(typename_list)>
|
|
820
|
+
void define_method_and_auto_wrap(
|
|
821
|
+
VALUE klass,
|
|
822
|
+
char const * name,
|
|
823
|
+
Ret_T (*func)(%(typenames)),
|
|
824
|
+
Exception_Handler const * handler = 0);
|
|
825
|
+
|
|
826
|
+
template<typename Ret_T, typename Self_T%(typename_list_no_self)>
|
|
827
|
+
void define_method_and_auto_wrap(
|
|
828
|
+
VALUE klass,
|
|
829
|
+
char const * name,
|
|
830
|
+
Ret_T (Self_T::*func)(%(typenames_no_self_no_comma)),
|
|
831
|
+
Exception_Handler const * handler = 0);
|
|
832
|
+
|
|
833
|
+
// ---------------------------------------------------------------------
|
|
834
|
+
END
|
|
835
|
+
hpp_head = <<END
|
|
836
|
+
#include "Exception_Handler.hpp"
|
|
837
|
+
END
|
|
838
|
+
ipp_head = <<END
|
|
839
|
+
#include "Auto_Function_Wrapper.hpp"
|
|
840
|
+
#include "Auto_Member_Function_Wrapper.hpp"
|
|
841
|
+
END
|
|
842
|
+
ipp_filename = 'detail/define_method_and_auto_wrap.ipp'
|
|
843
|
+
hpp_filename = 'detail/define_method_and_auto_wrap.hpp'
|
|
844
|
+
wrap_header(hpp_filename, 'Rice::detail', docstring, true, hpp_head) do |hpp|
|
|
845
|
+
wrap_header(ipp_filename, 'Rice::detail', nil, false, ipp_head) do |ipp|
|
|
846
|
+
for j in 0..MAX_ARGS do
|
|
847
|
+
t_array = (0..j).to_a
|
|
848
|
+
typenames = t_array.map { |x| "Arg#{x}_T" }.join(', ')
|
|
849
|
+
typename_list = t_array.map { |x| "typename Arg#{x}_T" }.join(', ')
|
|
850
|
+
t_array.shift
|
|
851
|
+
typenames_no_self = t_array.map { |x| ", Arg#{x}_T" }
|
|
852
|
+
typename_list_no_self = t_array.map { |x| ", typename Arg#{x}_T" }
|
|
853
|
+
typenames_no_self_no_comma = typenames_no_self.to_s.sub(', ', '')
|
|
854
|
+
ipp.puts fill_template(ipp_template, {
|
|
855
|
+
:typenames => typenames,
|
|
856
|
+
:typename_list => typename_list,
|
|
857
|
+
:typenames_no_self => typenames_no_self,
|
|
858
|
+
:typename_list_no_self => typename_list_no_self,
|
|
859
|
+
:typenames_no_self_no_comma => typenames_no_self_no_comma,
|
|
860
|
+
:j => j,
|
|
861
|
+
})
|
|
862
|
+
hpp.puts fill_template(hpp_template, {
|
|
863
|
+
:typenames => typenames,
|
|
864
|
+
:typename_list => typename_list,
|
|
865
|
+
:typename_list_no_self => typename_list_no_self,
|
|
866
|
+
:typenames_no_self_no_comma => typenames_no_self_no_comma,
|
|
867
|
+
})
|
|
868
|
+
end
|
|
869
|
+
end
|
|
870
|
+
end
|
|
871
|
+
# ======================================================================
|
|
872
|
+
=end
|
|
873
|
+
|
|
874
|
+
docstring = <<END
|
|
875
|
+
END
|
|
876
|
+
ipp_template = <<END
|
|
877
|
+
template<typename Ret_T, %(typename_list)>
|
|
878
|
+
Wrapped_Function * wrap_function(
|
|
879
|
+
Ret_T (*func)(%(typenames)),
|
|
880
|
+
Exception_Handler const * handler)
|
|
881
|
+
{
|
|
882
|
+
typedef Ret_T (*Func)(%(typenames));
|
|
883
|
+
return new Auto_Function_Wrapper<Func, Ret_T, %(typenames)>(func, handler);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
template<typename Ret_T, typename Self_T%(typename_list_no_self)>
|
|
887
|
+
Wrapped_Function * wrap_function(
|
|
888
|
+
Ret_T (Self_T::*func)(%(typenames_no_self_no_comma)),
|
|
889
|
+
Exception_Handler const * handler)
|
|
890
|
+
{
|
|
891
|
+
typedef Ret_T (Self_T::*Func)(%(typenames_no_self_no_comma));
|
|
892
|
+
return new Auto_Member_Function_Wrapper<Func, Ret_T, Self_T%(typenames_no_self)>(func, handler);
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
template<typename Ret_T, typename Self_T%(typename_list_no_self)>
|
|
896
|
+
Wrapped_Function * wrap_function(
|
|
897
|
+
Ret_T (Self_T::*func)(%(typenames_no_self_no_comma)) const,
|
|
898
|
+
Exception_Handler const * handler)
|
|
899
|
+
{
|
|
900
|
+
typedef Ret_T (Self_T::*Func)(%(typenames_no_self_no_comma)) const;
|
|
901
|
+
return new Auto_Member_Function_Wrapper<Func, Ret_T, Self_T%(typenames_no_self)>(func, handler);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
// ---------------------------------------------------------------------
|
|
905
|
+
END
|
|
906
|
+
hpp_template = <<END
|
|
907
|
+
template<typename Ret_T, %(typename_list)>
|
|
908
|
+
Wrapped_Function * wrap_function(
|
|
909
|
+
Ret_T (*func)(%(typenames)),
|
|
910
|
+
Exception_Handler const * handler = 0);
|
|
911
|
+
|
|
912
|
+
template<typename Ret_T, typename Self_T%(typename_list_no_self)>
|
|
913
|
+
Wrapped_Function * wrap_function(
|
|
914
|
+
Ret_T (Self_T::*func)(%(typenames_no_self_no_comma)),
|
|
915
|
+
Exception_Handler const * handler = 0);
|
|
916
|
+
|
|
917
|
+
template<typename Ret_T, typename Self_T%(typename_list_no_self)>
|
|
918
|
+
Wrapped_Function * wrap_function(
|
|
919
|
+
Ret_T (Self_T::*func)(%(typenames_no_self_no_comma)) const,
|
|
920
|
+
Exception_Handler const * handler = 0);
|
|
921
|
+
|
|
922
|
+
// ---------------------------------------------------------------------
|
|
923
|
+
END
|
|
924
|
+
hpp_head = <<END
|
|
925
|
+
#include "Exception_Handler.hpp"
|
|
926
|
+
#include "Wrapped_Function.hpp"
|
|
927
|
+
|
|
928
|
+
END
|
|
929
|
+
ipp_head = <<END
|
|
930
|
+
#include "Auto_Function_Wrapper.hpp"
|
|
931
|
+
#include "Auto_Member_Function_Wrapper.hpp"
|
|
932
|
+
END
|
|
933
|
+
ipp_filename = 'detail/wrap_function.ipp'
|
|
934
|
+
hpp_filename = 'detail/wrap_function.hpp'
|
|
935
|
+
wrap_header(hpp_filename, 'Rice::detail', docstring, true, hpp_head) do |hpp|
|
|
936
|
+
wrap_header(ipp_filename, 'Rice::detail', nil, false, ipp_head) do |ipp|
|
|
937
|
+
for j in 0..MAX_ARGS do
|
|
938
|
+
t_array = (0..j).to_a
|
|
939
|
+
typenames = t_array.map { |x| "Arg#{x}_T" }.join(', ')
|
|
940
|
+
typename_list = t_array.map { |x| "typename Arg#{x}_T" }.join(', ')
|
|
941
|
+
t_array.shift
|
|
942
|
+
typenames_no_self = t_array.map { |x| ", Arg#{x}_T" }
|
|
943
|
+
typename_list_no_self = t_array.map { |x| ", typename Arg#{x}_T" }
|
|
944
|
+
typenames_no_self_no_comma = typenames_no_self.to_s.sub(', ', '')
|
|
945
|
+
ipp.puts fill_template(ipp_template, {
|
|
946
|
+
:typenames => typenames,
|
|
947
|
+
:typename_list => typename_list,
|
|
948
|
+
:typenames_no_self => typenames_no_self,
|
|
949
|
+
:typename_list_no_self => typename_list_no_self,
|
|
950
|
+
:typenames_no_self_no_comma => typenames_no_self_no_comma,
|
|
951
|
+
})
|
|
952
|
+
hpp.puts fill_template(hpp_template, {
|
|
953
|
+
:typenames => typenames,
|
|
954
|
+
:typename_list => typename_list,
|
|
955
|
+
:typename_list_no_self => typename_list_no_self,
|
|
956
|
+
:typenames_no_self_no_comma => typenames_no_self_no_comma,
|
|
957
|
+
})
|
|
958
|
+
end
|
|
959
|
+
end
|
|
960
|
+
end
|
|
961
|
+
|
|
962
|
+
# ======================================================================
|
|
963
|
+
# TODO: we have to implement this function in the class definition due
|
|
964
|
+
# to a bug in g++
|
|
965
|
+
void_list = (0..MAX_ARGS).to_a.map { |x| ", typename Arg#{x}_T=void" }
|
|
966
|
+
hpp_start = <<END
|
|
967
|
+
template<typename T#{void_list}>
|
|
968
|
+
class Constructor
|
|
969
|
+
{
|
|
970
|
+
private:
|
|
971
|
+
Constructor()
|
|
972
|
+
{
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
|
|
976
|
+
END
|
|
977
|
+
hpp_template = <<END
|
|
978
|
+
template<typename T%(typename_list)>
|
|
979
|
+
class Constructor<T%(type_list)%(void_list)>
|
|
980
|
+
{
|
|
981
|
+
public:
|
|
982
|
+
static void construct(Object self%(arg_list))
|
|
983
|
+
{
|
|
984
|
+
DATA_PTR(self.value()) = new T(%(arg_names));
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
|
|
988
|
+
END
|
|
989
|
+
hpp_head = <<END
|
|
990
|
+
#include "to_from_ruby_defn.hpp"
|
|
991
|
+
#include "detail/method_data.hpp"
|
|
992
|
+
END
|
|
993
|
+
hpp_filename = 'Constructor.hpp'
|
|
994
|
+
wrap_header(hpp_filename, 'Rice', nil, false, hpp_head) do |hpp|
|
|
995
|
+
hpp.puts hpp_start
|
|
996
|
+
for j in 0..MAX_ARGS do
|
|
997
|
+
t_array = (1..j).to_a
|
|
998
|
+
o_array = (j..MAX_ARGS).to_a
|
|
999
|
+
typename_list = t_array.map { |x| ", typename Arg#{x}_T" }
|
|
1000
|
+
type_list = t_array.map { |x| ", Arg#{x}_T" }
|
|
1001
|
+
void_list = o_array.map { |x| ", void" }
|
|
1002
|
+
arg_list = t_array.map { |x| ", Arg#{x}_T arg#{x}" }
|
|
1003
|
+
arg_names = t_array.map { |x| "arg#{x}" }.join(', ')
|
|
1004
|
+
hpp.puts fill_template(hpp_template, {
|
|
1005
|
+
:typename_list => typename_list,
|
|
1006
|
+
:type_list => type_list,
|
|
1007
|
+
:void_list => void_list,
|
|
1008
|
+
:arg_list => arg_list,
|
|
1009
|
+
:arg_names => arg_names,
|
|
1010
|
+
})
|
|
1011
|
+
end
|
|
1012
|
+
end
|
|
1013
|
+
|
|
1014
|
+
if ARGV[0] == '--clean' then
|
|
1015
|
+
$filenames.each do |filename|
|
|
1016
|
+
File.rm_f(filename)
|
|
1017
|
+
end
|
|
1018
|
+
end
|
|
1019
|
+
|
|
1020
|
+
=begin
|
|
1021
|
+
# ======================================================================
|
|
1022
|
+
docstring = <<END
|
|
1023
|
+
END
|
|
1024
|
+
hpp_template = <<END
|
|
1025
|
+
struct Function_Traits<Ret_T, %(typenames)>
|
|
1026
|
+
{
|
|
1027
|
+
typedef Ret_T Result_Type;
|
|
1028
|
+
typedef
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
template<typename Ret_T, %(typename_list)>
|
|
1032
|
+
Function_Traits<Ret_T, %(typenames)> functor_traits(
|
|
1033
|
+
Ret_T (*func)(%(typenames)),
|
|
1034
|
+
Exception_Handler const * handler = 0);
|
|
1035
|
+
|
|
1036
|
+
template<typename Ret_T, typename Self_T%(typename_list_no_self)>
|
|
1037
|
+
Function_Traits<Ret_T, %(typenames)> functor_traits(
|
|
1038
|
+
Ret_T (Self_T::*func)(%(typenames_no_self_no_comma)),
|
|
1039
|
+
Exception_Handler const * handler = 0);
|
|
1040
|
+
|
|
1041
|
+
template<typename Ret_T, typename Self_T%(typename_list_no_self)>
|
|
1042
|
+
Member_Function_Traits<Ret_T, Self_T%(typenames_no_self) > functor_traits(
|
|
1043
|
+
Ret_T (Self_T::*func)(%(typenames_no_self_no_comma)) const,
|
|
1044
|
+
Exception_Handler const * handler = 0);
|
|
1045
|
+
|
|
1046
|
+
// ---------------------------------------------------------------------
|
|
1047
|
+
END
|
|
1048
|
+
hpp_head = <<END
|
|
1049
|
+
#include "Exception_Handler.hpp"
|
|
1050
|
+
#include "Wrapped_Function.hpp"
|
|
1051
|
+
|
|
1052
|
+
END
|
|
1053
|
+
hpp_tail = <<END
|
|
1054
|
+
|
|
1055
|
+
template<typename T>
|
|
1056
|
+
functor_traits(&T::operator())
|
|
1057
|
+
|
|
1058
|
+
END
|
|
1059
|
+
ipp_head = <<END
|
|
1060
|
+
#include "Auto_Function_Wrapper.hpp"
|
|
1061
|
+
#include "Auto_Member_Function_Wrapper.hpp"
|
|
1062
|
+
END
|
|
1063
|
+
ipp_filename = 'detail/function_traits.ipp'
|
|
1064
|
+
hpp_filename = 'detail/function_traits.hpp'
|
|
1065
|
+
wrap_header(hpp_filename, 'Rice::detail', docstring, true, hpp_head, hpp_tail) do |hpp|
|
|
1066
|
+
for j in 0..MAX_ARGS do
|
|
1067
|
+
t_array = (0..j).to_a
|
|
1068
|
+
typenames = t_array.map { |x| "Arg#{x}_T" }.join(', ')
|
|
1069
|
+
typename_list = t_array.map { |x| "typename Arg#{x}_T" }.join(', ')
|
|
1070
|
+
t_array.shift
|
|
1071
|
+
typenames_no_self = t_array.map { |x| ", Arg#{x}_T" }
|
|
1072
|
+
typename_list_no_self = t_array.map { |x| ", typename Arg#{x}_T" }
|
|
1073
|
+
typenames_no_self_no_comma = typenames_no_self.to_s.sub(', ', '')
|
|
1074
|
+
ipp.puts fill_template(ipp_template, {
|
|
1075
|
+
:typenames => typenames,
|
|
1076
|
+
:typename_list => typename_list,
|
|
1077
|
+
:typenames_no_self => typenames_no_self,
|
|
1078
|
+
:typename_list_no_self => typename_list_no_self,
|
|
1079
|
+
:typenames_no_self_no_comma => typenames_no_self_no_comma,
|
|
1080
|
+
})
|
|
1081
|
+
hpp.puts fill_template(hpp_template, {
|
|
1082
|
+
:typenames => typenames,
|
|
1083
|
+
:typename_list => typename_list,
|
|
1084
|
+
:typename_list_no_self => typename_list_no_self,
|
|
1085
|
+
:typenames_no_self_no_comma => typenames_no_self_no_comma,
|
|
1086
|
+
})
|
|
1087
|
+
end
|
|
1088
|
+
end
|
|
1089
|
+
=end
|
|
1090
|
+
|
|
1091
|
+
end # if __FILE__ == $0 then
|
|
1092
|
+
|