Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qobjectdefs_impl.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
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#error Do not include qobjectdefs_impl.h directly
7#include <QtCore/qnamespace.h>
8#endif
9
10#if 0
11#pragma qt_sync_skip_header_check
12#pragma qt_sync_stop_processing
13#endif
14
15#include <QtCore/qfunctionaltools_impl.h>
16
18class QObject;
19class QObjectPrivate;
20class QMetaMethod;
21class QByteArray;
22
23namespace QtPrivate {
24 template <typename T> struct RemoveRef { typedef T Type; };
25 template <typename T> struct RemoveRef<T&> { typedef T Type; };
26 template <typename T> struct RemoveConstRef { typedef T Type; };
27 template <typename T> struct RemoveConstRef<const T&> { typedef T Type; };
28
29 /*
30 The following List classes are used to help to handle the list of arguments.
31 It follow the same principles as the lisp lists.
32 List_Left<L,N> take a list and a number as a parameter and returns (via the Value typedef,
33 the list composed of the first N element of the list
34 */
35 // With variadic template, lists are represented using a variadic template argument instead of the lisp way
36 template <typename... Ts> struct List { static constexpr size_t size = sizeof...(Ts); };
37 template<typename T> struct SizeOfList { static constexpr size_t value = 1; };
38 template<> struct SizeOfList<List<>> { static constexpr size_t value = 0; };
39 template<typename ...Ts> struct SizeOfList<List<Ts...>> { static constexpr size_t value = List<Ts...>::size; };
40 template <typename Head, typename... Tail> struct List<Head, Tail...> {
41 static constexpr size_t size = 1 + sizeof...(Tail);
42 typedef Head Car; typedef List<Tail...> Cdr;
43 };
44 template <typename, typename> struct List_Append;
45 template <typename... L1, typename...L2> struct List_Append<List<L1...>, List<L2...>> { typedef List<L1..., L2...> Value; };
46 template <typename L, int N> struct List_Left {
47 typedef typename List_Append<List<typename L::Car>,typename List_Left<typename L::Cdr, N - 1>::Value>::Value Value;
48 };
49 template <typename L> struct List_Left<L, 0> { typedef List<> Value; };
50
51 /*
52 Trick to set the return value of a slot that works even if the signal or the slot returns void
53 to be used like
54 function(), ApplyReturnValue<ReturnType>(&return_value)
55 if function() returns a value, the operator,(T, ApplyReturnValue<ReturnType>) is called, but if it
56 returns void, the built-in one is used without an error.
57 */
58 template <typename T>
60 void *data;
61 explicit ApplyReturnValue(void *data_) : data(data_) {}
62 };
63 template<typename T, typename U>
64 void operator,(T &&value, const ApplyReturnValue<U> &container) {
65 if (container.data)
66 *reinterpret_cast<U *>(container.data) = std::forward<T>(value);
67 }
68 template<typename T>
70
71
72 /*
73 The FunctionPointer<Func> struct is a type trait for function pointer.
74 - ArgumentCount is the number of argument, or -1 if it is unknown
75 - the Object typedef is the Object of a pointer to member function
76 - the Arguments typedef is the list of argument (in a QtPrivate::List)
77 - the Function typedef is an alias to the template parameter Func
78 - the call<Args, R>(f,o,args) method is used to call that slot
79 Args is the list of argument of the signal
80 R is the return type of the signal
81 f is the function pointer
82 o is the receiver object
83 and args is the array of pointer to arguments, as used in qt_metacall
84
85 The Functor<Func,N> struct is the helper to call a functor of N argument.
86 Its call function is the same as the FunctionPointer::call function.
87 */
88 template<class T> using InvokeGenSeq = typename T::Type;
89
90 template<int...> struct IndexesList { using Type = IndexesList; };
91
92 template<int N, class S1, class S2> struct ConcatSeqImpl;
93
94 template<int N, int... I1, int... I2>
95 struct ConcatSeqImpl<N, IndexesList<I1...>, IndexesList<I2...>>
96 : IndexesList<I1..., (N + I2)...>{};
97
98 template<int N, class S1, class S2>
100
101 template<int N> struct GenSeq;
103
104 template<int N>
105 struct GenSeq : ConcatSeq<N/2, makeIndexSequence<N/2>, makeIndexSequence<N - N/2>>{};
106
107 template<> struct GenSeq<0> : IndexesList<>{};
108 template<> struct GenSeq<1> : IndexesList<0>{};
109
110 template<int N>
111 struct Indexes { using Value = makeIndexSequence<N>; };
112
113 template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1, IsPointerToMemberFunction = false}; };
114
115 template<typename ObjPrivate> inline void assertObjectType(QObjectPrivate *d);
116 template<typename Obj> inline void assertObjectType(QObject *o)
117 {
118 // ensure all three compile
119 [[maybe_unused]] auto staticcast = [](QObject *obj) { return static_cast<Obj *>(obj); };
120 [[maybe_unused]] auto qobjcast = [](QObject *obj) { return Obj::staticMetaObject.cast(obj); };
121#ifdef __cpp_rtti
122 [[maybe_unused]] auto dyncast = [](QObject *obj) { return dynamic_cast<Obj *>(obj); };
123 auto cast = dyncast;
124#else
125 auto cast = qobjcast;
126#endif
127 Q_ASSERT_X(cast(o), Obj::staticMetaObject.className(),
128 "Called object is not of the correct type (class destructor may have already run)");
129 }
130
131 template <typename, typename, typename, typename> struct FunctorCall;
132 template <int... II, typename... SignalArgs, typename R, typename Function>
133 struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, Function> {
134 static void call(Function &f, void **arg) {
135 f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
136 }
137 };
138 template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
139 struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...)> {
140 static void call(SlotRet (Obj::*f)(SlotArgs...), Obj *o, void **arg)
141 {
142 assertObjectType<Obj>(o);
143 (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
144 }
145 };
146 template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
147 struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...) const> {
148 static void call(SlotRet (Obj::*f)(SlotArgs...) const, Obj *o, void **arg)
149 {
150 assertObjectType<Obj>(o);
151 (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
152 }
153 };
154 template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
155 struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...) noexcept> {
156 static void call(SlotRet (Obj::*f)(SlotArgs...) noexcept, Obj *o, void **arg)
157 {
158 assertObjectType<Obj>(o);
159 (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
160 }
161 };
162 template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
163 struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...) const noexcept> {
164 static void call(SlotRet (Obj::*f)(SlotArgs...) const noexcept, Obj *o, void **arg)
165 {
166 assertObjectType<Obj>(o);
167 (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
168 }
169 };
170
171 template<class Obj, typename Ret, typename... Args> struct FunctionPointer<Ret (Obj::*) (Args...)>
172 {
173 typedef Obj Object;
174 typedef List<Args...> Arguments;
175 typedef Ret ReturnType;
176 typedef Ret (Obj::*Function) (Args...);
177 enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true};
178 template <typename SignalArgs, typename R>
179 static void call(Function f, Obj *o, void **arg) {
181 }
182 };
183 template<class Obj, typename Ret, typename... Args> struct FunctionPointer<Ret (Obj::*) (Args...) const>
184 {
185 typedef Obj Object;
186 typedef List<Args...> Arguments;
187 typedef Ret ReturnType;
188 typedef Ret (Obj::*Function) (Args...) const;
189 enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true};
190 template <typename SignalArgs, typename R>
191 static void call(Function f, Obj *o, void **arg) {
193 }
194 };
195
196 template<typename Ret, typename... Args> struct FunctionPointer<Ret (*) (Args...)>
197 {
198 typedef List<Args...> Arguments;
199 typedef Ret ReturnType;
200 typedef Ret (*Function) (Args...);
201 enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = false};
202 template <typename SignalArgs, typename R>
203 static void call(Function f, void *, void **arg) {
205 }
206 };
207
208 template<class Obj, typename Ret, typename... Args> struct FunctionPointer<Ret (Obj::*) (Args...) noexcept>
209 {
210 typedef Obj Object;
211 typedef List<Args...> Arguments;
212 typedef Ret ReturnType;
213 typedef Ret (Obj::*Function) (Args...) noexcept;
214 enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true};
215 template <typename SignalArgs, typename R>
216 static void call(Function f, Obj *o, void **arg) {
218 }
219 };
220 template<class Obj, typename Ret, typename... Args> struct FunctionPointer<Ret (Obj::*) (Args...) const noexcept>
221 {
222 typedef Obj Object;
223 typedef List<Args...> Arguments;
224 typedef Ret ReturnType;
225 typedef Ret (Obj::*Function) (Args...) const noexcept;
226 enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true};
227 template <typename SignalArgs, typename R>
228 static void call(Function f, Obj *o, void **arg) {
230 }
231 };
232
233 template<typename Ret, typename... Args> struct FunctionPointer<Ret (*) (Args...) noexcept>
234 {
235 typedef List<Args...> Arguments;
236 typedef Ret ReturnType;
237 typedef Ret (*Function) (Args...) noexcept;
238 enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = false};
239 template <typename SignalArgs, typename R>
240 static void call(Function f, void *, void **arg) {
242 }
243 };
244
245 // Traits to detect if there is a conversion between two types,
246 // and that conversion does not include a narrowing conversion.
247 template <typename T>
248 struct NarrowingDetector { T t[1]; }; // from P0608
249
250 template <typename From, typename To, typename Enable = void>
251 struct IsConvertibleWithoutNarrowing : std::false_type {};
252
253 template <typename From, typename To>
255 std::void_t< decltype( NarrowingDetector<To>{ {std::declval<From>()} } ) >
256 > : std::true_type {};
257
258 // Check for the actual arguments. If they are exactly the same,
259 // then don't bother checking for narrowing; as a by-product,
260 // this solves the problem of incomplete types (which must be supported,
261 // or they would error out in the trait above).
262 template <typename From, typename To, typename Enable = void>
264
265 template <typename From, typename To>
267 std::enable_if_t<
268 std::disjunction_v<std::is_same<From, To>, IsConvertibleWithoutNarrowing<From, To>>
269 >
270 > : std::true_type {};
271
272 /*
273 Logic that check if the arguments of the slot matches the argument of the signal.
274 To be used like this:
275 static_assert(CheckCompatibleArguments<FunctionPointer<Signal>::Arguments, FunctionPointer<Slot>::Arguments>::value)
276 */
277 template<typename A1, typename A2> struct AreArgumentsCompatible {
278 static int test(const std::remove_reference_t<A2>&);
279 static char test(...);
280 enum { value = sizeof(test(std::declval<std::remove_reference_t<A1>>())) == sizeof(int) };
281#ifdef QT_NO_NARROWING_CONVERSIONS_IN_CONNECT
282 using AreArgumentsConvertibleWithoutNarrowing = AreArgumentsConvertibleWithoutNarrowingBase<std::decay_t<A1>, std::decay_t<A2>>;
283 static_assert(AreArgumentsConvertibleWithoutNarrowing::value, "Signal and slot arguments are not compatible (narrowing)");
284#endif
285 };
286 template<typename A1, typename A2> struct AreArgumentsCompatible<A1, A2&> { enum { value = false }; };
287 template<typename A> struct AreArgumentsCompatible<A&, A&> { enum { value = true }; };
288 // void as a return value
289 template<typename A> struct AreArgumentsCompatible<void, A> { enum { value = true }; };
290 template<typename A> struct AreArgumentsCompatible<A, void> { enum { value = true }; };
291 template<> struct AreArgumentsCompatible<void, void> { enum { value = true }; };
292
293 template <typename List1, typename List2> struct CheckCompatibleArguments { enum { value = false }; };
294 template <> struct CheckCompatibleArguments<List<>, List<>> { enum { value = true }; };
295 template <typename List1> struct CheckCompatibleArguments<List1, List<>> { enum { value = true }; };
296 template <typename Arg1, typename Arg2, typename... Tail1, typename... Tail2>
297 struct CheckCompatibleArguments<List<Arg1, Tail1...>, List<Arg2, Tail2...>>
298 {
300 && CheckCompatibleArguments<List<Tail1...>, List<Tail2...>>::value };
301 };
302
303 /*
304 Find the maximum number of arguments a functor object can take and be still compatible with
305 the arguments from the signal.
306 Value is the number of arguments, or -1 if nothing matches.
307 */
308 template <typename Functor, typename ArgList> struct ComputeFunctorArgumentCount;
309
310 template <typename Functor, typename ArgList, bool Done> struct ComputeFunctorArgumentCountHelper
311 { enum { Value = -1 }; };
312 template <typename Functor, typename First, typename... ArgList>
315 typename List_Left<List<First, ArgList...>, sizeof...(ArgList)>::Value> {};
316
317 template <typename Functor, typename... ArgList> struct ComputeFunctorArgumentCount<Functor, List<ArgList...>>
318 {
319 template <typename F> static auto test(F f) -> decltype(((f.operator()((std::declval<ArgList>())...)), int()));
320 static char test(...);
321 enum {
322 Ok = sizeof(test(std::declval<Functor>())) == sizeof(int),
323 Value = Ok ? int(sizeof...(ArgList)) : int(ComputeFunctorArgumentCountHelper<Functor, List<ArgList...>, Ok>::Value)
324 };
325 };
326
327 /* get the return type of a functor, given the signal argument list */
328 template <typename Functor, typename ArgList> struct FunctorReturnType;
329 template <typename Functor, typename ... ArgList> struct FunctorReturnType<Functor, List<ArgList...>> {
330 typedef decltype(std::declval<Functor>().operator()((std::declval<ArgList>())...)) Value;
331 };
332
333 template<typename Function, int N> struct Functor
334 {
335 template <typename SignalArgs, typename R>
336 static void call(Function &f, void *, void **arg) {
338 }
339 };
340
341 template<typename Func>
342 struct ZeroArgFunctor : Functor<Func, 0>
343 {
344 using ReturnType = decltype(std::declval<Func>()());
345 using Function = ReturnType(*)();
346 enum {ArgumentCount = 0};
348 };
349
350 template<typename Func>
351 using Callable = std::conditional_t<FunctionPointer<std::decay_t<Func>>::ArgumentCount == -1,
354 >;
355
356 /*
357 Wrapper around ComputeFunctorArgumentCount and CheckCompatibleArgument,
358 depending on whether \a Functor is a PMF or not. Returns -1 if \a Func is
359 not compatible with the \a ExpectedArguments, otherwise returns >= 0.
360 */
361 template<typename Prototype, typename Functor>
362 inline constexpr std::enable_if_t<!std::disjunction_v<std::is_convertible<Prototype, const char *>,
363 std::is_same<std::decay_t<Prototype>, QMetaMethod>,
364 std::is_convertible<Functor, const char *>,
365 std::is_same<std::decay_t<Functor>, QMetaMethod>
366 >,
367 int>
369 {
370 using ExpectedArguments = typename QtPrivate::FunctionPointer<Prototype>::Arguments;
371 using Actual = std::decay_t<Functor>;
372
375 // PMF or free function
376 using ActualArguments = typename QtPrivate::FunctionPointer<Actual>::Arguments;
379 else
380 return -1;
381 } else {
382 // lambda or functor
384 }
385 }
386
387 // internal base class (interface) containing functions required to call a slot managed by a pointer to function.
389 {
390 // Don't use virtual functions here; we don't want the
391 // compiler to create tons of per-polymorphic-class stuff that
392 // we'll never need. We just use one function pointer, and the
393 // Operations enum below to distinguish requests
394#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
395 QAtomicInt m_ref = 1;
396 typedef void (*ImplFn)(int which, QSlotObjectBase* this_, QObject *receiver, void **args, bool *ret);
397 const ImplFn m_impl;
398#else
399 using ImplFn = void (*)(QSlotObjectBase* this_, QObject *receiver, void **args, int which, bool *ret);
400 const ImplFn m_impl;
401 QAtomicInt m_ref = 1;
402#endif
403 protected:
404 // The operations that can be requested by calls to m_impl,
405 // see the member functions that call m_impl below for details
410
411 NumOperations
412 };
413 public:
414 explicit QSlotObjectBase(ImplFn fn) : m_impl(fn) {}
415
416 inline int ref() noexcept { return m_ref.ref(); }
417#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
418 inline void destroyIfLastRef() noexcept
419 { if (!m_ref.deref()) m_impl(Destroy, this, nullptr, nullptr, nullptr); }
420
421 inline bool compare(void **a) { bool ret = false; m_impl(Compare, this, nullptr, a, &ret); return ret; }
422 inline void call(QObject *r, void **a) { m_impl(Call, this, r, a, nullptr); }
423#else
424 inline void destroyIfLastRef() noexcept
425 { if (!m_ref.deref()) m_impl(this, nullptr, nullptr, Destroy, nullptr); }
426
427 inline bool compare(void **a)
428 {
429 bool ret = false;
430 m_impl(this, nullptr, a, Compare, &ret);
431 return ret;
432 }
433 inline void call(QObject *r, void **a) { m_impl(this, r, a, Call, nullptr); }
434#endif
435 bool isImpl(ImplFn f) const { return m_impl == f; }
436 protected:
438 private:
439 Q_DISABLE_COPY_MOVE(QSlotObjectBase)
440 };
441
442 // Implementation of QSlotObjectBase for which the slot is a callable (function, PMF, functor, or lambda).
443 // Args and R are the List of arguments and the return type of the signal to which the slot is connected.
444 template <typename Func, typename Args, typename R>
446 private QtPrivate::CompactStorage<std::decay_t<Func>>
447 {
448 using FunctorValue = std::decay_t<Func>;
450 using FuncType = std::conditional_t<std::is_member_function_pointer_v<FunctorValue>,
453 >;
454
455#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
456 Q_DECL_HIDDEN static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret)
457#else
458 // Design note: the first three arguments match those for typical Call
459 // and Destroy uses. We return void to enable tail call optimization
460 // for those too.
461 Q_DECL_HIDDEN static void impl(QSlotObjectBase *this_, QObject *r, void **a, int which, bool *ret)
462#endif
463 {
464 const auto that = static_cast<QCallableObject*>(this_);
465 switch (which) {
466 case Destroy:
467 delete that;
468 break;
469 case Call:
470 if constexpr (std::is_member_function_pointer_v<FunctorValue>)
471 FuncType::template call<Args, R>(that->object(), static_cast<typename FuncType::Object *>(r), a);
472 else
473 FuncType::template call<Args, R>(that->object(), r, a);
474 break;
475 case Compare:
476 if constexpr (std::is_member_function_pointer_v<FunctorValue>) {
477 *ret = *reinterpret_cast<FunctorValue *>(a) == that->object();
478 break;
479 }
480 // not implemented otherwise
482 case NumOperations:
483 Q_UNUSED(ret);
484 }
485 }
486 public:
487 explicit QCallableObject(Func &&f) : QSlotObjectBase(&impl), Storage{std::move(f)} {}
488 explicit QCallableObject(const Func &f) : QSlotObjectBase(&impl), Storage{f} {}
489 };
490
491 // Helper to detect the context object type based on the functor type:
492 // QObject for free functions and lambdas; the callee for member function
493 // pointers. The default declaration doesn't have the ContextType typedef,
494 // and so non-functor APIs (like old-style string-based slots) are removed
495 // from the overload set.
496 template <typename Func, typename = void>
498
499 template <typename Func>
501 std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
502 std::is_member_function_pointer<Func>
503 >
504 >
505 >
506 {
508 };
509 template <typename Func>
511 std::enable_if_t<std::conjunction_v<std::negation<std::is_convertible<Func, const char *>>,
512 std::is_member_function_pointer<Func>,
513 std::is_convertible<typename QtPrivate::FunctionPointer<Func>::Object *, QObject *>
514 >
515 >
516 >
517 {
519 };
520
521 /*
522 Returns a suitable QSlotObjectBase object that holds \a func, if possible.
523
524 Not available (and thus produces compile-time errors) if the Functor provided is
525 not compatible with the expected Prototype.
526 */
527 template <typename Prototype, typename Functor>
528 static constexpr std::enable_if_t<QtPrivate::countMatchingArguments<Prototype, Functor>() >= 0,
531 {
532 using ExpectedSignature = QtPrivate::FunctionPointer<Prototype>;
533 using ExpectedReturnType = typename ExpectedSignature::ReturnType;
534 using ExpectedArguments = typename ExpectedSignature::Arguments;
535
536 using ActualSignature = QtPrivate::FunctionPointer<Functor>;
537 constexpr int MatchingArgumentCount = QtPrivate::countMatchingArguments<Prototype, Functor>();
539
540 static_assert(int(ActualSignature::ArgumentCount) <= int(ExpectedSignature::ArgumentCount),
541 "Functor requires more arguments than what can be provided.");
542
543 return new QtPrivate::QCallableObject<std::decay_t<Functor>, ActualArguments, ExpectedReturnType>(std::forward<Functor>(func));
544 }
545
546 template<typename Prototype, typename Functor, typename = void>
547 struct AreFunctionsCompatible : std::false_type {};
548 template<typename Prototype, typename Functor>
549 struct AreFunctionsCompatible<Prototype, Functor, std::enable_if_t<
550 std::is_same_v<decltype(QtPrivate::makeCallableObject<Prototype>(std::forward<Functor>(std::declval<Functor>()))),
551 QtPrivate::QSlotObjectBase *>>
552 > : std::true_type {};
553
554 template<typename Prototype, typename Functor>
555 inline constexpr bool AssertCompatibleFunctions() {
557 "Functor is not compatible with expected prototype!");
558 return true;
559 }
560}
561
563
\inmodule QtCore
Definition qatomic.h:112
bool ref() noexcept
bool deref() noexcept
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
Definition qmetaobject.h:18
\inmodule QtCore
Definition qobject.h:90
bool isImpl(ImplFn f) const
void call(QObject *r, void **a)
Combined button and popup list for selecting options.
\macro QT_NAMESPACE
void assertObjectType(QObjectPrivate *d)
Definition qobject_p.h:261
InvokeGenSeq< ConcatSeqImpl< N, S1, S2 > > ConcatSeq
typename T::Type InvokeGenSeq
constexpr std::enable_if_t<!std::disjunction_v< std::is_convertible< Prototype, const char * >, std::is_same< std::decay_t< Prototype >, QMetaMethod >, std::is_convertible< Functor, const char * >, std::is_same< std::decay_t< Functor >, QMetaMethod > >, int > countMatchingArguments()
constexpr bool AssertCompatibleFunctions()
InvokeGenSeq< GenSeq< N > > makeIndexSequence
std::conditional_t< FunctionPointer< std::decay_t< Func > >::ArgumentCount==-1, ZeroArgFunctor< std::decay_t< Func > >, FunctionPointer< std::decay_t< Func > > > Callable
static constexpr QtPrivate::QSlotObjectBase * makeCallableObject(Functor &&func)
typename std::conditional_t< std::conjunction_v< std::is_empty< Object >, std::negation< std::is_final< Object > > >, detail::StorageEmptyBaseClassOptimization< Object, Tag >, detail::StorageByValue< Object, Tag > > CompactStorage
void operator,(T &&value, const ApplyReturnValue< U > &container)
@ Ok
Definition qbezier.cpp:275
#define Q_FALLTHROUGH()
#define Q_DECL_HIDDEN
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
return ret
n varying highp vec2 A
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLfloat GLfloat f
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLhandleARB obj
[2]
GLenum func
Definition qopenglext.h:663
GLdouble GLdouble t
Definition qopenglext.h:243
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
SSL_CTX int(*) void arg)
#define Q_UNUSED(x)
static int compare(quint64 a, quint64 b)
const char className[16]
[1]
Definition qwizard.cpp:100
QJSValueList args
static int test(const std::remove_reference_t< A2 > &)
static auto test(F f) -> decltype(((f.operator()((std::declval< ArgList >())...)), int()))
static void call(Function f, Obj *o, void **arg)
static void call(Function f, Obj *o, void **arg)
static void call(Function f, Obj *o, void **arg)
static void call(Function f, void *, void **arg)
static void call(Function f, void *, void **arg)
decltype(std::declval< Functor >().operator()((std::declval< ArgList >())...)) Value
static void call(Function &f, void *, void **arg)
makeIndexSequence< N > Value
List_Append< List< typenameL::Car >, typenameList_Left< typenameL::Cdr, N-1 >::Value >::Value Value
decltype(std::declval< Func >()()) ReturnType
virtual HRESULT STDMETHODCALLTYPE Compare(__RPC__in_opt ITextRangeProvider *range, __RPC__out BOOL *pRetVal)=0