rice 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/Doxyfile +1 -1
  2. data/Makefile.in +3 -2
  3. data/README +247 -16
  4. data/aclocal.m4 +62 -51
  5. data/configure +1585 -1456
  6. data/extconf.rb +9 -1
  7. data/rice/Arg.hpp +8 -0
  8. data/rice/Arg_impl.hpp +124 -0
  9. data/rice/Arg_operators.cpp +21 -0
  10. data/rice/Arg_operators.hpp +19 -0
  11. data/rice/Constructor.hpp +150 -0
  12. data/rice/Data_Type.ipp +51 -6
  13. data/rice/Director.cpp +19 -0
  14. data/rice/Director.hpp +47 -0
  15. data/rice/Enum.hpp +2 -3
  16. data/rice/Enum.ipp +1 -1
  17. data/rice/Hash.hpp +1 -1
  18. data/rice/Makefile.am +7 -0
  19. data/rice/Makefile.in +18 -7
  20. data/rice/Module_impl.hpp +36 -3
  21. data/rice/Module_impl.ipp +56 -7
  22. data/rice/VM.cpp +2 -2
  23. data/rice/config.hpp +1 -1
  24. data/rice/detail/Arguments.hpp +118 -0
  25. data/rice/detail/Auto_Function_Wrapper.hpp +206 -96
  26. data/rice/detail/Auto_Function_Wrapper.ipp +1687 -144
  27. data/rice/detail/Auto_Member_Function_Wrapper.hpp +234 -123
  28. data/rice/detail/Auto_Member_Function_Wrapper.ipp +1133 -306
  29. data/rice/detail/Caster.hpp +3 -1
  30. data/rice/detail/creation_funcs.hpp +0 -8
  31. data/rice/detail/creation_funcs.ipp +1 -27
  32. data/rice/detail/define_method_and_auto_wrap.hpp +3 -1
  33. data/rice/detail/define_method_and_auto_wrap.ipp +4 -3
  34. data/rice/detail/object_call.ipp +1 -1
  35. data/rice/detail/ruby.hpp +1 -33
  36. data/rice/detail/wrap_function.hpp +103 -48
  37. data/rice/detail/wrap_function.ipp +154 -96
  38. data/rice/generate_code.rb +520 -55
  39. data/rice/global_function.hpp +12 -1
  40. data/rice/global_function.ipp +14 -2
  41. data/ruby/Makefile.in +5 -4
  42. data/ruby/lib/Makefile.in +4 -3
  43. data/ruby/lib/version.rb +1 -1
  44. data/sample/Makefile.in +4 -3
  45. data/test/Makefile.am +2 -0
  46. data/test/Makefile.in +32 -13
  47. data/test/test_Class.cpp +36 -14
  48. data/test/test_Constructor.cpp +176 -1
  49. data/test/test_Data_Type.cpp +121 -0
  50. data/test/test_Director.cpp +225 -0
  51. data/test/test_Enum.cpp +33 -0
  52. data/test/test_Module.cpp +175 -0
  53. data/test/test_global_functions.cpp +70 -1
  54. metadata +27 -7
data/extconf.rb CHANGED
@@ -19,4 +19,12 @@ gem_name = "rice-#{Rice::VERSION}"
19
19
  prefix_dir = File.join(Gem.default_dir, "gems", gem_name, "ruby", "lib")
20
20
  with_ruby = File.join(Config::CONFIG["bindir"], Config::CONFIG["RUBY_INSTALL_NAME"])
21
21
 
