Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qobjectdefs.h
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2019 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QOBJECTDEFS_H
6#define QOBJECTDEFS_H
7
8#if defined(__OBJC__) && !defined(__cplusplus)
9# warning "File built in Objective-C mode (.m), but using Qt requires Objective-C++ (.mm)"
10#endif
11
12#include <QtCore/qnamespace.h>
13#include <QtCore/qobjectdefs_impl.h>
14#include <QtCore/qtcoreexports.h>
15#include <QtCore/qtmetamacros.h>
16
18
19class QByteArray;
20struct QArrayData;
21
22class QString;
23
24#ifndef QT_NO_META_MACROS
25// macro for onaming members
26#ifdef METHOD
27#undef METHOD
28#endif
29#ifdef SLOT
30#undef SLOT
31#endif
32#ifdef SIGNAL
33#undef SIGNAL
34#endif
35#endif // QT_NO_META_MACROS
36
37Q_CORE_EXPORT const char *qFlagLocation(const char *method);
38
39#ifndef QT_NO_META_MACROS
40# define QMETHOD_CODE 0 // member type codes
41# define QSLOT_CODE 1
42# define QSIGNAL_CODE 2
43# define QT_PREFIX_CODE(code, a) QT_STRINGIFY(code) #a
44# define QT_STRINGIFY_METHOD(a) QT_PREFIX_CODE(QMETHOD_CODE, a)
45# define QT_STRINGIFY_SLOT(a) QT_PREFIX_CODE(QSLOT_CODE, a)
46# define QT_STRINGIFY_SIGNAL(a) QT_PREFIX_CODE(QSIGNAL_CODE, a)
47# ifndef QT_NO_DEBUG
48# define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__)
49# ifndef QT_NO_KEYWORDS
50# define METHOD(a) qFlagLocation(QT_STRINGIFY_METHOD(a) QLOCATION)
51# endif
52# define SLOT(a) qFlagLocation(QT_STRINGIFY_SLOT(a) QLOCATION)
53# define SIGNAL(a) qFlagLocation(QT_STRINGIFY_SIGNAL(a) QLOCATION)
54# else
55# ifndef QT_NO_KEYWORDS
56# define METHOD(a) QT_STRINGIFY_METHOD(a)
57# endif
58# define SLOT(a) QT_STRINGIFY_SLOT(a)
59# define SIGNAL(a) QT_STRINGIFY_SIGNAL(a)
60# endif
61#endif // QT_NO_META_MACROS
62
63#define Q_ARG(Type, data) QtPrivate::Invoke::argument<Type>(QT_STRINGIFY(Type), data)
64#define Q_RETURN_ARG(Type, data) QtPrivate::Invoke::returnArgument<Type>(QT_STRINGIFY(Type), data)
65
66class QObject;
67class QMetaMethod;
68class QMetaEnum;
69class QMetaProperty;
70class QMetaClassInfo;
71
72namespace QtPrivate {
74template<typename T> constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType();
75}
76
78{
79 void **arguments;
80};
81
82#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
83class Q_CORE_EXPORT QGenericArgument
84{
85public:
86 inline QGenericArgument(const char *aName = nullptr, const void *aData = nullptr)
87 : _data(aData), _name(aName) {}
88 inline void *data() const { return const_cast<void *>(_data); }
89 inline const char *name() const { return _name; }
90
91private:
92 const void *_data;
93 const char *_name;
94};
95
96class Q_CORE_EXPORT QGenericReturnArgument: public QGenericArgument
97{
98public:
99 inline QGenericReturnArgument(const char *aName = nullptr, void *aData = nullptr)
100 : QGenericArgument(aName, aData)
101 {}
102};
103
104template <class T>
105class QArgument: public QGenericArgument
106{
107public:
108 inline QArgument(const char *aName, const T &aData)
109 : QGenericArgument(aName, static_cast<const void *>(&aData))
110 {}
111};
112template <class T>
113class QArgument<T &>: public QGenericArgument
114{
115public:
116 inline QArgument(const char *aName, T &aData)
117 : QGenericArgument(aName, static_cast<const void *>(&aData))
118 {}
119};
120
121
122template <typename T>
123class QReturnArgument: public QGenericReturnArgument
124{
125public:
126 inline QReturnArgument(const char *aName, T &aData)
127 : QGenericReturnArgument(aName, static_cast<void *>(&aData))
128 {}
129};
130#endif
131
133{
135 const char *name;
136 const void *data;
137};
138
145
146template <typename T>
151
152namespace QtPrivate {
153namespace Invoke {
154#if QT_VERSION <= QT_VERSION_CHECK(7, 0, 0)
155template <typename... Args>
157
158template <typename T, typename... Args> using IfNotOldStyleArgs =
160#else
161template <typename T, typename... Args> using IfNotOldStyleArgs = T;
162#endif
163
164template <typename T> inline QMetaMethodArgument argument(const char *name, const T &t)
165{
166 if constexpr ((std::is_lvalue_reference_v<T> && std::is_const_v<std::remove_reference_t<T>>) ||
167 !std::is_reference_v<T>) {
168 return { qMetaTypeInterfaceForType<T>(), name, std::addressof(t) };
169 } else {
170 return { nullptr, name, std::addressof(t) };
171 }
172}
173
174template <typename T>
175inline QTemplatedMetaMethodReturnArgument<T> returnArgument(const char *name, T &t)
176{
177 return { qMetaTypeInterfaceForType<T>(), name, std::addressof(t) };
178}
179
180template <typename T> inline const char *typenameHelper(const T &)
181{
182 return nullptr;
183}
184template <typename T> inline const void *dataHelper(const T &t)
185{
186 return std::addressof(t);
187}
188template <typename T> inline const QMetaTypeInterface *metaTypeHelper(const T &)
189{
190 return qMetaTypeInterfaceForType<T>();
191}
192
194{ return a.name; }
195inline const void *dataHelper(QMetaMethodArgument a)
196{ return a.data; }
199
200inline const char *typenameHelper(const char *) = delete;
201template <typename T> inline const void *dataHelper(const char *) = delete;
202inline const QMetaTypeInterface *metaTypeHelper(const char *) = delete;
203inline const char *typenameHelper(const char16_t *) = delete;
204template <typename T> inline const void *dataHelper(const char16_t *) = delete;
205inline const QMetaTypeInterface *metaTypeHelper(const char16_t *) = delete;
206
207} // namespace QtPrivate::Invoke
208
209template <typename... Args> inline auto invokeMethodHelper(QMetaMethodReturnArgument r, const Args &... arguments)
210{
211 std::array params = { const_cast<const void *>(r.data), Invoke::dataHelper(arguments)... };
212 std::array names = { r.name, Invoke::typenameHelper(arguments)... };
213 std::array types = { r.metaType, Invoke::metaTypeHelper(arguments)... };
214 static_assert(params.size() == types.size());
215 static_assert(params.size() == names.size());
216
217 struct R {
218 decltype(params) parameters;
219 decltype(names) typeNames;
220 decltype(types) metaTypes;
221 constexpr qsizetype parameterCount() const { return qsizetype(parameters.size()); }
222 };
223 return R { params, names, types };
224}
225} // namespace QtPrivate
226
227template <typename T> void qReturnArg(const T &&) = delete;
228template <typename T> inline QTemplatedMetaMethodReturnArgument<T> qReturnArg(T &data)
229{
230 return QtPrivate::Invoke::returnArgument(nullptr, data);
231}
232
233struct Q_CORE_EXPORT QMetaObject
234{
235 class Connection;
236 const char *className() const;
237 const QMetaObject *superClass() const;
238
239 bool inherits(const QMetaObject *metaObject) const noexcept;
240 QObject *cast(QObject *obj) const
241 { return const_cast<QObject *>(cast(const_cast<const QObject *>(obj))); }
242 const QObject *cast(const QObject *obj) const;
243
244#if !defined(QT_NO_TRANSLATION) || defined(Q_QDOC)
245 QString tr(const char *s, const char *c, int n = -1) const;
246#endif // QT_NO_TRANSLATION
247
248 QMetaType metaType() const;
249
250 const char *metaObjectHash() const;
251
252 int methodOffset() const;
253 int enumeratorOffset() const;
254 int propertyOffset() const;
255 int classInfoOffset() const;
256
257 int constructorCount() const;
258 int methodCount() const;
259 int enumeratorCount() const;
260 int propertyCount() const;
261 int classInfoCount() const;
262
263 int indexOfConstructor(const char *constructor) const;
264 int indexOfMethod(const char *method) const;
265 int indexOfSignal(const char *signal) const;
266 int indexOfSlot(const char *slot) const;
267 int indexOfEnumerator(const char *name) const;
268
269 int indexOfProperty(const char *name) const;
270 int indexOfClassInfo(const char *name) const;
271
272 QMetaMethod constructor(int index) const;
273 QMetaMethod method(int index) const;
274 QMetaEnum enumerator(int index) const;
275 QMetaProperty property(int index) const;
276 QMetaClassInfo classInfo(int index) const;
277 QMetaProperty userProperty() const;
278
279 static bool checkConnectArgs(const char *signal, const char *method);
280 static bool checkConnectArgs(const QMetaMethod &signal,
281 const QMetaMethod &method);
282 static QByteArray normalizedSignature(const char *method);
283 static QByteArray normalizedType(const char *type);
284
285 // internal index-based connect
286 static Connection connect(const QObject *sender, int signal_index,
287 const QObject *receiver, int method_index,
288 int type = 0, int *types = nullptr);
289 // internal index-based disconnect
290 static bool disconnect(const QObject *sender, int signal_index,
291 const QObject *receiver, int method_index);
292 static bool disconnectOne(const QObject *sender, int signal_index,
293 const QObject *receiver, int method_index);
294 // internal slot-name based connect
295 static void connectSlotsByName(QObject *o);
296
297#ifdef Q_QDOC
298 template<typename PointerToMemberFunction>
299 static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection);
300 template<typename Functor>
301 static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection);
302#else
303 template <typename Func>
304 static inline Connection
305 connect(const QObject *sender, const QMetaMethod &signal,
306 const typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *context, Func &&slot,
307 Qt::ConnectionType type = Qt::AutoConnection);
308#endif // Q_QDOC
309
310 // internal index-based signal activation
311 static void activate(QObject *sender, int signal_index, void **argv);
312 static void activate(QObject *sender, const QMetaObject *, int local_signal_index, void **argv);
313 static void activate(QObject *sender, int signal_offset, int local_signal_index, void **argv);
314 template <typename Ret, typename... Args> static inline void
315 activate(QObject *sender, const QMetaObject *mo, int local_signal_index, Ret *ret, const Args &... args)
316 {
317 void *_a[] = {
318 const_cast<void *>(reinterpret_cast<const volatile void *>(ret)),
319 const_cast<void *>(reinterpret_cast<const volatile void *>(std::addressof(args)))...
320 };
321 activate(sender, mo, local_signal_index, _a);
322 }
323
324#if QT_VERSION <= QT_VERSION_CHECK(7, 0, 0)
325 static bool invokeMethod(QObject *obj, const char *member,
326 Qt::ConnectionType,
327 QGenericReturnArgument ret,
328 QGenericArgument val0 = QGenericArgument(nullptr),
329 QGenericArgument val1 = QGenericArgument(),
330 QGenericArgument val2 = QGenericArgument(),
331 QGenericArgument val3 = QGenericArgument(),
332 QGenericArgument val4 = QGenericArgument(),
333 QGenericArgument val5 = QGenericArgument(),
334 QGenericArgument val6 = QGenericArgument(),
335 QGenericArgument val7 = QGenericArgument(),
336 QGenericArgument val8 = QGenericArgument(),
337 QGenericArgument val9 = QGenericArgument());
338
339 static inline bool invokeMethod(QObject *obj, const char *member,
340 QGenericReturnArgument ret,
341 QGenericArgument val0 = QGenericArgument(nullptr),
342 QGenericArgument val1 = QGenericArgument(),
343 QGenericArgument val2 = QGenericArgument(),
344 QGenericArgument val3 = QGenericArgument(),
345 QGenericArgument val4 = QGenericArgument(),
346 QGenericArgument val5 = QGenericArgument(),
347 QGenericArgument val6 = QGenericArgument(),
348 QGenericArgument val7 = QGenericArgument(),
349 QGenericArgument val8 = QGenericArgument(),
350 QGenericArgument val9 = QGenericArgument())
351 {
352 return invokeMethod(obj, member, Qt::AutoConnection, ret, val0, val1, val2, val3,
353 val4, val5, val6, val7, val8, val9);
354 }
355
356 static inline bool invokeMethod(QObject *obj, const char *member,
357 Qt::ConnectionType type,
358 QGenericArgument val0,
359 QGenericArgument val1 = QGenericArgument(),
360 QGenericArgument val2 = QGenericArgument(),
361 QGenericArgument val3 = QGenericArgument(),
362 QGenericArgument val4 = QGenericArgument(),
363 QGenericArgument val5 = QGenericArgument(),
364 QGenericArgument val6 = QGenericArgument(),
365 QGenericArgument val7 = QGenericArgument(),
366 QGenericArgument val8 = QGenericArgument(),
367 QGenericArgument val9 = QGenericArgument())
368 {
369 return invokeMethod(obj, member, type, QGenericReturnArgument(), val0, val1, val2,
370 val3, val4, val5, val6, val7, val8, val9);
371 }
372
373 static inline bool invokeMethod(QObject *obj, const char *member,
374 QGenericArgument val0,
375 QGenericArgument val1 = QGenericArgument(),
376 QGenericArgument val2 = QGenericArgument(),
377 QGenericArgument val3 = QGenericArgument(),
378 QGenericArgument val4 = QGenericArgument(),
379 QGenericArgument val5 = QGenericArgument(),
380 QGenericArgument val6 = QGenericArgument(),
381 QGenericArgument val7 = QGenericArgument(),
382 QGenericArgument val8 = QGenericArgument(),
383 QGenericArgument val9 = QGenericArgument())
384 {
385 return invokeMethod(obj, member, Qt::AutoConnection, QGenericReturnArgument(), val0,
386 val1, val2, val3, val4, val5, val6, val7, val8, val9);
387 }
388#endif // Qt < 7.0
389
390 template <typename ReturnArg, typename... Args> static
391#ifdef Q_QDOC
392 bool
393#else
394 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
395#endif
396 invokeMethod(QObject *obj, const char *member, Qt::ConnectionType c,
397 QTemplatedMetaMethodReturnArgument<ReturnArg> r, Args &&... arguments)
398 {
399 auto h = QtPrivate::invokeMethodHelper(r, std::forward<Args>(arguments)...);
400 return invokeMethodImpl(obj, member, c, h.parameterCount(), h.parameters.data(),
401 h.typeNames.data(), h.metaTypes.data());
402 }
403
404 template <typename... Args> static
405#ifdef Q_QDOC
406 bool
407#else
408 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
409#endif
410 invokeMethod(QObject *obj, const char *member, Qt::ConnectionType c, Args &&... arguments)
411 {
412 QTemplatedMetaMethodReturnArgument<void> r = {};
413 return invokeMethod(obj, member, c, r, std::forward<Args>(arguments)...);
414 }
415
416 template <typename ReturnArg, typename... Args> static
417#ifdef Q_QDOC
418 bool
419#else
420 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
421#endif
422 invokeMethod(QObject *obj, const char *member, QTemplatedMetaMethodReturnArgument<ReturnArg> r,
423 Args &&... arguments)
424 {
425 return invokeMethod(obj, member, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
426 }
427
428 template <typename... Args> static
429#ifdef Q_QDOC
430 bool
431#else
432 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
433#endif
434 invokeMethod(QObject *obj, const char *member, Args &&... arguments)
435 {
436 QTemplatedMetaMethodReturnArgument<void> r = {};
437 return invokeMethod(obj, member, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
438 }
439
440#ifdef Q_QDOC
441 template<typename Functor, typename FunctorReturnType>
442 static bool invokeMethod(QObject *context, Functor &&function, Qt::ConnectionType type = Qt::AutoConnection, FunctorReturnType *ret = nullptr);
443 template<typename Functor, typename FunctorReturnType>
444 static bool invokeMethod(QObject *context, Functor &&function, FunctorReturnType *ret);
445
446 template<typename Functor, typename FunctorReturnType, typename... Args>
447 static bool invokeMethod(QObject *context, Functor &&function, Qt::ConnectionType type, QTemplatedMetaMethodReturnArgument<FunctorReturnType> ret, Args &&...arguments);
448 template<typename Functor, typename FunctorReturnType, typename... Args>
449 static bool invokeMethod(QObject *context, Functor &&function, QTemplatedMetaMethodReturnArgument<FunctorReturnType> ret, Args &&...arguments);
450 template<typename Functor, typename... Args>
451 static bool invokeMethod(QObject *context, Functor &&function, Qt::ConnectionType type, Args &&...arguments);
452 template<typename Functor, typename... Args>
453 static bool invokeMethod(QObject *context, Functor &&function, Args &&...arguments);
454#else
455 template <typename Func>
456 static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
457 QtPrivate::Invoke::AreOldStyleArgs<Func>>,
458 bool>
459 invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
460 Func &&function, Qt::ConnectionType type,
461 typename QtPrivate::Callable<Func>::ReturnType *ret)
462 {
463 using R = typename QtPrivate::Callable<Func>::ReturnType;
464 const auto getReturnArg = [ret]() -> QTemplatedMetaMethodReturnArgument<R> {
465 if constexpr (std::is_void_v<R>)
466 return {};
467 else
468 return ret ? qReturnArg(*ret) : QTemplatedMetaMethodReturnArgument<R>{};
469 };
470 return invokeMethod(object, std::forward<Func>(function), type, getReturnArg());
471 }
472 template <typename Func>
473 static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
474 QtPrivate::Invoke::AreOldStyleArgs<Func>>,
475 bool>
476 invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
477 Func &&function, typename QtPrivate::Callable<Func>::ReturnType *ret)
478 {
479 return invokeMethod(object, std::forward<Func>(function), Qt::AutoConnection, ret);
480 }
481
482 template <typename Func, typename... Args>
483 static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
484 QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
485 bool>
486 invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
487 Func &&function, Qt::ConnectionType type,
488 QTemplatedMetaMethodReturnArgument<
489 typename QtPrivate::Callable<Func, Args...>::ReturnType>
490 ret,
491 Args &&...args)
492 {
493 return invokeMethodCallableHelper(object, std::forward<Func>(function), type, ret,
494 std::forward<Args>(args)...);
495 }
496
497 template <typename Func, typename... Args>
498 static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
499 QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
500 bool>
501 invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
502 Func &&function, Qt::ConnectionType type, Args &&...args)
503 {
504 using R = typename QtPrivate::Callable<Func, Args...>::ReturnType;
505 QTemplatedMetaMethodReturnArgument<R> r{ QtPrivate::qMetaTypeInterfaceForType<R>(), nullptr,
506 nullptr };
507 return invokeMethod(object, std::forward<Func>(function), type, r,
508 std::forward<Args>(args)...);
509 }
510
511 template <typename Func, typename... Args>
512 static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
513 QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
514 bool>
515 invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
516 Func &&function,
517 QTemplatedMetaMethodReturnArgument<
518 typename QtPrivate::Callable<Func, Args...>::ReturnType>
519 ret,
520 Args &&...args)
521 {
522 return invokeMethod(object, std::forward<Func>(function), Qt::AutoConnection, ret,
523 std::forward<Args>(args)...);
524 }
525
526 template <typename Func, typename... Args>
527 static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
528 QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
529 bool>
530 invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
531 Func &&function, Args &&...args)
532 {
533 using R = typename QtPrivate::Callable<Func, Args...>::ReturnType;
534 QTemplatedMetaMethodReturnArgument<R> r{ QtPrivate::qMetaTypeInterfaceForType<R>(), nullptr,
535 nullptr };
536 return invokeMethod(object, std::forward<Func>(function), Qt::AutoConnection, r,
537 std::forward<Args>(args)...);
538 }
539
540#endif
541
542#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
543 QObject *newInstance(QGenericArgument val0,
544 QGenericArgument val1 = QGenericArgument(),
545 QGenericArgument val2 = QGenericArgument(),
546 QGenericArgument val3 = QGenericArgument(),
547 QGenericArgument val4 = QGenericArgument(),
548 QGenericArgument val5 = QGenericArgument(),
549 QGenericArgument val6 = QGenericArgument(),
550 QGenericArgument val7 = QGenericArgument(),
551 QGenericArgument val8 = QGenericArgument(),
552 QGenericArgument val9 = QGenericArgument()) const;
553#endif
554
555 template <typename... Args>
556#ifdef Q_QDOC
557 QObject *
558#else
559 QtPrivate::Invoke::IfNotOldStyleArgs<QObject *, Args...>
560#endif
561 newInstance(Args &&... arguments) const
562 {
563 auto h = QtPrivate::invokeMethodHelper(QMetaMethodReturnArgument{}, std::forward<Args>(arguments)...);
564 return newInstanceImpl(this, h.parameterCount(), h.parameters.data(),
565 h.typeNames.data(), h.metaTypes.data());
566 }
567
568 enum Call {
569 InvokeMetaMethod,
570 ReadProperty,
571 WriteProperty,
572 ResetProperty,
573 CreateInstance,
574 IndexOfMethod,
575 RegisterPropertyMetaType,
576 RegisterMethodArgumentMetaType,
577 BindableProperty,
578 CustomCall,
579 ConstructInPlace,
580 };
581
582 int static_metacall(Call, int, void **) const;
583 static int metacall(QObject *, Call, int, void **);
584
585 template <const QMetaObject &MO> static constexpr const QMetaObject *staticMetaObject()
586 {
587 return &MO;
588 }
589
590 struct SuperData {
591 using Getter = const QMetaObject *(*)();
592 const QMetaObject *direct;
593 SuperData() = default;
594 constexpr SuperData(std::nullptr_t) : direct(nullptr) {}
595 constexpr SuperData(const QMetaObject *mo) : direct(mo) {}
596
597 constexpr const QMetaObject *operator->() const { return operator const QMetaObject *(); }
598
599#ifdef QT_NO_DATA_RELOCATION
600 Getter indirect = nullptr;
601 constexpr SuperData(Getter g) : direct(nullptr), indirect(g) {}
602 constexpr operator const QMetaObject *() const
603 { return indirect ? indirect() : direct; }
604 template <const QMetaObject &MO> static constexpr SuperData link()
605 { return SuperData(QMetaObject::staticMetaObject<MO>); }
606#else
607 constexpr SuperData(Getter g) : direct(g()) {}
608 constexpr operator const QMetaObject *() const
609 { return direct; }
610 template <const QMetaObject &MO> static constexpr SuperData link()
611 { return SuperData(QMetaObject::staticMetaObject<MO>()); }
612#endif
613 };
614
615 struct Data { // private data
616 SuperData superdata;
617 const uint *stringdata;
618 const uint *data;
619 typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
620 StaticMetacallFunction static_metacall;
621 const SuperData *relatedMetaObjects;
622 const QtPrivate::QMetaTypeInterface *const *metaTypes;
623 void *extradata; //reserved for future use
624 } d;
625
626private:
627 // Just need to have this here with a separate name so the other inline
628 // functions can call this without any ambiguity
629 template <typename Func, typename... Args>
630 static bool
631 invokeMethodCallableHelper(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
632 Func &&function, Qt::ConnectionType type, const QMetaMethodReturnArgument &ret,
633 Args &&...args)
634 {
635 using Callable = QtPrivate::Callable<Func, Args...>;
636 using ExpectedArguments = typename Callable::Arguments;
637 static_assert(sizeof...(Args) <= ExpectedArguments::size, "Too many arguments");
638 using ActualArguments = QtPrivate::List<Args...>;
639 static_assert(QtPrivate::CheckCompatibleArguments<ActualArguments,
640 ExpectedArguments>::value,
641 "Incompatible arguments");
642
643 auto h = QtPrivate::invokeMethodHelper(ret, std::forward<Args>(args)...);
644
645 // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks)
646 auto callable = new QtPrivate::QCallableObject<std::decay_t<Func>, ActualArguments,
647 typename Callable::ReturnType>(std::forward<Func>(function));
648 return invokeMethodImpl(object, callable, type, h.parameterCount(), h.parameters.data(),
649 h.typeNames.data(), h.metaTypes.data());
650 // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
651 }
652
653 static bool invokeMethodImpl(QObject *object, const char *member, Qt::ConnectionType type,
654 qsizetype parameterCount, const void *const *parameters, const char *const *names,
655 const QtPrivate::QMetaTypeInterface * const *metaTypes);
656 static bool invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slotObj,
657 Qt::ConnectionType type, qsizetype parameterCount,
658 const void *const *params, const char *const *names,
659 const QtPrivate::QMetaTypeInterface *const *metaTypes);
660#if QT_CORE_REMOVED_SINCE(6, 7)
661 static bool invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type, void *ret);
662#endif
663 static QObject *newInstanceImpl(const QMetaObject *mobj, qsizetype parameterCount,
664 const void **parameters, const char **typeNames,
665 const QtPrivate::QMetaTypeInterface **metaTypes);
666
667 static QMetaObject::Connection connectImpl(const QObject *sender, const QMetaMethod& signal,
668 const QObject *receiver, void **slotPtr,
669 QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type);
670
671 friend class QTimer;
672 friend class QChronoTimer;
673};
674
675class Q_CORE_EXPORT QMetaObject::Connection {
676 void *d_ptr; //QObjectPrivate::Connection*
677 explicit Connection(void *data) : d_ptr(data) { }
678 friend class QObject;
679 friend class QObjectPrivate;
680 friend struct QMetaObject;
681 bool isConnected_helper() const;
682public:
683 ~Connection();
684 Connection();
685 Connection(const Connection &other);
686 Connection &operator=(const Connection &other);
687#ifdef Q_QDOC
688 operator bool() const;
689#else
690 // still using the restricted bool trick here, in order to support
691 // code using copy-init (e.g. `bool ok = connect(...)`)
692 typedef void *Connection::*RestrictedBool;
693 operator RestrictedBool() const { return d_ptr && isConnected_helper() ? &Connection::d_ptr : nullptr; }
694#endif
695
696 Connection(Connection &&other) noexcept : d_ptr(std::exchange(other.d_ptr, nullptr)) {}
697 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Connection)
698 void swap(Connection &other) noexcept { qt_ptr_swap(d_ptr, other.d_ptr); }
699};
700
701template <typename Func>
702QMetaObject::Connection
703 QMetaObject::connect(const QObject *sender, const QMetaMethod &signal,
704 const typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *context, Func &&slot,
705 Qt::ConnectionType type)
706{
707 using Slot = std::decay_t<Func>;
708 using FunctionSlotType = QtPrivate::FunctionPointer<Slot>;
709 void **pSlot = nullptr;
710 QtPrivate::QSlotObjectBase *slotObject;
711 if constexpr (FunctionSlotType::ArgumentCount != -1) {
712 slotObject = new QtPrivate::QCallableObject<Slot, typename FunctionSlotType::Arguments, typename FunctionSlotType::ReturnType>(std::forward<Func>(slot));
713 if constexpr (FunctionSlotType::IsPointerToMemberFunction) {
714 pSlot = const_cast<void **>(reinterpret_cast<void *const *>(&slot));
715 } else {
716 Q_ASSERT_X((type & Qt::UniqueConnection) == 0, "",
717 "QObject::connect: Unique connection requires the slot to be a pointer to "
718 "a member function of a QObject subclass.");
719 }
720 } else {
721 using FunctorSlotType = QtPrivate::FunctionPointer<decltype(&Slot::operator())>;
722 slotObject = new QtPrivate::QCallableObject<Slot, typename FunctorSlotType::Arguments, typename FunctorSlotType::ReturnType>(std::forward<Func>(slot));
723 }
724 return QMetaObject::connectImpl(sender, signal, context, pSlot, slotObject, type);
725}
726
727inline void swap(QMetaObject::Connection &lhs, QMetaObject::Connection &rhs) noexcept
728{
729 lhs.swap(rhs);
730}
731
732inline const QMetaObject *QMetaObject::superClass() const
733{ return d.superdata; }
734
735namespace QtPrivate {
736 // Trait that tells if a QObject has a Q_OBJECT macro
737 template <typename Object> struct HasQ_OBJECT_Macro {
738 template <typename T>
739 static char test(int (T::*)(QMetaObject::Call, int, void **));
740 static int test(int (Object::*)(QMetaObject::Call, int, void **));
741 enum { Value = sizeof(test(&Object::qt_metacall)) == sizeof(int) };
742 };
743
744 template <class TgtType, class SrcType>
745 inline TgtType qobject_cast_helper(SrcType *object)
746 {
747 using ObjType = std::remove_cv_t<std::remove_pointer_t<TgtType>> ;
748 static_assert(std::is_pointer_v<TgtType>,
749 "qobject_cast requires to cast towards a pointer type");
750 static_assert(HasQ_OBJECT_Macro<ObjType>::Value,
751 "qobject_cast requires the type to have a Q_OBJECT macro");
752
753 if constexpr (std::is_final_v<ObjType>) {
754 if (object && object->metaObject() == &ObjType::staticMetaObject)
755 return static_cast<TgtType>(object);
756 return nullptr;
757 } else {
758 return static_cast<TgtType>(ObjType::staticMetaObject.cast(object));
759 }
760 }
761}
762
763QT_END_NAMESPACE
764
765#endif // QOBJECTDEFS_H
\inmodule QtCore
Definition qrandom.h:212
void discard(unsigned long long z)
Definition qrandom.h:240
result_type operator()()
Generates a 64-bit random quantity and returns it.
Definition qrandom.h:220
static constexpr result_type min()
Definition qrandom.h:247
quint64 result_type
A typedef to the type that operator() returns.
Definition qrandom.h:219
QRandomGenerator64(std::seed_seq &sseq) noexcept
Definition qrandom.h:232
QRandomGenerator64(const QRandomGenerator &other)
Definition qrandom.h:238
quint64 generate()
Generates one 64-bit random value and returns it.
Definition qrandom.h:217
QRandomGenerator64(quint32 seedValue=1)
Definition qrandom.h:223
QRandomGenerator64(const quint32 *begin, const quint32 *end)
Definition qrandom.h:235
QRandomGenerator64(const quint32 *seedBuffer, qsizetype len)
Definition qrandom.h:229
static constexpr result_type max()
Definition qrandom.h:248
QRandomGenerator64(const quint32(&seedBuffer)[N])
Definition qrandom.h:226
Combined button and popup list for selecting options.
QTemplatedMetaMethodReturnArgument< T > returnArgument(const char *name, T &t)
const void * dataHelper(const char *)=delete
const char * typenameHelper(QMetaMethodArgument a)
const QMetaTypeInterface * metaTypeHelper(const T &)
const QMetaTypeInterface * metaTypeHelper(const char16_t *)=delete
const QMetaTypeInterface * metaTypeHelper(QMetaMethodArgument a)
const QMetaTypeInterface * metaTypeHelper(const char *)=delete
const char * typenameHelper(const T &)
const void * dataHelper(const char16_t *)=delete
const void * dataHelper(QMetaMethodArgument a)
QMetaMethodArgument argument(const char *name, const T &t)
const void * dataHelper(const T &t)
const char * typenameHelper(const char16_t *)=delete
const char * typenameHelper(const char *)=delete
auto invokeMethodHelper(QMetaMethodReturnArgument r, const Args &... arguments)
TgtType qobject_cast_helper(SrcType *object)
constexpr const QMetaTypeInterface * qMetaTypeInterfaceForType()
Definition qmetatype.h:2646
#define assert
QMutex QBasicMutex
Definition qmutex.h:360
#define QT_STRINGIFY_METHOD(a)
Definition qobjectdefs.h:44
#define QT_PREFIX_CODE(code, a)
Definition qobjectdefs.h:43
#define QT_STRINGIFY_SIGNAL(a)
Definition qobjectdefs.h:46
void swap(QMetaObject::Connection &lhs, QMetaObject::Connection &rhs) noexcept
#define QSIGNAL_CODE
Definition qobjectdefs.h:42
QTemplatedMetaMethodReturnArgument< T > qReturnArg(T &data)
void qReturnArg(const T &&)=delete
#define QT_STRINGIFY_SLOT(a)
Definition qobjectdefs.h:45
#define QLOCATION
Definition qobjectdefs.h:48
Q_CORE_EXPORT const char * qFlagLocation(const char *method)
Definition qobject.cpp:2623
#define QSLOT_CODE
Definition qobjectdefs.h:41
#define QMETHOD_CODE
Definition qobjectdefs.h:40
static qsizetype callFillBuffer(FillBufferType f, T *v)
Definition qrandom.cpp:1265
static Q_NEVER_INLINE void fallback_fill(quint32 *ptr, qsizetype left) noexcept
Definition qrandom.cpp:210
static void fallback_update_seed(unsigned value)
Definition qrandom.cpp:198
bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
Definition qrandom.cpp:1218
#define Q_ASSERT(cond)
Definition qrandom.cpp:48
QRandomGenerator::InitialRandomData qt_initial_random_value() noexcept
Definition qrandom.cpp:1286
RNGType
Definition qrandom_p.h:33
@ MersenneTwister
Definition qrandom_p.h:35
@ SystemRNG
Definition qrandom_p.h:34
QRandomGeneratorControl
Definition qrandom_p.h:24
@ UseSystemRNG
Definition qrandom_p.h:25
@ SkipSystemRNG
Definition qrandom_p.h:26
@ SetRandomData
Definition qrandom_p.h:27
@ RandomDataMask
Definition qrandom_p.h:30
const char * name
const QtPrivate::QMetaTypeInterface * metaType
const void * data
const QtPrivate::QMetaTypeInterface * metaType
\inmodule QtCore
static QRandomGenerator64 * system()
Definition qrandom.cpp:350
static void securelySeed(QRandomGenerator *rng)
Definition qrandom.cpp:367
static SystemAndGlobalGenerators * self()
Definition qrandom.cpp:343
static QRandomGenerator64 * globalNoInit()
Definition qrandom.cpp:359
uchar data[sizeof(QRandomGenerator64)]
Definition qrandom.cpp:327
void generate(quint32 *begin, quint32 *end) noexcept(FillBufferNoexcept)
Definition qrandom.cpp:283
static SystemGenerator & self()
Definition qrandom.cpp:394
void generate(T *begin, T *end)
Definition qrandom.cpp:153
static char test(int(T::*)(QMetaObject::Call, int, void **))
static int test(int(Object::*)(QMetaObject::Call, int, void **))