rice 2.1.3 → 4.0.2

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 (246) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +121 -0
  3. data/CONTRIBUTORS.md +19 -0
  4. data/COPYING +2 -2
  5. data/Gemfile +3 -0
  6. data/README.md +45 -1028
  7. data/Rakefile +95 -12
  8. data/include/rice/rice.hpp +7766 -0
  9. data/include/rice/stl.hpp +1113 -0
  10. data/lib/mkmf-rice.rb +127 -0
  11. data/lib/version.rb +3 -0
  12. data/rice/Address_Registration_Guard.ipp +75 -32
  13. data/rice/Address_Registration_Guard_defn.hpp +60 -56
  14. data/rice/Arg.hpp +80 -4
  15. data/rice/Arg.ipp +51 -0
  16. data/rice/Constructor.hpp +30 -376
  17. data/rice/Data_Object.ipp +234 -107
  18. data/rice/Data_Object_defn.hpp +77 -117
  19. data/rice/Data_Type.hpp +1 -2
  20. data/rice/Data_Type.ipp +251 -295
  21. data/rice/Data_Type_defn.hpp +175 -243
  22. data/rice/Director.hpp +14 -9
  23. data/rice/Enum.hpp +54 -104
  24. data/rice/Enum.ipp +104 -230
  25. data/rice/Exception.hpp +2 -8
  26. data/rice/Exception.ipp +65 -0
  27. data/rice/Exception_defn.hpp +46 -47
  28. data/rice/Identifier.hpp +28 -28
  29. data/rice/Identifier.ipp +23 -27
  30. data/rice/Return.hpp +39 -0
  31. data/rice/Return.ipp +33 -0
  32. data/rice/detail/Exception_Handler.ipp +22 -62
  33. data/rice/detail/Exception_Handler_defn.hpp +76 -91
  34. data/rice/detail/Iterator.hpp +18 -88
  35. data/rice/detail/Iterator.ipp +47 -0
  36. data/rice/detail/Jump_Tag.hpp +21 -0
  37. data/rice/detail/MethodInfo.hpp +44 -0
  38. data/rice/detail/MethodInfo.ipp +78 -0
  39. data/rice/detail/NativeAttribute.hpp +53 -0
  40. data/rice/detail/NativeAttribute.ipp +83 -0
  41. data/rice/detail/NativeFunction.hpp +69 -0
  42. data/rice/detail/NativeFunction.ipp +248 -0
  43. data/rice/detail/RubyFunction.hpp +39 -0
  44. data/rice/detail/RubyFunction.ipp +92 -0
  45. data/rice/detail/Type.hpp +29 -0
  46. data/rice/detail/Type.ipp +138 -0
  47. data/rice/detail/TypeRegistry.hpp +50 -0
  48. data/rice/detail/TypeRegistry.ipp +106 -0
  49. data/rice/detail/Wrapper.hpp +51 -0
  50. data/rice/detail/Wrapper.ipp +151 -0
  51. data/rice/detail/default_allocation_func.hpp +8 -19
  52. data/rice/detail/default_allocation_func.ipp +9 -8
  53. data/rice/detail/from_ruby.hpp +2 -37
  54. data/rice/detail/from_ruby.ipp +1020 -46
  55. data/rice/detail/from_ruby_defn.hpp +38 -0
  56. data/rice/detail/function_traits.hpp +124 -0
  57. data/rice/detail/method_data.hpp +23 -15
  58. data/rice/detail/method_data.ipp +53 -0
  59. data/rice/detail/rice_traits.hpp +116 -0
  60. data/rice/detail/ruby.hpp +9 -50
  61. data/rice/detail/to_ruby.hpp +3 -17
  62. data/rice/detail/to_ruby.ipp +409 -31
  63. data/rice/detail/to_ruby_defn.hpp +48 -0
  64. data/rice/forward_declares.ipp +82 -0
  65. data/rice/global_function.hpp +16 -20
  66. data/rice/global_function.ipp +8 -17
  67. data/rice/rice.hpp +59 -0
  68. data/rice/ruby_mark.hpp +5 -3
  69. data/rice/ruby_try_catch.hpp +4 -4
  70. data/rice/stl.hpp +11 -0
  71. data/sample/callbacks/extconf.rb +6 -0
  72. data/sample/callbacks/sample_callbacks.cpp +35 -0
  73. data/sample/callbacks/test.rb +28 -0
  74. data/sample/enum/extconf.rb +3 -0
  75. data/sample/enum/sample_enum.cpp +3 -17
  76. data/sample/enum/test.rb +2 -2
  77. data/sample/inheritance/animals.cpp +8 -24
  78. data/sample/inheritance/extconf.rb +3 -0
  79. data/sample/inheritance/test.rb +1 -1
  80. data/sample/map/extconf.rb +3 -0
  81. data/sample/map/map.cpp +10 -18
  82. data/sample/map/test.rb +1 -1
  83. data/test/embed_ruby.cpp +34 -0
  84. data/test/embed_ruby.hpp +4 -0
  85. data/test/ext/t1/extconf.rb +3 -0
  86. data/test/ext/t1/t1.cpp +1 -3
  87. data/test/ext/t2/extconf.rb +3 -0
  88. data/test/ext/t2/t2.cpp +1 -1
  89. data/test/extconf.rb +23 -0
  90. data/test/ruby/test_callbacks_sample.rb +28 -0
  91. data/test/ruby/test_multiple_extensions.rb +18 -0
  92. data/test/ruby/test_multiple_extensions_same_class.rb +14 -0
  93. data/test/ruby/test_multiple_extensions_with_inheritance.rb +20 -0
  94. data/test/test_Address_Registration_Guard.cpp +25 -11
  95. data/test/test_Array.cpp +131 -74
  96. data/test/test_Attribute.cpp +147 -0
  97. data/test/test_Builtin_Object.cpp +36 -15
  98. data/test/test_Class.cpp +151 -276
  99. data/test/test_Constructor.cpp +10 -9
  100. data/test/test_Data_Object.cpp +135 -193
  101. data/test/test_Data_Type.cpp +323 -252
  102. data/test/test_Director.cpp +56 -42
  103. data/test/test_Enum.cpp +230 -104
  104. data/test/test_Exception.cpp +7 -7
  105. data/test/test_Hash.cpp +33 -31
  106. data/test/test_Identifier.cpp +6 -6
  107. data/test/test_Inheritance.cpp +221 -0
  108. data/test/test_Iterator.cpp +161 -0
  109. data/test/test_Jump_Tag.cpp +1 -1
  110. data/test/test_Keep_Alive.cpp +161 -0
  111. data/test/test_Memory_Management.cpp +4 -5
  112. data/test/test_Module.cpp +169 -111
  113. data/test/test_Object.cpp +51 -19
  114. data/test/test_Ownership.cpp +275 -0
  115. data/test/test_Self.cpp +205 -0
  116. data/test/test_Stl_Optional.cpp +90 -0
  117. data/test/test_Stl_Pair.cpp +144 -0
  118. data/test/test_Stl_SmartPointer.cpp +200 -0
  119. data/test/test_Stl_String.cpp +74 -0
  120. data/test/test_Stl_Vector.cpp +652 -0
  121. data/test/test_String.cpp +3 -3
  122. data/test/test_Struct.cpp +31 -40
  123. data/test/test_Symbol.cpp +3 -3
  124. data/test/test_To_From_Ruby.cpp +283 -218
  125. data/test/test_global_functions.cpp +41 -20
  126. data/test/unittest.cpp +34 -8
  127. data/test/unittest.hpp +0 -4
  128. metadata +121 -136
  129. data/Doxyfile +0 -2268
  130. data/Makefile.am +0 -26
  131. data/Makefile.in +0 -923
  132. data/README.mingw +0 -8
  133. data/aclocal.m4 +0 -1088
  134. data/bootstrap +0 -8
  135. data/check_stdcxx_11.ac +0 -103
  136. data/config.guess +0 -1421
  137. data/config.sub +0 -1807
  138. data/configure +0 -7367
  139. data/configure.ac +0 -55
  140. data/depcomp +0 -791
  141. data/doxygen.ac +0 -314
  142. data/doxygen.am +0 -186
  143. data/extconf.rb +0 -69
  144. data/install-sh +0 -501
  145. data/missing +0 -215
  146. data/post-autoconf.rb +0 -22
  147. data/post-automake.rb +0 -28
  148. data/rice/Address_Registration_Guard.cpp +0 -22
  149. data/rice/Arg_impl.hpp +0 -129
  150. data/rice/Arg_operators.cpp +0 -21
  151. data/rice/Arg_operators.hpp +0 -19
  152. data/rice/Array.hpp +0 -214
  153. data/rice/Array.ipp +0 -256
  154. data/rice/Builtin_Object.hpp +0 -8
  155. data/rice/Builtin_Object.ipp +0 -50
  156. data/rice/Builtin_Object_defn.hpp +0 -50
  157. data/rice/Class.cpp +0 -57
  158. data/rice/Class.hpp +0 -8
  159. data/rice/Class.ipp +0 -6
  160. data/rice/Class_defn.hpp +0 -83
  161. data/rice/Data_Type.cpp +0 -54
  162. data/rice/Data_Type_fwd.hpp +0 -12
  163. data/rice/Director.cpp +0 -13
  164. data/rice/Exception.cpp +0 -59
  165. data/rice/Exception_Base.hpp +0 -8
  166. data/rice/Exception_Base.ipp +0 -13
  167. data/rice/Exception_Base_defn.hpp +0 -27
  168. data/rice/Hash.hpp +0 -227
  169. data/rice/Hash.ipp +0 -329
  170. data/rice/Identifier.cpp +0 -8
  171. data/rice/Jump_Tag.hpp +0 -24
  172. data/rice/Makefile.am +0 -125
  173. data/rice/Makefile.in +0 -888
  174. data/rice/Module.cpp +0 -84
  175. data/rice/Module.hpp +0 -8
  176. data/rice/Module.ipp +0 -6
  177. data/rice/Module_defn.hpp +0 -88
  178. data/rice/Module_impl.hpp +0 -281
  179. data/rice/Module_impl.ipp +0 -345
  180. data/rice/Object.cpp +0 -169
  181. data/rice/Object.hpp +0 -8
  182. data/rice/Object.ipp +0 -19
  183. data/rice/Object_defn.hpp +0 -191
  184. data/rice/Require_Guard.hpp +0 -21
  185. data/rice/String.cpp +0 -94
  186. data/rice/String.hpp +0 -91
  187. data/rice/Struct.cpp +0 -117
  188. data/rice/Struct.hpp +0 -162
  189. data/rice/Struct.ipp +0 -26
  190. data/rice/Symbol.cpp +0 -25
  191. data/rice/Symbol.hpp +0 -66
  192. data/rice/Symbol.ipp +0 -44
  193. data/rice/config.hpp +0 -47
  194. data/rice/config.hpp.in +0 -46
  195. data/rice/detail/Arguments.hpp +0 -118
  196. data/rice/detail/Auto_Function_Wrapper.hpp +0 -898
  197. data/rice/detail/Auto_Function_Wrapper.ipp +0 -3694
  198. data/rice/detail/Auto_Member_Function_Wrapper.hpp +0 -897
  199. data/rice/detail/Auto_Member_Function_Wrapper.ipp +0 -2774
  200. data/rice/detail/Caster.hpp +0 -103
  201. data/rice/detail/Not_Copyable.hpp +0 -25
  202. data/rice/detail/Wrapped_Function.hpp +0 -33
  203. data/rice/detail/cfp.hpp +0 -24
  204. data/rice/detail/cfp.ipp +0 -51
  205. data/rice/detail/check_ruby_type.cpp +0 -27
  206. data/rice/detail/check_ruby_type.hpp +0 -23
  207. data/rice/detail/creation_funcs.hpp +0 -37
  208. data/rice/detail/creation_funcs.ipp +0 -36
  209. data/rice/detail/define_method_and_auto_wrap.hpp +0 -31
  210. data/rice/detail/define_method_and_auto_wrap.ipp +0 -30
  211. data/rice/detail/demangle.cpp +0 -56
  212. data/rice/detail/demangle.hpp +0 -19
  213. data/rice/detail/env.hpp +0 -11
  214. data/rice/detail/method_data.cpp +0 -86
  215. data/rice/detail/node.hpp +0 -13
  216. data/rice/detail/object_call.hpp +0 -69
  217. data/rice/detail/object_call.ipp +0 -131
  218. data/rice/detail/protect.cpp +0 -29
  219. data/rice/detail/protect.hpp +0 -34
  220. data/rice/detail/ruby_version_code.hpp +0 -6
  221. data/rice/detail/ruby_version_code.hpp.in +0 -6
  222. data/rice/detail/st.hpp +0 -22
  223. data/rice/detail/traits.hpp +0 -43
  224. data/rice/detail/win32.hpp +0 -16
  225. data/rice/detail/wrap_function.hpp +0 -341
  226. data/rice/detail/wrap_function.ipp +0 -514
  227. data/rice/protect.hpp +0 -92
  228. data/rice/protect.ipp +0 -1134
  229. data/rice/rubypp.rb +0 -97
  230. data/rice/to_from_ruby.hpp +0 -8
  231. data/rice/to_from_ruby.ipp +0 -294
  232. data/rice/to_from_ruby_defn.hpp +0 -70
  233. data/ruby.ac +0 -135
  234. data/ruby/Makefile.am +0 -1
  235. data/ruby/Makefile.in +0 -628
  236. data/ruby/lib/Makefile.am +0 -3
  237. data/ruby/lib/Makefile.in +0 -506
  238. data/ruby/lib/mkmf-rice.rb.in +0 -217
  239. data/ruby/lib/version.rb +0 -3
  240. data/sample/Makefile.am +0 -47
  241. data/sample/Makefile.in +0 -489
  242. data/test/Makefile.am +0 -72
  243. data/test/Makefile.in +0 -1213
  244. data/test/ext/Makefile.am +0 -41
  245. data/test/ext/Makefile.in +0 -483
  246. data/test/test_rice.rb +0 -41
