rice 2.1.1 → 4.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 (246) hide show
  1. checksums.yaml +5 -5
  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 +69 -0
  7. data/Rakefile +95 -12
  8. data/include/rice/rice.hpp +7766 -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 +30 -376
  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 +14 -9
  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 -49
  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 +6 -0
  71. data/sample/callbacks/sample_callbacks.cpp +35 -0
  72. data/sample/callbacks/test.rb +28 -0
  73. data/sample/enum/extconf.rb +3 -0
  74. data/sample/enum/sample_enum.cpp +3 -17
  75. data/sample/enum/test.rb +2 -2
  76. data/sample/inheritance/animals.cpp +8 -24
  77. data/sample/inheritance/extconf.rb +3 -0
  78. data/sample/inheritance/test.rb +1 -1
  79. data/sample/map/extconf.rb +3 -0
  80. data/sample/map/map.cpp +10 -18
  81. data/sample/map/test.rb +1 -1
  82. data/test/embed_ruby.cpp +34 -0
  83. data/test/embed_ruby.hpp +4 -0
  84. data/test/ext/t1/extconf.rb +3 -0
  85. data/test/ext/t1/t1.cpp +1 -3
  86. data/test/ext/t2/extconf.rb +3 -0
  87. data/test/ext/t2/t2.cpp +1 -1
  88. data/test/extconf.rb +23 -0
  89. data/test/ruby/test_callbacks_sample.rb +28 -0
  90. data/test/ruby/test_multiple_extensions.rb +18 -0
  91. data/test/ruby/test_multiple_extensions_same_class.rb +14 -0
  92. data/test/ruby/test_multiple_extensions_with_inheritance.rb +20 -0
  93. data/test/test_Address_Registration_Guard.cpp +25 -11
  94. data/test/test_Array.cpp +131 -74
  95. data/test/test_Attribute.cpp +147 -0
  96. data/test/test_Builtin_Object.cpp +36 -15
  97. data/test/test_Class.cpp +151 -274
  98. data/test/test_Constructor.cpp +10 -9
  99. data/test/test_Data_Object.cpp +135 -193
  100. data/test/test_Data_Type.cpp +323 -252
  101. data/test/test_Director.cpp +56 -42
  102. data/test/test_Enum.cpp +230 -104
  103. data/test/test_Exception.cpp +7 -7
  104. data/test/test_Hash.cpp +33 -31
  105. data/test/test_Identifier.cpp +6 -6
  106. data/test/test_Inheritance.cpp +221 -0
  107. data/test/test_Iterator.cpp +161 -0
  108. data/test/test_Jump_Tag.cpp +1 -1
  109. data/test/test_Keep_Alive.cpp +161 -0
  110. data/test/test_Memory_Management.cpp +4 -5
  111. data/test/test_Module.cpp +169 -111
  112. data/test/test_Object.cpp +51 -19
  113. data/test/test_Ownership.cpp +275 -0
  114. data/test/test_Self.cpp +205 -0
  115. data/test/test_Stl_Optional.cpp +90 -0
  116. data/test/test_Stl_Pair.cpp +144 -0
  117. data/test/test_Stl_SmartPointer.cpp +200 -0
  118. data/test/test_Stl_String.cpp +74 -0
  119. data/test/test_Stl_Vector.cpp +652 -0
  120. data/test/test_String.cpp +3 -3
  121. data/test/test_Struct.cpp +31 -40
  122. data/test/test_Symbol.cpp +3 -3
  123. data/test/test_To_From_Ruby.cpp +283 -218
  124. data/test/test_global_functions.cpp +41 -20
  125. data/test/unittest.cpp +34 -8
  126. data/test/unittest.hpp +0 -4
  127. metadata +117 -137
  128. data/Doxyfile +0 -2280
  129. data/Makefile.am +0 -26
  130. data/Makefile.in +0 -920
  131. data/README +0 -1055
  132. data/README.mingw +0 -8
  133. data/aclocal.m4 +0 -1088
  134. data/bootstrap +0 -8
  135. data/check_stdcxx_11.ac +0 -142
  136. data/config.guess +0 -1421
  137. data/config.sub +0 -1807
  138. data/configure +0 -7481
  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 -124
  173. data/rice/Makefile.in +0 -839
  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 -625
  236. data/ruby/lib/Makefile.am +0 -3
  237. data/ruby/lib/Makefile.in +0 -503
  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 -486
  242. data/test/Makefile.am +0 -72
  243. data/test/Makefile.in +0 -1150
  244. data/test/ext/Makefile.am +0 -41
  245. data/test/ext/Makefile.in +0 -480
  246. data/test/test_rice.rb +0 -41
