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.
Files changed (166) hide show
  1. data/COPYING +23 -0
  2. data/Doxyfile +1253 -0
  3. data/Makefile.am +26 -0
  4. data/Makefile.in +736 -0
  5. data/README +881 -0
  6. data/README.mingw +8 -0
  7. data/bootstrap +8 -0
  8. data/config.guess +1535 -0
  9. data/config.sub +1644 -0
  10. data/configure +7310 -0
  11. data/configure.ac +48 -0
  12. data/depcomp +584 -0
  13. data/doxygen.ac +314 -0
  14. data/doxygen.am +186 -0
  15. data/install-sh +507 -0
  16. data/missing +367 -0
  17. data/post-autoconf.rb +22 -0
  18. data/post-automake.rb +28 -0
  19. data/rice/Address_Registration_Guard.hpp +7 -0
  20. data/rice/Address_Registration_Guard.ipp +34 -0
  21. data/rice/Address_Registration_Guard_defn.hpp +65 -0
  22. data/rice/Allocation_Strategies.hpp +37 -0
  23. data/rice/Array.hpp +220 -0
  24. data/rice/Array.ipp +262 -0
  25. data/rice/Builtin_Object.hpp +8 -0
  26. data/rice/Builtin_Object.ipp +50 -0
  27. data/rice/Builtin_Object_defn.hpp +51 -0
  28. data/rice/Class.cpp +57 -0
  29. data/rice/Class.hpp +8 -0
  30. data/rice/Class.ipp +4 -0
  31. data/rice/Class_defn.hpp +83 -0
  32. data/rice/Constructor.hpp +189 -0
  33. data/rice/Critical_Guard.hpp +34 -0
  34. data/rice/Critical_Guard.ipp +20 -0
  35. data/rice/Data_Object.hpp +127 -0
  36. data/rice/Data_Object.ipp +129 -0
  37. data/rice/Data_Type.cpp +21 -0
  38. data/rice/Data_Type.hpp +8 -0
  39. data/rice/Data_Type.ipp +227 -0
  40. data/rice/Data_Type_defn.hpp +219 -0
  41. data/rice/Data_Type_fwd.hpp +12 -0
  42. data/rice/Enum.hpp +118 -0
  43. data/rice/Enum.ipp +246 -0
  44. data/rice/Exception.cpp +59 -0
  45. data/rice/Exception.hpp +69 -0
  46. data/rice/Exception_Base.hpp +30 -0
  47. data/rice/Exception_Base.ipp +11 -0
  48. data/rice/Hash.hpp +206 -0
  49. data/rice/Hash.ipp +336 -0
  50. data/rice/Identifier.cpp +8 -0
  51. data/rice/Identifier.hpp +50 -0
  52. data/rice/Identifier.ipp +33 -0
  53. data/rice/Jump_Tag.hpp +24 -0
  54. data/rice/Makefile.am +112 -0
  55. data/rice/Makefile.in +675 -0
  56. data/rice/Module.cpp +75 -0
  57. data/rice/Module.hpp +8 -0
  58. data/rice/Module.ipp +6 -0
  59. data/rice/Module_defn.hpp +87 -0
  60. data/rice/Module_impl.hpp +237 -0
  61. data/rice/Module_impl.ipp +302 -0
  62. data/rice/Object.cpp +153 -0
  63. data/rice/Object.hpp +8 -0
  64. data/rice/Object.ipp +19 -0
  65. data/rice/Object_defn.hpp +183 -0
  66. data/rice/Require_Guard.hpp +21 -0
  67. data/rice/String.cpp +93 -0
  68. data/rice/String.hpp +88 -0
  69. data/rice/Struct.cpp +117 -0
  70. data/rice/Struct.hpp +162 -0
  71. data/rice/Struct.ipp +26 -0
  72. data/rice/Symbol.cpp +25 -0
  73. data/rice/Symbol.hpp +66 -0
  74. data/rice/Symbol.ipp +44 -0
  75. data/rice/VM.cpp +79 -0
  76. data/rice/VM.hpp +27 -0
  77. data/rice/config.hpp +23 -0
  78. data/rice/config.hpp.in +22 -0
  79. data/rice/detail/Auto_Function_Wrapper.hpp +719 -0
  80. data/rice/detail/Auto_Function_Wrapper.ipp +1354 -0
  81. data/rice/detail/Auto_Member_Function_Wrapper.hpp +685 -0
  82. data/rice/detail/Auto_Member_Function_Wrapper.ipp +1435 -0
  83. data/rice/detail/Caster.hpp +61 -0
  84. data/rice/detail/Exception_Handler.hpp +118 -0
  85. data/rice/detail/Iterator_Definer.hpp +98 -0
  86. data/rice/detail/Not_Copyable.hpp +25 -0
  87. data/rice/detail/Wrapped_Function.hpp +33 -0
  88. data/rice/detail/check_ruby_type.cpp +21 -0
  89. data/rice/detail/check_ruby_type.hpp +23 -0
  90. data/rice/detail/creation_funcs.hpp +45 -0
  91. data/rice/detail/creation_funcs.ipp +62 -0
  92. data/rice/detail/default_allocation_func.hpp +23 -0
  93. data/rice/detail/default_allocation_func.ipp +11 -0
  94. data/rice/detail/define_method_and_auto_wrap.hpp +27 -0
  95. data/rice/detail/define_method_and_auto_wrap.ipp +20 -0
  96. data/rice/detail/env.hpp +13 -0
  97. data/rice/detail/from_ruby.hpp +43 -0
  98. data/rice/detail/from_ruby.ipp +74 -0
  99. data/rice/detail/method_data.cpp +105 -0
  100. data/rice/detail/method_data.hpp +33 -0
  101. data/rice/detail/node.hpp +13 -0
  102. data/rice/detail/object_call.hpp +85 -0
  103. data/rice/detail/object_call.ipp +147 -0
  104. data/rice/detail/protect.cpp +27 -0
  105. data/rice/detail/protect.hpp +34 -0
  106. data/rice/detail/remove_const.hpp +21 -0
  107. data/rice/detail/ruby.hpp +85 -0
  108. data/rice/detail/rubysig.hpp +13 -0
  109. data/rice/detail/st.hpp +56 -0
  110. data/rice/detail/to_ruby.hpp +16 -0
  111. data/rice/detail/to_ruby.ipp +10 -0
  112. data/rice/detail/win32.hpp +16 -0
  113. data/rice/detail/wrap_function.hpp +288 -0
  114. data/rice/detail/wrap_function.ipp +473 -0
  115. data/rice/generate_code.rb +1092 -0
  116. data/rice/global_function.hpp +16 -0
  117. data/rice/global_function.ipp +11 -0
  118. data/rice/protect.hpp +91 -0
  119. data/rice/protect.ipp +803 -0
  120. data/rice/ruby_try_catch.hpp +86 -0
  121. data/rice/to_from_ruby.hpp +8 -0
  122. data/rice/to_from_ruby.ipp +299 -0
  123. data/rice/to_from_ruby_defn.hpp +71 -0
  124. data/ruby.ac +105 -0
  125. data/ruby/Makefile.am +1 -0
  126. data/ruby/Makefile.in +493 -0
  127. data/ruby/lib/Makefile.am +3 -0
  128. data/ruby/lib/Makefile.in +369 -0
  129. data/ruby/lib/mkmf-rice.rb.in +199 -0
  130. data/sample/Makefile.am +47 -0
  131. data/sample/Makefile.in +375 -0
  132. data/sample/enum/extconf.rb +3 -0
  133. data/sample/enum/sample_enum.cpp +54 -0
  134. data/sample/enum/test.rb +8 -0
  135. data/sample/inheritance/animals.cpp +98 -0
  136. data/sample/inheritance/extconf.rb +3 -0
  137. data/sample/inheritance/test.rb +7 -0
  138. data/sample/map/extconf.rb +3 -0
  139. data/sample/map/map.cpp +81 -0
  140. data/sample/map/test.rb +7 -0
  141. data/test/Makefile.am +44 -0
  142. data/test/Makefile.in +575 -0
  143. data/test/test_Address_Registration_Guard.cpp +43 -0
  144. data/test/test_Allocation_Strategies.cpp +77 -0
  145. data/test/test_Array.cpp +241 -0
  146. data/test/test_Builtin_Object.cpp +72 -0
  147. data/test/test_Class.cpp +350 -0
  148. data/test/test_Constructor.cpp +30 -0
  149. data/test/test_Critical_Guard.cpp +47 -0
  150. data/test/test_Data_Object.cpp +235 -0
  151. data/test/test_Enum.cpp +162 -0
  152. data/test/test_Exception.cpp +46 -0
  153. data/test/test_Hash.cpp +195 -0
  154. data/test/test_Identifier.cpp +70 -0
  155. data/test/test_Jump_Tag.cpp +17 -0
  156. data/test/test_Module.cpp +253 -0
  157. data/test/test_Object.cpp +148 -0
  158. data/test/test_String.cpp +94 -0
  159. data/test/test_Struct.cpp +192 -0
  160. data/test/test_Symbol.cpp +63 -0
  161. data/test/test_To_From_Ruby.cpp +281 -0
  162. data/test/test_VM.cpp +26 -0
  163. data/test/test_rice.rb +30 -0
  164. data/test/unittest.cpp +136 -0
  165. data/test/unittest.hpp +292 -0
  166. metadata +209 -0