data/rice/Enum.hpp CHANGED
@@ -1,117 +1,67 @@
1
1
  #ifndef Rice__Enum__hpp_
2
2
  #define Rice__Enum__hpp_
3
3
 
4
- #include "to_from_ruby_defn.hpp"
5
- #include "Address_Registration_Guard.hpp"
6
- #include "Array.hpp"
7
- #include "Hash.hpp"
8
- #include "String.hpp"
9
- #include "Module.hpp"
10
4
  #include "Data_Type.hpp"
5
+ #include <map>
11
6
 
12
7
  namespace Rice
13
8
  {
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>("Color")
40
- * .define_value("Red", Red)
41
- * .define_value("Green", Green)
42
- * .define_value("Blue", Blue);
43
- * \endcode
44
- */
45
- template<typename Enum_T, typename Enum_Traits = Default_Enum_Traits<Enum_T> >
46
- class Enum
47
- : public Module_impl<Data_Type<Enum_T>, Enum<Enum_T, Enum_Traits> >
48
- {
49
- public:
50
- //! Default constructor.
51
- Enum();
52
-
53
- //! Construct and initialize.
54
- Enum(
55
- char const * name,
56
- Module module = rb_cObject);
57
-
58
- //! Copy constructor.
59
- Enum(Enum const & other);
60
-
61
- //! Assignment operator.
62
- Enum & operator=(Enum const & other);
63
-
64
- //! Destructor.
65
- virtual ~Enum();
66
-
67
- //! Define a new enum value.
68
- /*! \param name the name of the enum value.
69
- * \param value the value to associate with name.
70
- * \return *this
9
+ /*!
10
+ * \example enum/sample_enum.cpp
71
11
  */
72
- Enum<Enum_T, Enum_Traits> & define_value(
73
- char const * name,
74
- Enum_T value);
75
-
76
- void swap(Enum & other);
77
-
78
- private:
79
- //! Initialize the enum type.
80
- /*! Must be called only once.
81
- * \param name the name of the class to define
82
- * \param module the module in which to place the enum class.
83
- * \return *this
84
- */
85
- Enum<Enum_T, Enum_Traits> & initialize(
86
- char const * name,
87
- Module module = rb_cObject);
88
-
89
- private:
90
- static Object each(Object self);
91
- static Object to_s(Object self);
92
- static Object to_i(Object self);
93
- static Object inspect(Object self);
94
- static Object compare(Object lhs, Object rhs);
95
- static Object eql(Object lhs, Object rhs);
96
- static Object hash(Object self);
97
- static Object from_int(Class klass, Object i);
98
-
99
- private:
100
- Array enums_;
101
- Address_Registration_Guard enums_guard_;
102
-
103
- Hash names_;
104
- Address_Registration_Guard names_guard_;
105
- };
106
-
107
- template<typename T>
108
- Enum<T> define_enum(
109
- char const * name,
110
- Module module = rb_cObject);
111
12
 
13
+ //! A wrapper for enumerated types.
14
+ /*! Provides a simple type-safe wrapper for enumerated types. At the
15
+ * ruby level, the class will have convenience methods for iterating
16
+ * over all the defined enum values, converting the values to strings,
17
+ * and more.
18
+ *
19
+ * \param Enum_T the enumerated type
20
+ *
21
+ * Example:
22
+ * \code
23
+ * enum Color { Red, Green, Blue };
24
+ * Enum<Color> rb_cColor = define_enum<Color>("Color")
25
+ * .define_value("Red", Red)
26
+ * .define_value("Green", Green)
27
+ * .define_value("Blue", Blue);
28
+ * \endcode
29
+ */
30
+ template<typename Enum_T>
31
+ class Enum : public Data_Type<Enum_T>
32
+ {
33
+ using Underlying_T = std::underlying_type_t<Enum_T>;
34
+
35
+ public:
36
+
37
+ Enum() = default;
38
+
39
+ //! Construct and initialize.
40
+ Enum(char const* name, Module module = rb_cObject);
41
+
42
+ //! Define a new enum value.
43
+ /*! \param name the name of the enum value.
44
+ * \param value the value to associate with name.
45
+ * \return *this
46
+ */
47
+ Enum<Enum_T>& define_value(std::string name, Enum_T value);
48
+
49
+ //! Maps an enum value to the correct Ruby object
50
+ /*! \param klass The bound Ruby class
51
+ * \param enumValue The enum value
52
+ * \return Object - The Ruby wrapper */
53
+ static Object from_enum(Class klass, Enum_T enumValue);
54
+
55
+ private:
56
+ void define_methods(Data_Type<Enum_T> klass);
57
+
58
+ static inline std::map<Enum_T, std::string> valuesToNames_;
59
+ };
60
+
61
+ template<typename T>
62
+ Enum<T> define_enum(char const* name, Module module = rb_cObject);
112
63
  } // namespace Rice