@@ -0,0 +1,51 @@
1
+ #ifndef Rice__detail__Wrapper__hpp_
2
+ #define Rice__detail__Wrapper__hpp_
3
+
4
+ #include "ruby.hpp"
5
+
6
+ namespace Rice
7
+ {
8
+ namespace detail
9
+ {
10
+
11
+ class Wrapper
12
+ {
13
+ public:
14
+ virtual ~Wrapper() = default;
15
+ virtual void* get() = 0;
16
+
17
+ void ruby_mark();
18
+ void addKeepAlive(VALUE value);
19
+
20
+ private:
21
+ // We use a vector for speed and memory locality versus a set which does
22
+ // not scale well when getting to tens of thousands of objects (not expecting
23
+ // that to happen...but just in case)
24
+ std::vector<VALUE> keepAlive_;
25
+ };
26
+
27
+ template <typename T, typename Wrapper_T = void>
28
+ VALUE wrap(VALUE klass, rb_data_type_t* rb_type, T& data, bool isOwner);
29
+
30
+ template <typename T, typename Wrapper_T = void>
31
+ VALUE wrap(VALUE klass, rb_data_type_t* rb_type, T* data, bool isOwner);
32
+
33
+ template <typename T>
34
+ T* unwrap(VALUE value, rb_data_type_t* rb_type);
35
+
36
+ Wrapper* getWrapper(VALUE value, rb_data_type_t* rb_type);
37
+
38
+ void* unwrap(VALUE value);
39
+
40
+ template <typename T>
41
+ void replace(VALUE value, rb_data_type_t* rb_type, T* data, bool isOwner);
42
+
43
+ Wrapper* getWrapper(VALUE value);
44
+
45
+ } // namespace detail
46
+ } // namespace Rice
47
+
48
+ #include "Wrapper.ipp"
49
+
50
+ #endif // Rice__detail__Wrapper__hpp_
51
+
@@ -0,0 +1,151 @@
1
+ #include <memory>
2
+
3
+ namespace Rice::detail
4
+ {
5
+ inline void Wrapper::ruby_mark()
6
+ {
7
+ for (VALUE value : this->keepAlive_)
8
+ {
9
+ rb_gc_mark(value);
10
+ }
11
+ }
12
+
13
+ inline void Wrapper::addKeepAlive(VALUE value)
14
+ {
15
+ this->keepAlive_.push_back(value);
16
+ }
17
+
18
+ template <typename T>
19
+ class WrapperValue : public Wrapper
20
+ {
21
+ public:
22
+ WrapperValue(T& data): data_(std::move(data))
23
+ {
24
+ }
25
+
26
+ void* get() override
27
+ {
28
+ return (void*)&this->data_;
29
+ }
30
+
31
+ private:
32
+ T data_;
33
+ };
34
+
35
+ template <typename T>
36
+ class WrapperReference : public Wrapper
37
+ {
38
+ public:
39
+ WrapperReference(const T& data): data_(data)
40
+ {
41
+ }
42
+
43
+ void* get() override
44
+ {
45
+ return (void*)&this->data_;
46
+ }
47
+
48
+ private:
49
+ const T& data_;
50
+ };
51
+
52
+ template <typename T>
53
+ class WrapperPointer : public Wrapper
54
+ {
55
+ public:
56
+ WrapperPointer(T* data, bool isOwner) : data_(data), isOwner_(isOwner)
57
+ {
58
+ }
59
+
60
+ ~WrapperPointer()
61
+ {
62
+ if (this->isOwner_)
63
+ {
64
+ delete this->data_;
65
+ }
66
+ }
67
+
68
+ void* get() override
69
+ {
70
+ return (void*)this->data_;
71
+ }
72
+
73
+ private:
74
+ T* data_ = nullptr;
75
+ bool isOwner_ = false;
76
+ };
77
+
78
+ // ---- Helper Functions -------
79
+ template <typename T, typename Wrapper_T>
80
+ inline VALUE wrap(VALUE klass, rb_data_type_t* rb_type, T& data, bool isOwner)
81
+ {
82
+ if constexpr (!std::is_void_v<Wrapper_T>)
83
+ {
84
+ Wrapper_T* wrapper = new Wrapper_T(data);
85
+ return TypedData_Wrap_Struct(klass, rb_type, wrapper);
86
+ }
87
+ else if (isOwner)
88
+ {
89
+ WrapperValue<T>* wrapper = new WrapperValue<T>(data);
90
+ return TypedData_Wrap_Struct(klass, rb_type, wrapper);
91
+ }
92
+ else
93
+ {
94
+ WrapperReference<T>* wrapper = new WrapperReference<T>(data);
95
+ return TypedData_Wrap_Struct(klass, rb_type, wrapper);
96
+ }
97
+ };
98
+
99
+ template <typename T, typename Wrapper_T>
100
+ inline VALUE wrap(VALUE klass, rb_data_type_t* rb_type, T* data, bool isOwner)
101
+ {
102
+ if constexpr (!std::is_void_v<Wrapper_T>)
103
+ {
104
+ Wrapper_T* wrapper = new Wrapper_T(data);
105
+ return TypedData_Wrap_Struct(klass, rb_type, wrapper);
106
+ }
107
+ else
108
+ {
109
+ WrapperPointer<T>* wrapper = new WrapperPointer<T>(data, isOwner);
110
+ return TypedData_Wrap_Struct(klass, rb_type, wrapper);
111
+ }
112
+ };
113
+
114
+ template <typename T>
115
+ inline T* unwrap(VALUE value, rb_data_type_t* rb_type)
116
+ {
117
+ Wrapper* wrapper = getWrapper(value, rb_type);
118
+ TypedData_Get_Struct(value, Wrapper, rb_type, wrapper);
119
+ return static_cast<T*>(wrapper->get());
120
+ }
121
+
122
+ inline void* unwrap(VALUE value)
123
+ {
124
+ // Direct access to avoid any type checking
125
+ Wrapper* wrapper = (Wrapper*)RTYPEDDATA_DATA(value);
126
+ return wrapper->get();
127
+ }
128
+
129
+ inline Wrapper* getWrapper(VALUE value, rb_data_type_t* rb_type)
130
+ {
131
+ Wrapper* wrapper = nullptr;
132
+ TypedData_Get_Struct(value, Wrapper, rb_type, wrapper);
133
+ return wrapper;
134
+ }
135
+
136
+ template <typename T>
137
+ inline void replace(VALUE value, rb_data_type_t* rb_type, T* data, bool isOwner)
138
+ {
139
+ WrapperPointer<T>* wrapper = nullptr;
140
+ TypedData_Get_Struct(value, WrapperPointer<T>, rb_type, wrapper);
141
+ delete wrapper;
142
+
143
+ wrapper = new WrapperPointer<T>(data, true);
144
+ RTYPEDDATA_DATA(value) = wrapper;
145
+ }
146
+
147
+ inline Wrapper* getWrapper(VALUE value)
148
+ {
149
+ return static_cast<Wrapper*>(RTYPEDDATA_DATA(value));
150
+ }
151
+ } // namespace
@@ -1,23 +1,12 @@
1
1
  #ifndef Rice__detail__default_allocation_func__hpp_
