rice 3.0.0 → 4.0.3

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 (238) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +121 -0
  3. data/CONTRIBUTORS.md +19 -0
  4. data/Gemfile +3 -0
  5. data/README.md +44 -1025
  6. data/Rakefile +95 -12
  7. data/include/rice/rice.hpp +7766 -0
  8. data/include/rice/stl.hpp +1113 -0
  9. data/lib/mkmf-rice.rb +127 -0
  10. data/lib/version.rb +3 -0
  11. data/rice/Address_Registration_Guard.ipp +75 -32
  12. data/rice/Address_Registration_Guard_defn.hpp +60 -56
  13. data/rice/Arg.hpp +80 -4
  14. data/rice/Arg.ipp +51 -0
  15. data/rice/Constructor.hpp +12 -14
  16. data/rice/Data_Object.ipp +234 -107
  17. data/rice/Data_Object_defn.hpp +77 -117
  18. data/rice/Data_Type.hpp +1 -2
  19. data/rice/Data_Type.ipp +251 -295
  20. data/rice/Data_Type_defn.hpp +175 -243
  21. data/rice/Director.hpp +11 -6
  22. data/rice/Enum.hpp +54 -104
  23. data/rice/Enum.ipp +104 -230
  24. data/rice/Exception.hpp +2 -8
  25. data/rice/Exception.ipp +65 -0
  26. data/rice/Exception_defn.hpp +46 -47
  27. data/rice/Identifier.hpp +28 -28
  28. data/rice/Identifier.ipp +23 -27
  29. data/rice/Return.hpp +39 -0
  30. data/rice/Return.ipp +33 -0
  31. data/rice/detail/Exception_Handler.ipp +22 -62
  32. data/rice/detail/Exception_Handler_defn.hpp +76 -91
  33. data/rice/detail/Iterator.hpp +18 -88
  34. data/rice/detail/Iterator.ipp +47 -0
  35. data/rice/detail/Jump_Tag.hpp +21 -0
  36. data/rice/detail/MethodInfo.hpp +44 -0
  37. data/rice/detail/MethodInfo.ipp +78 -0
  38. data/rice/detail/NativeAttribute.hpp +53 -0
  39. data/rice/detail/NativeAttribute.ipp +83 -0
  40. data/rice/detail/NativeFunction.hpp +69 -0
  41. data/rice/detail/NativeFunction.ipp +248 -0
  42. data/rice/detail/RubyFunction.hpp +39 -0
  43. data/rice/detail/RubyFunction.ipp +92 -0
  44. data/rice/detail/Type.hpp +29 -0
  45. data/rice/detail/Type.ipp +138 -0
  46. data/rice/detail/TypeRegistry.hpp +50 -0
  47. data/rice/detail/TypeRegistry.ipp +106 -0
  48. data/rice/detail/Wrapper.hpp +51 -0
  49. data/rice/detail/Wrapper.ipp +151 -0
  50. data/rice/detail/default_allocation_func.hpp +8 -19
  51. data/rice/detail/default_allocation_func.ipp +9 -8
  52. data/rice/detail/from_ruby.hpp +2 -37
  53. data/rice/detail/from_ruby.ipp +1020 -46
  54. data/rice/detail/from_ruby_defn.hpp +38 -0
  55. data/rice/detail/function_traits.hpp +124 -0
  56. data/rice/detail/method_data.hpp +23 -15
  57. data/rice/detail/method_data.ipp +53 -0
  58. data/rice/detail/rice_traits.hpp +116 -0
  59. data/rice/detail/ruby.hpp +9 -46
  60. data/rice/detail/to_ruby.hpp +3 -17
  61. data/rice/detail/to_ruby.ipp +409 -31
  62. data/rice/detail/to_ruby_defn.hpp +48 -0
  63. data/rice/forward_declares.ipp +82 -0
  64. data/rice/global_function.hpp +16 -20
  65. data/rice/global_function.ipp +8 -17
  66. data/rice/rice.hpp +59 -0
  67. data/rice/ruby_mark.hpp +5 -3
  68. data/rice/ruby_try_catch.hpp +4 -4
  69. data/rice/stl.hpp +11 -0
  70. data/sample/callbacks/extconf.rb +3 -0
  71. data/sample/callbacks/sample_callbacks.cpp +10 -13
  72. data/sample/enum/extconf.rb +3 -0
  73. data/sample/enum/sample_enum.cpp +3 -17
  74. data/sample/enum/test.rb +2 -2
  75. data/sample/inheritance/animals.cpp +8 -24
  76. data/sample/inheritance/extconf.rb +3 -0
  77. data/sample/inheritance/test.rb +1 -1
  78. data/sample/map/extconf.rb +3 -0
  79. data/sample/map/map.cpp +10 -18
  80. data/sample/map/test.rb +1 -1
  81. data/test/embed_ruby.cpp +18 -5
  82. data/test/ext/t1/extconf.rb +3 -0
  83. data/test/ext/t1/t1.cpp +1 -3
  84. data/test/ext/t2/extconf.rb +3 -0
  85. data/test/ext/t2/t2.cpp +1 -1
  86. data/test/extconf.rb +23 -0
  87. data/test/ruby/test_callbacks_sample.rb +28 -0
  88. data/test/ruby/test_multiple_extensions.rb +18 -0
  89. data/test/ruby/test_multiple_extensions_same_class.rb +14 -0
  90. data/test/ruby/test_multiple_extensions_with_inheritance.rb +20 -0
  91. data/test/test_Address_Registration_Guard.cpp +23 -10
  92. data/test/test_Array.cpp +129 -73
  93. data/test/test_Attribute.cpp +147 -0
  94. data/test/test_Builtin_Object.cpp +34 -14
  95. data/test/test_Class.cpp +149 -275
  96. data/test/test_Constructor.cpp +10 -9
  97. data/test/test_Data_Object.cpp +133 -192
  98. data/test/test_Data_Type.cpp +322 -252
  99. data/test/test_Director.cpp +54 -41
  100. data/test/test_Enum.cpp +228 -103
  101. data/test/test_Exception.cpp +5 -6
  102. data/test/test_Hash.cpp +31 -30
  103. data/test/test_Identifier.cpp +4 -5
  104. data/test/test_Inheritance.cpp +221 -0
  105. data/test/test_Iterator.cpp +161 -0
  106. data/test/test_Jump_Tag.cpp +1 -1
  107. data/test/test_Keep_Alive.cpp +161 -0
  108. data/test/test_Memory_Management.cpp +2 -4
  109. data/test/test_Module.cpp +167 -110
  110. data/test/test_Object.cpp +41 -21
  111. data/test/test_Ownership.cpp +275 -0
  112. data/test/test_Self.cpp +205 -0
  113. data/test/test_Stl_Optional.cpp +90 -0
  114. data/test/test_Stl_Pair.cpp +144 -0
  115. data/test/test_Stl_SmartPointer.cpp +200 -0
  116. data/test/test_Stl_String.cpp +74 -0
  117. data/test/test_Stl_Vector.cpp +652 -0
  118. data/test/test_String.cpp +1 -2
  119. data/test/test_Struct.cpp +29 -39
  120. data/test/test_Symbol.cpp +1 -2
  121. data/test/test_To_From_Ruby.cpp +249 -285
  122. data/test/test_global_functions.cpp +39 -19
  123. data/test/unittest.hpp +0 -4
  124. metadata +70 -141
  125. data/Doxyfile +0 -2268
  126. data/Makefile.am +0 -26
  127. data/Makefile.in +0 -931
  128. data/README.mingw +0 -8
  129. data/aclocal.m4 +0 -1085
  130. data/ax_cxx_compile_stdcxx.m4 +0 -951
  131. data/bootstrap +0 -8
  132. data/config.guess +0 -1421
  133. data/config.sub +0 -1807
  134. data/configure +0 -7792
  135. data/configure.ac +0 -55
  136. data/depcomp +0 -791
  137. data/doxygen.ac +0 -314
  138. data/doxygen.am +0 -186
  139. data/extconf.rb +0 -70
  140. data/install-sh +0 -501
  141. data/missing +0 -215
  142. data/post-autoconf.rb +0 -22
  143. data/post-automake.rb +0 -28
  144. data/rice/Address_Registration_Guard.cpp +0 -22
  145. data/rice/Arg_impl.hpp +0 -129
  146. data/rice/Arg_operators.cpp +0 -21
  147. data/rice/Arg_operators.hpp +0 -19
  148. data/rice/Array.hpp +0 -214
  149. data/rice/Array.ipp +0 -256
  150. data/rice/Builtin_Object.hpp +0 -8
  151. data/rice/Builtin_Object.ipp +0 -50
  152. data/rice/Builtin_Object_defn.hpp +0 -50
  153. data/rice/Class.cpp +0 -57
  154. data/rice/Class.hpp +0 -8
  155. data/rice/Class.ipp +0 -6
  156. data/rice/Class_defn.hpp +0 -84
  157. data/rice/Data_Type.cpp +0 -54
  158. data/rice/Data_Type_fwd.hpp +0 -12
  159. data/rice/Director.cpp +0 -13
  160. data/rice/Exception.cpp +0 -54
  161. data/rice/Exception_Base.hpp +0 -8
  162. data/rice/Exception_Base.ipp +0 -13
  163. data/rice/Exception_Base_defn.hpp +0 -27
  164. data/rice/Hash.hpp +0 -230
  165. data/rice/Hash.ipp +0 -329
  166. data/rice/Identifier.cpp +0 -8
  167. data/rice/Jump_Tag.hpp +0 -24
  168. data/rice/Makefile.am +0 -121
  169. data/rice/Makefile.in +0 -884
  170. data/rice/Module.cpp +0 -84
  171. data/rice/Module.hpp +0 -8
  172. data/rice/Module.ipp +0 -6
  173. data/rice/Module_defn.hpp +0 -88
  174. data/rice/Module_impl.hpp +0 -281
  175. data/rice/Module_impl.ipp +0 -345
  176. data/rice/Object.cpp +0 -169
  177. data/rice/Object.hpp +0 -8
  178. data/rice/Object.ipp +0 -33
  179. data/rice/Object_defn.hpp +0 -214
  180. data/rice/Require_Guard.hpp +0 -21
  181. data/rice/String.cpp +0 -89
  182. data/rice/String.hpp +0 -91
  183. data/rice/Struct.cpp +0 -117
  184. data/rice/Struct.hpp +0 -162
  185. data/rice/Struct.ipp +0 -26
  186. data/rice/Symbol.cpp +0 -25
  187. data/rice/Symbol.hpp +0 -66
  188. data/rice/Symbol.ipp +0 -44
  189. data/rice/config.hpp +0 -47
  190. data/rice/config.hpp.in +0 -46
  191. data/rice/detail/Arguments.hpp +0 -118
  192. data/rice/detail/Auto_Function_Wrapper.hpp +0 -898
  193. data/rice/detail/Auto_Function_Wrapper.ipp +0 -3181
  194. data/rice/detail/Auto_Member_Function_Wrapper.hpp +0 -897
  195. data/rice/detail/Auto_Member_Function_Wrapper.ipp +0 -2501
  196. data/rice/detail/Caster.hpp +0 -103
  197. data/rice/detail/Not_Copyable.hpp +0 -25
  198. data/rice/detail/Wrapped_Function.hpp +0 -33
  199. data/rice/detail/cfp.hpp +0 -24
  200. data/rice/detail/cfp.ipp +0 -51
  201. data/rice/detail/check_ruby_type.cpp +0 -27
  202. data/rice/detail/check_ruby_type.hpp +0 -23
  203. data/rice/detail/creation_funcs.hpp +0 -37
  204. data/rice/detail/creation_funcs.ipp +0 -36
  205. data/rice/detail/define_method_and_auto_wrap.hpp +0 -31
  206. data/rice/detail/define_method_and_auto_wrap.ipp +0 -30
  207. data/rice/detail/demangle.cpp +0 -56
  208. data/rice/detail/demangle.hpp +0 -19
  209. data/rice/detail/env.hpp +0 -11
  210. data/rice/detail/method_data.cpp +0 -92
  211. data/rice/detail/node.hpp +0 -13
  212. data/rice/detail/protect.cpp +0 -29
  213. data/rice/detail/protect.hpp +0 -34
  214. data/rice/detail/ruby_version_code.hpp +0 -6
  215. data/rice/detail/ruby_version_code.hpp.in +0 -6
  216. data/rice/detail/st.hpp +0 -22
  217. data/rice/detail/win32.hpp +0 -16
  218. data/rice/detail/wrap_function.hpp +0 -66
  219. data/rice/protect.hpp +0 -38
  220. data/rice/protect.ipp +0 -1134
  221. data/rice/rubypp.rb +0 -97
  222. data/rice/to_from_ruby.hpp +0 -8
  223. data/rice/to_from_ruby.ipp +0 -418
  224. data/rice/to_from_ruby_defn.hpp +0 -70
  225. data/ruby/Makefile.am +0 -1
  226. data/ruby/Makefile.in +0 -628
  227. data/ruby/lib/Makefile.am +0 -3
  228. data/ruby/lib/Makefile.in +0 -506
  229. data/ruby/lib/mkmf-rice.rb.in +0 -217
  230. data/ruby/lib/version.rb +0 -3
  231. data/ruby.ac +0 -135
  232. data/sample/Makefile.am +0 -53
  233. data/sample/Makefile.in +0 -495
  234. data/test/Makefile.am +0 -73
  235. data/test/Makefile.in +0 -1219
  236. data/test/ext/Makefile.am +0 -41
  237. data/test/ext/Makefile.in +0 -483
  238. data/test/test_rice.rb +0 -45
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
+ }
data/rice/Exception.hpp CHANGED
@@ -1,13 +1,7 @@
1
1
  #ifndef Rice__Exception__hpp_
