knowL: Knowledge Libraries
Loading...
Searching...
No Matches
qt.h
1#include <rice/rice.hpp>
2#include <rice/stl.hpp>
3
4namespace rice_qt
5{
6
7 template<typename _T_>
9 {
10 public:
12 Rice::detail::Convertible is_convertible(VALUE value)
13 {
14 return Rice::detail::From_Ruby<_T_>().is_convertible(value);
15 }
16 _T_* convert(VALUE value)
17 {
18 this->converted_ = Rice::detail::From_Ruby<_T_>().convert(value);
19 return &this->converted_;
20 }
21 private:
22 _T_ converted_;
23 };
24
25 template<typename _T_>
27 {
28 public:
30 From_Ruby_Ref() = default;
31
32 explicit From_Ruby_Ref(Rice::Arg* arg) : arg_(arg) {}
33
34 Rice::detail::Convertible is_convertible(VALUE value)
35 {
36 return Rice::detail::From_Ruby<_T_>().is_convertible(value);
37 }
38
39 _T_& convert(VALUE value)
40 {
41 if(value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
42 {
43 return this->arg_->template defaultValue<_T_>();
44 }
45 else
46 {
47 this->converted_ = Rice::detail::From_Ruby<_T_>().convert(value);
48 return this->converted_;
49 }
50 }
51 private:
52 Rice::Arg* arg_ = nullptr;
53 _T_ converted_;
54 };
55} // namespace rice_qt
56
57namespace Rice::detail
58{
59
60 // QString
61
62 template<>
63 struct Type<QString>
64 {
65 static bool verify() { return true; }
66 };
67
68 template<>
69 class To_Ruby<QString>
70 {
71 public:
72 VALUE convert(QString const& x) { return To_Ruby<std::string>().convert(x.toStdString()); }
73 };
74
75 template<>
76 class To_Ruby<QString&>
77 {
78 public:
79 VALUE convert(QString const& x) { return To_Ruby<std::string>().convert(x.toStdString()); }
80 };
81
82 template<>
83 class From_Ruby<QString>
84 {
85 public:
86 From_Ruby() = default;
87
88 explicit From_Ruby(Arg* arg) : arg_(arg) {}
89
90 Rice::detail::Convertible is_convertible(VALUE value)
91 {
92 return From_Ruby<std::string>().is_convertible(value);
93 }
94
95 QString convert(VALUE value)
96 {
97 if(value == Qnil && this->arg_ && this->arg_->hasDefaultValue())
98 {
99 return this->arg_->defaultValue<QString>();
100 }
101 else
102 {
103 return QString::fromStdString(From_Ruby<std::string>().convert(value));
104 }
105 }
106 private:
107 Arg* arg_ = nullptr;
108 };
109
110 template<>
111 struct From_Ruby<QString*> : public rice_qt::From_Ruby_Ptr<QString>
112 {
114 };
115
116 template<>
117 struct From_Ruby<QString&> : public rice_qt::From_Ruby_Ref<QString>
118 {
120 };
121
122 // QList
123
124 template<typename T>
125 struct Type<QList<T>>
126 {
127 static bool verify()
128 {
129 Type<T>::verify();
130 return true;
131 }
132 };
133
134 template<>
135 struct Type<QStringList>
136 {
137 static bool verify() { return true; }
138 };
139
140 template<typename T>
141 VALUE qlistToArray(const QList<T>& value)
142 {
143 VALUE r_arr = detail::protect(rb_ary_new);
144 for(const T& t : value)
145 {
146 detail::protect(rb_ary_push, r_arr, detail::To_Ruby<T>().convert(t));
147 }
148 return r_arr;
149 }
150
151 template<typename T>
152 class To_Ruby<QList<T>>
153 {
154 public:
155 VALUE convert(QList<T> const& x) { return qlistToArray(x); }
156 };
157
158 template<typename T>
159 class To_Ruby<QList<T>&>
160 {
161 public:
162 VALUE convert(QList<T> const& x) { return qlistToArray(x); }
163 };
164 template<typename T>
165 QList<T> qlistFromArray(VALUE value)
166 {
167 size_t length = protect(rb_array_len, value);
168 QList<T> result;
169 result.reserve(length);
170
171 for(size_t i = 0; i < length; i++)
172 {
173 VALUE element = protect(rb_ary_entry, value, i);
174 result.append(From_Ruby<T>().convert(element));
175 }
176
177 return result;
178 }
179
180 template<typename T>
181 class From_Ruby<QList<T>>
182 {
183 public:
184 From_Ruby() = default;
185
186 explicit From_Ruby(Arg* arg) : arg_(arg) {}
187
188 Convertible is_convertible(VALUE value)
189 {
190 switch(rb_type(value))
191 {
192 case RUBY_T_DATA:
193 return Convertible::Exact;
194 break;
195 case RUBY_T_ARRAY:
196 return Convertible::Cast;
197 break;
198 default:
199 return Convertible::None;
200 }
201 }
202
203 QList<T> convert(VALUE value)
204 {
205 switch(rb_type(value))
206 {
207 case T_DATA:
208 {
209 // This is a wrapped vector (hopefully!)
210 return *Data_Object<QList<T>>::from_ruby(value);
211 }
212 case T_ARRAY:
213 {
214 // If this an Ruby array and the vector type is copyable
215 if constexpr(std::is_default_constructible_v<T>)
216 {
217 return qlistFromArray<T>(value);
218 }
219 }
220 case T_NIL:
221 {
222 if(this->arg_ && this->arg_->hasDefaultValue())
223 {
224 return this->arg_->template defaultValue<QList<T>>();
225 }
226 [[fallthrough]];
227 }
228 default:
229 {
230 throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
231 detail::protect(rb_obj_classname, value), "QList");
232 }
233 }
234 }
235 private:
236 Arg* arg_ = nullptr;
237 };
238
239 template<typename T>
240 struct From_Ruby<QList<T>*> : public rice_qt::From_Ruby_Ptr<QList<T>>
241 {
242 using rice_qt::From_Ruby_Ptr<QList<T>>::From_Ruby_Ptr;
243 };
244
245 template<typename T>
246 struct From_Ruby<QList<T>&> : public rice_qt::From_Ruby_Ref<QList<T>>
247 {
248 using typename rice_qt::From_Ruby_Ref<QList<T>>::From_Ruby_Ref_T;
249 };
250
251 // QHash
252
253 template<typename K, typename V>
254 struct Type<QHash<K, V>>
255 {
256 static bool verify() { return Type<K>::verify() and Type<V>::verify(); }
257 };
258
259 template<typename K, typename V>
260 VALUE qhashToHash(const QHash<K, V>& value)
261 {
262 VALUE r_hash = detail::protect(rb_hash_new);
263 for(auto it = value.begin(); it != value.end(); ++it)
264 {
265 detail::protect(rb_hash_aset, r_hash, detail::To_Ruby<K>().convert(it.key()),
266 detail::To_Ruby<V>().convert(it.value()));
267 }
268 return r_hash;
269 }
270
271 template<typename K, typename V>
272 class To_Ruby<QHash<K, V>>
273 {
274 public:
275 VALUE convert(QHash<K, V> const& x) { return qhashToHash(x); }
276 };
277
278 template<typename K, typename V>
279 class To_Ruby<QHash<K, V>&>
280 {
281 public:
282 VALUE convert(QHash<K, V> const& x) { return qhashToHash(x); }
283 };
284
285 template<typename K, typename V>
286 int qhashFromHash_convertPair(VALUE key, VALUE value, VALUE user_data)
287 {
288 QHash<K, V>* result = (QHash<K, V>*)(user_data);
289 return cpp_protect(
290 [&]
291 {
292 result->operator[](From_Ruby<K>().convert(key)) = From_Ruby<V>().convert(value);
293 return ST_CONTINUE;
294 });
295 }
296
297 template<typename K, typename V>
298 QHash<K, V> qhashFromHash(VALUE value)
299 {
300 QHash<K, V> result;
301 VALUE user_data = (VALUE)(&result);
302
303 // MSVC needs help here, but g++ does not
304 using Rb_Hash_ForEach_T = void (*)(VALUE, int (*)(VALUE, VALUE, VALUE), VALUE);
305 detail::protect<Rb_Hash_ForEach_T>(rb_hash_foreach, value, qhashFromHash_convertPair<K, V>,
306 user_data);
307
308 return result;
309 }
310
311 template<typename K, typename V>
312 class From_Ruby<QHash<K, V>>
313 {
314 public:
315 From_Ruby() = default;
316
317 explicit From_Ruby(Arg* arg) : arg_(arg) {}
318
319 Convertible is_convertible(VALUE value)
320 {
321 switch(rb_type(value))
322 {
323 case RUBY_T_DATA:
324 return Convertible::Exact;
325 break;
326 case RUBY_T_NIL:
327 return Convertible::Exact;
328 break;
329 case RUBY_T_HASH:
330 return Convertible::Cast;
331 break;
332 default:
333 return Convertible::None;
334 }
335 }
336
337 QHash<K, V> convert(VALUE value)
338 {
339 switch(rb_type(value))
340 {
341 case T_DATA:
342 {
343 // This is a wrapped vector (hopefully!)
344 return *Data_Object<QHash<K, V>>::from_ruby(value);
345 }
346 case T_HASH:
347 {
348 // If this an Ruby array and the vector type is copyable
349 if constexpr(std::is_default_constructible_v<V>)
350 {
351 return qhashFromHash<K, V>(value);
352 }
353 }
354 case T_NIL:
355 {
356 if(this->arg_ && this->arg_->hasDefaultValue())
357 {
358 return this->arg_->template defaultValue<QHash<K, V>>();
359 }
360 }
361 default:
362 {
363 throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
364 detail::protect(rb_obj_classname, value), "QHash");
365 }
366 }
367 }
368 private:
369 Arg* arg_ = nullptr;
370 };
371
372 template<typename K, typename V>
373 struct From_Ruby<QHash<K, V>*> : public rice_qt::From_Ruby_Ptr<QHash<K, V>>
374 {
375 using rice_qt::From_Ruby_Ptr<QHash<K, V>>::From_Ruby_Ptr;
376 };
377
378 template<typename K, typename V>
379 struct From_Ruby<QHash<K, V>&> : public rice_qt::From_Ruby_Ref<QHash<K, V>>
380 {
381 using rice_qt::From_Ruby_Ref<QHash<K, V>>::From_Ruby_Ref;
382 };
383
384} // namespace Rice::detail
Definition Forward.h:10
Definition Forward.h:14
Definition qt.h:9
Definition qt.h:27