2
2
  #define Rice__detail__default_allocation_func__hpp_
3
3
 
4
- namespace Rice
4
+ namespace Rice::detail
5
5
  {
6
-
7
- namespace detail
8
- {
9
-
10
- //! A default implementation of an allocate_func. This function does no
11
- //! actual allocation; the initialize_func can later do the real
12
- //! allocation with: DATA_PTR(self) = new Type(arg1, arg2, ...)
13
- template<typename T>
14
- VALUE default_allocation_func(VALUE klass);
15
-
16
- } // detail
17
-
18
- } // Rice
19
-
20
- #include "default_allocation_func.ipp"
21
-
22
- #endif // Rice__detail__default_allocation_func__hpp_
23
-
6
+ //! A default implementation of an allocate_func. This function does no
7
+ //! actual allocation; the initialize_func can later do the real
8
+ //! allocation with: DATA_PTR(self) = new Type(arg1, arg2, ...)
9
+ template<typename T>
10
+ VALUE default_allocation_func(VALUE klass);
11
+ }
12
+ #endif // Rice__detail__default_allocation_func__hpp_
@@ -1,11 +1,12 @@
1
1
  #include "../Data_Object.hpp"
2
2
 
3
- template<typename T>
4
- VALUE Rice::detail::
5
- default_allocation_func(VALUE klass)
3
+ namespace Rice::detail
6
4
  {
7
- Data_Object<T> m(static_cast<T*>(0), klass);
8
- return m.value();
9
- }
10
-
11
-
5
+ template<typename T>
6
+ VALUE default_allocation_func(VALUE klass)
7
+ {
8
+ // Create a new Ruby object but since we do not yet have a C++ object
9
+ // just pass a nullptr. It will be set via the Constructor call
10
+ return TypedData_Wrap_Struct(klass, Data_Type<T>::rb_type(), nullptr);
11
+ }
12
+ }
@@ -1,43 +1,8 @@
1
1
  #ifndef Rice__detail__from_ruby__hpp_
2
2
  #define Rice__detail__from_ruby__hpp_
3
3
 
4
- namespace Rice
5
- {
6
- namespace detail
7
- {
8
- template<typename T>
9
- struct from_ruby_
10
- {
11
- typedef T Retval_T;
12
-
13
- static T convert(Rice::Object x);
14
- };
15
-
16
- template<typename T>
17
- struct from_ruby_<T *>
18
- {
19
- typedef T * Retval_T;
20
-
21
- static T * convert(Rice::Object x);
22
- };
23
-
24
- template<typename T>
25
- struct from_ruby_<T const *>
26
- {
27
- typedef T const * Retval_T;
28
-
29
- static T const * convert(Rice::Object x);
30
- };
31
-
32
- template<typename T>
33
- struct from_ruby_<T &>
34
- {
35
- typedef T & Retval_T;
36
-
37
- static T & convert(Rice::Object x);
38
- };
39
- } // detail
40
- } // Rice
4
+ #include "from_ruby_defn.hpp"
5
+ #include "from_ruby.ipp"
41
6
 
42
7
  #endif // Rice__detail__from_ruby__hpp_
43
8
 
@@ -1,60 +1,1034 @@
1
1
  #ifndef Rice__detail__from_ruby__ipp_
2
2
  #define Rice__detail__from_ruby__ipp_
3
3
 
