rice2 2.2.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.
Files changed (190) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +23 -0
  3. data/Doxyfile +2268 -0
  4. data/Makefile.am +26 -0
  5. data/Makefile.in +929 -0
  6. data/README.md +1054 -0
  7. data/README.mingw +8 -0
  8. data/Rakefile +24 -0
  9. data/aclocal.m4 +1090 -0
  10. data/bootstrap +8 -0
  11. data/config.guess +1667 -0
  12. data/config.sub +1793 -0
  13. data/configure +8209 -0
  14. data/configure.ac +55 -0
  15. data/depcomp +791 -0
  16. data/doxygen.ac +314 -0
  17. data/doxygen.am +186 -0
  18. data/extconf.rb +66 -0
  19. data/install-sh +529 -0
  20. data/missing +215 -0
  21. data/post-autoconf.rb +22 -0
  22. data/post-automake.rb +28 -0
  23. data/rice/Address_Registration_Guard.cpp +22 -0
  24. data/rice/Address_Registration_Guard.hpp +7 -0
  25. data/rice/Address_Registration_Guard.ipp +37 -0
  26. data/rice/Address_Registration_Guard_defn.hpp +75 -0
  27. data/rice/Arg.hpp +8 -0
  28. data/rice/Arg_impl.hpp +129 -0
  29. data/rice/Arg_operators.cpp +21 -0
  30. data/rice/Arg_operators.hpp +19 -0
  31. data/rice/Array.hpp +214 -0
  32. data/rice/Array.ipp +256 -0
  33. data/rice/Builtin_Object.hpp +8 -0
  34. data/rice/Builtin_Object.ipp +50 -0
  35. data/rice/Builtin_Object_defn.hpp +50 -0
  36. data/rice/Class.cpp +57 -0
  37. data/rice/Class.hpp +8 -0
  38. data/rice/Class.ipp +6 -0
  39. data/rice/Class_defn.hpp +83 -0
  40. data/rice/Constructor.hpp +47 -0
  41. data/rice/Data_Object.hpp +8 -0
  42. data/rice/Data_Object.ipp +133 -0
  43. data/rice/Data_Object_defn.hpp +138 -0
  44. data/rice/Data_Type.cpp +54 -0
  45. data/rice/Data_Type.hpp +8 -0
  46. data/rice/Data_Type.ipp +365 -0
  47. data/rice/Data_Type_defn.hpp +261 -0
  48. data/rice/Data_Type_fwd.hpp +12 -0
  49. data/rice/Director.cpp +13 -0
  50. data/rice/Director.hpp +39 -0
  51. data/rice/Enum.hpp +117 -0
  52. data/rice/Enum.ipp +246 -0
  53. data/rice/Exception.cpp +59 -0
  54. data/rice/Exception.hpp +13 -0
  55. data/rice/Exception_Base.hpp +8 -0
  56. data/rice/Exception_Base.ipp +13 -0
  57. data/rice/Exception_Base_defn.hpp +27 -0
  58. data/rice/Exception_defn.hpp +69 -0
  59. data/rice/Hash.hpp +227 -0
  60. data/rice/Hash.ipp +329 -0
  61. data/rice/Identifier.cpp +8 -0
  62. data/rice/Identifier.hpp +50 -0
  63. data/rice/Identifier.ipp +33 -0
  64. data/rice/Jump_Tag.hpp +24 -0
  65. data/rice/Makefile.am +122 -0
  66. data/rice/Makefile.in +885 -0
  67. data/rice/Module.cpp +84 -0
  68. data/rice/Module.hpp +8 -0
  69. data/rice/Module.ipp +6 -0
  70. data/rice/Module_defn.hpp +88 -0
  71. data/rice/Module_impl.hpp +281 -0
  72. data/rice/Module_impl.ipp +345 -0
  73. data/rice/Object.cpp +169 -0
  74. data/rice/Object.hpp +8 -0
  75. data/rice/Object.ipp +33 -0
  76. data/rice/Object_defn.hpp +214 -0
  77. data/rice/Require_Guard.hpp +21 -0
  78. data/rice/String.cpp +94 -0
  79. data/rice/String.hpp +91 -0
  80. data/rice/Struct.cpp +117 -0
  81. data/rice/Struct.hpp +162 -0
  82. data/rice/Struct.ipp +26 -0
  83. data/rice/Symbol.cpp +25 -0
  84. data/rice/Symbol.hpp +66 -0
  85. data/rice/Symbol.ipp +44 -0
  86. data/rice/config.hpp +47 -0
  87. data/rice/config.hpp.in +46 -0
  88. data/rice/detail/Arguments.hpp +118 -0
  89. data/rice/detail/Auto_Function_Wrapper.hpp +898 -0
  90. data/rice/detail/Auto_Function_Wrapper.ipp +3694 -0
  91. data/rice/detail/Auto_Member_Function_Wrapper.hpp +897 -0
  92. data/rice/detail/Auto_Member_Function_Wrapper.ipp +2774 -0
  93. data/rice/detail/Caster.hpp +103 -0
  94. data/rice/detail/Exception_Handler.hpp +8 -0
  95. data/rice/detail/Exception_Handler.ipp +68 -0
  96. data/rice/detail/Exception_Handler_defn.hpp +96 -0
  97. data/rice/detail/Iterator.hpp +93 -0
  98. data/rice/detail/Not_Copyable.hpp +25 -0
  99. data/rice/detail/Wrapped_Function.hpp +33 -0
  100. data/rice/detail/cfp.hpp +24 -0
  101. data/rice/detail/cfp.ipp +51 -0
  102. data/rice/detail/check_ruby_type.cpp +27 -0
  103. data/rice/detail/check_ruby_type.hpp +23 -0
  104. data/rice/detail/creation_funcs.hpp +37 -0
  105. data/rice/detail/creation_funcs.ipp +36 -0
  106. data/rice/detail/default_allocation_func.hpp +23 -0
  107. data/rice/detail/default_allocation_func.ipp +11 -0
  108. data/rice/detail/define_method_and_auto_wrap.hpp +31 -0
  109. data/rice/detail/define_method_and_auto_wrap.ipp +30 -0
  110. data/rice/detail/demangle.cpp +56 -0
  111. data/rice/detail/demangle.hpp +19 -0
  112. data/rice/detail/env.hpp +11 -0
  113. data/rice/detail/from_ruby.hpp +43 -0
  114. data/rice/detail/from_ruby.ipp +60 -0
  115. data/rice/detail/method_data.cpp +92 -0
  116. data/rice/detail/method_data.hpp +21 -0
  117. data/rice/detail/node.hpp +13 -0
  118. data/rice/detail/protect.cpp +29 -0
  119. data/rice/detail/protect.hpp +34 -0
  120. data/rice/detail/ruby.hpp +74 -0
  121. data/rice/detail/ruby_version_code.hpp +6 -0
  122. data/rice/detail/ruby_version_code.hpp.in +6 -0
  123. data/rice/detail/st.hpp +22 -0
  124. data/rice/detail/to_ruby.hpp +22 -0
  125. data/rice/detail/to_ruby.ipp +36 -0
  126. data/rice/detail/traits.hpp +43 -0
  127. data/rice/detail/win32.hpp +16 -0
  128. data/rice/detail/wrap_function.hpp +66 -0
  129. data/rice/global_function.hpp +33 -0
  130. data/rice/global_function.ipp +22 -0
  131. data/rice/protect.hpp +38 -0
  132. data/rice/protect.ipp +1134 -0
  133. data/rice/ruby_mark.hpp +13 -0
  134. data/rice/ruby_try_catch.hpp +86 -0
  135. data/rice/rubypp.rb +97 -0
  136. data/rice/to_from_ruby.hpp +8 -0
  137. data/rice/to_from_ruby.ipp +418 -0
  138. data/rice/to_from_ruby_defn.hpp +70 -0
  139. data/ruby.ac +135 -0
  140. data/ruby/Makefile.am +1 -0
  141. data/ruby/Makefile.in +628 -0
  142. data/ruby/lib/Makefile.am +3 -0
  143. data/ruby/lib/Makefile.in +506 -0
  144. data/ruby/lib/mkmf-rice.rb.in +217 -0
  145. data/ruby/lib/version.rb +3 -0
  146. data/sample/Makefile.am +47 -0
  147. data/sample/Makefile.in +489 -0
  148. data/sample/enum/extconf.rb +3 -0
  149. data/sample/enum/sample_enum.cpp +54 -0
  150. data/sample/enum/test.rb +8 -0
  151. data/sample/inheritance/animals.cpp +98 -0
  152. data/sample/inheritance/extconf.rb +3 -0
  153. data/sample/inheritance/test.rb +7 -0
  154. data/sample/map/extconf.rb +3 -0
  155. data/sample/map/map.cpp +81 -0
  156. data/sample/map/test.rb +7 -0
  157. data/test/Makefile.am +72 -0
  158. data/test/Makefile.in +1213 -0
  159. data/test/ext/Makefile.am +41 -0
  160. data/test/ext/Makefile.in +483 -0
  161. data/test/ext/t1/Foo.hpp +10 -0
  162. data/test/ext/t1/extconf.rb +2 -0
  163. data/test/ext/t1/t1.cpp +15 -0
  164. data/test/ext/t2/extconf.rb +2 -0
  165. data/test/ext/t2/t2.cpp +11 -0
  166. data/test/test_Address_Registration_Guard.cpp +43 -0
  167. data/test/test_Array.cpp +248 -0
  168. data/test/test_Builtin_Object.cpp +71 -0
  169. data/test/test_Class.cpp +496 -0
  170. data/test/test_Constructor.cpp +128 -0
  171. data/test/test_Data_Object.cpp +275 -0
  172. data/test/test_Data_Type.cpp +348 -0
  173. data/test/test_Director.cpp +308 -0
  174. data/test/test_Enum.cpp +215 -0
  175. data/test/test_Exception.cpp +47 -0
  176. data/test/test_Hash.cpp +212 -0
  177. data/test/test_Identifier.cpp +70 -0
  178. data/test/test_Jump_Tag.cpp +17 -0
  179. data/test/test_Memory_Management.cpp +50 -0
  180. data/test/test_Module.cpp +497 -0
  181. data/test/test_Object.cpp +159 -0
  182. data/test/test_String.cpp +107 -0
  183. data/test/test_Struct.cpp +205 -0
  184. data/test/test_Symbol.cpp +63 -0
  185. data/test/test_To_From_Ruby.cpp +428 -0
  186. data/test/test_global_functions.cpp +114 -0
  187. data/test/test_rice.rb +41 -0
  188. data/test/unittest.cpp +136 -0
  189. data/test/unittest.hpp +294 -0
  190. metadata +297 -0