2
2
  #define Rice__Exception__hpp_
3
3
 
4
- namespace Rice {
5
- class Exception;
6
- }
7
-
8
4
  #include "Exception_defn.hpp"
9
- #include "Exception_Base.hpp"
10
- #include "Address_Registration_Guard.hpp"
11
-
12
- #endif // Rice__Exception__hpp_
5
+ #include "Exception.ipp"
13
6
 
7
+ #endif // Rice__Exception__hpp_
@@ -0,0 +1,65 @@
1
+ #ifndef Rice__Exception__ipp_
2
+ #define Rice__Exception__ipp_
3
+
4
+ #include "detail/from_ruby.hpp"
5
+
6
+ namespace Rice
7
+ {
8
+ inline Exception::Exception(VALUE exception) : exception_(exception)
9
+ {
10
+ }
11
+
12
+ template <typename... Arg_Ts>
13
+ inline Exception::Exception(const Exception& other, char const* fmt, Arg_Ts&&...args)
14
+ : Exception(other.class_of(), fmt, std::forward<Arg_Ts>(args)...)
15
+ {
16
+ }
17
+
18
+ template <typename... Arg_Ts>
19
+ inline Exception::Exception(const VALUE exceptionClass, char const* fmt, Arg_Ts&&...args)
20
+ {
21
+ #ifdef __GNUC__
22
+ #pragma GCC diagnostic push
23
+ #pragma GCC diagnostic ignored "-Wformat-security"
24
+ #endif
25
+
26
+ size_t size = std::snprintf(nullptr, 0, fmt, std::forward<Arg_Ts>(args)...);
27
+ this->message_ = std::string(size, '\0');
28
+
29
+ // size+1 avoids truncating the string. Otherwise snprintf writes n - 1 characters
30
+ // to allow space for null character but we don't need that since std::string
31
+ // will add a null character internally at n + 1
32
+ std::snprintf(&this->message_[0], size + 1, fmt, std::forward<Arg_Ts>(args)...);
33
+
34
+ #ifdef __GNUC__
35
+ #pragma GCC diagnostic pop
36
+ #endif
37
+
38
+ // Now create the Ruby exception
39
+ this->exception_ = detail::protect(rb_exc_new2, exceptionClass, this->message_.c_str());
40
+ }
41
+
42
+ inline char const* Exception::what() const noexcept
43
+ {
44
+ if (this->message_.empty())
45
+ {
46
+ // Cache the message - this allows the returned pointer to be valid for the
47
+ // lifetime of this exception instance.
48
+ VALUE rubyMessage = rb_funcall(this->exception_, rb_intern("message"), 0);
49
+ //this->message_ = detail::From_Ruby<std::string>::convert(rubyMessage);
50
+ this->message_ = std::string(RSTRING_PTR(rubyMessage), RSTRING_LEN(rubyMessage));
51
+ }
52
+ return this->message_.c_str();
53
+ }
54
+
55
+ inline VALUE Exception::class_of() const
56
+ {
57
+ return detail::protect(rb_class_of, this->exception_);
58
+ }
59
+
60
+ inline VALUE Exception::value() const
61
+ {
62
+ return this->exception_;
63
+ }
64
+ }
65
+ #endif // Rice__Exception__ipp_
@@ -1,69 +1,68 @@
1
1
  #ifndef Rice__Exception_defn__hpp_