113
64
 
114
65
  #include "Enum.ipp"
115
66
 
116
- #endif // Rice__Enum__hpp_
117
-
67
+ #endif // Rice__Enum__hpp_
data/rice/Enum.ipp CHANGED
@@ -1,246 +1,120 @@
1
- #ifndef Rice__Enum__ipp_
2
- #define Rice__Enum__ipp_
3
-
1
+ #include "detail/TypeRegistry.hpp"
4
2
  #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_unique_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
- }
3
+ #include "cpp_api/String.hpp"
111
4
 
5
+ #include <stdexcept>
112
6
 
113
- template<typename Enum_T, typename Enum_Traits>
114
- void Rice::Enum<Enum_T, Enum_Traits>::
115
- swap(Enum<Enum_T, Enum_Traits> & other)
7
+ namespace Rice
116
8
  {
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
- Array enums(enums_v);
129
- for(size_t j = 0; j < enums.size(); ++j)
9
+ template<typename Enum_T>
10
+ Enum<Enum_T>::Enum(char const* name, Module module) : Data_Type<Enum_T>()
130
11
  {
131
- rb_yield(enums[j].value());
12
+ Data_Type<Enum_T> klass = define_class_under<Enum_T>(module, name);
13
+ define_methods(klass);
132
14
  }
133
- return Qnil;
134
- }
135
15
 
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())
16
+ template<typename Enum_T>
17
+ inline Enum<Enum_T>& Enum<Enum_T>::define_value(std::string name, Enum_T value)
146
18
  {
147
- return String::format("INVALID(%d)", Enum_Traits::as_long(*m));
148
- }
149
- else
150
- {
151
- return String(name);
152
- }
153
- }
19
+ // Save mapping from value to name
20
+ valuesToNames_[value] = name;
154
21
 
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().name()).c_str(),
162
- String(to_s(self)).c_str());
163
- }
22
+ // Store value as class constant available to Ruby
23
+ Data_Object<Enum_T> object(value, true, Enum<Enum_T>::klass());
24
+ this->const_set(name, object);
164
25
 
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().name());
172
- String rhs_name(rhs.class_of().name());
173
- rb_raise(
174
- rb_eTypeError,
175
- "Cannot compare %s to %s",
176
- lhs_name.c_str(),
177
- rhs_name.c_str());
26
+ return *this;
178
27
  }
