summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qobjectdefs_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qobjectdefs_impl.h')
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index 5eae70ecc5..e94e713e1f 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -50,6 +50,8 @@
#pragma qt_sync_stop_processing
#endif
+#include <type_traits>
+
QT_BEGIN_NAMESPACE
@@ -194,6 +196,46 @@ namespace QtPrivate {
};
/*
+ Logic that checks if the underlying type of an enum is signed or not.
+ Needs an external, explicit check that E is indeed an enum. Works
+ around the fact that it's undefined behavior to instantiate
+ std::underlying_type on non-enums (cf. §20.13.7.6 [meta.trans.other]).
+ */
+ template<typename E, typename Enable = void>
+ struct IsEnumUnderlyingTypeSigned : std::false_type
+ {
+ };
+
+ template<typename E>
+ struct IsEnumUnderlyingTypeSigned<E, typename std::enable_if<std::is_enum<E>::value>::type>
+ : std::integral_constant<bool, std::is_signed<typename std::underlying_type<E>::type>::value>
+ {
+ };
+
+ /*
+ Logic that checks if the argument of the slot does not narrow the
+ argument of the signal when used in list initialization. Cf. §8.5.4.7
+ [dcl.init.list] for the definition of narrowing.
+ For incomplete From/To types, there's no narrowing.
+ */
+ template<typename From, typename To, typename Enable = void>
+ struct AreArgumentsNarrowedBase : std::false_type
+ {
+ };
+
+ template<typename From, typename To>
+ struct AreArgumentsNarrowedBase<From, To, typename std::enable_if<sizeof(From) && sizeof(To)>::type>
+ : std::integral_constant<bool,
+ (std::is_floating_point<From>::value && std::is_integral<To>::value) ||
+ (std::is_floating_point<From>::value && std::is_floating_point<To>::value && sizeof(From) > sizeof(To)) ||
+ ((std::is_integral<From>::value || std::is_enum<From>::value) && std::is_floating_point<To>::value) ||
+ (std::is_integral<From>::value && std::is_integral<To>::value && (sizeof(From) > sizeof(To) || std::is_signed<From>::value != std::is_signed<To>::value)) ||
+ (std::is_enum<From>::value && std::is_integral<To>::value && (sizeof(From) > sizeof(To) || IsEnumUnderlyingTypeSigned<From>::value != std::is_signed<To>::value))
+ >
+ {
+ };
+
+ /*
Logic that check if the arguments of the slot matches the argument of the signal.
To be used like this:
Q_STATIC_ASSERT(CheckCompatibleArguments<FunctionPointer<Signal>::Arguments, FunctionPointer<Slot>::Arguments>::value)
@@ -203,6 +245,10 @@ namespace QtPrivate {
static char test(...);
static const typename RemoveRef<A1>::Type &dummy();
enum { value = sizeof(test(dummy())) == sizeof(int) };
+#ifdef QT_NO_NARROWING_CONVERSIONS_IN_CONNECT
+ struct AreArgumentsNarrowed : AreArgumentsNarrowedBase<typename RemoveRef<A1>::Type, typename RemoveRef<A2>::Type> {};
+ Q_STATIC_ASSERT_X(!AreArgumentsNarrowed::value, "Signal and slot arguments are not compatible (narrowing)");
+#endif
};
template<typename A1, typename A2> struct AreArgumentsCompatible<A1, A2&> { enum { value = false }; };
template<typename A> struct AreArgumentsCompatible<A&, A&> { enum { value = true }; };