1 /* 2 * DQt - D bindings for the Qt Toolkit 3 * 4 * GNU Lesser General Public License Usage 5 * This file may be used under the terms of the GNU Lesser 6 * General Public License version 3 as published by the Free Software 7 * Foundation and appearing in the file LICENSE.LGPL3 included in the 8 * packaging of this file. Please review the following information to 9 * ensure the GNU Lesser General Public License version 3 requirements 10 * will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 11 */ 12 module qt.core.typeinfo; 13 14 import std.algorithm; 15 import std.traits; 16 import std.meta; 17 18 enum QTypeInfoFlags { 19 Q_COMPLEX_TYPE = 0, 20 Q_PRIMITIVE_TYPE = 0x1, 21 Q_STATIC_TYPE = 0, 22 Q_MOVABLE_TYPE = 0x2, // ### Qt6: merge movable and relocatable once QList no longer depends on it 23 Q_DUMMY_TYPE = 0x4, 24 Q_RELOCATABLE_TYPE = 0x8 25 }; 26 /*static foreach(name; __traits(allMembers, QTypeInfoFlags)) 27 { 28 mixin("enum " + name + " = QTypeInfoFlags." + name + ";"); 29 }*/ 30 enum Q_MOVABLE_TYPE = QTypeInfoFlags.Q_MOVABLE_TYPE; 31 enum Q_PRIMITIVE_TYPE = QTypeInfoFlags.Q_PRIMITIVE_TYPE; 32 enum Q_RELOCATABLE_TYPE = QTypeInfoFlags.Q_RELOCATABLE_TYPE; 33 34 template is_integral(T) 35 { 36 enum is_integral = isIntegral!T || isBoolean!T || isSomeChar!T; 37 } 38 39 template qIsTrivial(T) 40 { 41 enum qIsTrivial = is(T==enum) || is_integral!T; 42 } 43 44 template qIsRelocatable(T) 45 { 46 enum qIsRelocatable = is(T==enum) || is_integral!T; 47 } 48 49 template QTypeInfo(T) 50 { 51 static if(is(T == R*, R) || is(T == class)) 52 { 53 enum isRelocatable = true; 54 enum isComplex = false; 55 } 56 else static if(is(T == int) || is(T == uint) || is(T == double)) 57 { 58 enum isRelocatable = true; 59 enum isComplex = false; 60 } 61 else static if(is(T == void)) 62 { 63 enum isRelocatable = false; 64 enum isComplex = false; 65 } 66 else static if(is(T == enum)) 67 { 68 enum isRelocatable = true; 69 enum isComplex = false; 70 } 71 else static if(fullyQualifiedName!T.startsWith("qt.core.pair.pair!")) 72 { 73 enum isRelocatable = QTypeInfo!(T.first_type).isRelocatable && QTypeInfo!(T.second_type).isRelocatable; 74 enum isComplex = QTypeInfo!(T.first_type).isComplex || QTypeInfo!(T.second_type).isComplex; 75 } 76 else static if(fullyQualifiedName!T.startsWith("qt.core.list.QList!") || fullyQualifiedName!T.startsWith("qt.core.vector.QVector!")) 77 { 78 enum isRelocatable = true; 79 enum isComplex = true; 80 } 81 else static if(fullyQualifiedName!T.startsWith("qt.core.flags.QFlags!")) 82 { 83 enum isRelocatable = true; 84 enum isComplex = false; 85 } 86 else static if(qIsTrivial!T) 87 { 88 enum isRelocatable = qIsRelocatable!T; 89 enum isComplex = !qIsTrivial!T; 90 } 91 else static if(getUDAs!(T, QTypeInfoFlags).length) 92 { 93 enum combinedFlags = (){ 94 QTypeInfoFlags r; 95 foreach(flag; getUDAs!(T, QTypeInfoFlags)) 96 { 97 r |= flag; 98 } 99 return r; 100 }(); 101 enum isComplex = (combinedFlags & Q_PRIMITIVE_TYPE) == 0 && !qIsTrivial!T; 102 enum isRelocatable = !isComplex || ((combinedFlags) & Q_RELOCATABLE_TYPE) || qIsRelocatable!T; 103 } 104 else 105 { 106 enum isRelocatable = qIsRelocatable!T; 107 enum isComplex = !qIsTrivial!T; 108 } 109 enum isLarge = T.sizeof > (void*).sizeof; 110 enum isIntegral = is_integral!T; 111 enum isPointer = is(T == X*, X); 112 113 //pragma(msg, T.stringof, " ", isRelocatable, isComplex, isLarge); 114 } 115 alias QTypeInfoQuery = QTypeInfo;