2
2
  #define Rice__Exception_defn__hpp_
3
3
 
4
- #include "Exception_Base_defn.hpp"
5
- #include "String.hpp"
6
- #include "Address_Registration_Guard_defn.hpp"
7
-
8
4
  #include <stdexcept>
9
5
  #include "detail/ruby.hpp"
10
6
 
11
7
  namespace Rice
12
8
  {
9
+ //! A placeholder for Ruby exceptions.
10
+ /*! You can use this to safely throw a Ruby exception using C++ syntax:
11
+ * \code
12
+ * VALUE foo(VALUE self) {
13
+ * RUBY_TRY {
14
+ * throw Rice::Exception(rb_eMyException, "uh oh!");
15
+ * RUBY_CATCH
16
+ * }
17
+ * \endcode
18
+ */
19
+ class Exception
20
+ : public std::exception
21
+ {
22
+ public:
23
+ //! Construct a Exception with a Ruby exception instance
24
+ explicit Exception(VALUE exception);
13
25
 
14
- //! A placeholder for Ruby exceptions.
15
- /*! You can use this to safely throw a Ruby exception using C++ syntax:
16
- * \code
17
- * VALUE foo(VALUE self) {
18
- * RUBY_TRY {
19
- * throw Rice::Exception(rb_eMyException, "uh oh!");
20
- * RUBY_CATCH
21
- * }
22
- * \endcode
23
- */
24
- class Exception
25
- : public Exception_Base
26
- {
27
- public:
28
- //! Construct a Exception with the exception e.
29
- explicit Exception(VALUE e);
30
-
31
- //! Copy constructor.
32
- Exception(Exception const & other);
26
+ //! Construct a Exception with printf-style formatting.
27
+ /*! \param exc either an exception object or a class that inherits
28
+ * from Exception.
29
+ * \param fmt a printf-style format string
30
+ * \param ... the arguments to the format string.
31
+ */
32
+ template <typename... Arg_Ts>
33
+ Exception(const Exception& other, char const* fmt, Arg_Ts&&...args);
33
34
 
34
- //! Construct a Exception with printf-style formatting.
35
+ //! Construct a Exception with printf-style formatting.
35
36
  /*! \param exc either an exception object or a class that inherits
36
37
  * from Exception.
37
38
  * \param fmt a printf-style format string
38
39
  * \param ... the arguments to the format string.
39
40
  */
40
- Exception(Object exc, char const * fmt, ...);
41
+ template <typename... Arg_Ts>
42
+ Exception(const VALUE exceptionType, char const* fmt, Arg_Ts&&...args);
41
43
 
42
- //! Destructor
43
- virtual ~Exception() throw() { }
44
+ //! Destructor
45
+ virtual ~Exception() noexcept = default;
44
46
 
45
- //! Get the message the exception holds
46
- /*! \return the result of calling message() on the underlying
47
- * exception object.
48
- */
49
- String message() const;
47
+ //! Get message as a char const *.
48
+ /*! If message is a non-string object, then this function will attempt
49
+ * to throw an exception (which it can't do because of the no-throw
50
+ * specification).
51
+ * \return the underlying C pointer of the underlying message object.
52
+ */
53
+ virtual char const* what() const noexcept override;
50
54
 
51
- //! Get message as a char const *.
52
- /*! If message is a non-string object, then this function will attempt
53
- * to throw an exception (which it can't do because of the no-throw
54
- * specification).
55
- * \return the underlying C pointer of the underlying message object.
56
- */
57
- virtual char const * what() const throw();
55
+ //! Returns the Ruby exception class
56
+ VALUE class_of() const;
58
57
 
59
- private:
60
- // Keep message around in case someone calls what() and then the GC
61
- // gets invoked.
62
- mutable VALUE message_;
63
- Address_Registration_Guard message_guard_;
64
- };
58
+ //! Returns an instance of a Ruby exception
59
+ VALUE value() const;
65
60
 
61
+ private:
62
+ // TODO: Do we need to tell the Ruby gc about an exception instance?
63
+ mutable VALUE exception_ = Qnil;
64
+ mutable std::string message_;
65
+ };
66
66
  } // namespace Rice