22
- system "./configure --with-ruby=#{with_ruby} --prefix=#{prefix_dir}"
22
+ other_opts = ""
23
+ env = ""
24
+
25
+ if RUBY_PLATFORM =~ /darwin10/
26
+ other_opts = "--disable-dependency-tracking"
27
+ env = "ARCHFLAGS='-arch x86_64'"
28
+ end
29
+
30
+ system "#{env} ./configure --with-ruby=#{with_ruby} --prefix=#{prefix_dir} #{other_opts}"
@@ -0,0 +1,8 @@
1
+ #ifndef Rice__Arg__hpp_
2
+ #define Rice__Arg__hpp_
3
+
4
+ #include "Arg_impl.hpp"
5
+ #include "detail/Arguments.hpp"
6
+ #include "Arg_operators.hpp"
7
+
8
+ #endif // Rice__Arg__hpp_
@@ -0,0 +1,124 @@
1
+ #ifndef Rice__Arg_Impl_hpp_
2
+ #define Rice__Arg_Impl_hpp_
3
+
4
+ namespace Rice {
5
+
6
+ //! Helper for defining default arguments of a method
7
+ /*! This class exposes the ability to define the default values of a
8
+ * wrapped method. Inspired by how Boost.Python handles keyword and
9
+ * default arguments, the syntax is simple:
10
+ *
11
+ * define_method(
12
+ * "method",
13
+ * &method,
14
+ * (Arg("arg1"), Arg("arg2") = 3, Arg("arg3") = true)
15
+ * );
16
+ *
17
+ * which means "for method &method, it takes 3 arguments
18
+ * [arg1, arg2, arg3]. Of these arguments, arg2's default is 3
19
+ * and arg3's default is true.
20
+ *
21
+ * It may be required to explicitly cast the type of the default
22
+ * value to prevent compilation errors.
23
+ */
24
+ class Arg
25
+ {
26
+ public:
27
+ //! Initialize a new Arg with the name of the argument
28
+ /*! We require the name of the argument because 1) it makes code
29
+ * easier to read and 2) hopefully Ruby gets keyword arguments
30
+ * in the future and this means Rice will be ready for it.
31
+ */
32
+ Arg(const char* name)
33
+ : name_(name)
34
+ , defaultValue(0)
35
+ {}
36
+
37
+ //! Copy Constructor
38
+ Arg(const Arg& other)
39
+ : name_(other.name()),
40
+ defaultValue(other.defaultValue ? other.defaultValue->clone() : 0)
41
+ {}
42
+
43
+ virtual ~Arg()
44
+ {
45
+ }
46
+
47
+ //! Set the default value for this Arg
48
+ /*! Set the default value for this argument.
49
+ * If this isn't called on this Arg, then this
50
+ * Arg is required in the method call.
51
+ *
52
+ * \param val the value to store as default
53
+ */
54
+ template<typename Arg_Type>
55
+ Arg& operator=(Arg_Type const& val)
56
+ {
57
+ defaultValue = new type<Arg_Type>(val);
58
+ return *this;
59
+ }
60
+
61
+ //! Check if this Arg has a default value associated with it
62
+ bool hasDefaultValue() const {
63
+ return defaultValue != 0;
64
+ }
65
+
66
+ //! Return the default value associated with this Arg
67
+ /*! \return the type saved to this Arg
68
+ */
69
+ template<typename Arg_Type>
70
+ Arg_Type getDefaultValue() const
71
+ {
72
+ return static_cast< type<Arg_Type>* >(defaultValue)->held;
73
+ }
74
+
75
+ //! Get the name of this Arg
76
+ const char* name() const
77
+ {
78
+ return name_;
79
+ }
80
+
81
+ private:
82
+
83
+ //! Name of the argument
84
+ const char* name_;
85
+
86
+ /**
87
+ * The following is a stripped down version of
88
+ * Boost.Any.
89
+ */
90
+
91
+ class type_base
92
+ {
93
+ public:
94
+ virtual ~type_base() {}
95
+ virtual type_base* clone() const = 0;
96
+ };
97
+
98
+ template<typename Type>
99
+ class type : public type_base
100
+ {
101
+ public:
102
+ type(Type value)
103
+ :held(value)
104
+ {}
105
+
106
+ virtual ~type() { }
107
+
108
+ virtual type_base* clone() const
109
+ {
110
+ return new type(held);
111
+ }
112
+
113
+ Type held;
114
+ };
115
+
116
+ public:
117
+
118
+ //! Our saved default value
119
+ type_base* defaultValue;
120
+ };
121
+
122
+ }
123
+
124
+ #endif // Rice__Arg_Impl_hpp_
@@ -0,0 +1,21 @@
1
+ #include "Arg_impl.hpp"
2
+ #include "detail/Arguments.hpp"
3
+ #include "Arg_operators.hpp"
4
+
5
+ namespace Rice {
6
+
7
+ Arguments* operator,(const Arg& arg1, const Arg& arg2)
8
+ {
9
+ Arguments* a = new Arguments();
10
+ a->add(arg1);
11
+ a->add(arg2);
12
+ return a;
13
+ }
14
+
15
+ Arguments* operator,(Arguments* arguments, const Arg& arg)
16
+ {
17
+ arguments->add(arg);
18
+ return arguments;
19
+ }
20
+
21
+ }
@@ -0,0 +1,19 @@
1
+ #ifndef Rice__Arg_Operators_hpp_
2
+ #define Rice__Arg_Operators_hpp_
3
+
4
+ namespace Rice
5
+ {
6
+
7
+ //! Build the list of Arg objects into an Arguments object
8
+ /*! Take a list of Arg objects and build up a single Argument
9
+ * object used later in method dispatch
10
+ */
11
+ Arguments* operator,(const Arg& arg1, const Arg& arg2);
12
+
13
+ /*! @see operator,(Arg, Arg)
14
+ */
15
+ Arguments* operator,(Arguments* arguments, const Arg& arg);
16
+
17
+ }
18
+
19
+ #endif // Rice__Arg_Operators_hpp_
@@ -181,6 +181,156 @@ public:
181
181
  }
