File indexing completed on 2026-09-17 09:25:04
0001
0002
0003
0004
0005 #ifndef QNATIVEINTERFACE_H
0006 #define QNATIVEINTERFACE_H
0007
0008 #include <QtCore/qglobal.h>
0009
0010 QT_BEGIN_NAMESPACE
0011
0012
0013
0014
0015
0016
0017 #define QT_DECLARE_NATIVE_INTERFACE_3(NativeInterface, Revision, BaseType) \
0018 protected: \
0019 virtual ~NativeInterface(); \
0020 \
0021 struct TypeInfo { \
0022 using baseType = BaseType; \
0023 static constexpr char const *name = QT_STRINGIFY(NativeInterface); \
0024 static constexpr int revision = Revision; \
0025 }; \
0026 \
0027 template <typename, typename> \
0028 friend struct QNativeInterface::Private::has_type_info; \
0029 \
0030 template <typename> \
0031 friend bool constexpr QNativeInterface::Private::hasTypeInfo(); \
0032 \
0033 template <typename> \
0034 friend struct QNativeInterface::Private::TypeInfo; \
0035 public: \
0036 NativeInterface() = default; \
0037 Q_DISABLE_COPY_MOVE(NativeInterface)
0038
0039
0040
0041
0042 #define QT_DECLARE_NATIVE_INTERFACE_2(NativeInterface, Revision) \
0043 static_assert(false, "Must provide a base type when specifying revision");
0044
0045 #define QT_DECLARE_NATIVE_INTERFACE_1(NativeInterface) \
0046 QT_DECLARE_NATIVE_INTERFACE_3(NativeInterface, 0, void)
0047
0048 #define QT_DECLARE_NATIVE_INTERFACE(...) \
0049 QT_OVERLOADED_MACRO(QT_DECLARE_NATIVE_INTERFACE, __VA_ARGS__)
0050
0051 namespace QNativeInterface::Private {
0052
0053
0054
0055 template <typename NativeInterface, typename = void>
0056 struct has_type_info : std::false_type {};
0057
0058
0059
0060 template <typename NativeInterface>
0061 struct has_type_info<NativeInterface, std::void_t<
0062 typename NativeInterface::TypeInfo,
0063 typename NativeInterface::TypeInfo::baseType,
0064 decltype(&NativeInterface::TypeInfo::name),
0065 decltype(&NativeInterface::TypeInfo::revision)
0066 >> : std::true_type {};
0067
0068
0069
0070
0071 template <typename NativeInterface>
0072 bool constexpr hasTypeInfo()
0073 {
0074 return has_type_info<NativeInterface>::value;
0075 }
0076
0077 template <typename NativeInterface>
0078 struct TypeInfo
0079 {
0080
0081
0082
0083 static constexpr bool haveTypeInfo = hasTypeInfo<NativeInterface>();
0084
0085
0086
0087 template <typename BaseType>
0088 static constexpr bool isCompatibleHelper()
0089 {
0090 if constexpr (haveTypeInfo)
0091 return std::is_base_of<typename NativeInterface::TypeInfo::baseType, BaseType>::value;
0092 else
0093 return false;
0094 }
0095
0096
0097
0098
0099 template <typename BaseType>
0100 static constexpr bool isCompatibleWith = isCompatibleHelper<BaseType>();
0101
0102
0103
0104
0105 static constexpr int revision()
0106 {
0107 if constexpr (haveTypeInfo)
0108 return NativeInterface::TypeInfo::revision;
0109 else
0110 return 0;
0111 }
0112
0113 static constexpr char const *name()
0114 {
0115 if constexpr (haveTypeInfo)
0116 return NativeInterface::TypeInfo::name;
0117 else
0118 return nullptr;
0119 }
0120 };
0121
0122
0123
0124 template <typename I>
0125 struct NativeInterface : TypeInfo<I> {};
0126 }
0127
0128
0129 #ifdef Q_QDOC
0130 #define QT_DECLARE_NATIVE_INTERFACE_ACCESSOR(T) \
0131 template <typename QNativeInterface> \
0132 QNativeInterface *nativeInterface() const;
0133 #else
0134 #define QT_DECLARE_NATIVE_INTERFACE_ACCESSOR(T) \
0135 template <typename NativeInterface, typename TypeInfo = QNativeInterface::Private::NativeInterface<NativeInterface>, \
0136 typename BaseType = T, std::enable_if_t<TypeInfo::template isCompatibleWith<T>, bool> = true> \
0137 NativeInterface *nativeInterface() const \
0138 { \
0139 return static_cast<NativeInterface*>(resolveInterface( \
0140 TypeInfo::name(), TypeInfo::revision())); \
0141 } \
0142 protected: \
0143 void *resolveInterface(const char *name, int revision) const; \
0144 public:
0145 #endif
0146
0147 QT_END_NAMESPACE
0148
0149 #endif