comparison d1/qt/QGlobal.d @ 311:8674fd5f34f4 lifetime

Added d1/d2 top directories
author maxter <spambox@d-coding.com>
date Wed, 23 Dec 2009 16:17:22 +0200
parents
children 80b52f5e97b6
comparison
equal deleted inserted replaced
310:5bcfe9e7db7f 311:8674fd5f34f4
1 module qt.QGlobal;
2
3 public import qt.qtd.Str;
4 public import qt.QDefines;
5
6 version (D_Version2)
7 {
8 import std.stdio;
9 package import std.c.stdlib,
10 core.memory;
11 }
12 else
13 {
14 import tango.io.Stdout;
15 import tango.core.Thread;
16
17 void writeln(string s)
18 {
19 Stdout(s).newline;
20 }
21 package import tango.stdc.stdlib,
22 tango.core.Memory;
23 }
24
25 private enum : size_t { stackSize = 1024 * 1024 }
26
27 final class StackAlloc
28 {
29 alias typeof(this) This;
30 private void* _data;
31
32 private static size_t align16(size_t size)
33 {
34 return size + 16 - (size - size & ~15);
35 }
36
37 this(size_t size)
38 {
39 _data = (new void[size]).ptr;
40 }
41
42 void* alloc(size_t size)
43 {
44 void* res = _data;
45 _data += align16(size);
46 return res;
47 }
48
49 void free(size_t size)
50 {
51 _data -= align16(size);
52 }
53 }
54
55 version (D_Version2)
56 {
57 StackAlloc __stackAlloc()
58 {
59 static StackAlloc instance; // thread-local instance
60 // COMPILER BUG: No thread-local static constructors, Using lazy construction
61 if (!instance)
62 instance = new StackAlloc(stackSize);
63 return instance;
64 }
65 }
66 else
67 {
68 private static ThreadLocal!(StackAlloc) stackAllocInst;
69
70 static this()
71 {
72 stackAllocInst = new ThreadLocal!(StackAlloc);
73 }
74
75 static StackAlloc __stackAlloc()
76 {
77 auto res = stackAllocInst.val;
78 if (!res)
79 {
80 res = new StackAlloc(stackSize);
81 stackAllocInst.val = res;
82 }
83 return res;
84 }
85 }
86
87 T static_cast(T, U)(U obj)
88 {
89 return cast(T)cast(void*)obj;
90 }
91
92 template QT_BEGIN_NAMESPACE() {
93 }
94
95 template QT_END_NAMESPACE() {
96 }
97
98 template QT_BEGIN_HEADER() {
99 }
100
101 template QT_END_HEADER() {
102 }
103
104 mixin QT_BEGIN_HEADER;
105 mixin QT_BEGIN_NAMESPACE;
106
107 extern(C) void qtd_dummy() {}
108 // Defined in QtdObject.d
109 extern(C) void qtd_delete_d_object(void* dPtr);
110
111 version(cpp_shared)
112 {
113 extern (C) void qtd_core_initCallBacks(void* toUtf8, void* dummy, void* del_d_obj);
114 static this() {
115 qtd_core_initCallBacks(&qtd_toUtf8, &qtd_dummy, &qtd_delete_d_object);
116 }
117 }
118
119 string tr(string arg) {
120 return arg;
121 }
122
123 /*
124 can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
125 */
126 bool QT_VERSION_CHECK( ushort major, ushort minor, ushort patch )
127 {
128 return cast(bool)((major<<16)|(minor<<8)|(patch));
129 }
130 //TODO(katrina) get this from the C++ side
131 const char[] QT_PACKAGEDATE_STR = "2008-09-27";
132 //TODO(katrina) get this from the C++ side
133 const char[] QT_PACKAGE_TAG = "gc9953de622c6a0f655322e0d9f5bd6dc2803b470";
134
135 /*
136 Size-dependent types (architechture-dependent byte order)
137
138 Make sure to update QMetaType when changing these typedefs
139 */
140
141 alias char qint8; /* 8 bit signed */
142 alias char quint8; /* 8 bit unsigned */
143 alias short qint16; /* 16 bit signed */
144 alias ushort quint16; /* 16 bit unsigned */
145 alias int qint32; /* 32 bit signed */
146 alias uint quint32; /* 32 bit unsigned */
147 alias long qint64; /* 64 bit signed */
148 alias ulong quint64; /* 64 bit unsigned */
149
150 version (X86)
151 {
152 alias quint32 quintptr;
153 alias qint32 qptrdiff;
154 }
155 else version (X86_64)
156 {
157 alias quint64 quintptr;
158 alias qint64 qptrdiff;
159 }
160
161 const byte QT_POINTER_SIZE = 8;
162
163 alias int QNoImplicitBoolCast;
164
165 alias double qreal;
166
167
168 /*
169 Utility macros and inline functions
170 TODO(katrina) see if we need to do anything to make these
171 able to be evaluated at compile time
172 */
173
174 T qAbs(T)(T t) { return t >= 0 ? t : -t; }
175
176 int qRound(qreal d)
177 { return d >= 0.0 ? cast(int)(d + 0.5) : cast(int)(d - cast(int)(d-1) + 0.5) + cast(int)(d-1); }
178
179 qint64 qRound64(qreal d)
180 { return d >= 0.0 ? cast(qint64)(d + 0.5) : cast(qint64)(d - cast(qint64)(d-1) + 0.5) + cast(qint64)(d-1); }
181
182 T qMin(T)(T a,T b) { if (a < b) return a; return b; }
183 T qMax(T)(T a, T b) { if (a < b) return b; return a; }
184 T qBound(T)(T min, T val,T max) { return qMax(min, qMin(max, val)); }
185
186 /*
187 Data stream functions are provided by many classes (defined in qdatastream.h)
188 */
189
190 //class QDataStream;
191
192 /*
193 System information
194 */
195
196 class QSysInfo {
197 public:
198 enum Sizes {
199 WordSize = ((void *).sizeof<<3)
200 };
201
202 enum Endian {
203 BigEndian,
204 LittleEndian,
205 ByteOrder = BigEndian
206 };
207 /* needed to bootstrap qmake */
208 static const int ByteOrder;
209
210 enum WinVersion {
211 WV_32s = 0x0001,
212 WV_95 = 0x0002,
213 WV_98 = 0x0003,
214 WV_Me = 0x0004,
215 WV_DOS_based= 0x000f,
216
217 WV_NT = 0x0010,
218 WV_2000 = 0x0020,
219 WV_XP = 0x0030,
220 WV_2003 = 0x0040,
221 WV_VISTA = 0x0080,
222 WV_NT_based = 0x00f0,
223
224 WV_CE = 0x0100,
225 WV_CENET = 0x0200,
226 WV_CE_5 = 0x0300,
227 WV_CE_6 = 0x0400,
228 WV_CE_based = 0x0f00
229 };
230 static const WinVersion WindowsVersion;
231 static WinVersion windowsVersion();
232
233 enum MacVersion {
234 MV_Unknown = 0x0000,
235
236 /* version */
237 MV_9 = 0x0001,
238 MV_10_0 = 0x0002,
239 MV_10_1 = 0x0003,
240 MV_10_2 = 0x0004,
241 MV_10_3 = 0x0005,
242 MV_10_4 = 0x0006,
243 MV_10_5 = 0x0007,
244
245 /* codenames */
246 MV_CHEETAH = MV_10_0,
247 MV_PUMA = MV_10_1,
248 MV_JAGUAR = MV_10_2,
249 MV_PANTHER = MV_10_3,
250 MV_TIGER = MV_10_4,
251 MV_LEOPARD = MV_10_5
252 };
253 static const MacVersion MacintoshVersion;
254 };
255
256
257 extern(C) stringz qtd_qVersion();
258 ///
259 string qVersion()
260 {
261 return fromStringz(qtd_qVersion);
262 }
263
264 extern(C) bool qtd_qSharedBuild();
265 ///
266 bool qSharedBuild()
267 {
268 return qtd_qSharedBuild;
269 }
270
271 ///
272 int qMacVersion() { return QSysInfo.MacintoshVersion; }
273
274 ///
275 void qUnused(T)(T x) { cast(void) x; }
276 ///
277 void Q_UNUSED(T)(T x) { qUnused(x); }
278
279 /*
280 Debugging and error handling
281 */
282
283 //class QString;
284 //char[] qPrintable(QString string) { string.toLocal8Bit().constData(); }
285 //TODO(katrina) These should probably actually call into the c++ functions
286 void qDebug(string str) /* print debug message */
287 { writeln(str); }
288
289 extern (C) void Qt_qWarning( char * );
290
291 void qWarning(char[] str) /* print warning message */
292 { writeln(str); }
293
294 //QString qt_error_string(int errorCode = -1);
295 void qCritical(char[] str) /* print critical message */
296 { writeln(str); }
297
298 /*
299 Forward declarations only.
300
301 In order to use the qDebug() stream, you must #include<QDebug>
302 */
303 //class QDebug;
304 //class QNoDebug;
305 //QDebug qDebug();
306 //QDebug qWarning();
307 //QDebug qCritical();
308
309 void qt_noop() {}
310 //TODO(katrina) Implement these
311 void qt_assert(char[] assertion, char[] file, int line);
312
313 void qt_assert_x(char[] where, char[] what, char[] file, int line);
314
315 void qt_check_pointer(char[], int);
316
317 enum QtMsgType { QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, QtSystemMsg = QtCriticalMsg };
318
319 void qt_message_output(QtMsgType, char[] buf);
320 //class QtMsgHandler;
321 //QtMsgHandler qInstallMsgHandler(QtMsgHandler);
322
323 // forward declaration, since qatomic.h needs qglobal.h
324 class QBasicAtomicPointer(T);
325
326 // POD for Q_GLOBAL_STATIC
327 class QGlobalStatic(T)
328 {
329 public:
330 QBasicAtomicPointer!(T) pointer;
331 bool destroyed;
332 };
333
334 // Created as a function-local static to delete a QGlobalStatic<T>
335 class QGlobalStaticDeleter(T)
336 {
337 public:
338 QGlobalStatic!(T) globalStatic;
339 this(QGlobalStatic!(T) _globalStatic) {
340 globalStatic(_globalStatic);
341 }
342
343 ~this()
344 {
345 delete globalStatic.pointer;
346 globalStatic.pointer = 0;
347 globalStatic.destroyed = true;
348 }
349 };
350
351 class QBool
352 {
353 bool b;
354
355 public:
356 this(bool B) { b = B; }
357 // void *() const
358 // { return b ? static_cast<const void *>(this) : static_cast<const void *>(0); }
359 }
360
361 bool qFuzzyCompare(double p1, double p2)
362 {
363 return (qAbs(p1 - p2) <= 0.000000000001 * qMin(qAbs(p1), qAbs(p2)));
364 }
365
366 bool qFuzzyCompare(float p1, float p2)
367 {
368 return (qAbs(p1 - p2) <= 0.00001f * qMin(qAbs(p1), qAbs(p2)));
369 }
370
371 /*
372 This function tests a double for a null value. It doesn't
373 check whether the actual value is 0 or close to 0, but whether
374 it is binary 0.
375 */
376 bool qIsNull(double d)
377 {
378 union U {
379 double d;
380 quint64 u;
381 };
382 U val;
383 val.d = d;
384 return val.u == cast(quint64)(0);
385 }
386
387 /*
388 This function tests a float for a null value. It doesn't
389 check whether the actual value is 0 or close to 0, but whether
390 it is binary 0.
391 */
392 bool qIsNull(float f)
393 {
394 union U {
395 float f;
396 quint32 u;
397 };
398 U val;
399 val.f = f;
400 return val.u == 0u;
401 }
402
403 /*
404 Compilers which follow outdated template instantiation rules
405 require a class to have a comparison operator to exist when
406 a QList of this type is instantiated. It's not actually
407 used in the list, though. Hence the dummy implementation.
408 Just in case other code relies on it we better trigger a warning
409 mandating a real implementation.
410 */
411
412
413 /*
414 QTypeInfo - type trait functionality
415 qIsDetached - data sharing functionality
416 */
417
418 /*
419 The catch-all template.
420 */
421
422 bool qIsDetached(T)(T) { return true; }
423
424 class QTypeInfossss(T)
425 {
426 public:
427 enum {
428 isPointer = false,
429 isComplex = true,
430 isStatic = true,
431 isLarge = ((T).sizeof>(void*).sizeof),
432 isDummy = false
433 };
434 };
435
436 class QTypeInfo(T)
437 {
438 public:
439 enum {
440 isPointer = true,
441 isComplex = false,
442 isStatic = false,
443 isLarge = false,
444 isDummy = false
445 };
446 };
447
448
449 /*
450 Specialize a specific type with:
451
452 Q_DECLARE_TYPEINFO(type, flags);
453
454 where 'type' is the name of the type to specialize and 'flags' is
455 logically-OR'ed combination of the flags below.
456 */
457 enum { /* TYPEINFO flags */
458 Q_COMPLEX_TYPE = 0,
459 Q_PRIMITIVE_TYPE = 0x1,
460 Q_STATIC_TYPE = 0,
461 Q_MOVABLE_TYPE = 0x2,
462 Q_DUMMY_TYPE = 0x4
463 };
464
465 /*
466 Specialize a shared type with:
467
468 Q_DECLARE_SHARED(type);
469
470 where 'type' is the name of the type to specialize. NOTE: shared
471 types must declare a 'bool isDetached(void) const;' member for this
472 to work.
473 */
474 void qSwap_helper(T)(ref T value1, ref T value2, T*)
475 {
476 T t = value1;
477 value1 = value2;
478 value2 = t;
479 }
480 bool qIsDetached(T)(ref T t) { return t.isDetached(); }
481 void qSwap_helper(T)(ref T value1, ref T value2, T*)
482 {
483 const T.DataPtr t = value1.data_ptr();
484 value1.data_ptr() = value2.data_ptr();
485 value2.data_ptr() = t;
486 }
487
488 void qSwap(T)(ref T value1, ref T value2)
489 {
490 T t = value1;
491 value1 = value2;
492 value2 = t;
493 }
494
495 /*
496 QTypeInfo primitive specializations
497 TODO(katrina) Find out what we need to do here
498 */
499 /*
500 Q_DECLARE_TYPEINFO(bool, Q_PRIMITIVE_TYPE);
501 Q_DECLARE_TYPEINFO(char, Q_PRIMITIVE_TYPE);
502 Q_DECLARE_TYPEINFO(signed char, Q_PRIMITIVE_TYPE);
503 Q_DECLARE_TYPEINFO(uchar, Q_PRIMITIVE_TYPE);
504 Q_DECLARE_TYPEINFO(short, Q_PRIMITIVE_TYPE);
505 Q_DECLARE_TYPEINFO(ushort, Q_PRIMITIVE_TYPE);
506 Q_DECLARE_TYPEINFO(int, Q_PRIMITIVE_TYPE);
507 Q_DECLARE_TYPEINFO(uint, Q_PRIMITIVE_TYPE);
508 Q_DECLARE_TYPEINFO(long, Q_PRIMITIVE_TYPE);
509 Q_DECLARE_TYPEINFO(ulong, Q_PRIMITIVE_TYPE);
510 Q_DECLARE_TYPEINFO(qint64, Q_PRIMITIVE_TYPE);
511 Q_DECLARE_TYPEINFO(quint64, Q_PRIMITIVE_TYPE);
512 Q_DECLARE_TYPEINFO(float, Q_PRIMITIVE_TYPE);
513 Q_DECLARE_TYPEINFO(double, Q_PRIMITIVE_TYPE);
514 #ifndef Q_OS_DARWIN
515 Q_DECLARE_TYPEINFO(long double, Q_PRIMITIVE_TYPE);
516 #endif
517 */
518 /*
519 These functions make it possible to use standard C++ functions with
520 a similar name from Qt header files (especially template classes).
521 TODO(katrina) Implement these
522 */
523 void * qMalloc(size_t size);
524 void qFree(void * ptr);
525 void * qRealloc(void * ptr, size_t size);
526 void * qMemCopy(void * dest, void * src, size_t n);
527 void * qMemSet(void * dest, int c, size_t n);
528
529 struct QFlags(Enum)
530 {
531 private:
532 alias void **Zero;
533 int i;
534
535 public:
536 alias Enum enum_type;
537
538 public static QFlags!(Enum) opCall(Enum)(QFlags f) {
539 QFlags!(Enum) res;
540 res.i = f.i;
541 return res;
542 }
543
544 public static QFlags opCall(Enum)(Enum f) {
545 QFlags!(Enum) res;
546 res.i = f;
547 return res;
548 }
549
550 public static QFlags opCall(Enum)(int f) {
551 QFlags!(Enum) res;
552 res.i = cast(Enum) f;
553 return res;
554 }
555
556 // this(Zero = 0) : i(0) {}
557 // this(QFlag f) : i(f) {}
558
559 // QFlags!(Enum) opAssign(QFlags f) { i = f.i; return *this; }
560 QFlags!(Enum) opAssign(int f) { i = f; return *this; }
561 QFlags!(Enum) opAndAssign(int mask) { i &= mask; return *this; }
562 QFlags!(Enum) opAndAssign(uint mask) { i &= mask; return *this; }
563 QFlags!(Enum) opOrAssign(QFlags f) { i |= f.i; return *this; }
564 QFlags!(Enum) opOrAssign(Enum f) { i |= f; return *this; }
565 QFlags!(Enum) opXorAssign(QFlags f) { i ^= f.i; return *this; }
566 QFlags!(Enum) opXorAssign(Enum f) { i ^= f; return *this; }
567
568 int toInt() { return i; }
569
570 QFlags!(Enum) opOr(QFlags f) { QFlags g; g.i = i | f.i; return g; }
571 QFlags!(Enum) opOr(Enum f) { QFlags g; g.i = i | f; return g; }
572 QFlags!(Enum) opXor(QFlags f) { QFlags g; g.i = i ^ f.i; return g; }
573 QFlags!(Enum) opXor(Enum f) { QFlags g; g.i = i ^ f; return g; }
574 QFlags!(Enum) opAnd(int mask) { QFlags g; g.i = i & mask; return g; }
575 QFlags!(Enum) opAnd(uint mask) { QFlags g; g.i = i & mask; return g; }
576 QFlags!(Enum) opAnd(Enum f) { QFlags g; g.i = i & f; return g; }
577 QFlags!(Enum) opCom() { QFlags g; g.i = ~i; return g; }
578
579 // bool operator!() { return !i; }
580
581 // bool testFlag(Enum f) { return i & f; }
582 }
583
584 /* TODO typesafety
585 #define Q_DECLARE_FLAGS(Flags, Enum)\
586 typedef QFlags<Enum> Flags;
587 #define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags) \
588 QFlags<Flags::enum_type> operator|(Flags::enum_type f1, Flags::enum_type f2) \
589 { return QFlags<Flags::enum_type>(f1) | f2; } \
590 QFlags<Flags::enum_type> operator|(Flags::enum_type f1, QFlags<Flags::enum_type> f2) \
591 { return f2 | f1; }
592 */
593
594 char[] QT_TR_NOOP(char[] x) { return x; }
595 char[] QT_TRANSLATE_NOOP(char[] s, char[] x) { return x; }
596 char[] QT_TRANSLATE_NOOP3(char[] s, char[] x, char[] comment) { return x; }
597
598 //class QByteArray;
599 //QByteArray qgetenv(char[] varName);
600 //bool qputenv(char[] varName, QByteArray value);
601
602 int qIntCast(double f) { return cast(int)(f); }
603 int qIntCast(float f) { return cast(int)(f); }
604
605 /*
606 Reentrant versions of basic rand() functions for random number generation
607 */
608 void qsrand(uint seed);
609 int qrand();
610
611
612 /*
613 This gives us the possibility to check which modules the user can
614 use. These are purely compile time checks and will generate no code.
615 */
616
617 /* Qt modules */
618
619 const ushort QT_MODULE_CORE = 0x0001;
620 const ushort QT_MODULE_GUI = 0x0002;
621 const ushort QT_MODULE_NETWORK = 0x0004;
622 const ushort QT_MODULE_OPENGL = 0x0008;
623 const ushort QT_MODULE_SQL = 0x0010;
624 const ushort QT_MODULE_XML = 0x0020;
625 const ushort QT_MODULE_QT3SUPPORTLIGHT = 0x0040;
626 const ushort QT_MODULE_QT3SUPPORT = 0x0080;
627 const ushort QT_MODULE_SVG = 0x0100;
628 const ushort QT_MODULE_ACTIVEQT = 0x0200;
629 const ushort QT_MODULE_GRAPHICSVIEW = 0x0400;
630 const ushort QT_MODULE_SCRIPT = 0x0800;
631 const ushort QT_MODULE_XMLPATTERNS = 0x1000;
632 const ushort QT_MODULE_HELP = 0x2000;
633 const ushort QT_MODULE_TEST = 0x4000;
634 const ushort QT_MODULE_DBUS = 0x8000;
635
636 /* Qt editions */
637
638 const ushort QT_EDITION_CONSOLE = (QT_MODULE_CORE
639 | QT_MODULE_NETWORK
640 | QT_MODULE_SQL
641 | QT_MODULE_SCRIPT
642 | QT_MODULE_XML
643 | QT_MODULE_XMLPATTERNS
644 | QT_MODULE_TEST
645 | QT_MODULE_DBUS);
646 const ushort QT_EDITION_DESKTOPLIGHT = (QT_MODULE_CORE
647 | QT_MODULE_GUI
648 | QT_MODULE_QT3SUPPORTLIGHT
649 | QT_MODULE_TEST
650 | QT_MODULE_DBUS);
651 const ushort QT_EDITION_OPENSOURCE = (QT_MODULE_CORE
652 | QT_MODULE_GUI
653 | QT_MODULE_NETWORK
654 | QT_MODULE_OPENGL
655 | QT_MODULE_SQL
656 | QT_MODULE_XML
657 | QT_MODULE_XMLPATTERNS
658 | QT_MODULE_SCRIPT
659 | QT_MODULE_QT3SUPPORTLIGHT
660 | QT_MODULE_QT3SUPPORT
661 | QT_MODULE_SVG
662 | QT_MODULE_GRAPHICSVIEW
663 | QT_MODULE_HELP
664 | QT_MODULE_TEST
665 | QT_MODULE_DBUS);
666 const ushort QT_EDITION_DESKTOP = (QT_EDITION_OPENSOURCE
667 | QT_MODULE_ACTIVEQT);
668 const ushort QT_EDITION_UNIVERSAL = QT_EDITION_DESKTOP;
669 const ushort QT_EDITION_ACADEMIC = QT_EDITION_DESKTOP;
670 const ushort QT_EDITION_EDUCATIONAL = QT_EDITION_DESKTOP;
671 const ushort QT_EDITION_EVALUATION = QT_EDITION_DESKTOP;
672
673 mixin QT_END_NAMESPACE;
674
675 private
676 struct Align
677 {
678 ubyte a;
679 void* b;
680 }
681
682 private
683 const PTR_ALIGN = Align.tupleof[1].alignof;
684
685 private
686 template AlignPad(size_t base, size_t aligned)
687 {
688 static if( aligned == 0 )
689 const AlignPad = base;
690 else
691 const AlignPad = ((base+PTR_ALIGN-1)/PTR_ALIGN)*PTR_ALIGN
692 + aligned;
693 }
694
695 template InstanceSize(T)
696 {
697 static if( is( T == Object ) )
698 const InstanceSize = 2*(void*).sizeof;
699 else
700 const InstanceSize = Max!(
701 AlignPad!(
702 InstanceSize!(Super!(T)),
703 InterfaceCount!(T)*(void*).sizeof),
704
705 AlignPad!(
706 InstanceSizeImpl!(T, 0),
707 + InterfaceCount!(T)*(void*).sizeof));
708 }
709
710 private
711 template Super(T)
712 {
713 static if( is( T S == super ) )
714 alias First!(S) Super;
715 else
716 static assert(false, "Can't get super of "~T.mangleof);
717 }
718
719 private
720 template First(T)
721 {
722 alias T First;
723 }
724
725 private
726 template First(T, Ts...)
727 {
728 alias T First;
729 }
730
731 private
732 template InstanceSizeImpl(T, size_t i)
733 {
734 static if( i < T.tupleof.length )
735 const InstanceSizeImpl = Max!(
736 T.tupleof[i].offsetof + T.tupleof[i].sizeof,
737 InstanceSizeImpl!(T, i+1));
738 else
739 // This is necessary to account for classes without member
740 // variables.
741 const InstanceSizeImpl = 2*(void*).sizeof;
742 }
743
744 private
745 template Max(size_t a, size_t b)
746 {
747 static if( a > b )
748 const Max = a;
749 else
750 const Max = b;
751 }
752
753 private
754 template InterfaceCount(T)
755 {
756 static if( is( T == Object ) )
757 const InterfaceCount = 0u;
758 else static if( is( T S == super ) )
759 const InterfaceCount = InterfaceCountImpl!(S);
760 }
761
762 private
763 template InterfaceCountImpl(TBase, TInterfaces...)
764 {
765 const InterfaceCountImpl = TInterfaces.length;
766 }
767
768 /+
769 scope class StackObject(C)
770 {
771 byte[InstanceSize!(C)] data;
772 bool constructed;
773
774 C opCall(A...)(A args)
775 {
776 assert(!constructed);
777
778 auto r = new(&data)C(args);
779 r.__stackAllocated = true;
780 constructed = true;
781
782 return r;
783 }
784
785 ~this()
786 {
787 if (constructed)
788 {
789 auto obj = cast(C)&data;
790 delete obj;
791 }
792 }
793 }
794 +/
795
796 mixin QT_END_HEADER;
797