rice 4.5.0 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/CMakeLists.txt +31 -0
  4. data/CMakePresets.json +75 -0
  5. data/COPYING +3 -2
  6. data/FindRuby.cmake +437 -0
  7. data/Rakefile +5 -4
  8. data/include/rice/rice.hpp +5436 -3201
  9. data/include/rice/stl.hpp +2355 -1269
  10. data/lib/make_rice_headers.rb +79 -0
  11. data/lib/mkmf-rice.rb +4 -0
  12. data/lib/rice/version.rb +3 -0
  13. data/lib/rice.rb +1 -0
  14. data/lib/rubygems/builder.rb +11 -0
  15. data/lib/rubygems/cmake_builder.rb +113 -0
  16. data/lib/rubygems_plugin.rb +9 -0
  17. data/rice/Arg.hpp +7 -1
  18. data/rice/Arg.ipp +11 -2
  19. data/rice/Buffer.hpp +123 -0
  20. data/rice/Buffer.ipp +599 -0
  21. data/rice/Constructor.ipp +3 -3
  22. data/rice/Data_Object.hpp +2 -3
  23. data/rice/Data_Object.ipp +188 -188
  24. data/rice/Data_Type.hpp +4 -5
  25. data/rice/Data_Type.ipp +42 -26
  26. data/rice/Enum.hpp +0 -1
  27. data/rice/Enum.ipp +26 -23
  28. data/rice/Init.hpp +8 -0
  29. data/rice/Init.ipp +8 -0
  30. data/rice/MemoryView.ipp +1 -41
  31. data/rice/Return.hpp +1 -1
  32. data/rice/Return.ipp +6 -0
  33. data/rice/cpp_api/Array.hpp +209 -0
  34. data/rice/cpp_api/Array.ipp +304 -0
  35. data/rice/cpp_api/Builtin_Object.hpp +31 -0
  36. data/rice/cpp_api/Builtin_Object.ipp +37 -0
  37. data/rice/cpp_api/Class.hpp +70 -0
  38. data/rice/cpp_api/Class.ipp +97 -0
  39. data/rice/cpp_api/Encoding.hpp +32 -0
  40. data/rice/cpp_api/Encoding.ipp +59 -0
  41. data/rice/cpp_api/Hash.hpp +194 -0
  42. data/rice/cpp_api/Hash.ipp +257 -0
  43. data/rice/cpp_api/Identifier.hpp +46 -0
  44. data/rice/cpp_api/Identifier.ipp +31 -0
  45. data/rice/cpp_api/Module.hpp +72 -0
  46. data/rice/cpp_api/Module.ipp +101 -0
  47. data/rice/cpp_api/Object.hpp +272 -0
  48. data/rice/cpp_api/Object.ipp +235 -0
  49. data/rice/cpp_api/String.hpp +74 -0
  50. data/rice/cpp_api/String.ipp +120 -0
  51. data/rice/cpp_api/Struct.hpp +113 -0
  52. data/rice/cpp_api/Struct.ipp +92 -0
  53. data/rice/cpp_api/Symbol.hpp +46 -0
  54. data/rice/cpp_api/Symbol.ipp +93 -0
  55. data/rice/cpp_api/shared_methods.hpp +134 -0
  56. data/rice/detail/MethodInfo.hpp +1 -9
  57. data/rice/detail/MethodInfo.ipp +5 -72
  58. data/rice/detail/Native.hpp +3 -2
  59. data/rice/detail/Native.ipp +32 -4
  60. data/rice/detail/NativeAttributeGet.hpp +3 -2
  61. data/rice/detail/NativeAttributeGet.ipp +8 -2
  62. data/rice/detail/NativeAttributeSet.hpp +3 -2
  63. data/rice/detail/NativeAttributeSet.ipp +8 -2
  64. data/rice/detail/NativeCallbackFFI.ipp +1 -1
  65. data/rice/detail/NativeFunction.hpp +17 -6
  66. data/rice/detail/NativeFunction.ipp +168 -64
  67. data/rice/detail/NativeIterator.hpp +3 -2
  68. data/rice/detail/NativeIterator.ipp +8 -2
  69. data/rice/detail/RubyType.hpp +2 -5
  70. data/rice/detail/RubyType.ipp +50 -5
  71. data/rice/detail/Type.hpp +3 -1
  72. data/rice/detail/Type.ipp +61 -31
  73. data/rice/detail/Wrapper.hpp +68 -33
  74. data/rice/detail/Wrapper.ipp +103 -113
  75. data/rice/detail/from_ruby.hpp +5 -4
  76. data/rice/detail/from_ruby.ipp +737 -365
  77. data/rice/detail/to_ruby.ipp +1092 -186
  78. data/rice/global_function.ipp +1 -1
  79. data/rice/libc/file.hpp +11 -0
  80. data/rice/libc/file.ipp +32 -0
  81. data/rice/rice.hpp +23 -16
  82. data/rice/stl/complex.hpp +6 -0
  83. data/rice/stl/complex.ipp +93 -0
  84. data/rice/stl/exception.hpp +11 -0
  85. data/rice/stl/exception.ipp +29 -0
  86. data/rice/stl/exception_ptr.hpp +6 -0
  87. data/rice/stl/exception_ptr.ipp +27 -0
  88. data/rice/stl/map.hpp +12 -0
  89. data/rice/stl/map.ipp +469 -0
  90. data/rice/stl/monostate.hpp +6 -0
  91. data/rice/stl/monostate.ipp +80 -0
  92. data/rice/stl/multimap.hpp +14 -0
  93. data/rice/stl/multimap.ipp +448 -0
  94. data/rice/stl/optional.hpp +6 -0
  95. data/rice/stl/optional.ipp +118 -0
  96. data/rice/stl/pair.hpp +13 -0
  97. data/rice/stl/pair.ipp +155 -0
  98. data/rice/stl/reference_wrapper.hpp +6 -0
  99. data/rice/stl/reference_wrapper.ipp +41 -0
  100. data/rice/stl/set.hpp +12 -0
  101. data/rice/stl/set.ipp +495 -0
  102. data/rice/stl/shared_ptr.hpp +28 -0
  103. data/rice/stl/shared_ptr.ipp +224 -0
  104. data/rice/stl/string.hpp +6 -0
  105. data/rice/stl/string.ipp +158 -0
  106. data/rice/stl/string_view.hpp +6 -0
  107. data/rice/stl/string_view.ipp +65 -0
  108. data/rice/stl/tuple.hpp +6 -0
  109. data/rice/stl/tuple.ipp +128 -0
  110. data/rice/stl/type_index.hpp +6 -0
  111. data/rice/stl/type_index.ipp +30 -0
  112. data/rice/stl/type_info.hpp +6 -0
  113. data/rice/stl/type_info.ipp +29 -0
  114. data/rice/stl/unique_ptr.hpp +22 -0
  115. data/rice/stl/unique_ptr.ipp +139 -0
  116. data/rice/stl/unordered_map.hpp +12 -0
  117. data/rice/stl/unordered_map.ipp +469 -0
  118. data/rice/stl/variant.hpp +6 -0
  119. data/rice/stl/variant.ipp +242 -0
  120. data/rice/stl/vector.hpp +12 -0
  121. data/rice/stl/vector.ipp +590 -0
  122. data/rice/stl.hpp +7 -3
  123. data/rice/traits/attribute_traits.hpp +26 -0
  124. data/rice/traits/function_traits.hpp +95 -0
  125. data/rice/traits/method_traits.hpp +47 -0
  126. data/rice/traits/rice_traits.hpp +160 -0
  127. data/rice.gemspec +85 -0
  128. data/test/embed_ruby.cpp +3 -0
  129. data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
  130. data/test/test_Array.cpp +6 -3
  131. data/test/test_Attribute.cpp +34 -1
  132. data/test/test_Buffer.cpp +285 -0
  133. data/test/test_Callback.cpp +2 -3
  134. data/test/test_Data_Object.cpp +88 -34
  135. data/test/test_Data_Type.cpp +106 -65
  136. data/test/test_Director.cpp +7 -3
  137. data/test/test_Enum.cpp +5 -2
  138. data/test/test_File.cpp +1 -1
  139. data/test/test_From_Ruby.cpp +181 -114
  140. data/test/test_Iterator.cpp +1 -1
  141. data/test/{test_JumpException.cpp → test_Jump_Exception.cpp} +1 -0
  142. data/test/test_Keep_Alive.cpp +7 -18
  143. data/test/test_Keep_Alive_No_Wrapper.cpp +0 -1
  144. data/test/test_Module.cpp +13 -6
  145. data/test/test_Native_Registry.cpp +0 -1
  146. data/test/test_Overloads.cpp +180 -5
  147. data/test/test_Ownership.cpp +100 -57
  148. data/test/test_Proc.cpp +0 -1
  149. data/test/test_Self.cpp +4 -4
  150. data/test/test_Stl_Map.cpp +37 -39
  151. data/test/test_Stl_Multimap.cpp +693 -0
  152. data/test/test_Stl_Pair.cpp +8 -8
  153. data/test/test_Stl_Reference_Wrapper.cpp +4 -2
  154. data/test/test_Stl_Set.cpp +790 -0
  155. data/test/{test_Stl_SmartPointer.cpp → test_Stl_SharedPtr.cpp} +97 -127
  156. data/test/test_Stl_Tuple.cpp +116 -0
  157. data/test/test_Stl_Type.cpp +1 -1
  158. data/test/test_Stl_UniquePtr.cpp +202 -0
  159. data/test/test_Stl_Unordered_Map.cpp +28 -34
  160. data/test/test_Stl_Variant.cpp +217 -89
  161. data/test/test_Stl_Vector.cpp +209 -83
  162. data/test/test_To_Ruby.cpp +373 -1
  163. data/test/test_Type.cpp +85 -14
  164. data/test/test_global_functions.cpp +17 -4
  165. metadata +94 -10
  166. data/rice/detail/TupleIterator.hpp +0 -14