4
- #include "../Data_Type.hpp"
5
- #include "../String.hpp"
6
- #include "demangle.hpp"
7
- #include <typeinfo>
8
-
9
- template<typename T>
10
- T Rice::detail::from_ruby_<T>::
11
- convert(Rice::Object x)
4
+ #include <optional>
5
+ #include <stdexcept>
6
+ #include "../Exception_defn.hpp"
7
+ #include "../Arg.hpp"
8
+ #include "RubyFunction.hpp"
9
+
10
+ /* This file implements conversions from Ruby to native values fo fundamental types
11
+ such as bool, int, float, etc. It also includes conversions for chars and strings */
12
+ namespace Rice::detail
12
13
  {
13
- if(rb_type(x.value()) == T_DATA)
14
+ // =========== short ============
15
+ template<>
16
+ class From_Ruby<short>
14
17
  {
15
- return *Data_Type<T>::from_ruby(x);
16
- }
17
- else
18
+ public:
19
+ From_Ruby() = default;
20
+
21
+ explicit From_Ruby(Arg* arg) : arg_(arg)
22
+ {
23
+ }
24
+
25
+ short convert(VALUE value)
26
+ {
27
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
28
+ {
29
+ return this->arg_->defaultValue<short>();
30
+ }
31
+ else
32
+ {
33
+ return protect(rb_num2short_inline, value);
34
+ }
35
+ }
36
+
37
+ private:
38
+ Arg* arg_ = nullptr;
39
+ };
40
+
41
+ template<>
42
+ class From_Ruby<short&>
18
43
  {
19
- std::string s("Unable to convert ");
20
- s += x.class_of().name().c_str();
21
- s += " to ";
22
- s += demangle(typeid(T).name());
23
- throw std::invalid_argument(s.c_str());
24
- }
25
- }
44
+ public:
45
+ From_Ruby() = default;
26
46
 