182
182
  };
183
183
 
184
+ template<typename T>
185
+ class Constructor<T, Object, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
186
+ {
187
+ public:
188
+ static void construct(Object self)
189
+ {
190
+ DATA_PTR(self.value()) = new T(self);
191
+ }
192
+ };
193
+
194
+ template<typename T, typename Arg1_T>
195
+ class Constructor<T, Object, Arg1_T, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
196
+ {
197
+ public:
198
+ static void construct(Object self, Arg1_T arg1)
199
+ {
200
+ DATA_PTR(self.value()) = new T(self, arg1);
201
+ }
202
+ };
203
+
204
+ template<typename T, typename Arg1_T, typename Arg2_T>
205
+ class Constructor<T, Object, Arg1_T, Arg2_T, void, void, void, void, void, void, void, void, void, void, void, void, void>
206
+ {
207
+ public:
208
+ static void construct(Object self, Arg1_T arg1, Arg2_T arg2)
209
+ {
210
+ DATA_PTR(self.value()) = new T(self, arg1, arg2);
211
+ }
212
+ };
213
+
214
+ template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T>
215
+ class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, void, void, void, void, void, void, void, void, void, void, void, void>
216
+ {
217
+ public:
218
+ static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3)
219
+ {
220
+ DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3);
221
+ }
222
+ };
223
+
224
+ template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T>
225
+ class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, void, void, void, void, void, void, void, void, void, void, void>
226
+ {
227
+ public:
228
+ static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4)
229
+ {
230
+ DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4);
231
+ }
232
+ };
233
+
234
+ template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T>
235
+ class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, void, void, void, void, void, void, void, void, void, void>
236
+ {
237
+ public:
238
+ static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5)
239
+ {
240
+ DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5);
241
+ }
242
+ };
243
+
244
+ template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T>
245
+ class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, void, void, void, void, void, void, void, void, void>
246
+ {
247
+ public:
248
+ static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6)
249
+ {
250
+ DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6);
251
+ }
252
+ };
253
+
254
+ template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T>
255
+ class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, void, void, void, void, void, void, void, void>
256
+ {
257
+ public:
258
+ static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7)
259
+ {
260
+ DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
261
+ }
262
+ };
263
+
264
+ template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T>
265
+ class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, void, void, void, void, void, void, void>
266
+ {
267
+ public:
268
+ static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8)
269
+ {
270
+ DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
271
+ }
272
+ };
273
+
274
+ template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T, typename Arg9_T>
275
+ class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, Arg9_T, void, void, void, void, void, void>
276
+ {
277
+ public:
278
+ static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8, Arg9_T arg9)
279
+ {
280
+ DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
281
+ }
282
+ };
283
+
284
+ template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T, typename Arg9_T, typename Arg10_T>
285
+ class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, Arg9_T, Arg10_T, void, void, void, void, void>
286
+ {
287
+ public:
288
+ static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8, Arg9_T arg9, Arg10_T arg10)
289
+ {
290
+ DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
291
+ }
292
+ };
293
+
294
+ template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T, typename Arg9_T, typename Arg10_T, typename Arg11_T>
295
+ class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, Arg9_T, Arg10_T, Arg11_T, void, void, void, void>
296
+ {
297
+ public:
298
+ static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8, Arg9_T arg9, Arg10_T arg10, Arg11_T arg11)
299
+ {
300
+ DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
301
+ }
302
+ };
303
+
304
+ template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T, typename Arg9_T, typename Arg10_T, typename Arg11_T, typename Arg12_T>
305
+ class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, Arg9_T, Arg10_T, Arg11_T, Arg12_T, void, void, void>
306
+ {
307
+ public:
308
+ static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8, Arg9_T arg9, Arg10_T arg10, Arg11_T arg11, Arg12_T arg12)
309
+ {
310
+ DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
311
+ }
312
+ };
313
+
314
+ template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T, typename Arg9_T, typename Arg10_T, typename Arg11_T, typename Arg12_T, typename Arg13_T>
315
+ class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, Arg9_T, Arg10_T, Arg11_T, Arg12_T, Arg13_T, void, void>
316
+ {
317
+ public:
318
+ static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8, Arg9_T arg9, Arg10_T arg10, Arg11_T arg11, Arg12_T arg12, Arg13_T arg13)
319
+ {
320
+ DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13);
321
+ }
322
+ };
323
+
324
+ template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T, typename Arg9_T, typename Arg10_T, typename Arg11_T, typename Arg12_T, typename Arg13_T, typename Arg14_T>
325
+ class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, Arg9_T, Arg10_T, Arg11_T, Arg12_T, Arg13_T, Arg14_T, void>
326
+ {
327
+ public:
328
+ static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8, Arg9_T arg9, Arg10_T arg10, Arg11_T arg11, Arg12_T arg12, Arg13_T arg13, Arg14_T arg14)
329
+ {
330
+ DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14);
331
+ }
332
+ };
333
+
184
334
 