67
67
 
68
- #endif // Rice__Exception_defn__hpp_
69
-
68
+ #endif // Rice__Exception_defn__hpp_
data/rice/Identifier.hpp CHANGED
@@ -1,48 +1,48 @@
1
1
  #ifndef Rice__Identifier__hpp_
2
2
  #define Rice__Identifier__hpp_
3
3
 
4
- #include "detail/ruby.hpp"
5
4
  #include <string>
6
5
 
7
6
  namespace Rice
8
7
  {
8
+ class Symbol;
9
9
 
10
- class Symbol;
10
+ //! A wrapper for the ID type
11
+ /*! An ID is ruby's internal representation of a Symbol object.
12
+ */
13
+ class Identifier
14
+ {
15
+ public:
16
+ //! Construct a new Identifier from an ID.
17
+ Identifier(ID id);
11
18
 
12
- //! A wrapper for the ID type
13
- /*! An ID is ruby's internal representation of a Symbol object.
14
- */
15
- class Identifier
16
- {
17
- public:
18
- //! Construct a new Identifier from an ID.
19
- Identifier(ID id);
20
-
21
- //! Construct a new Identifier from a Symbol.
22
- Identifier(Symbol const & symbol);
19
+ //! Construct a new Identifier from a Symbol.
20
+ Identifier(Symbol const& symbol);
23
21
 
24
- //! Construct a new Identifier from a string.
25
- Identifier(char const * s = "");
22
+ //! Construct a new Identifier from a c string.
23
+ Identifier(char const* s);
26
24
 
27
- //! Return a string representation of the Identifier.
28
- char const * c_str() const;
25
+ //! Construct a new Identifier from a string.
26
+ Identifier(std::string const string);
29
27
 
30
- //! Return a string representation of the Identifier.
31
- std::string str() const;
28
+ //! Return a string representation of the Identifier.
29
+ char const* c_str() const;
32
30
 
33
- //! Return the underlying ID
34
- ID id() const { return id_; }
31
+ //! Return a string representation of the Identifier.
32
+ std::string str() const;
35
33
 
36
- //! Return the underlying ID
37
- operator ID() const { return id_; }
34
+ //! Return the underlying ID
35
+ ID id() const { return id_; }
38
36
 
39
- //! Return the ID as a Symbol
40
- VALUE to_sym() const;
37
+ //! Return the underlying ID
38
+ operator ID() const { return id_; }
41
39
 
42
- private:
43
- ID id_;
44
- };
40
+ //! Return the ID as a Symbol
41
+ VALUE to_sym() const;
45
42
 
43
+ private:
44
+ ID id_;
45
+ };
46
46
  } // namespace Rice