27
- template<typename T>
28
- T * Rice::detail::from_ruby_<T *>::
29
- convert(Rice::Object x)
30
- {
31
- if(rb_type(x.value()) == T_DATA)
47
+ explicit From_Ruby(Arg* arg) : arg_(arg)
48
+ {
49
+ }
50
+
51
+ short& convert(VALUE value)
52
+ {
53
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
54
+ {
55
+ return this->arg_->defaultValue<short>();
56
+ }
57
+ else
58
+ {
59
+ this->converted_ = protect(rb_num2short_inline, value);
60
+ return this->converted_;
61
+ }
62
+ }
63
+
64
+ private:
65
+ Arg* arg_ = nullptr;
66
+ short converted_ = 0;
67
+ };
68
+
69
+ template<>
70
+ class From_Ruby<short*>
32
71
  {
33
- return Data_Type<T>::from_ruby(x);
34
- }
35
- else
72
+ public:
73
+ short* convert(VALUE value)
74
+ {
75
+ if (value == Qnil)
76
+ {
77
+ return nullptr;
78
+ }
79
+ else
80
+ {
81
+ this->converted_ = protect(rb_num2short_inline, value);
82
+ return &this->converted_;
83
+ }
84
+ }
85
+
86
+ private:
87
+ short converted_ = 0;
88
+ };
89
+
90
+ // =========== int ============
91
+ template<>
92
+ class From_Ruby<int>
93
+ {
94
+ public:
95
+ From_Ruby() = default;
96
+
97
+ explicit From_Ruby(Arg* arg) : arg_(arg)
98
+ {
99
+ }
100
+
101
+ int convert(VALUE value)
102
+ {
103
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
104
+ {
105
+ return this->arg_->defaultValue<int>();
106
+ }
107
+ else
108
+ {
109
+ return (int)protect(rb_num2long_inline, value);
110
+ }
111
+ }
112
+
113
+ private:
114
+ Arg* arg_ = nullptr;
115
+ };
116
+
117
+ template<>
118
+ class From_Ruby<int&>
119
+ {
120
+ public:
121
+ From_Ruby() = default;
122
+
123
+ explicit From_Ruby(Arg* arg) : arg_(arg)
124
+ {
125
+ }
126
+
127
+ int& convert(VALUE value)
128
+ {
129
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
130
+ {
131
+ return this->arg_->defaultValue<int>();
132
+ }
133
+ else
134
+ {
135
+ this->converted_ = (int)protect(rb_num2long_inline, value);
136
+ return this->converted_;
137
+ }
138
+ }
139
+
140
+ private:
141
+ Arg* arg_ = nullptr;
142
+ int converted_ = 0;
143
+ };
144
+
145
+ template<>
146
+ class From_Ruby<int*>
147
+ {
148
+ public:
149
+ int* convert(VALUE value)
150
+ {
151
+ if (value == Qnil)
152
+ {
153
+ return nullptr;
154
+ }
155
+ else
156
+ {
157
+ this->converted_ = (int)protect(rb_num2long_inline, value);
158
+ return &this->converted_;
159
+ }
160
+ }
161
+
162
+ private:
163
+ int converted_;
164
+ };
165
+
166
+ // =========== long ============
167
+ template<>
168
+ class From_Ruby<long>
169
+ {
170
+ public:
171
+ From_Ruby() = default;
172
+
173
+ explicit From_Ruby(Arg* arg) : arg_(arg)
174
+ {
175
+ }
176
+
177
+ long convert(VALUE value)
178
+ {
179
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
180
+ {
181
+ return this->arg_->defaultValue<long>();
182
+ }
183
+ else
184
+ {
185
+ return protect(rb_num2long_inline, value);
186
+ }
187
+ }
188
+
189
+ private:
190
+ Arg* arg_ = nullptr;
191
+ };
192
+
193
+ template<>
194
+ class From_Ruby<long&>
36
195
  {
37
- std::string s("Unable to convert ");
38
- s += x.class_of().name().c_str();
39
- s += " to ";
40
- s += demangle(typeid(T *).name());
41
- throw std::invalid_argument(s.c_str());
196
+ public:
197
+ From_Ruby() = default;
198
+
199
+ explicit From_Ruby(Arg* arg) : arg_(arg)
200
+ {
201
+ }
202
+
203
+ long& convert(VALUE value)
204
+ {
205
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
206
+ {
207
+ return this->arg_->defaultValue<long>();
208
+ }
209
+ else
210
+ {
211
+ this->converted_ = protect(rb_num2long_inline, value);
212
+ return this->converted_;
213
+ }
214
+ }
215
+
216
+ private:
217
+ Arg* arg_ = nullptr;
218
+ long converted_ = 0;
219
+ };
220
+
221
+ template<>
222
+ class From_Ruby<long*>
223
+ {
224
+ public:
225
+ long* convert(VALUE value)
226
+ {
227
+ if (value == Qnil)
228
+ {
229
+ return nullptr;
230
+ }
231
+ else
232
+ {
233
+ this->converted_ = protect(rb_num2long_inline, value);
234
+ return &this->converted_;
235
+ }
236
+ }
237
+
238
+ private:
239
+ long converted_ = 0;
240
+ };
241
+
242
+ // =========== long long ============
243
+ template<>
244
+ class From_Ruby<long long>
245
+ {
246
+ public:
247
+ From_Ruby() = default;
248
+
249
+ explicit From_Ruby(Arg* arg) : arg_(arg)
250
+ {
251
+ }
252
+
253
+ long long convert(VALUE value)
254
+ {
255
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
256
+ {
257
+ return this->arg_->defaultValue<long long>();
258
+ }
259
+ else
260
+ {
261
+ return protect(rb_num2ll_inline, value);
262
+ }
263
+ }
264
+
265
+ private:
266
+ Arg* arg_ = nullptr;
267
+ };
268
+
269
+ template<>
270
+ class From_Ruby<long long&>
271
+ {
272
+ public:
273
+ From_Ruby() = default;
274
+
275
+ explicit From_Ruby(Arg* arg) : arg_(arg)
276
+ {
277
+ }
278
+
279
+ long long& convert(VALUE value)
280
+ {
281
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
282
+ {
283
+ return this->arg_->defaultValue<long long>();
284
+ }
285
+ else
286
+ {
287
+ this->converted_ = protect(rb_num2ll_inline, value);
288
+ return this->converted_;
289
+ }
290
+ }
291
+
292
+ private:
293
+ Arg* arg_ = nullptr;
294
+ long long converted_ = 0;
295
+ };
296
+
297
+ template<>
298
+ class From_Ruby<long long*>
299
+ {
300
+ public:
301
+ long long* convert(VALUE value)
302
+ {
303
+ if (value == Qnil)
304
+ {
305
+ return nullptr;
306
+ }
307
+ else
308
+ {
309
+ this->converted_ = protect(rb_num2ll_inline, value);
310
+ return &this->converted_;
311
+ }
312
+ }
313
+
314
+ private:
315
+ long long converted_ = 0;
316
+ };
317
+
318
+ // =========== unsigned short ============
319
+ template<>
320
+ class From_Ruby<unsigned short>
321
+ {
322
+ public:
323
+ From_Ruby() = default;
324
+
325
+ explicit From_Ruby(Arg* arg) : arg_(arg)
326
+ {
327
+ }
328
+
329
+ unsigned short convert(VALUE value)
330
+ {
331
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
332
+ {
333
+ return this->arg_->defaultValue<unsigned short>();
334
+ }
335
+ else
336
+ {
337
+ return protect(rb_num2ushort, value);
338
+ }
339
+ }
340
+
341
+ private:
342
+ Arg* arg_ = nullptr;
343
+ };
344
+
345
+ template<>
346
+ class From_Ruby<unsigned short&>
347
+ {
348
+ public:
349
+ From_Ruby() = default;
350
+
351
+ explicit From_Ruby(Arg* arg) : arg_(arg)
352
+ {
353
+ }
354
+
355
+ unsigned short& convert(VALUE value)
356
+ {
357
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
358
+ {
359
+ return this->arg_->defaultValue<unsigned short>();
360
+ }
361
+ else
362
+ {
363
+ this->converted_ = protect(rb_num2ushort, value);
364
+ return this->converted_;
365
+ }
366
+ }
367
+
368
+ private:
369
+ Arg* arg_ = nullptr;
370
+ unsigned short converted_ = 0;
371
+ };
372
+
373
+ template<>
374
+ class From_Ruby<unsigned short*>
375
+ {
376
+ public:
377
+ unsigned short* convert(VALUE value)
378
+ {
379
+ if (value == Qnil)
380
+ {
381
+ return nullptr;
382
+ }
383
+ else
384
+ {
385
+ this->converted_ = protect(rb_num2ushort, value);
386
+ return &this->converted_;
387
+ }
388
+ }
389
+
390
+ private:
391
+ unsigned short converted_ = 0;
392
+ };
393
+
394
+ // =========== unsigned int ============
395
+ template<>
396
+ class From_Ruby<unsigned int>
397
+ {
398
+ public:
399
+ From_Ruby() = default;
400
+
401
+ explicit From_Ruby(Arg* arg) : arg_(arg)
402
+ {
403
+ }
404
+
405
+ unsigned int convert(VALUE value)
406
+ {
407
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
408
+ {
409
+ return this->arg_->defaultValue<unsigned int>();
410
+ }
411
+ else
412
+ {
413
+ return (unsigned int)protect(rb_num2ulong_inline, value);
414
+ }
415
+ }
416
+
417
+ private:
418
+ Arg* arg_ = nullptr;
419
+ };
420
+
421
+ template<>
422
+ class From_Ruby<unsigned int&>
423
+ {
424
+ public:
425
+ From_Ruby() = default;
426
+
427
+ explicit From_Ruby(Arg* arg) : arg_(arg)
428
+ {
429
+ }
430
+
431
+ unsigned int& convert(VALUE value)
432
+ {
433
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
434
+ {
435
+ return this->arg_->defaultValue<unsigned int>();
436
+ }
437
+ else
438
+ {
439
+ this->converted_ = (unsigned int)protect(rb_num2ulong_inline, value);
440
+ return this->converted_;
441
+ }
442
+ }
443
+
444
+ private:
445
+ Arg* arg_ = nullptr;
446
+ unsigned int converted_ = 0;
447
+ };
448
+
449
+ template<>
450
+ class From_Ruby<unsigned int*>
451
+ {
452
+ public:
453
+ unsigned int* convert(VALUE value)
454
+ {
455
+ if (value == Qnil)
456
+ {
457
+ return nullptr;
458
+ }
459
+ else
460
+ {
461
+ this->converted_ = (unsigned int)protect(rb_num2ulong_inline, value);
462
+ return &this->converted_;
463
+ }
464
+ }
465
+
466
+ private:
467
+ unsigned int converted_ = 0;
468
+ };
469
+
470
+ // =========== unsigned long ============
471
+ template<>
472
+ class From_Ruby<unsigned long>
473
+ {
474
+ public:
475
+ From_Ruby() = default;
476
+
477
+ explicit From_Ruby(Arg* arg) : arg_(arg)
478
+ {
479
+ }
480
+
481
+ unsigned long convert(VALUE value)
482
+ {
483
+ if (this->arg_ && this->arg_->getIsValue())
484
+ {
485
+ return (unsigned long)value;
486
+ }
487
+ else if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
488
+ {
489
+ return this->arg_->defaultValue<unsigned long>();
490
+ }
491
+ else
492
+ {
493
+ return protect(rb_num2ulong_inline, value);
494
+ }
495
+ }
496
+
497
+ private:
498
+ Arg* arg_ = nullptr;
499
+ };
500
+
501
+ template<>
502
+ class From_Ruby<unsigned long&>
503
+ {
504
+ public:
505
+ From_Ruby() = default;
506
+
507
+ explicit From_Ruby(Arg* arg) : arg_(arg)
508
+ {
509
+ }
510
+
511
+ unsigned long& convert(VALUE value)
512
+ {
513
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
514
+ {
515
+ return this->arg_->defaultValue<unsigned long>();
516
+ }
517
+ else
518
+ {
519
+ this->converted_ = protect(rb_num2ulong_inline, value);
520
+ return this->converted_;
521
+ }
522
+ }
523
+
524
+ private:
525
+ Arg* arg_ = nullptr;
526
+ unsigned long converted_ = 0;
527
+ };
528
+
529
+ template<>
530
+ class From_Ruby<unsigned long*>
531
+ {
532
+ public:
533
+ unsigned long* convert(VALUE value)
534
+ {
535
+ if (value == Qnil)
536
+ {
537
+ return nullptr;
538
+ }
539
+ else
540
+ {
541
+ this->converted_ = protect(rb_num2ulong_inline, value);
542
+ return &this->converted_;
543
+ }
544
+ }
545
+
546
+ private:
547
+ unsigned long converted_ = 0;
548
+ };
549
+
550
+ // =========== unsigned long long ============
551
+ template<>
552
+ class From_Ruby<unsigned long long>
553
+ {
554
+ public:
555
+ From_Ruby() = default;
556
+
557
+ explicit From_Ruby(Arg* arg) : arg_(arg)
558
+ {
559
+ }
560
+
561
+ unsigned long long convert(VALUE value)
562
+ {
563
+ if (this->arg_ && this->arg_->getIsValue())
564
+ {
565
+ return value;
566
+ }
567
+ else if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
568
+ {
569
+ return this->arg_->defaultValue<unsigned long long>();
570
+ }
571
+ else
572
+ {
573
+ return protect(rb_num2ull, value);
574
+ }
575
+ }
576
+
577
+ private:
578
+ Arg* arg_ = nullptr;
579
+ };
580
+
581
+ template<>
582
+ class From_Ruby<unsigned long long&>
583
+ {
584
+ public:
585
+ From_Ruby() = default;
586
+
587
+ explicit From_Ruby(Arg* arg) : arg_(arg)
588
+ {
589
+ }
590
+
591
+ unsigned long long& convert(VALUE value)
592
+ {
593
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
594
+ {
595
+ return this->arg_->defaultValue<unsigned long long>();
596
+ }
597
+ else
598
+ {
599
+ this->converted_ = protect(rb_num2ull, value);
600
+ return this->converted_;
601
+ }
602
+ }
603
+
604
+ private:
605
+ Arg* arg_ = nullptr;
606
+ unsigned long long converted_ = 0;
607
+ };
608
+
609
+ template<>
610
+ class From_Ruby<unsigned long long*>
611
+ {
612
+ public:
613
+ unsigned long long* convert(VALUE value)
614
+ {
615
+ if (value == Qnil)
616
+ {
617
+ return nullptr;
618
+ }
619
+ else
620
+ {
621
+ this->converted_ = protect(rb_num2ull, value);
622
+ return &this->converted_;
623
+ }
624
+ }
625
+
626
+ private:
627
+ unsigned long long converted_ = 0;
628
+ };
629
+
630
+ // =========== bool ============
631
+ template<>
632
+ class From_Ruby<bool>
633
+ {
634
+ public:
635
+ From_Ruby() = default;
636
+
637
+ explicit From_Ruby(Arg* arg) : arg_(arg)
638
+ {
639
+ }
640
+
641
+ bool convert(VALUE value)
642
+ {
643
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
644
+ {
645
+ return this->arg_->defaultValue<bool>();
646
+ }
647
+ else
648
+ {
649
+ return RTEST(value);
650
+ }
651
+ }
652
+
653
+ private:
654
+ Arg* arg_ = nullptr;
655
+ };
656
+
657
+ template<>
658
+ class From_Ruby<bool&>
659
+ {
660
+ public:
661
+ From_Ruby() = default;
662
+
663
+ explicit From_Ruby(Arg* arg) : arg_(arg)
664
+ {
665
+ }
666
+
667
+ bool& convert(VALUE value)
668
+ {
669
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
670
+ {
671
+ return this->arg_->defaultValue<bool>();
672
+ }
673
+ else
674
+ {
675
+ this->converted_ = RTEST(value);
676
+ return this->converted_;
677
+ }
678
+ }
679
+
680
+ private:
681
+ Arg* arg_ = nullptr;
682
+ bool converted_ = false;
683
+ };
684
+
685
+ template<>
686
+ class From_Ruby<bool*>
687
+ {
688
+ public:
689
+ bool* convert(VALUE value)
690
+ {
691
+ if (value == Qnil)
692
+ {
693
+ return nullptr;
694
+ }
695
+ else
696
+ {
697
+ this->converted_ = RTEST(value);
698
+ return &this->converted_;
699
+ }
700
+ }
701
+
702
+ private:
703
+ bool converted_ = false;
704
+ };
705
+
706
+ // =========== char ============
707
+ template<typename T>
708
+ inline T charFromRuby(VALUE value)
709
+ {
710
+ switch (rb_type(value))
711
+ {
712
+ case T_STRING:
713
+ {
714
+ if (RSTRING_LEN(value) == 1)
715
+ {
716
+ return RSTRING_PTR(value)[0];
717
+ }
718
+ else
719
+ {
720
+ throw std::invalid_argument("from_ruby<char>: string must have length 1");
721
+ }
722
+ break;
723
+ }
724
+ case T_FIXNUM:
725
+ {
726
+ return From_Ruby<long>().convert(value) & 0xff;
727
+ break;
728
+ }
729
+ default:
730
+ {
731
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
732
+ detail::protect(rb_obj_classname, value), "char type");
733
+ }
734
+ }
42
735
  }