@@ -0,0 +1,138 @@
1
+ #ifndef Rice__Data_Object_defn__hpp_
2
+ #define Rice__Data_Object_defn__hpp_
3
+
4
+ #include "Object_defn.hpp"
5
+ #include "Data_Type_fwd.hpp"
6
+ #include "ruby_mark.hpp"
7
+ #include "detail/to_ruby.hpp"
8
+ #include "detail/ruby.hpp"
9
+
10
+ /*! \file
11
+ * \brief Provides a helper class for wrapping and unwrapping C++
12
+ * objects as Ruby objects.
13
+ */
14
+
15
+ namespace Rice
16
+ {
17
+
18
+ template<typename T>
19
+ struct Default_Mark_Function
20
+ {
21
+ typedef void (*Ruby_Data_Func)(T * obj);
22
+ static const Ruby_Data_Func mark;
23
+ };
24
+
25
+ template<typename T>
26
+ struct Default_Free_Function
27
+ {
28
+ static void free(T * obj) { delete obj; }
29
+ };
30
+
31
+
32
+ //! A smartpointer-like wrapper for Ruby data objects.
33
+ /*! A data object is a ruby object of type T_DATA, which is usually
34
+ * created by using the Data_Wrap_Struct or Data_Make_Struct macro.
35
+ * This class wraps creation of the data structure, providing a
36
+ * type-safe object-oriented interface to the underlying C interface.
37
+ * This class works in conjunction with the Data_Type class to ensure
38
+ * type safety.
39
+ *
40
+ * Example:
41
+ * \code
42
+ * class Foo { };
43
+ * ...
44
+ * Data_Type<Foo> rb_cFoo = define_class("Foo");
45
+ * ...
46
+ * // Wrap:
47
+ * Data_Object<Foo> foo1(new Foo);
48
+ *
49
+ * // Get value to return:
50
+ * VALUE v = foo1.value()
51
+ *
52
+ * // Unwrap:
53
+ * Data_Object<Foo> foo2(v, rb_cFoo);
54
+ * \endcode
55
+ */
56
+ template<typename T>
57
+ class Data_Object
58
+ : public Object
59
+ {
60
+ public:
61
+ //! A function that takes a T* and returns void.
62
+ typedef void (*Ruby_Data_Func)(T * obj);
63
+
64
+ //! Wrap a C++ object.
65
+ /*! This constructor is analogous to calling Data_Wrap_Struct. Be
66
+ * careful not to call this function more than once for the same
67
+ * pointer (in general, it should only be called for newly
68
+ * constructed objects that need to be managed by Ruby's garbage
69
+ * collector).
70
+ * \param obj the object to wrap.
71
+ * \param klass the Ruby class to use for the newly created Ruby
72
+ * object.
73
+ * \param mark_func a function that gets called by the garbage
74
+ * collector to mark the object's children.
75
+ * \param free_func a function that gets called by the garbage
76
+ * collector to free the object.
77
+ */
78
+ Data_Object(
79
+ T * obj,
80
+ VALUE klass = Data_Type<T>::klass(),
81
+ Ruby_Data_Func mark_func = Default_Mark_Function<T>::mark,
82
+ Ruby_Data_Func free_func = Default_Free_Function<T>::free);
83
+
84
+ //! Unwrap a Ruby object.
85
+ /*! This constructor is analogous to calling Data_Get_Struct. Uses
86
+ * Data_Type<T>::klass as the class of the object.
87
+ * \param value the Ruby object to unwrap.
88
+ */
89
+ Data_Object(
90
+ Object value);
91
+
92
+ //! Unwrap a Ruby object.
93
+ /*! This constructor is analogous to calling Data_Get_Struct. Will
94
+ * throw an exception if the class of the object differs from the
95
+ * specified class.
96
+ * \param value the Ruby object to unwrap.
97
+ * \param klass the expected class of the object.
98
+ */
99
+ template<typename U>
100
+ Data_Object(
101
+ Object value,
102
+ Data_Type<U> const & klass = Data_Type<T>::klass());
103
+
104
+ //! Make a copy of a Data_Object
105
+ /*! \param other the Data_Object to copy.
106
+ */
107
+ Data_Object(Data_Object const & other);
108
+
109
+ T & operator*() const { return *obj_; } //!< Return a reference to obj_
110
+ T * operator->() const { return obj_; } //!< Return a pointer to obj_
111
+ T * get() const { return obj_; } //!< Return a pointer to obj_
112
+
113
+ //! Swap with another data object of the same type
114
+ /*! \param ref the object with which to swap.
115
+ */
116
+ template<typename U>
117
+ void swap(Data_Object<U> & ref);
118
+
119
+ private:
120
+ static void check_cpp_type(Data_Type<T> const & klass);
121
+
122
+ private:
123
+ T * obj_;
124
+ };
125
+
126
+ namespace detail
127
+ {
128
+ template<typename T>
129
+ struct to_ruby_<Data_Object<T> >
130
+ {
131
+ static Rice::Object convert(Data_Object<T> const & x);
132
+ };
133
+ }
134
+
135
+ } // namespace Rice
136
+
137
+ #endif // Rice__Data_Object_defn__hpp_
138
+
@@ -0,0 +1,54 @@
1
+ #include "Data_Type.hpp"
2
+
3
+ Rice::Data_Type_Base::Casters * Rice::Data_Type_Base::casters_ = 0;
4
+
5
+ Rice::Data_Type_Base::
6
+ Data_Type_Base()
7
+ : Module_impl<Class, Data_Type_Base>()
8
+ {
9
+ }
10
+
11
+ Rice::Data_Type_Base::
12
+ Data_Type_Base(VALUE v)
13
+ : Module_impl<Class, Data_Type_Base>(v)
14
+ {
15
+ }
16
+
17
+ Rice::Data_Type_Base::
18
+ ~Data_Type_Base()
19
+ {
20
+ }
21
+
22
+ Rice::Data_Type_Base::Casters &
23
+ Rice::Data_Type_Base::
24
+ casters()
25
+ {
26
+ // Initialize the casters_ if it is null
27
+ if (!casters_)
28
+ {
29
+ // First, see if it has been previously registered with the
30
+ // interpreter (possibly by another extension)
31
+ Class object(rb_cObject);
32
+ Object casters_object(object.attr_get("__rice_casters__"));
33
+
34
+ if (casters_object.is_nil())
35
+ {
36
+ // If it is unset, then set it for the first time
37
+ Data_Object<Casters> casters(
38
+ new Casters,
39
+ rb_cObject);
40
+ object.iv_set("__rice_casters__", casters);
41
+ casters_ = casters.get();
42
+ }
43
+ else
44
+ {
45
+ // If it is set, then use the existing value
46
+ Data_Object<Casters> casters(
47
+ casters_object);
48
+ casters_ = casters.get();
49
+ }
50
+ }
51
+
52
+ return *casters_;
53
+ }
54
+
@@ -0,0 +1,8 @@
1
+ #ifndef Rice__Data_Type__hpp_
2
+ #define Rice__Data_Type__hpp_
3
+
4
+ #include "Data_Type_defn.hpp"
5
+ #include "Data_Type.ipp"
6
+
7
+ #endif // Rice__Data_Type__hpp_
8
+
@@ -0,0 +1,365 @@
1
+ #ifndef Rice__Data_Type__ipp_
2
+ #define Rice__Data_Type__ipp_
3
+
4
+ #include "Class.hpp"
5
+ #include "String.hpp"
6
+ #include "Data_Object.hpp"
7
+ #include "detail/default_allocation_func.hpp"
8
+ #include "detail/creation_funcs.hpp"
9
+ #include "detail/method_data.hpp"
10
+ #include "detail/Caster.hpp"
11
+ #include "detail/demangle.hpp"
12
+
13
+ #include <stdexcept>
14
+ #include <typeinfo>
15
+
16
+ template<typename T>
17
+ VALUE Rice::Data_Type<T>::klass_ = Qnil;
18
+
19
+ template<typename T>
20
+ std_unique_ptr<Rice::detail::Abstract_Caster> Rice::Data_Type<T>::caster_;
21
+
22
+ template<typename T>
23
+ template<typename Base_T>
24
+ inline Rice::Data_Type<T> Rice::Data_Type<T>::
25
+ bind(Module const & klass)
26
+ {
27
+ if(klass.value() == klass_)
28
+ {
29
+ return Data_Type<T>();
30
+ }
31
+
32
+ if(is_bound())
33
+ {
34
+ std::string s;
35
+ s = "Data type ";
36
+ s += detail::demangle(typeid(T).name());
37
+ s += " is already bound to a different type";
38
+ throw std::runtime_error(s.c_str());
39
+ }
40
+
41
+ // TODO: Make sure base type is bound; throw an exception otherwise.
42
+ // We can't do this just yet, because we don't have a specialization
43
+ // for binding to void.
44
+ klass_ = klass;
45
+
46
+ // TODO: do we need to unregister when the program exits? we have to
47
+ // be careful if we do, because the ruby interpreter might have
48
+ // already shut down. The correct behavior is probably to register an
49
+ // exit proc with the interpreter, so the proc gets called before the
50
+ // GC shuts down.
51
+ rb_gc_register_address(&klass_);
52
+
53
+ for(typename Instances::iterator it = unbound_instances().begin(),
54
+ end = unbound_instances().end();
55
+ it != end;
56
+ unbound_instances().erase(it++))
57
+ {
58
+ (*it)->set_value(klass);
59
+ }
60
+
61
+ detail::Abstract_Caster * base_caster = Data_Type<Base_T>().caster();
62
+ caster_.reset(new detail::Caster<T, Base_T>(base_caster, klass));
63
+ Data_Type_Base::casters().insert(std::make_pair(klass, caster_.get()));
64
+ return Data_Type<T>();
65
+ }
66
+
67
+ template<typename T>
68
+ inline Rice::Data_Type<T>::
69
+ Data_Type()
70
+ : Module_impl<Data_Type_Base, Data_Type<T> >(
71
+ klass_ == Qnil ? rb_cObject : klass_)
72
+ {
73
+ if(!is_bound())
74
+ {
75
+ unbound_instances().insert(this);
76
+ }
77
+ }
78
+
79
+ template<typename T>
80
+ inline Rice::Data_Type<T>::
81
+ Data_Type(Module const & klass)
82
+ : Module_impl<Data_Type_Base, Data_Type<T> >(
83
+ klass)
84
+ {
85
+ this->bind<void>(klass);
86
+ }
87
+
88
+ template<typename T>
89
+ inline Rice::Data_Type<T>::
90
+ ~Data_Type()
91
+ {
92
+ unbound_instances().erase(this);
93
+ }
94
+
95
+ template<typename T>
96
+ Rice::Module
97
+ Rice::Data_Type<T>::
98
+ klass() {
99
+ if(is_bound())
100
+ {
101
+ return klass_;
102
+ }
103
+ else
104
+ {
105
+ std::string s;
106
+ s += detail::demangle(typeid(T *).name());
107
+ s += " is unbound";
108
+ throw std::runtime_error(s.c_str());
109
+ }
110
+ }
111
+
112
+ template<typename T>
113
+ Rice::Data_Type<T> & Rice::Data_Type<T>::
114
+ operator=(Module const & klass)
115
+ {
116
+ this->bind<void>(klass);
117
+ return *this;
118
+ }
119
+
120
+ template<typename T>
121
+ template<typename Constructor_T>
122
+ inline Rice::Data_Type<T> & Rice::Data_Type<T>::
123
+ define_constructor(
124
+ Constructor_T /* constructor */,
125
+ Arguments* arguments)
126
+ {
127
+ check_is_bound();
128
+
129
+ // Normal constructor pattern with new/initialize
130
+ rb_define_alloc_func(
131
+ static_cast<VALUE>(*this),
132
+ detail::default_allocation_func<T>);
133
+ this->define_method(
134
+ "initialize",
135
+ &Constructor_T::construct,
136
+ arguments
137
+ );
138
+
139
+ return *this;
140
+ }
141
+
142
+ template<typename T>
143
+ template<typename Constructor_T>
144
+ inline Rice::Data_Type<T> & Rice::Data_Type<T>::
145
+ define_constructor(
146
+ Constructor_T constructor,
147
+ Arg const& arg)
148
+ {
149
+ Arguments* args = new Arguments();
150
+ args->add(arg);
151
+ return define_constructor(constructor, args);
152
+ }
153
+
154
+
155
+ template<typename T>
156
+ template<typename Director_T>
157
+ inline Rice::Data_Type<T>& Rice::Data_Type<T>::
158
+ define_director()
159
+ {
160
+ Rice::Data_Type<Director_T>::template bind<T>(*this);
161
+ return *this;
162
+ }
163
+
164
+ template<typename T>
165
+ inline T * Rice::Data_Type<T>::
166
+ from_ruby(Object x)
167
+ {
168
+ check_is_bound();
169
+
170
+ void * v = DATA_PTR(x.value());
171
+ Class klass = x.class_of();
172
+
173
+ if(klass.value() == klass_)
174
+ {
175
+ // Great, not converting to a base/derived type
176
+ Data_Type<T> data_klass;
177
+ Data_Object<T> obj(x, data_klass);
178
+ return obj.get();
179
+ }
180
+
181
+ Data_Type_Base::Casters::const_iterator it = Data_Type_Base::casters().begin();
182
+ Data_Type_Base::Casters::const_iterator end = Data_Type_Base::casters().end();
183
+
184
+ // Finding the bound type that relates to the given klass is
185
+ // a two step process. We iterate over the list of known type casters,
186
+ // looking for:
187
+ //
188
+ // 1) casters that handle this direct type
189
+ // 2) casters that handle types that are ancestors of klass
190
+ //
191
+ // Step 2 allows us to handle the case where a Rice-wrapped class
192
+ // is subclassed in Ruby but then an instance of that class is passed
193
+ // back into C++ (say, in a Listener / callback construction)
194
+ //
195
+
196
+ VALUE ancestors = rb_mod_ancestors(klass.value());
197
+
198
+ long earliest = RARRAY_LEN(ancestors) + 1;
199
+
200
+ int index;
201
+ VALUE indexFound;
202
+ Data_Type_Base::Casters::const_iterator toUse = end;
203
+
204
+ for(; it != end; it++) {
205
+ // Do we match directly?
206
+ if(klass.value() == it->first) {
207
+ toUse = it;
208
+ break;
209
+ }
210
+
211
+ // Check for ancestors. Trick is, we need to find the lowest
212
+ // ancestor that does have a Caster to make sure that we're casting
213
+ // to the closest C++ type that the Ruby class is subclassing.
214
+ // There might be multiple ancestors that are also wrapped in
215
+ // the extension, so find the earliest in the list and use that one.
216
+ indexFound = rb_funcall(ancestors, rb_intern("index"), 1, it->first);
217
+
218
+ if(indexFound != Qnil) {
219
+ index = NUM2INT(indexFound);
220
+
221
+ if(index < earliest) {
222
+ earliest = index;
223
+ toUse = it;
224
+ }
225
+ }
226
+ }
227
+
228
+ if(toUse == end)
229
+ {
230
+ std::string s = "Class ";
231
+ s += klass.name().str();
232
+ s += " is not registered/bound in Rice";
233
+ throw std::runtime_error(s);
234
+ }
235
+
236
+ detail::Abstract_Caster * caster = toUse->second;
237
+ if(caster)
238
+ {
239
+ T * result = static_cast<T *>(caster->cast_to_base(v, klass_));
240
+ return result;
241
+ }
242
+ else
243
+ {
244
+ return static_cast<T *>(v);
245
+ }
246
+ }
247
+
248
+ template<typename T>
249
+ inline bool Rice::Data_Type<T>::
250
+ is_bound()
251
+ {
252
+ return klass_ != Qnil;
253
+ }
254
+
255
+ template<typename T>
256
+ inline Rice::detail::Abstract_Caster * Rice::Data_Type<T>::
257
+ caster() const
258
+ {
259
+ check_is_bound();
260
+ return caster_.get();
261
+ }
262
+
263
+ namespace Rice
264
+ {
265
+
266
+ template<>
267
+ inline detail::Abstract_Caster * Data_Type<void>::
268
+ caster() const
269
+ {
270
+ return 0;
271
+ }
272
+
273
+ template<typename T>
274
+ void Data_Type<T>::
275
+ check_is_bound()
276
+ {
277
+ if(!is_bound())
278
+ {
279
+ std::string s;
280
+ s = "Data type ";
281
+ s += detail::demangle(typeid(T).name());
282
+ s += " is not bound";
283
+ throw std::runtime_error(s.c_str());
284
+ }
285
+ }
286
+
287
+ } // Rice
288
+
289
+ template<typename T>
290
+ inline Rice::Data_Type<T> Rice::
291
+ define_class_under(
292
+ Object module,
293
+ char const * name)
294
+ {
295
+ Class c(define_class_under(module, name, rb_cObject));
296
+ c.undef_creation_funcs();
297
+ return Data_Type<T>::template bind<void>(c);
298
+ }
299
+
300
+ template<typename T, typename Base_T>
301
+ inline Rice::Data_Type<T> Rice::
302
+ define_class_under(
303
+ Object module,
304
+ char const * name)
305
+ {
306
+ Data_Type<Base_T> base_dt;
307
+ Class c(define_class_under(module, name, base_dt));
308
+ c.undef_creation_funcs();
309
+ return Data_Type<T>::template bind<Base_T>(c);
310
+ }
311
+
312
+ template<typename T>
313
+ inline Rice::Data_Type<T> Rice::
314
+ define_class(
315
+ char const * name)
316
+ {
317
+ Class c(define_class(name, rb_cObject));
318
+ c.undef_creation_funcs();
319
+ return Data_Type<T>::template bind<void>(c);
320
+ }
321
+
322
+ template<typename T, typename Base_T>
323
+ inline Rice::Data_Type<T> Rice::
324
+ define_class(
325
+ char const * name)
326
+ {
327
+ Data_Type<Base_T> base_dt;
328
+ Class c(define_class(name, base_dt));
329
+ c.undef_creation_funcs();
330
+ return Data_Type<T>::template bind<Base_T>(c);
331
+ }
332
+
333
+ template<typename From_T, typename To_T>
334
+ inline void
335
+ Rice::define_implicit_cast()
336
+ {
337
+ // As Rice currently expects only one entry into
338
+ // this list for a given klass VALUE, we need to get
339
+ // the current caster for From_T and insert in our
340
+ // new caster as the head of the caster list
341
+
342
+ Class from_class = Data_Type<From_T>::klass().value();
343
+ Class to_class = Data_Type<To_T>::klass().value();
344
+
345
+ detail::Abstract_Caster* from_caster =
346
+ Data_Type<From_T>::caster_.release();
347
+
348
+ detail::Abstract_Caster* new_caster =
349
+ new detail::Implicit_Caster<To_T, From_T>(from_caster, to_class);
350
+
351
+ // Insert our new caster into the list for the from class
352
+ Data_Type_Base::casters().erase(from_class);
353
+ Data_Type_Base::casters().insert(
354
+ std::make_pair(
355
+ from_class,
356
+ new_caster
357
+ )
358
+ );
359
+
360
+ // And make sure the from_class has direct access to the
361
+ // updated caster list
362
+ Data_Type<From_T>::caster_.reset(new_caster);
363
+ }
364
+
365
+ #endif // Rice__Data_Type__ipp_