@@ -0,0 +1,28 @@
1
+ #ifndef Rice__stl__shared_ptr__hpp_
2
+ #define Rice__stl__shared_ptr__hpp_
3
+
4
+ namespace Rice::detail
5
+ {
6
+ template<typename T>
7
+ class Wrapper<std::shared_ptr<T>> : public WrapperBase
8
+ {
9
+ public:
10
+ Wrapper(const std::shared_ptr<T>& data);
11
+ ~Wrapper();
12
+ void* get() override;
13
+ std::shared_ptr<T>& data();
14
+
15
+ private:
16
+ std::shared_ptr<T> data_;
17
+ };
18
+ }
19
+
20
+ namespace Rice
21
+ {
22
+ template<typename T>
23
+ Data_Type<std::shared_ptr<T>> define_shared_ptr(std::string klassName = "");
24
+ }
25
+
26
+ #include "shared_ptr.ipp"
27
+
28
+ #endif // Rice__stl__shared_ptr__hpp_
@@ -0,0 +1,224 @@
1
+ #include <memory>
2
+
3
+ // --------- Enable creation of std::shared_ptr from Ruby ---------
4
+ namespace Rice
5
+ {
6
+ template<typename T>
7
+ Data_Type<std::shared_ptr<T>> define_shared_ptr(std::string klassName)
8
+ {
9
+ using SharedPtr_T = std::shared_ptr<T>;
10
+ using Data_Type_T = Data_Type<SharedPtr_T>;
11
+
12
+ if (klassName.empty())
13
+ {
14
+ std::string typeName = detail::typeName(typeid(SharedPtr_T));
15
+ klassName = detail::rubyClassName(typeName);
16
+ }
17
+
18
+ Module rb_mStd = define_module("Std");
19
+ if (Data_Type_T::check_defined(klassName, rb_mStd))
20
+ {
21
+ return Data_Type_T();
22
+ }
23
+
24
+ Identifier id(klassName);
25
+ Data_Type_T result = define_class_under<detail::intrinsic_type<SharedPtr_T>>(rb_mStd, id).
26
+ define_constructor(Constructor<SharedPtr_T, typename SharedPtr_T::element_type*>(), Arg("value").takeOwnership());
27
+
28
+ return result;
29
+ }
30
+ }
31
+
32
+ // --------- Wrapper ---------
33
+ namespace Rice::detail
34
+ {
35
+ template<typename T>
36
+ inline Wrapper<std::shared_ptr<T>>::Wrapper(const std::shared_ptr<T>& data)
37
+ : data_(data)
38
+ {
39
+ }
40
+
41
+ template<typename T>
42
+ inline Wrapper<std::shared_ptr<T>>::~Wrapper()
43
+ {
44
+ Registries::instance.instances.remove(this->get());
45
+ }
46
+
47
+ template<typename T>
48
+ inline void* Wrapper<std::shared_ptr<T>>::get()
49
+ {
50
+ return (void*)this->data_.get();
51
+ }
52
+
53
+ template<typename T>
54
+ inline std::shared_ptr<T>& Wrapper<std::shared_ptr<T>>::data()
55
+ {
56
+ return data_;
57
+ }
58
+ }
59
+
60
+ // --------- Type/To_Ruby/From_Ruby ---------
61
+ namespace Rice::detail
62
+ {
63
+ template<typename T>
64
+ struct Type<std::shared_ptr<T>>
65
+ {
66
+ static bool verify()
67
+ {
68
+ return Type<T>::verify();
69
+ }
70
+ };
71
+
72
+ template <typename T>
73
+ class To_Ruby<std::shared_ptr<T>>
74
+ {
75
+ public:
76
+ VALUE convert(std::shared_ptr<T>& data)
77
+ {
78
+ if constexpr (std::is_fundamental_v<T>)
79
+ {
80
+ return detail::wrap(Data_Type<T>::klass(), Data_Type<T>::ruby_data_type(), data, true);
81
+ }
82
+ else
83
+ {
84
+ return detail::wrap<std::shared_ptr<T>>(Data_Type<T>::klass(), Data_Type<T>::ruby_data_type(), data, true);
85
+ }
86
+ }
87
+
88
+ VALUE convert(std::shared_ptr<T>&& data)
89
+ {
90
+ if constexpr (std::is_fundamental_v<T>)
91
+ {
92
+ return detail::wrap(Data_Type<T>::klass(), Data_Type<T>::ruby_data_type(), data, true);
93
+ }
94
+ else
95
+ {
96
+ return detail::wrap<std::shared_ptr<T>>(Data_Type<T>::klass(), Data_Type<T>::ruby_data_type(), data, true);
97
+ }
98
+ }
99
+ };
100
+
101
+ template <typename T>
102
+ class From_Ruby<std::shared_ptr<T>>
103
+ {
104
+ public:
105
+ From_Ruby() = default;
106
+
107
+ explicit From_Ruby(Arg * arg) : arg_(arg)
108
+ {
109
+ }
110
+
111
+ Convertible is_convertible(VALUE value)
112
+ {
113
+ switch (rb_type(value))
114
+ {
115
+ case RUBY_T_DATA:
116
+ return Convertible::Exact;
117
+ break;
118
+ default:
119
+ return Convertible::None;
120
+ }
121
+ }
122
+
123
+ std::shared_ptr<T> convert(VALUE value)
124
+ {
125
+ // Get the wrapper
126
+ WrapperBase* wrapperBase = detail::getWrapper(value);
127
+
128
+ // Was this shared_ptr created by the user from Ruby? If so it will
129
+ // be wrapped as a pointer, std::shared_ptr<T>*. In the case just
130
+ // return the shared pointer
131
+ if (dynamic_cast<Wrapper<std::shared_ptr<T>*>*>(wrapperBase))
132
+ {
133
+ // Use unwrap to validate the underlying wrapper is the correct type
134
+ std::shared_ptr<T>* ptr = unwrap<std::shared_ptr<T>>(value, Data_Type<std::shared_ptr<T>>::ruby_data_type(), false);
135
+ return *ptr;
136
+ }
137
+ else if constexpr (std::is_fundamental_v<T>)
138
+ {
139
+ // Get the wrapper again to validate T's type
140
+ Wrapper<std::shared_ptr<T>>* wrapper = getWrapper<Wrapper<std::shared_ptr<T>>>(value, Data_Type<T>::ruby_data_type());
141
+ return wrapper->data();
142
+ }
143
+ else
144
+ {
145
+ // Get the wrapper again to validate T's type
146
+ Wrapper<std::shared_ptr<T>>* wrapper = getWrapper<Wrapper<std::shared_ptr<T>>>(value, Data_Type<T>::ruby_data_type());
147
+ return wrapper->data();
148
+ }
149
+ }
150
+ private:
151
+ Arg* arg_ = nullptr;
152
+ };
153
+
154
+ template <typename T>
155
+ class To_Ruby<std::shared_ptr<T>&>
156
+ {
157
+ public:
158
+ VALUE convert(std::shared_ptr<T>& data)
159
+ {
160
+ if constexpr (std::is_fundamental_v<T>)
161
+ {
162
+ return detail::wrap(Data_Type<T>::klass(), Data_Type<T>::ruby_data_type(), data, true);
163
+ }
164
+ else
165
+ {
166
+ return detail::wrap<std::shared_ptr<T>>(Data_Type<T>::klass(), Data_Type<T>::ruby_data_type(), data, true);
167
+ }
168
+ }
169
+ };
170
+
171
+ template <typename T>
172
+ class From_Ruby<std::shared_ptr<T>&>
173
+ {
174
+ public:
175
+ From_Ruby() = default;
176
+
177
+ explicit From_Ruby(Arg * arg) : arg_(arg)
178
+ {
179
+ }
180
+
181
+ Convertible is_convertible(VALUE value)
182
+ {
183
+ switch (rb_type(value))
184
+ {
185
+ case RUBY_T_DATA:
186
+ return Convertible::Exact;
187
+ break;
188
+ default:
189
+ return Convertible::None;
190
+ }
191
+ }
192
+
193
+ std::shared_ptr<T>& convert(VALUE value)
194
+ {
195
+ // Get the wrapper
196
+ WrapperBase* wrapperBase = detail::getWrapper(value);
197
+
198
+ // Was this shared_ptr created by the user from Ruby? If so it will
199
+ // be wrapped as a pointer, std::shared_ptr<T>*. In the case just
200
+ // return the shared pointer
201
+ if (dynamic_cast<Wrapper<std::shared_ptr<T>*>*>(wrapperBase))
202
+ {
203
+ // Use unwrap to validate the underlying wrapper is the correct type
204
+ std::shared_ptr<T>* ptr = unwrap<std::shared_ptr<T>>(value, Data_Type<std::shared_ptr<T>>::ruby_data_type(), false);
205
+ return *ptr;
206
+ }
207
+ else if constexpr (std::is_fundamental_v<T>)
208
+ {
209
+ // Get the wrapper again to validate T's type
210
+ Wrapper<std::shared_ptr<T>>* wrapper = getWrapper<Wrapper<std::shared_ptr<T>>>(value, Data_Type<T>::ruby_data_type());
211
+ return wrapper->data();
212
+ }
213
+ else
214
+ {
215
+ // Get the wrapper again to validate T's type
216
+ Wrapper<std::shared_ptr<T>>* wrapper = getWrapper<Wrapper<std::shared_ptr<T>>>(value, Data_Type<T>::ruby_data_type());
217
+ return wrapper->data();
218
+ }
219
+ }
220
+
221
+ private:
222
+ Arg* arg_ = nullptr;
223
+ };
224
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef Rice__stl__string__hpp_
2
+ #define Rice__stl__string__hpp_
3
+
4
+ #include "string.ipp"
5
+
6
+ #endif // Rice__stl__string__hpp_
@@ -0,0 +1,158 @@
1
+ #include <string>
2
+
3
+ namespace Rice::detail
4
+ {
5
+ template<>
6
+ struct Type<std::string>
7
+ {
8
+ static bool verify()
9
+ {
10
+ return true;
11
+ }
12
+ };
13
+
14
+ template<>
15
+ class To_Ruby<std::string>
16
+ {
17
+ public:
18
+ VALUE convert(const std::string& x)
19
+ {
20
+ return detail::protect(rb_external_str_new, x.data(), (long)x.size());
21
+ }
22
+ };
23
+
24
+ template<>
25
+ class To_Ruby<std::string&>
26
+ {
27
+ public:
28
+ VALUE convert(const std::string& x)
29
+ {
30
+ return detail::protect(rb_external_str_new, x.data(), (long)x.size());
31
+ }
32
+ };
33
+
34
+ template<>
35
+ class To_Ruby<std::string*>
36
+ {
37
+ public:
38
+ VALUE convert(const std::string* x)
39
+ {
40
+ return detail::protect(rb_external_str_new, x->data(), (long)x->size());
41
+ }
42
+ };
43
+
44
+ template<>
45
+ class To_Ruby<std::string*&>
46
+ {
47
+ public:
48
+ VALUE convert(const std::string* x)
49
+ {
50
+ return detail::protect(rb_external_str_new, x->data(), (long)x->size());
51
+ }
52
+ };
53
+
54
+ template<>
55
+ class To_Ruby<std::string**>
56
+ {
57
+ public:
58
+ VALUE convert(std::string** data)
59
+ {
60
+ Buffer<std::string*> buffer(data);
61
+ Data_Object<Buffer<std::string*>> dataObject(std::move(buffer));
62
+ return dataObject.value();
63
+ }
64
+ };
65
+
66
+ template<>
67
+ class From_Ruby<std::string>
68
+ {
69
+ public:
70
+ From_Ruby() = default;
71
+
72
+ explicit From_Ruby(Arg* arg) : arg_(arg)
73
+ {
74
+ }
75
+
76
+ Convertible is_convertible(VALUE value)
77
+ {
78
+ switch (rb_type(value))
79
+ {
80
+ case RUBY_T_STRING:
81
+ return Convertible::Exact;
82
+ break;
83
+ default:
84
+ return Convertible::None;
85
+ }
86
+ }
87
+
88
+ std::string convert(VALUE value)
89
+ {
90
+ detail::protect(rb_check_type, value, (int)T_STRING);
91
+ return std::string(RSTRING_PTR(value), RSTRING_LEN(value));
92
+ }
93
+
94
+ private:
95
+ Arg* arg_ = nullptr;
96
+ };
97
+
98
+ template<>
99
+ class From_Ruby<std::string&>
100
+ {
101
+ public:
102
+ From_Ruby() = default;
103
+
104
+ explicit From_Ruby(Arg* arg) : arg_(arg)
105
+ {
106
+ }
107
+
108
+ Convertible is_convertible(VALUE value)
109
+ {
110
+ switch (rb_type(value))
111
+ {
112
+ case RUBY_T_STRING:
113
+ return Convertible::Exact;
114
+ break;
115
+ default:
116
+ return Convertible::None;
117
+ }
118
+ }
119
+
120
+ std::string& convert(VALUE value)
121
+ {
122
+ detail::protect(rb_check_type, value, (int)T_STRING);
123
+ this->converted_ = std::string(RSTRING_PTR(value), RSTRING_LEN(value));
124
+ return this->converted_;
125
+ }
126
+
127
+ private:
128
+ Arg* arg_ = nullptr;
129
+ std::string converted_ = "";
130
+ };
131
+
132
+ template<>
133
+ class From_Ruby<std::string*>
134
+ {
135
+ public:
136
+ Convertible is_convertible(VALUE value)
137
+ {
138
+ switch (rb_type(value))
139
+ {
140
+ case RUBY_T_STRING:
141
+ return Convertible::Exact;
142
+ break;
143
+ default:
144
+ return Convertible::None;
145
+ }
146
+ }
147
+
148
+ std::string* convert(VALUE value)
149
+ {
150
+ detail::protect(rb_check_type, value, (int)T_STRING);
151
+ this->converted_ = std::string(RSTRING_PTR(value), RSTRING_LEN(value));
152
+ return &this->converted_;
153
+ }
154
+
155
+ private:
156
+ std::string converted_;
157
+ };
158
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef Rice__stl__string_view__hpp_
2
+ #define Rice__stl__string_view__hpp_
3
+
4
+ #include "string_view.ipp"
5
+
6
+ #endif // Rice__stl__string_view__hpp_
@@ -0,0 +1,65 @@
1
+ #include <string_view>
2
+
3
+ namespace Rice::detail
4
+ {
5
+ template<>
6
+ struct Type<std::string_view>
7
+ {
8
+ static bool verify()
9
+ {
10
+ return true;
11
+ }
12
+ };
13
+
14
+ template<>
15
+ class To_Ruby<std::string_view>
16
+ {
17
+ public:
18
+ VALUE convert(std::string_view const& x)
19
+ {
20
+ return detail::protect(rb_external_str_new, x.data(), (long)x.size());
21
+ }
22
+ };
23
+
24
+ template<>
25
+ class To_Ruby<std::string_view&>
26
+ {
27
+ public:
28
+ VALUE convert(std::string_view const& x)
29
+ {
30
+ return detail::protect(rb_external_str_new, x.data(), (long)x.size());
31
+ }
32
+ };
33
+
34
+ template<>
35
+ class From_Ruby<std::string_view>
36
+ {
37
+ public:
38
+ From_Ruby() = default;
39
+
40
+ explicit From_Ruby(Arg* arg) : arg_(arg)
41
+ {
42
+ }
43
+
44
+ Convertible is_convertible(VALUE value)
45
+ {
46
+ switch (rb_type(value))
47
+ {
48
+ case RUBY_T_STRING:
49
+ return Convertible::Exact;
50
+ break;
51
+ default:
52
+ return Convertible::None;
53
+ }
54
+ }
55
+
56
+ std::string_view convert(VALUE value)
57
+ {
58
+ detail::protect(rb_check_type, value, (int)T_STRING);
59
+ return std::string_view(RSTRING_PTR(value), RSTRING_LEN(value));
60
+ }
61
+
62
+ private:
63
+ Arg* arg_ = nullptr;
64
+ };
65
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef Rice__stl__tuple__hpp_
2
+ #define Rice__stl__tuple__hpp_
3
+
4
+ #include "tuple.ipp"
5
+
6
+ #endif // Rice__stl__tuple__hpp_
@@ -0,0 +1,128 @@
1
+ #include <tuple>
2
+
3
+ namespace Rice::detail
4
+ {
5
+ template<typename...Types>
6
+ struct Type<std::tuple<Types...>>
7
+ {
8
+ using Tuple_T = std::tuple<Types...>;
9
+
10
+ template<std::size_t... I>
11
+ constexpr static bool verifyTypes(std::index_sequence<I...>& indices)
12
+ {
13
+ return (Type<std::tuple_element_t<I, Tuple_T>>::verify() && ...);
14
+ }
15
+
16
+ template<std::size_t... I>
17
+ constexpr static bool verify()
18
+ {
19
+ auto indices = std::make_index_sequence<std::tuple_size_v<std::tuple<Types...>>>{};
20
+ return verifyTypes(indices);
21
+ }
22
+ };
23
+
24
+ template<typename...Types>
25
+ class To_Ruby<std::tuple<Types...>>
26
+ {
27
+ public:
28
+ static VALUE convert(const std::tuple<Types...>& data, bool takeOwnership = false)
29
+ {
30
+ Array result;
31
+
32
+ for_each_tuple(data, [&](auto element)
33
+ {
34
+ using Element_T = decltype(element);
35
+ result.push<Element_T>((Element_T)element);
36
+ });
37
+
38
+ return result.value();
39
+ }
40
+ };
41
+
42
+ template<typename...Types>
43
+ class To_Ruby<std::tuple<Types...>&>
44
+ {
45
+ public:
46
+ static VALUE convert(const std::tuple<Types...>& data, bool takeOwnership = false)
47
+ {
48
+ Array result;
49
+
50
+ for_each_tuple(data, [&](auto& value)
51
+ {
52
+ VALUE element = detail::To_Ruby<decltype(value)>().convert(value);
53
+ result.push(element);
54
+ });
55
+
56
+ return result.value();
57
+ }
58
+ };
59
+
60
+ template<typename...Types>
61
+ class From_Ruby<std::tuple<Types...>>
62
+ {
63
+ public:
64
+ using Tuple_T = std::tuple<Types...>;
65
+
66
+ template<std::size_t... I>
67
+ constexpr static bool verifyTypes(Array& array, std::index_sequence<I...>& indices)
68
+ {
69
+ return (Type<std::tuple_element_t<I, Tuple_T>>::verify() && ...);
70
+ }
71
+
72
+ Convertible is_convertible(VALUE value)
73
+ {
74
+ Convertible result = Convertible::None;
75
+
76
+ // The ruby value must be an array of the correct size
77
+ if (rb_type(value) != RUBY_T_ARRAY || Array(value).size() != std::tuple_size_v<Tuple_T>)
78
+ {
79
+ return result;
80
+ }
81
+
82
+ // Now check that each tuple type is convertible
83
+ Array array(value);
84
+ int i = 0;
85
+ for_each_tuple(this->fromRubys_,
86
+ [&](auto& fromRuby)
87
+ {
88
+ result = result | fromRuby.is_convertible(array[i].value());
89
+ i++;
90
+ });
91
+
92
+ return result;
93
+ }
94
+
95
+ template <std::size_t... I>
96
+ std::tuple<Types...> convertInternal(Array array, std::index_sequence<I...>& indices)
97
+ {
98
+ return std::forward_as_tuple(std::get<I>(this->fromRubys_).convert(array[I].value())...);
99
+ }
100
+
101
+ std::tuple<Types...> convert(VALUE value)
102
+ {
103
+ Array array(value);
104
+ auto indices = std::make_index_sequence<std::tuple_size_v<Tuple_T>>{};
105
+ return convertInternal(array, indices);
106
+ }
107
+
108
+ private:
109
+ // Possible converters we could use for this variant
110
+ using From_Ruby_Ts = std::tuple<From_Ruby<Types>...>;
111
+ From_Ruby_Ts fromRubys_;
112
+ };
113
+
114
+ /* template<typename...Types>
115
+ class From_Ruby<std::tuple<Types...>&> : public From_Ruby<std::tuple<Types...>>
116
+ {
117
+ public:
118
+ std::tuple<Types...>& convert(VALUE value)
119
+ {
120
+ int index = this->figureIndex(value);
121
+ this->converted_ = this->convertInternal(value, index);
122
+ return this->converted_;
123
+ }
124
+
125
+ private:
126
+ std::tuple<Types...> converted_;
127
+ };*/
128
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef Rice__stl__type_index__hpp_
2
+ #define Rice__stl__type_index__hpp_
3
+
4
+ #include "type_index.ipp"
5
+
6
+ #endif // Rice__stl__type_index__hpp_
@@ -0,0 +1,30 @@
1
+ #include <typeindex>
2
+
3
+ namespace Rice::stl
4
+ {
5
+ inline Data_Type<std::type_index> define_type_index()
6
+ {
7
+ Module rb_mStd = define_module("Std");
8
+ return define_class_under<std::type_index>(rb_mStd, "TypeIndex").
9
+ define_constructor(Constructor<std::type_index, const std::type_info&>()).
10
+ define_method("hash_code", &std::type_index::hash_code).
11
+ define_method("name", &std::type_index::name);
12
+ }
13
+ }
14
+
15
+ namespace Rice::detail
16
+ {
17
+ template<>
18
+ struct Type<std::type_index>
19
+ {
20
+ static bool verify()
21
+ {
22
+ if (!detail::Registries::instance.types.isDefined<std::type_index>())
23
+ {
24
+ stl::define_type_index();
25
+ }
26
+
27
+ return true;
28
+ }
29
+ };
30
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef Rice__stl__type_info__hpp_
2
+ #define Rice__stl__type_info__hpp_
3
+
4
+ #include "type_info.ipp"
5
+
6
+ #endif // Rice__stl__type_info__hpp_
@@ -0,0 +1,29 @@
1
+ #include <typeinfo>
2
+
3
+ namespace Rice::stl
4
+ {
5
+ inline Data_Type<std::type_info> define_type_info()
6
+ {
7
+ Module rb_mStd = define_module("Std");
8
+ return define_class_under<std::type_info>(rb_mStd, "TypeInfo").
9
+ define_method("hash_code", &std::type_info::hash_code).
10
+ define_method("name", &std::type_info::name);
11
+ }
12
+ }
13
+
14
+ namespace Rice::detail
15
+ {
16
+ template<>
17
+ struct Type<std::type_info>
18
+ {
19
+ static inline bool verify()
20
+ {
21
+ if (!detail::Registries::instance.types.isDefined<std::type_info>())
22
+ {
23
+ stl::define_type_info();
24
+ }
25
+
26
+ return true;
27
+ }
28
+ };
29
+ }