47
47
 
48
48
  #include "Identifier.ipp"
data/rice/Identifier.ipp CHANGED
@@ -1,33 +1,29 @@
1
- inline Rice::Identifier::
2
- Identifier(ID id)
3
- : id_(id)
1
+ namespace Rice
4
2
  {
5
- }
3
+ inline Identifier::Identifier(ID id) : id_(id)
4
+ {
5
+ }
6
6
 
7
- inline Rice::Identifier::
8
- Identifier(char const * s)
9
- : id_(rb_intern(s))
10
- {
11
- }
7
+ inline Identifier::Identifier(char const* s) : id_(rb_intern(s))
8
+ {
9
+ }
12
10
 
13
- inline char const *
14
- Rice::Identifier::
15
- c_str() const
16
- {
17
- return rb_id2name(id_);
18
- }
11
+ inline Identifier::Identifier(std::string const s) : id_(rb_intern(s.c_str()))
12
+ {
13
+ }
19
14
 
20
- inline std::string
21
- Rice::Identifier::
22
- str() const
23
- {
24
- return c_str();
25
- }
15
+ inline char const* Identifier::c_str() const
16
+ {
17
+ return detail::protect(rb_id2name, id_);
18
+ }
26
19
 
27
- inline VALUE
28
- Rice::Identifier::
29
- to_sym() const
30
- {
31
- return ID2SYM(id_);
32
- }
20
+ inline std::string Identifier::str() const
21
+ {
22
+ return c_str();
23
+ }
33
24
 
25
+ inline VALUE Identifier::to_sym() const
26
+ {
27
+ return ID2SYM(id_);
28
+ }
29
+ }