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