@@ -0,0 +1,34 @@
1
+ #ifndef Rice__ruby_Critical_Guard__hpp_
2
+ #define Rice__ruby_Critical_Guard__hpp_
3
+
4
+ namespace Rice
5
+ {
6
+
7
+ //! A guard to prevent Ruby from switching threads.
8
+ /*! Sets rb_thread_critical to 1 upon construction and back to its
9
+ * original value upon destruction. This prevents the scheduler from
10
+ * changing threads. This does not work on YARV, however, which has a
11
+ * different threading model.
12
+ */
13
+ class Critical_Guard
14
+ {
15
+ public:
16
+ //! Prevent ruby from switching threads.
17
+ /*! Prevent the ruby scheduler from switching threads by setting
18
+ * rb_thread_critical to 1.
19
+ */
20
+ Critical_Guard();
21
+
22
+ //! Allow ruby to switch threads.
23
+ /*! Allow the ruby scheduler to switch threads by setting
24
+ * rb_thread_critical to 0.
25
+ */
26
+ ~Critical_Guard();
27
+ };
28
+
29
+ }
30
+
31
+ #include "Critical_Guard.ipp"
32
+
33
+ #endif // Rice__ruby_Critical_Guard__hpp_
34
+
@@ -0,0 +1,20 @@
1
+ #ifndef Rice__ruby_Critical_Guard__ipp_
2
+ #define Rice__ruby_Critical_Guard__ipp_
3
+
4
+ #include "detail/ruby.hpp"
5
+ #include "detail/rubysig.hpp"
6
+
7
+ inline Rice::Critical_Guard::
8
+ Critical_Guard()
9
+ {
10
+ rb_thread_critical = 1;
11
+ }
12
+
13
+ inline Rice::Critical_Guard::
14
+ ~Critical_Guard()
15
+ {
16
+ rb_thread_critical = 0;
17
+ }
18
+
19
+ #endif // Rice__ruby_Critical_Guard__ipp_
20
+
@@ -0,0 +1,127 @@
1
+ #ifndef Rice__Data_Object__hpp_
2
+ #define Rice__Data_Object__hpp_
3
+
4
+ #include "Object_defn.hpp"
5
+ #include "Data_Type_fwd.hpp"
6
+ #include "Allocation_Strategies.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
+ //! A smartpointer-like wrapper for Ruby data objects.
19
+ /*! A data object is a ruby object of type T_DATA, which is usually
20
+ * created by using the Data_Wrap_Struct or Data_Make_Struct macro.
21
+ * This class wraps creation of the data structure, providing a
22
+ * type-safe object-oriented interface to the underlying C interface.
23
+ * This class works in conjunction with the Data_Type class to ensure
24
+ * type safety.
25
+ *
26
+ * Example:
27
+ * \code
28
+ * class Foo { };
29
+ * ...
30
+ * Data_Type<Foo> rb_cFoo = define_class("Foo");
31
+ * ...
32
+ * // Wrap:
33
+ * Data_Object<Foo> foo1(new Foo);
34
+ *
35
+ * // Get value to return:
36
+ * VALUE v = foo1.value()
37
+ *
38
+ * // Unwrap:
39
+ * Data_Object<Foo> foo2(v, rb_cFoo);
40
+ * \endcode
41
+ */
42
+ template<typename T>
43
+ class Data_Object
44
+ : public Object
45
+ {
46
+ public:
47
+ //! A function that takes a T* and returns void.
48
+ typedef void (*Ruby_Data_Func)(T * obj);
49
+
50
+ //! Wrap a C++ object.
51
+ /*! This constructor is analgous to calling Data_Wrap_Struct. Be
52
+ * careful not to call this function more than once for the same
53
+ * pointer (in general, it should only be called for newly
54
+ * constructed objects that need to be managed by Ruby's garbage
55
+ * collector).
56
+ * \param obj the object to wrap.
57
+ * \param klass the Ruby class to use for the newly created Ruby
58
+ * object.
59
+ * \param mark_func a function that gets called by the garbage
60
+ * collector to mark the object's children.
61
+ * \param free_func a function that gets called by the garbage
62
+ * collector to free the object.
63
+ */
64
+ Data_Object(
65
+ T * obj,
66
+ VALUE klass = Data_Type<T>::klass(),
67
+ Ruby_Data_Func mark_func = 0,
68
+ Ruby_Data_Func free_func = Default_Allocation_Strategy<T>::free);
69
+
70
+ //! Unwrap a Ruby object.
71
+ /*! This constructor is analgous to calling Data_Get_Struct. Uses
72
+ * Data_Type<T>::klass as the class of the object.
73
+ * \param value the Ruby object to unwrap.
74
+ */
75
+ Data_Object(
76
+ Object value);
77
+
78
+ //! Unwrap a Ruby object.
79
+ /*! This constructor is analgous to calling Data_Get_Struct. Will
80
+ * throw an exception if the class of the object differs from the
81
+ * specified class.
82
+ * \param value the Ruby object to unwrap.
83
+ * \param klass the expected class of the object.
84
+ */
85
+ template<typename U>
86
+ Data_Object(
87
+ Object value,
88
+ Data_Type<U> const & klass = Data_Type<T>::klass());
89
+
90
+ //! Make a copy of a Data_Object
91
+ /*! \param other the Data_Object to copy.
92
+ */
93
+ Data_Object(Data_Object const & other);
94
+
95
+ T & operator*() const { return *obj_; } //!< Return a reference to obj_
96
+ T * operator->() const { return obj_; } //!< Return a pointer to obj_
97
+ T * get() const { return obj_; } //!< Return a pointer to obj_
98
+
99
+ //! Swap with another data object of the same type
100
+ /*! \param ref the object with which to swap.
101
+ */
102
+ template<typename U>
103
+ void swap(Data_Object<U> & ref);
104
+
105
+ private:
106
+ static void check_cpp_type(Data_Type<T> const & klass);
107
+
108
+ private:
109
+ T * obj_;
110
+ };
111
+
112
+ namespace detail
113
+ {
114
+ template<typename T>
115
+ struct to_ruby_<Data_Object<T> >
116
+ {
117
+ static Rice::Object convert(Data_Object<T> const & x);
118
+ };
119
+ }
120
+
121
+ } // namespace Rice
122
+
123
+ #include "Object.hpp"
124
+ #include "Data_Object.ipp"
125
+
126
+ #endif // Rice__Data_Object__hpp_
127
+
@@ -0,0 +1,129 @@
1
+ #ifndef Rice__Data_Object__ipp_
2
+ #define Rice__Data_Object__ipp_
3
+
4
+ #include "detail/check_ruby_type.hpp"
5
+ #include "protect.hpp"
6
+
7
+ #include <algorithm>
8
+
9
+ namespace Rice
10
+ {
11
+
12
+ namespace detail
13
+ {
14
+
15
+ inline VALUE data_wrap_struct(
16
+ VALUE klass,
17
+ RUBY_DATA_FUNC mark,
18
+ RUBY_DATA_FUNC free,
19
+ void * obj)
20
+ {
21
+ return Data_Wrap_Struct(klass, mark, free, obj);
22
+ }
23
+
24
+ template<typename T>
25
+ inline VALUE wrap(
26
+ VALUE klass,
27
+ typename Data_Object<T>::Ruby_Data_Func mark,
28
+ typename Data_Object<T>::Ruby_Data_Func free,
29
+ T * obj)
30
+ {
31
+ // We cast to obj void* here before passing to Data_Wrap_Struct,
32
+ // becuase otherwise compilation will fail if obj is const. It's safe
33
+ // to do this, because unwrap() will always add the const back when
34
+ // the object is unwrapped.
35
+ return Rice::protect(data_wrap_struct,
36
+ klass,
37
+ reinterpret_cast<RUBY_DATA_FUNC>(mark),
38
+ reinterpret_cast<RUBY_DATA_FUNC>(free),
39
+ (void *)obj);
40
+ }
41
+
42
+ template<typename T>
43
+ inline VALUE data_get_struct(VALUE value, T * * obj)
44
+ {
45
+ Data_Get_Struct(value, T, *obj);
46
+ return Qnil;
47
+ }
48
+
49
+ template<typename T>
50
+ inline T * unwrap(VALUE value)
51
+ {
52
+ T * obj;
53
+ Rice::protect(data_get_struct<T>, value, &obj);
54
+ return obj;
55
+ }
56
+
57
+ } // namespace detail
58
+
59
+ } // namespace Rice
60
+
61
+ template<typename T>
62
+ inline Rice::Data_Object<T>::
63
+ Data_Object(
64
+ T * obj,
65
+ VALUE klass,
66
+ Ruby_Data_Func mark_func,
67
+ Ruby_Data_Func free_func)
68
+ : Object(detail::wrap(klass, mark_func, free_func, obj))
69
+ , obj_(obj)
70
+ {
71
+ }
72
+
73
+ template<typename T>
74
+ inline Rice::Data_Object<T>::
75
+ Data_Object(
76
+ Object value)
77
+ : Object(value)
78
+ , obj_(detail::unwrap<T>(value))
79
+ {
80
+ Data_Type<T> klass;
81
+ check_cpp_type(klass);
82
+ detail::check_ruby_type(value, klass, true);
83
+ }
84
+
85
+ template<typename T>
86
+ template<typename U>
87
+ inline Rice::Data_Object<T>::
88
+ Data_Object(
89
+ Object value,
90
+ Data_Type<U> const & klass)
91
+ : Object(value)
92
+ , obj_(detail::unwrap<T>(value))
93
+ {
94
+ check_cpp_type(klass);
95
+ detail::check_ruby_type(value, klass, true);
96
+ }
97
+
98
+ template<typename T>
99
+ inline Rice::Data_Object<T>::
100
+ Data_Object(Data_Object const & other)
101
+ : Object(other.value())
102
+ , obj_(other.obj_)
103
+ {
104
+ }
105
+
106
+ template<typename T>
107
+ template<typename U>
108
+ inline void Rice::Data_Object<T>::
109
+ swap(Data_Object<U> & ref)
110
+ {
111
+ std::swap(obj_, ref.obj_);
112
+ Object::swap(*this, ref);
113
+ }
114
+
115
+ template<typename T>
116
+ inline void Rice::Data_Object<T>::
117
+ check_cpp_type(Data_Type<T> const & /* klass */)
118
+ {
119
+ }
120
+
121
+ template<typename T>
122
+ Rice::Object Rice::detail::to_ruby_<Rice::Data_Object<T> >::
123
+ convert(Rice::Data_Object<T> const & x)
124
+ {
125
+ return x;
126
+ }
127
+
128
+ #endif // Rice__Data_Object__ipp_
129
+
@@ -0,0 +1,21 @@
1
+ #include "Data_Type.hpp"
2
+
3
+ Rice::Data_Type_Base::Casters Rice::Data_Type_Base::casters_;
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
+
@@ -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,227 @@
1
+ #ifndef Rice__Data_Type__ipp_
2
+ #define Rice__Data_Type__ipp_
3
+
4
+ #include "Class.hpp"
5
+ #include "Data_Object.hpp"
6
+ #include "detail/default_allocation_func.hpp"
7
+ #include "detail/creation_funcs.hpp"
8
+ #include "detail/method_data.hpp"
9
+ #include "detail/Caster.hpp"
10
+
11
+ #include <stdexcept>
12
+ #include <typeinfo>
13
+
14
+ template<typename T>
15
+ VALUE Rice::Data_Type<T>::klass_ = Qnil;
16
+
17
+ template<typename T>
18
+ std::auto_ptr<Rice::detail::Abstract_Caster> Rice::Data_Type<T>::caster_;
19
+
20
+ template<typename T>
21
+ template<typename Base_T>
22
+ inline Rice::Data_Type<T> Rice::Data_Type<T>::
23
+ bind(Module const & klass)
24
+ {
25
+ if(klass.value() == klass_)
26
+ {
27
+ return Data_Type<T>();
28
+ }
29
+
30
+ if(is_bound())
31
+ {
32
+ std::string s;
33
+ s = "Data type ";
34
+ s = typeid(T).name();
35
+ s += " is already bound to a different type";
36
+ throw std::runtime_error(s.c_str());
37
+ }
38
+
39
+ // TODO: Make sure base type is bound; throw an exception otherwise.
40
+ // We can't do this just yet, because we don't have a specialization
41
+ // for binding to void.
42
+ klass_ = klass;
43
+
44
+ // TODO: do we need to unregister when the program exits? we have to
45
+ // be careful if we do, because the ruby interpreter might have
46
+ // already shut down. The correct behavior is probably to register an
47
+ // exit proc with the interpreter, so the proc gets called before the
48
+ // GC shuts down.
49
+ rb_gc_register_address(&klass_);
50
+
51
+ for(typename Instances::iterator it = unbound_instances().begin(),
52
+ end = unbound_instances().end();
53
+ it != end;
54
+ unbound_instances().erase(it++))
55
+ {
56
+ (*it)->set_value(klass);
57
+ }
58
+
59
+ detail::Abstract_Caster * base_caster = Data_Type<Base_T>().caster();
60
+ caster_.reset(new detail::Caster<T, Base_T>(base_caster, klass));
61
+ Data_Type_Base::casters_.insert(std::make_pair(klass, caster_.get()));
62
+ return Data_Type<T>();
63
+ }
64
+
65
+ template<typename T>
66
+ inline Rice::Data_Type<T>::
67
+ Data_Type()
68
+ : Module_impl<Data_Type_Base, Data_Type<T> >(
69
+ klass_ == Qnil ? rb_cObject : klass_)
70
+ {
71
+ unbound_instances().insert(this);
72
+ }
73
+
74
+ template<typename T>
75
+ inline Rice::Data_Type<T>::
76
+ Data_Type(Module const & klass)
77
+ : Module_impl<Data_Type_Base, Data_Type<T> >(
78
+ klass)
79
+ {
80
+ this->bind<void>(klass);
81
+ }
82
+
83
+ template<typename T>
84
+ inline Rice::Data_Type<T>::
85
+ ~Data_Type()
86
+ {
87
+ unbound_instances().erase(this);
88
+ }
89
+
90
+ template<typename T>
91
+ Rice::Data_Type<T> & Rice::Data_Type<T>::
92
+ operator=(Module const & klass)
93
+ {
94
+ this->bind<void>(klass);
95
+ return *this;
96
+ }
97
+
98
+ template<typename T>
99
+ template<typename Constructor_T>
100
+ inline Rice::Data_Type<T> & Rice::Data_Type<T>::
101
+ define_constructor(
102
+ Constructor_T constructor)
103
+ {
104
+ check_is_bound();
105
+
106
+ // Normal constructor pattern with new/initialize
107
+ detail::define_alloc_func(
108
+ static_cast<VALUE>(*this),
109
+ detail::default_allocation_func<T>);
110
+ define_method("initialize", &Constructor_T::construct);
111
+
112
+ return *this;
113
+ }
114
+
115
+ template<typename T>
116
+ inline T * Rice::Data_Type<T>::
117
+ from_ruby(Object x)
118
+ {
119
+ check_is_bound();
120
+
121
+ void * v = DATA_PTR(x.value());
122
+ Class klass = x.class_of();
123
+ Data_Type_Base::Casters::const_iterator it(
124
+ Data_Type_Base::casters_.find(klass));
125
+ if(it == Data_Type_Base::casters_.end())
126
+ {
127
+ throw std::runtime_error("Derived type is unbound");
128
+ }
129
+
130
+ detail::Abstract_Caster * caster = it->second;
131
+ if(caster)
132
+ {
133
+ T * result = static_cast<T *>(caster->cast_to_base(v, klass_));
134
+ return result;
135
+ }
136
+ else
137
+ {
138
+ return static_cast<T *>(v);
139
+ }
140
+ }
141
+
142
+ template<typename T>
143
+ inline bool Rice::Data_Type<T>::
144
+ is_bound()
145
+ {
146
+ return klass_ != Qnil;
147
+ }
148
+
149
+ template<typename T>
150
+ inline Rice::detail::Abstract_Caster * Rice::Data_Type<T>::
151
+ caster() const
152
+ {
153
+ check_is_bound();
154
+ return caster_.get();
155
+ }
156
+
157
+ namespace Rice
158
+ {
159
+
160
+ template<>
161
+ inline detail::Abstract_Caster * Data_Type<void>::
162
+ caster() const
163
+ {
164
+ return 0;
165
+ }
166
+
167
+ template<typename T>
168
+ void Data_Type<T>::
169
+ check_is_bound()
170
+ {
171
+ if(!is_bound())
172
+ {
173
+ std::string s;
174
+ s = "Data type ";
175
+ s = typeid(T).name();
176
+ s += " is not bound";
177
+ throw std::runtime_error(s.c_str());
178
+ }
179
+ }
180
+
181
+ } // Rice
182
+
183
+ template<typename T>
184
+ inline Rice::Data_Type<T> Rice::
185
+ define_class_under(
186
+ Object module,
187
+ char const * name)
188
+ {
189
+ Class c(define_class_under(module, name, rb_cObject));
190
+ c.undef_creation_funcs();
191
+ return Data_Type<T>::template bind<void>(c);
192
+ }
193
+
194
+ template<typename T, typename Base_T>
195
+ inline Rice::Data_Type<T> Rice::
196
+ define_class_under(
197
+ Object module,
198
+ char const * name)
199
+ {
200
+ Data_Type<Base_T> base_dt;
201
+ Class c(define_class_under(module, name, base_dt));
202
+ c.undef_creation_funcs();
203
+ return Data_Type<T>::template bind<Base_T>(c);
204
+ }
205
+
206
+ template<typename T>
207
+ inline Rice::Data_Type<T> Rice::
208
+ define_class(
209
+ char const * name)
210
+ {
211
+ Class c(define_class(name, rb_cObject));
212
+ c.undef_creation_funcs();
213
+ return Data_Type<T>::template bind<void>(c);
214
+ }
215
+
216
+ template<typename T, typename Base_T>
217
+ inline Rice::Data_Type<T> Rice::
218
+ define_class(
219
+ char const * name)
220
+ {
221
+ Data_Type<Base_T> base_dt;
222
+ Class c(define_class(name, base_dt));
223
+ c.undef_creation_funcs();
224
+ return Data_Type<T>::template bind<Base_T>(c);
225
+ }
226
+
227
+ #endif // Rice__Data_Type__ipp_