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,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
|
+
|
data/rice/Data_Type.cpp
ADDED
|
@@ -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
|
+
|
data/rice/Data_Type.hpp
ADDED
data/rice/Data_Type.ipp
ADDED
|
@@ -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_
|