179
28
 
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
29
+ template<typename Enum_T>
30
+ inline void Enum<Enum_T>::define_methods(Data_Type<Enum_T> klass)
196
31
  {
197
- return INT2NUM(1);
32
+ // First we need a constructor
33
+ klass.define_constructor(Constructor<Enum_T>());
34
+
35
+ // Instance methods
36
+ klass.define_method("to_s", [](Enum_T& self)
37
+ {
38
+ // We have to return string because we don't know if std::string support has
39
+ // been included by the user
40
+ return String(valuesToNames_[self]);
41
+ })
42
+ .define_method("to_i", [](Enum_T& self) -> Underlying_T
43
+ {
44
+ return (Underlying_T)self;
45
+ })
46
+ .define_method("inspect", [](Enum_T& self)
47
+ {
48
+ std::stringstream result;
49
+ VALUE rubyKlass = Enum<Enum_T>::klass().value();
50
+ result << "#<" << detail::protect(rb_class2name, rubyKlass)
51
+ << "::" << Enum<Enum_T>::valuesToNames_[self] << ">";
52
+
53
+ // We have to return string because we don't know if std::string support has
54
+ // been included by the user
55
+ return String(result.str());
56
+ })
57
+ .define_method("<=>", [](Enum_T& self, Enum_T& other)
58
+ {
59
+ if (self == other)
60
+ {
61
+ return 0;
62
+ }
63
+ else if (self < other)
64
+ {
65
+ return -1;
66
+ }
67
+ else
68
+ {
69
+ return 1;
70
+ }
71
+ })
72
+ .define_method("hash", [](Enum_T& self) -> Underlying_T
73
+ {
74
+ return (Underlying_T)self;
75
+ })
76
+ .define_method("eql?", [](Enum_T& self, Enum_T& other)
77
+ {
78
+ return self == other;
79
+ });
80
+
81
+ // Add aliases
82
+ rb_define_alias(klass, "===", "eql?");
83
+
84
+ // Add comparable support
85
+ klass.include_module(rb_mComparable);
86
+
87
+ // Singleton methods
88
+ klass.define_singleton_method("each", [](VALUE klass)
89
+ {
90
+ for (auto& pair : valuesToNames_)
91
+ {
92
+ Enum_T enumValue = pair.first;
93
+ VALUE value = detail::To_Ruby<Enum_T>().convert(enumValue);
94
+ detail::protect(rb_yield, value);
95
+ }
96
+ })
97
+ .define_singleton_method("from_int", [](VALUE klass, int32_t value)
98
+ {
99
+ auto iter = Enum<Enum_T>::valuesToNames_.find((Enum_T)value);
100
+ if (iter == Enum<Enum_T>::valuesToNames_.end())
101
+ {
102
+ throw std::runtime_error("Unknown enum value: " + std::to_string(value));
103
+ }
104
+
105
+ std::string name = iter->second;
106
+ return Class(klass).const_get(name);
107
+ });
198
108
  }
199
- }
200
109
 
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_
110
+ template<typename Enum_T>
111
+ Enum<Enum_T> define_enum(char const* name, Module module)
112
+ {
113
+ if (detail::TypeRegistry::isDefined<Enum_T>())
114
+ {
115
+ return Enum<Enum_T>();
116
+ }
246
117
 
118
+ return Enum<Enum_T>(name, module);
119
+ }
120
+ }