185
335
  } // namespace Rice
186
336
 
@@ -126,7 +126,7 @@ define_constructor(
126
126
  check_is_bound();
127
127
 
128
128
  // Normal constructor pattern with new/initialize
129
- detail::define_alloc_func(
129
+ rb_define_alloc_func(
130
130
  static_cast<VALUE>(*this),
131
131
  detail::default_allocation_func<T>);
132
132
  define_method("initialize", &Constructor_T::construct);
@@ -151,17 +151,62 @@ from_ruby(Object x)
151
151
  return obj.get();
152
152
  }
153
153
 
154
- Data_Type_Base::Casters::const_iterator it(
155
- Data_Type_Base::casters_.find(klass));
156
- if(it == Data_Type_Base::casters_.end())
154
+ Data_Type_Base::Casters::const_iterator it = Data_Type_Base::casters_.begin();
155
+ Data_Type_Base::Casters::const_iterator end = Data_Type_Base::casters_.end();
156
+
157
+ // Finding the bound type that relates to the given klass is
158
+ // a two step process. We iterate over the list of known type casters,
159
+ // looking for:
160
+ //
161
+ // 1) casters that handle this direct type
162
+ // 2) casters that handle types that are ancestors of klass
163
+ //
164
+ // Step 2 allows us to handle the case where a Rice-wrapped class
165
+ // is subclassed in Ruby but then an instance of that class is passed
166
+ // back into C++ (say, in a Listener / callback construction)
167
+ //
168
+
169
+ VALUE ancestors = rb_mod_ancestors(klass.value());
170
+
171
+ int earliest = RARRAY_LEN(ancestors) + 1;
172
+
173
+ int index;
174
+ VALUE indexFound;
175
+ Data_Type_Base::Casters::const_iterator toUse = end;
176
+
177
+ for(; it != end; it++) {
178
+ // Do we match directly?
179
+ if(klass.value() == it->first) {
180
+ toUse = it;
181
+ break;
182
+ }
183
+
184
+ // Check for ancestors. Trick is, we need to find the lowest
185
+ // ancestor that does have a Caster to make sure that we're casting
186
+ // to the closest C++ type that the Ruby class is subclassing.
187
+ // There might be multiple ancestors that are also wrapped in
188
+ // the extension, so find the earliest in the list and use that one.
189
+ indexFound = rb_funcall(ancestors, rb_intern("index"), 1, it->first);
190
+
191
+ if(indexFound != Qnil) {
192
+ index = NUM2INT(indexFound);
193
+
194
+ if(index < earliest) {
195
+ earliest = index;
196
+ toUse = it;
197
+ }
198
+ }
199
+ }
200
+
201
+ if(toUse == end)
157
202
  {
158
- std::string s = "Derived class ";
203
+ std::string s = "Class ";
159
204
  s += klass.name().str();
160
205
  s += " is not registered/bound in Rice";
161
206
  throw std::runtime_error(s);
162
207
  }
163
208
 
164
- detail::Abstract_Caster * caster = it->second;
209
+ detail::Abstract_Caster * caster = toUse->second;
165
210
  if(caster)
166
211
  {
167
212
  T * result = static_cast<T *>(caster->cast_to_base(v, klass_));
@@ -0,0 +1,19 @@
1
+ #include "Director.hpp"
2
+
3
+ #include "detail/env.hpp"
4
+
5
+ namespace Rice {
6
+
7
+ Director::Director(Object self) {
8
+ self_ = self;
9
+ }
10
+
11
+ bool Director::callIsFromRuby(const char* methodName) const {
12
+ return (getSelf().value() == ruby_frame->self) && ( rb_id2name(ruby_frame->orig_func) != methodName );
13
+ }
14
+
15
+ void Director::raisePureVirtual() const {
16
+ rb_raise(rb_eNotImpError, "Cannot call super() into a pure-virtual C++ method");
17
+ }
18
+
19
+ }
@@ -0,0 +1,47 @@
1
+ #ifndef Rice__Director__hpp_
2
+ #define Rice__Director__hpp_
3
+
4
+ #include "Object.hpp"
5
+
6
+ namespace Rice {
7
+
8
+ /**
9
+ * A Director works exactly as a SWIG %director works (thus the name).
10
+ * You use this class to help build proxy classes so that polymorphism
11
+ * works from C++ into Ruby.
12
+ */
13
+ class Director
14
+ {
15
+ public:
16
+ //! Construct new Director. Needs the Ruby object so that the
17
+ // proxy class can call methods on that object.
18
+ Director(Object self);
19
+
20
+ virtual ~Director() { }
21
+
22
+ //! Is the current method call path coming from Ruby?
23
+ /*! This method allows one to choose the call chain according
24
+ * to the direction of the execution path. We need to do
25
+ * this to prevent infinite loops where super() calls could
26
+ * inadvertantly call methods back in Ruby
27
+ */
28
+ bool callIsFromRuby(const char* methodName) const;
29
+
30
+ //! Raise a ruby exception when a call comes through for a pure virtual method
31
+ /*! If a Ruby script calls 'super' on a method that's otherwise a pure virtual
32
+ * method, use this method to throw an exception in this case.
33
+ */
34
+ void raisePureVirtual() const;
35
+
36
+ //! Get the Ruby object linked to this C++ instance
37
+ Object getSelf() const { return self_; }
38
+
39
+ private:
40
+
41
+ // Save the Ruby object related to the instance of this class
42
+ Object self_;
43
+
44
+ };
45
+ }
46
+
47
+ #endif // Rice__Director__hpp_