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,219 @@
1
+ #ifndef Rice__Data_Type_defn__hpp_
2
+ #define Rice__Data_Type_defn__hpp_
3
+
4
+ #include "Class_defn.hpp"
5
+ #include "Data_Type_fwd.hpp"
6
+ #include "detail/ruby.hpp"
7
+ #include <memory>
8
+ #include <map>
9
+ #include <set>
10
+
11
+ /*!
12
+ * \example map/map.cpp
13
+ */
14
+
15
+ namespace Rice
16
+ {
17
+
18
+ namespace detail
19
+ {
20
+ class Abstract_Caster;
21
+ }
22
+
23
+ class Module;
24
+
25
+ //! The base class for all instantiations of Data_Type.
26
+ class Data_Type_Base
27
+ : public Module_impl<Class, Data_Type_Base>
28
+ {
29
+ public:
30
+ //! Default constructor.
31
+ Data_Type_Base();
32
+
33
+ //! Constructor.
34
+ Data_Type_Base(VALUE v);
35
+
36
+ //! Destructor.
37
+ virtual ~Data_Type_Base() = 0;
38
+
39
+ // Must be public to workaround gcc 3.3
40
+ typedef std::map<VALUE, detail::Abstract_Caster *> Casters;
41
+
42
+ protected:
43
+ virtual detail::Abstract_Caster * caster() const = 0;
44
+
45
+ static Casters casters_;
46
+ };
47
+
48
+ //! Define a new data class in the namespace given by module.
49
+ /*! The class will have a base class of Object.
50
+ * \param T the C++ type of the wrapped class.
51
+ * \param module the the Module in which to define the class.
52
+ * \return the new class.
53
+ */
54
+ template<typename T>
55
+ Rice::Data_Type<T> define_class_under(
56
+ Object module,
57
+ char const * name);
58
+
59
+ //! Define a new data class in the namespace given by module.
60
+ /*! The class with have a base class determined by Base_T (specifically,
61
+ * Data_Type<Base_T>::klass). Therefore, the type Base_T must already
62
+ * have been registered using define_class<> or define_class_under<>.
63
+ * \param T the C++ type of the wrapped class.
64
+ * \param module the the Module in which to define the class.
65
+ * \return the new class.
66
+ */
67
+ template<typename T, typename Base_T>
68
+ Rice::Data_Type<T> define_class_under(
69
+ Object module,
70
+ char const * name);
71
+
72
+ //! Define a new data class in the default namespace.
73
+ /*! The class will have a base class of Object.
74
+ * \param T the C++ type of the wrapped class.
75
+ * \return the new class.
76
+ */
77
+ template<typename T>
78
+ Rice::Data_Type<T> define_class(
79
+ char const * name);
80
+
81
+ //! Define a new data class in the default namespace.
82
+ /*! The class with have a base class determined by Base_T (specifically,
83
+ * Data_Type<Base_T>::klass). Therefore, the type Base_T must already
84
+ * have been registered using define_class<> or define_class_under<>.
85
+ * \param T the C++ type of the wrapped class.
86
+ * \param module the the Module in which to define the class.
87
+ * \return the new class.
88
+ */
89
+ template<typename T, typename Base_T>
90
+ Rice::Data_Type<T> define_class(
91
+ char const * name);
92
+
93
+
94
+ //! A mechanism for binding ruby types to C++ types.
95
+ /*! This class binds run-time types (Ruby VALUEs) to compile-time types
96
+ * (C++ types). The binding can occur only once.
97
+ */
98
+ template<typename T>
99
+ class Data_Type
100
+ : public Module_impl<Data_Type_Base, Data_Type<T> >
101
+ {
102
+ public:
103
+ //! The C++ type being held.
104
+ typedef T Type;
105
+
106
+ //! Default constructor which does not bind.
107
+ /*! No member functions must be called on this Data_Type except bind,
108
+ * until the type is bound.
109
+ */
110
+ Data_Type();
111
+
112
+ //! Constructor which takes a Module.
113
+ /*! Binds the type to the given VALUE according to the rules given
114
+ * above.
115
+ * \param klass the module to which to bind.
116
+ */
117
+ Data_Type(Module const & v);
118
+
119
+ //! Destructor.
120
+ virtual ~Data_Type();
121
+
122
+ //! Explictly return the Ruby type.
123
+ /*! \return the ruby class to which the type is bound.
124
+ */
125
+ static Module klass() { return klass_; }
126
+
127
+ //! Assignment operator which takes a Module
128
+ /*! \param klass must be the class to which this data type is already
129
+ * bound.
130
+ * \return *this
131
+ */
132
+ virtual Data_Type & operator=(Module const & klass);
133
+
134
+ //! Define a constructor for the class.
135
+ /*! Creates a singleton method allocate and an instance method called
136
+ * initialize which together create a new instance of the class. The
137
+ * allocate method allocates memory for the object reference and the
138
+ * initialize method constructs the object.
139
+ * \param constructor an object that has a static member function
140
+ * construct() that constructs a new instance of T and sets the object's data
141
+ * member to point to the new instance. A helper class Constructor
142
+ * is provided that does precisely this.
143
+ * For example:
144
+ * \code
145
+ * define_class<Foo>("Foo")
146
+ * .define_constructor(Constructor<Foo>());
147
+ * \endcode
148
+ */
149
+ template<typename Constructor_T>
150
+ Data_Type<T> & define_constructor(
151
+ Constructor_T constructor);
152
+
153
+ //! Convert ruby object x to type T.
154
+ /*! \param x the object to convert.
155
+ * \return the C++ object wrapped inside object x.
156
+ */
157
+ static T * from_ruby(Object x);
158
+
159
+ //! Determine if the type is bound.
160
+ /*! \return true if the object is bound, false otherwise.
161
+ */
162
+ static bool is_bound();
163
+
164
+ protected:
165
+ //! Bind a Data_Type to a VALUE.
166
+ /*! Throws an exception if the Data_Type is already bound to a
167
+ * different class. Any existing instances of the Data_Type will be
168
+ * bound after this function returns.
169
+ * \param klass the ruby type to which to bind.
170
+ * \return *this
171
+ */
172
+ template<typename Base_T>
173
+ static Data_Type bind(Module const & klass);
174
+
175
+ template<typename T_>
176
+ friend Rice::Data_Type<T_> define_class_under(
177
+ Object module,
178
+ char const * name);
179
+
180
+ template<typename T_, typename Base_T_>
181
+ friend Rice::Data_Type<T_> define_class_under(
182
+ Object module,
183
+ char const * name);
184
+
185
+ template<typename T_>
186
+ friend Rice::Data_Type<T_> Rice::define_class(
187
+ char const * name);
188
+
189
+ template<typename T_, typename Base_T_>
190
+ friend Rice::Data_Type<T_> define_class(
191
+ char const * name);
192
+
193
+ private:
194
+ template<typename T_>
195
+ friend class Data_Type;
196
+
197
+ virtual detail::Abstract_Caster * caster() const;
198
+
199
+ static void check_is_bound();
200
+
201
+ static VALUE klass_;
202
+ static std::auto_ptr<detail::Abstract_Caster> caster_;
203
+
204
+ typedef std::set<Data_Type<T> *> Instances;
205
+
206
+ static Instances & unbound_instances()
207
+ {
208
+ static Instances unbound_instances;
209
+ return unbound_instances;
210
+ }
211
+ };
212
+
213
+
214
+ } // namespace Rice
215
+
216
+ #include "Data_Type.ipp"
217
+
218
+ #endif // Rice__Data_Type_defn__hpp_
219
+
@@ -0,0 +1,12 @@
1
+ #ifndef Rice__Data_Type_fwd__hpp_
2
+ #define Rice__Data_Type_fwd__hpp_
3
+
4
+ namespace Rice
5
+ {
6
+
7
+ template<typename T>
8
+ class Data_Type;
9
+
10
+ } // Rice
11
+
12
+ #endif // Rice__Data_Type_fwd__hpp_
data/rice/Enum.hpp ADDED
@@ -0,0 +1,118 @@
1
+ #ifndef Rice__Enum__hpp_
2
+ #define Rice__Enum__hpp_
3
+
4
+ #include "to_from_ruby.hpp"
5
+ #include "Address_Registration_Guard.hpp"
6
+ #include "Array.hpp"
7
+ #include "Hash.hpp"
8
+ #include "String.hpp"
9
+ #include "Module.hpp"
10
+ #include "Data_Type.hpp"
11
+
12
+ namespace Rice
13
+ {
14
+
15
+ //! Default traits for the Enum class template.
16
+ template<typename Enum_T>
17
+ struct Default_Enum_Traits
18
+ {
19
+ //! Converts the enum value to a long.
20
+ static long as_long(Enum_T value);
21
+ };
22
+
23
+ /*!
24
+ * \example enum/sample_enum.cpp
25
+ */
26
+
27
+ //! A wrapper for enumerated types.
28
+ /*! Provides a simple type-safe wrapper for enumerated types. At the
29
+ * ruby level, the class will have convenience methods for iterating
30
+ * over all the defined enum values, converting the values to strings,
31
+ * and more.
32
+ *
33
+ * \param Enum_T the enumerated type
34
+ * \param Enum_Traits specifies the traits of the enumerated type.
35
+ *
36
+ * Example:
37
+ * \code
38
+ * enum Color { Red, Green, Blue };
39
+ * Enum<Color> rb_cColor = define_enum<Color>()
40
+ * .define_value("Red", Red)
41
+ * .define_value("Green", Green)
42
+ * .define_value("Blue", Blue)
43
+ * .initialize("Color");
44
+ * \endcode
45
+ */
46
+ template<typename Enum_T, typename Enum_Traits = Default_Enum_Traits<Enum_T> >
47
+ class Enum
48
+ : public Module_impl<Data_Type<Enum_T>, Enum<Enum_T, Enum_Traits> >
49
+ {
50
+ public:
51
+ //! Default constructor.
52
+ Enum();
53
+
54
+ //! Construct and initialize.
55
+ Enum(
56
+ char const * name,
57
+ Module module = rb_cObject);
58
+
59
+ //! Copy constructor.
60
+ Enum(Enum const & other);
61
+
62
+ //! Assignment operator.
63
+ Enum & operator=(Enum const & other);
64
+
65
+ //! Destructor.
66
+ virtual ~Enum();
67
+
68
+ //! Define a new enum value.
69
+ /*! \param name the name of the enum value.
70
+ * \param value the value to associate with name.
71
+ * \return *this
72
+ */
73
+ Enum<Enum_T, Enum_Traits> & define_value(
74
+ char const * name,
75
+ Enum_T value);
76
+
77
+ void swap(Enum & other);
78
+
79
+ private:
80
+ //! Initialize the enum type.
81
+ /*! Must be called only once.
82
+ * \param name the name of the class to define
83
+ * \param module the module in which to place the enum class.
84
+ * \return *this
85
+ */
86
+ Enum<Enum_T, Enum_Traits> & initialize(
87
+ char const * name,
88
+ Module module = rb_cObject);
89
+
90
+ private:
91
+ static Object each(Object self);
92
+ static Object to_s(Object self);
93
+ static Object to_i(Object self);
94
+ static Object inspect(Object self);
95
+ static Object compare(Object lhs, Object rhs);
96
+ static Object eql(Object lhs, Object rhs);
97
+ static Object hash(Object self);
98
+ static Object from_int(Class klass, Object i);
99
+
100
+ private:
101
+ Array enums_;
102
+ Address_Registration_Guard enums_guard_;
103
+
104
+ Hash names_;
105
+ Address_Registration_Guard names_guard_;
106
+ };
107
+
108
+ template<typename T>
109
+ Enum<T> define_enum(
110
+ char const * name,
111
+ Module module = rb_cObject);
112
+
113
+ } // namespace Rice
114
+
115
+ #include "Enum.ipp"
116
+
117
+ #endif // Rice__Enum__hpp_
118
+
data/rice/Enum.ipp ADDED
@@ -0,0 +1,246 @@
1
+ #ifndef Rice__Enum__ipp_
2
+ #define Rice__Enum__ipp_
3
+
4
+ #include "Data_Object.hpp"
5
+ #include "Class.hpp"
6
+ #include "String.hpp"
7
+ #include "protect.hpp"
8
+ #include <memory>
9
+
10
+ template<typename Enum_T>
11
+ long Rice::Default_Enum_Traits<Enum_T>::as_long(Enum_T value)
12
+ {
13
+ return static_cast<long>(value);
14
+ }
15
+
16
+ template<typename Enum_T, typename Enum_Traits>
17
+ Rice::Enum<Enum_T, Enum_Traits>::
18
+ Enum()
19
+ : Module_impl<Data_Type<Enum_T>, Enum<Enum_T, Enum_Traits> >()
20
+ , enums_()
21
+ , enums_guard_(&enums_)
22
+ , names_()
23
+ , names_guard_(&names_)
24
+ {
25
+ }
26
+
27
+ template<typename Enum_T, typename Enum_Traits>
28
+ Rice::Enum<Enum_T, Enum_Traits>::
29
+ Enum(
30
+ char const * name,
31
+ Module module)
32
+ : Module_impl<Data_Type<Enum_T>, Enum<Enum_T, Enum_Traits> >()
33
+ , enums_()
34
+ , enums_guard_(&enums_)
35
+ , names_()
36
+ , names_guard_(&names_)
37
+ {
38
+ this->template bind<void>(initialize(name, module));
39
+ }
40
+
41
+ template<typename Enum_T, typename Enum_Traits>
42
+ Rice::Enum<Enum_T, Enum_Traits>::
43
+ Enum(Enum<Enum_T, Enum_Traits> const & other)
44
+ : Module_impl<Data_Type<Enum_T>, Enum<Enum_T, Enum_Traits> >(other)
45
+ , enums_(other.enums_)
46
+ , enums_guard_(&enums_)
47
+ , names_(other.names_)
48
+ , names_guard_(&names_)
49
+ {
50
+ }
51
+
52
+ template<typename Enum_T, typename Enum_Traits>
53
+ Rice::Enum<Enum_T, Enum_Traits> & Rice::Enum<Enum_T, Enum_Traits>::
54
+ operator=(Rice::Enum<Enum_T, Enum_Traits> const & other)
55
+ {
56
+ Rice::Enum<Enum_T, Enum_Traits> tmp(other);
57
+ this->swap(tmp);
58
+ return *this;
59
+ }
60
+
61
+ template<typename Enum_T, typename Enum_Traits>
62
+ Rice::Enum<Enum_T, Enum_Traits>::
63
+ ~Enum()
64
+ {
65
+ }
66
+
67
+ template<typename Enum_T, typename Enum_Traits>
68
+ Rice::Enum<Enum_T, Enum_Traits> & Rice::Enum<Enum_T, Enum_Traits>::
69
+ initialize(
70
+ char const * name,
71
+ Module module)
72
+ {
73
+ Class c = Rice::define_class_under<Enum_T>(module, name)
74
+ .define_method("to_s", to_s)
75
+ .define_method("to_i", to_i)
76
+ .define_method("inspect", inspect)
77
+ .define_method("<=>", compare)
78
+ .define_method("hash", hash)
79
+ .define_method("eql?", eql)
80
+ .define_method("==", eql)
81
+ .define_method("===", eql)
82
+ .define_singleton_method("each", each)
83
+ .define_singleton_method("from_int", from_int)
84
+ .include_module(rb_mComparable);
85
+
86
+ // TODO: This should be unnecessary (it should be taken care of when
87
+ // define_class_under binds the C++ and ruby types)
88
+ this->set_value(c);
89
+
90
+ protect(rb_iv_set, c, "enums", enums_);
91
+ protect(rb_iv_set, c, "names", names_);
92
+
93
+ return *this;
94
+ }
95
+
96
+ template<typename Enum_T, typename Enum_Traits>
97
+ Rice::Enum<Enum_T, Enum_Traits> & Rice::Enum<Enum_T, Enum_Traits>::
98
+ define_value(
99
+ char const * name,
100
+ Enum_T value)
101
+ {
102
+ std::auto_ptr<Enum_T> copy(new Enum_T(value));
103
+ Rice::Data_Object<Enum_T> m(copy.get(), *this);
104
+ copy.release();
105
+ names_[m] = String(name);
106
+ this->const_set(name, m);
107
+ enums_.push(m);
108
+
109
+ return *this;
110
+ }
111
+
112
+
113
+ template<typename Enum_T, typename Enum_Traits>
114
+ void Rice::Enum<Enum_T, Enum_Traits>::
115
+ swap(Enum<Enum_T, Enum_Traits> & other)
116
+ {
117
+ Data_Type<Enum_T>::swap(other);
118
+ enums_.swap(other.enums_);
119
+ names_.swap(other.names_);
120
+ }
121
+
122
+ template<typename Enum_T, typename Enum_Traits>
123
+ Rice::Object Rice::Enum<Enum_T, Enum_Traits>::
124
+ each(Object self)
125
+ {
126
+ VALUE enums_v = rb_iv_get(self, "enums");
127
+ Check_Type(enums_v, T_ARRAY);
128
+ RArray * enums = RARRAY(enums_v);
129
+ for(int j = 0; j < enums->len; ++j)
130
+ {
131
+ rb_yield(enums->ptr[j]);
132
+ }
133
+ return Qnil;
134
+ }
135
+
136
+ template<typename Enum_T, typename Enum_Traits>
137
+ Rice::Object Rice::Enum<Enum_T, Enum_Traits>::
138
+ to_s(Object self)
139
+ {
140
+ Data_Type<Enum_T> klass;
141
+ Rice::Data_Object<Enum_T> m(self, klass);
142
+ Object enum_class = rb_class_of(m);
143
+ Hash names(rb_iv_get(enum_class, "names"));
144
+ Object name = names[m];
145
+ if(name.is_nil())
146
+ {
147
+ return String::format("INVALID(%d)", Enum_Traits::as_long(*m));
148
+ }
149
+ else
150
+ {
151
+ return String(name);
152
+ }
153
+ }
154
+
155
+ template<typename Enum_T, typename Enum_Traits>
156
+ Rice::Object Rice::Enum<Enum_T, Enum_Traits>::
157
+ inspect(Object self)
158
+ {
159
+ return String::format(
160
+ "#<%s::%s>",
161
+ String(self.class_of().mod_name()).c_str(),
162
+ String(to_s(self)).c_str());
163
+ }
164
+
165
+ template<typename Enum_T, typename Enum_Traits>
166
+ Rice::Object Rice::Enum<Enum_T, Enum_Traits>::
167
+ compare(Object lhs, Object rhs)
168
+ {
169
+ if(lhs.class_of() != rhs.class_of())
170
+ {
171
+ String lhs_name(lhs.class_of().mod_name());
172
+ String rhs_name(rhs.class_of().mod_name());
173
+ rb_raise(
174
+ rb_eTypeError,
175
+ "Cannot compare %s to %s",
176
+ lhs_name.c_str(),
177
+ rhs_name.c_str());
178
+ }
179
+
180
+ Data_Type<Enum_T> klass;
181
+ Rice::Data_Object<Enum_T> l(lhs, klass);
182
+ Rice::Data_Object<Enum_T> r(rhs, klass);
183
+
184
+ Enum_T left(*l);
185
+ Enum_T right(*r);
186
+
187
+ if(left == right)
188
+ {
189
+ return INT2NUM(0);
190
+ }
191
+ else if(Enum_Traits::as_long(left) < Enum_Traits::as_long(right))
192
+ {
193
+ return INT2NUM(-1);
194
+ }
195
+ else
196
+ {
197
+ return INT2NUM(1);
198
+ }
199
+ }
200
+
201
+ template<typename Enum_T, typename Enum_Traits>
202
+ Rice::Object Rice::Enum<Enum_T, Enum_Traits>::
203
+ eql(Object lhs, Object rhs)
204
+ {
205
+ using ::from_ruby; // Workaround for g++ 3.3.3
206
+ bool is_equal = from_ruby<int>(compare(lhs, rhs)) == 0;
207
+ return to_ruby(is_equal);
208
+ }
209
+
210
+ template<typename Enum_T, typename Enum_Traits>
211
+ Rice::Object Rice::Enum<Enum_T, Enum_Traits>::
212
+ to_i(Object self)
213
+ {
214
+ Data_Type<Enum_T> klass;
215
+ Rice::Data_Object<Enum_T> m(self, klass);
216
+ return LONG2NUM(Enum_Traits::as_long(*m));
217
+ }
218
+
219
+ template<typename Enum_T, typename Enum_Traits>
220
+ Rice::Object Rice::Enum<Enum_T, Enum_Traits>::
221
+ hash(Object self)
222
+ {
223
+ return to_i(self);
224
+ }
225
+
226
+ template<typename Enum_T, typename Enum_Traits>
227
+ Rice::Object Rice::Enum<Enum_T, Enum_Traits>::
228
+ from_int(Class klass, Object i)
229
+ {
230
+ using ::from_ruby; // Workaround for g++ 3.3.3
231
+ Rice::Data_Object<Enum_T> m(
232
+ new Enum_T(static_cast<Enum_T>(from_ruby<long>(i))),
233
+ klass);
234
+ return m.value();
235
+ }
236
+
237
+ template<typename T>
238
+ Rice::Enum<T> Rice::
239
+ define_enum(
240
+ char const * name,
241
+ Module module)
242
+ {
243
+ return Enum<T>(name, module);
244
+ }
245
+ #endif // Rice__Enum__ipp_
246
+