43
- }
736
+
737
+ template<>
738
+ class From_Ruby<char>
739
+ {
740
+ public:
741
+ From_Ruby() = default;
44
742
 
45
- template<typename T>
46
- T const * Rice::detail::from_ruby_<T const *>::
47
- convert(Rice::Object x)
48
- {
49
- return from_ruby<T *>(x);
50
- }
743
+ explicit From_Ruby(Arg* arg) : arg_(arg)
744
+ {
745
+ }
51
746
 
52
- template<typename T>
53
- T & Rice::detail::from_ruby_<T &>::
54
- convert(Rice::Object x)
55
- {
56
- return *from_ruby<T *>(x);
57
- }
747
+ char convert(VALUE value)
748
+ {
749
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
750
+ {
751
+ return this->arg_->defaultValue<char>();
752
+ }
753
+ else
754
+ {
755
+ return charFromRuby<char>(value);
756
+ }
757
+ }
758
+
759
+ private:
760
+ Arg* arg_ = nullptr;
761
+ };
58
762
 
59
- #endif // Rice__detail__from_ruby__ipp_
763
+ template<>
764
+ class From_Ruby<char&>
765
+ {
766
+ public:
767
+ From_Ruby() = default;
60
768
 
769
+ explicit From_Ruby(Arg* arg) : arg_(arg)
770
+ {
771
+ }
772
+
773
+ char& convert(VALUE value)
774
+ {
775
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
776
+ {
777
+ return this->arg_->defaultValue<char>();
778
+ }
779
+ else
780
+ {
781
+ this->converted_ = charFromRuby<char>(value);
782
+ return this->converted_;
783
+ }
784
+ }
785
+
786
+ private:
787
+ Arg* arg_ = nullptr;
788
+ char converted_ = 0;
789
+ };
790
+
791
+ template<>
792
+ class From_Ruby<char*>
793
+ {
794
+ public:
795
+ char* convert(VALUE value)
796
+ {
797
+ if (value == Qnil)
798
+ {
799
+ return nullptr;
800
+ }
801
+ else
802
+ {
803
+ detail::protect(rb_check_type, value, (int)T_STRING);
804
+ return RSTRING_PTR(value);
805
+ }
806
+ }
807
+ };
808
+
809
+ // This is mostly for testing. NativeFunction removes const before calling From_Ruby
810
+ template<>
811
+ class From_Ruby<char const*>
812
+ {
813
+ public:
814
+ char const* convert(VALUE value)
815
+ {
816
+ if (value == Qnil)
817
+ {
818
+ return nullptr;
819
+ }
820
+ else
821
+ {
822
+ detail::protect(rb_check_type, value, (int)T_STRING);
823
+ return RSTRING_PTR(value);
824
+ }
825
+ }
826
+ };
827
+
828
+ // =========== unsinged char ============
829
+ template<>
830
+ class From_Ruby<unsigned char>
831
+ {
832
+ public:
833
+ From_Ruby() = default;
834
+
835
+ explicit From_Ruby(Arg* arg) : arg_(arg)
836
+ {
837
+ }
838
+
839
+ unsigned char convert(VALUE value)
840
+ {
841
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
842
+ {
843
+ return this->arg_->defaultValue<unsigned char>();
844
+ }
845
+ else
846
+ {
847
+ return charFromRuby<unsigned char>(value);
848
+ }
849
+ }
850
+
851
+ private:
852
+ Arg* arg_ = nullptr;
853
+ };
854
+
855
+ // =========== signed char ============
856
+ template<>
857
+ class From_Ruby<signed char>
858
+ {
859
+ public:
860
+ From_Ruby() = default;
861
+
862
+ explicit From_Ruby(Arg* arg) : arg_(arg)
863
+ {
864
+ }
865
+
866
+ signed char convert(VALUE value)
867
+ {
868
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
869
+ {
870
+ return this->arg_->defaultValue<signed char>();
871
+ }
872
+ else
873
+ {
874
+ return charFromRuby<signed char>(value);
875
+ }
876
+ }
877
+
878
+ private:
879
+ Arg* arg_ = nullptr;
880
+ };
881
+
882
+ // =========== double ============
883
+ template<>
884
+ class From_Ruby<double>
885
+ {
886
+ public:
887
+ From_Ruby() = default;
888
+
889
+ explicit From_Ruby(Arg* arg) : arg_(arg)
890
+ {
891
+ }
892
+
893
+ double convert(VALUE value)
894
+ {
895
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
896
+ {
897
+ return this->arg_->defaultValue<double>();
898
+ }
899
+ else
900
+ {
901
+ return protect(rb_num2dbl, value);
902
+ }
903
+ }
904
+
905
+ private:
906
+ Arg* arg_ = nullptr;
907
+ };
908
+
909
+ template<>
910
+ class From_Ruby<double&>
911
+ {
912
+ public:
913
+ From_Ruby() = default;
914
+
915
+ explicit From_Ruby(Arg* arg) : arg_(arg)
916
+ {
917
+ }
918
+
919
+ double& convert(VALUE value)
920
+ {
921
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
922
+ {
923
+ return this->arg_->defaultValue<double>();
924
+ }
925
+ else
926
+ {
927
+ this->converted_ = protect(rb_num2dbl, value);
928
+ return this->converted_;
929
+ }
930
+ }
931
+
932
+ private:
933
+ Arg* arg_ = nullptr;
934
+ double converted_;
935
+ };
936
+
937
+ template<>
938
+ class From_Ruby<double*>
939
+ {
940
+ public:
941
+ double* convert(VALUE value)
942
+ {
943
+ if (value == Qnil)
944
+ {
945
+ return nullptr;
946
+ }
947
+ else
948
+ {
949
+ this->converted_ = protect(rb_num2dbl, value);
950
+ return &this->converted_;
951
+ }
952
+ }
953
+
954
+ private:
955
+ double converted_;
956
+ };
957
+
958
+ // =========== float ============
959
+ template<>
960
+ class From_Ruby<float>
961
+ {
962
+ public:
963
+ From_Ruby() = default;
964
+
965
+ explicit From_Ruby(Arg* arg) : arg_(arg)
966
+ {
967
+ }
968
+
969
+ float convert(VALUE value)
970
+ {
971
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
972
+ {
973
+ return this->arg_->defaultValue<float>();
974
+ }
975
+ else
976
+ {
977
+ return (float)protect(rb_num2dbl, value);
978
+ }
979
+ }
980
+
981
+ private:
982
+ Arg* arg_ = nullptr;
983
+ };
984
+
985
+ template<>
986
+ class From_Ruby<float&>
987
+ {
988
+ public:
989
+ From_Ruby() = default;
990
+
991
+ explicit From_Ruby(Arg* arg) : arg_(arg)
992
+ {
993
+ }
994
+
995
+ float& convert(VALUE value)
996
+ {
997
+ if (value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
998
+ {
999
+ return this->arg_->defaultValue<float>();
1000
+ }
1001
+ else
1002
+ {
1003
+ this->converted_ = (float)protect(rb_num2dbl, value);
1004
+ return this->converted_;
1005
+ }
1006
+ }
1007
+
1008
+ private:
1009
+ Arg* arg_ = nullptr;
1010
+ float converted_;
1011
+ };
1012
+
1013
+ template<>
1014
+ class From_Ruby<float*>
1015
+ {
1016
+ public:
1017
+ float* convert(VALUE value)
1018
+ {
1019
+ if (value == Qnil)
1020
+ {
1021
+ return nullptr;
1022
+ }
1023
+ else
1024
+ {
1025
+ this->converted_ = (float)protect(rb_num2dbl, value);
1026
+ return &this->converted_;
1027
+ }
1028
+ }
1029
+
1030
+ private:
1031
+ float converted_;
1032
+ };
1033
+ }
1034
+ #endif // Rice__detail__from_ruby__ipp_