OSDN Git Service

race conditions fix for global statics created via Q_GLOBAL_STATIC() and Q_GLOBAL_STA...
[kde/Katie.git] / src / core / global / qglobal.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Copyright (C) 2016 Ivailo Monev
5 **
6 ** This file is part of the QtCore module of the Katie Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 **
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser
12 ** General Public License version 2.1 as published by the Free Software
13 ** Foundation and appearing in the file LICENSE.LGPL included in the
14 ** packaging of this file.  Please review the following information to
15 ** ensure the GNU Lesser General Public License version 2.1 requirements
16 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** $QT_END_LICENSE$
19 **
20 ****************************************************************************/
21
22 #ifndef QGLOBAL_H
23 #define QGLOBAL_H
24
25 #include <qconfig.h>
26 #include <stddef.h>
27
28 /*
29    can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
30 */
31 #define QT_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
32
33 // Compatibility, used to be conditional
34 #define Q_WS_X11
35 #define Q_OS_UNIX
36
37 #include <utility> // std::swap
38 #include <cstdint> // std::uintptr_t
39
40 #if !defined(QT_NO_USING_NAMESPACE)
41
42 # define QT_NAMESPACE Katie
43 # define QT_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
44 # define QT_USE_NAMESPACE using namespace ::QT_NAMESPACE;
45
46 # define QT_BEGIN_NAMESPACE namespace QT_NAMESPACE {
47 # define QT_END_NAMESPACE }
48 # define QT_BEGIN_INCLUDE_NAMESPACE }
49 # define QT_END_INCLUDE_NAMESPACE namespace QT_NAMESPACE {
50
51 namespace QT_NAMESPACE {}
52
53 # ifdef QT_NAMESPACE_COMPAT
54 QT_USE_NAMESPACE
55 # endif
56
57 #else /* QT_NO_USING_NAMESPACE */
58
59 # define QT_NAMESPACE
60 # define QT_PREPEND_NAMESPACE(name) ::name
61 # define QT_USE_NAMESPACE
62
63 # define QT_BEGIN_NAMESPACE
64 # define QT_END_NAMESPACE
65 # define QT_BEGIN_INCLUDE_NAMESPACE
66 # define QT_END_INCLUDE_NAMESPACE
67
68 #endif /* QT_NO_USING_NAMESPACE */
69
70 #define QT_BEGIN_INCLUDE_HEADER
71 #define QT_END_INCLUDE_HEADER extern "C++"
72
73 /*
74    The compiler, must be one of: (Q_CC_x)
75
76      GNU      - GNU C++
77      CLANG    - C++ front-end for the LLVM compiler
78
79    Should be sorted most to least authoritative.
80
81    Paper             Macro                             SD-6 macro
82    N2672             Q_COMPILER_INITIALIZER_LISTS
83    N2118 N2844 N3053 Q_COMPILER_RVALUE_REFS            __cpp_rvalue_references = 200610
84
85   For any future version of the C++ standard, we use only the SD-6 macro.
86   For full listing, see
87    http://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
88 */
89 #if defined(__GNUC__)
90 #  define Q_CC_GNU
91 #  if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
92      /* C++0x features supported in GCC 4.3: */
93 #    define Q_COMPILER_RVALUE_REFS
94      /* C++0x features supported in GCC 4.4: */
95 #    define Q_COMPILER_INITIALIZER_LISTS
96      /* C++0x features supported in GCC 4.6: */
97 #    ifdef __EXCEPTIONS
98 #      define Q_COMPILER_EXCEPTIONS
99 #    endif
100 #  endif
101
102 #elif defined(__clang__)
103 #  define Q_CC_CLANG
104 #  if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
105     /* Detect C++ features using __has_feature(), see http://clang.llvm.org/docs/LanguageExtensions.html#cxx11 */
106 #    if __has_feature(cxx_generalized_initializers)
107 #      define Q_COMPILER_INITIALIZER_LISTS
108 #    endif
109 #    if __has_feature(cxx_rvalue_references)
110 #      define Q_COMPILER_RVALUE_REFS
111 #    endif
112 #    if __has_feature(cxx_exceptions)
113 #      define Q_COMPILER_EXCEPTIONS
114 #    endif
115 #  endif
116
117 #else
118 #  error "Katie has not been tested with this compiler"
119 #endif
120
121 #define Q_C_CALLBACKS
122 #define Q_ALIGNOF(type)   __alignof__(type)
123 #define Q_TYPEOF(expr)    __typeof__(expr)
124 #define Q_DECL_ALIGN(n)   __attribute__((__aligned__(n)))
125 #define Q_REQUIRED_RESULT __attribute__((warn_unused_result))
126 #define Q_LIKELY(expr)    __builtin_expect(!!(expr), true)
127 #define Q_UNLIKELY(expr)  __builtin_expect(!!(expr), false)
128 #define Q_FUNC_INFO       __PRETTY_FUNCTION__
129 #define Q_PACKED          __attribute__((__packed__))
130 #define Q_OUTOFLINE_TEMPLATE
131 #define Q_INLINE_TEMPLATE inline
132
133 #define Q_CONSTRUCTOR_FUNCTION(AFUNC) \
134     static const int __init_variable__ ## AFUNC = AFUNC();
135
136 #define Q_DESTRUCTOR_FUNCTION0(AFUNC) \
137     class AFUNC ## __dest_class__ { \
138     public: \
139        inline AFUNC ## __dest_class__() { } \
140        inline ~ AFUNC ## __dest_class__() { AFUNC(); } \
141     } AFUNC ## __dest_instance__;
142 #define Q_DESTRUCTOR_FUNCTION(AFUNC) Q_DESTRUCTOR_FUNCTION0(AFUNC)
143
144 QT_BEGIN_NAMESPACE
145
146 /*
147    Size-dependent types (architechture-dependent byte order)
148
149    Make sure to update QMetaType when changing these typedefs
150 */
151 typedef signed char qint8;         /* 8 bit signed */
152 typedef unsigned char quint8;      /* 8 bit unsigned */
153 typedef short qint16;              /* 16 bit signed */
154 typedef unsigned short quint16;    /* 16 bit unsigned */
155 typedef int qint32;                /* 32 bit signed */
156 typedef unsigned int quint32;      /* 32 bit unsigned */
157 #define Q_INT64_C(c) static_cast<long long>(c ## LL)     /* signed 64 bit constant */
158 #define Q_UINT64_C(c) static_cast<unsigned long long>(c ## ULL) /* unsigned 64 bit constant */
159 typedef long long qint64;           /* 64 bit signed */
160 typedef unsigned long long quint64; /* 64 bit unsigned */
161
162 typedef qint64 qlonglong;
163 typedef quint64 qulonglong;
164
165 #define Q_INIT_RESOURCE(name) \
166     extern int qInitResources_ ## name (); \
167     qInitResources_ ## name ();
168 #define Q_CLEANUP_RESOURCE(name) \
169     extern int qCleanupResources_ ## name (); \
170     qCleanupResources_ ## name ();
171
172 /*
173    Useful type definitions for Qt
174 */
175 typedef std::uintptr_t quintptr;
176 typedef std::ptrdiff_t qptrdiff;
177
178 QT_BEGIN_INCLUDE_NAMESPACE
179 typedef unsigned char uchar;
180 typedef unsigned short ushort;
181 typedef unsigned int uint;
182 typedef unsigned long ulong;
183 QT_END_INCLUDE_NAMESPACE
184
185 /*
186    Warnings and errors when using deprecated methods
187 */
188 #if defined(Q_MOC_RUN)
189 #  define Q_DECL_DEPRECATED Q_DECL_DEPRECATED
190 #else
191 #  define Q_DECL_DEPRECATED __attribute__((__deprecated__))
192 #endif
193
194 #if defined(QT_NO_DEPRECATED)
195 #  undef QT_DEPRECATED
196 #  undef QT_DEPRECATED_CONSTRUCTOR
197 #elif defined(QT_DEPRECATED_WARNINGS)
198 #  undef QT_DEPRECATED
199 #  define QT_DEPRECATED Q_DECL_DEPRECATED
200 #  undef QT_DEPRECATED_CONSTRUCTOR
201 #  define QT_DEPRECATED_CONSTRUCTOR explicit Q_DECL_DEPRECATED
202 #else
203 #  undef QT_DEPRECATED
204 #  define QT_DEPRECATED
205 #  undef QT_DEPRECATED_CONSTRUCTOR
206 #  define QT_DEPRECATED_CONSTRUCTOR
207 #endif
208
209 #ifdef QT_ASCII_CAST_WARNINGS
210 #  define QT_ASCII_CAST_WARN Q_DECL_DEPRECATED
211 #  define QT_ASCII_CAST_WARN_CONSTRUCTOR QT_DEPRECATED_CONSTRUCTOR
212 #else
213 #  define QT_ASCII_CAST_WARN
214 #  define QT_ASCII_CAST_WARN_CONSTRUCTOR
215 #endif
216
217 #if defined(QT_ARCH_I386)
218 #  define QT_FASTCALL __attribute__((regparm(3)))
219 #else
220 #  define QT_FASTCALL __attribute__((hot))
221 #endif
222
223 // This logic must match the one in qmetatype.h
224 #if !defined(QT_NO_FPU) && defined(QT_ARCH_ARM) || defined(QT_ARCH_AVR32) || defined(QT_ARCH_SH)
225 #  define QT_NO_FPU
226 #endif
227
228 #if defined(QT_NO_FPU)
229 typedef float qreal;
230 #else
231 typedef double qreal;
232 #endif
233
234 #define Q_DECL_EXPORT __attribute__((visibility("default")))
235 #define Q_DECL_HIDDEN __attribute__((visibility("hidden")))
236 #define Q_DECL_IMPORT
237
238 #ifdef KtCore_EXPORTS
239 #  define Q_CORE_EXPORT Q_DECL_EXPORT
240 #else
241 #  define Q_CORE_EXPORT Q_DECL_IMPORT
242 #endif
243
244 #ifdef KtGui_EXPORTS
245 #  define Q_GUI_EXPORT Q_DECL_EXPORT
246 #else
247 #  define Q_GUI_EXPORT Q_DECL_IMPORT
248 #endif
249
250 #ifdef KtSql_EXPORTS
251 #  define Q_SQL_EXPORT Q_DECL_EXPORT
252 #else
253 #  define Q_SQL_EXPORT Q_DECL_IMPORT
254 #endif
255
256 #ifdef KtNetwork_EXPORTS
257 #  define Q_NETWORK_EXPORT Q_DECL_EXPORT
258 #else
259 #  define Q_NETWORK_EXPORT Q_DECL_IMPORT
260 #endif
261
262 #ifdef KtSvg_EXPORTS
263 #  define Q_SVG_EXPORT Q_DECL_EXPORT
264 #else
265 #  define Q_SVG_EXPORT Q_DECL_IMPORT
266 #endif
267
268 #ifdef KtTest_EXPORTS
269 #  define Q_TEST_EXPORT Q_DECL_EXPORT
270 #else
271 #  define Q_TEST_EXPORT Q_DECL_IMPORT
272 #endif
273
274 #ifdef KtDeclarative_EXPORTS
275 #  define Q_DECLARATIVE_EXPORT Q_DECL_EXPORT
276 #else
277 #  define Q_DECLARATIVE_EXPORT Q_DECL_IMPORT
278 #endif
279
280 #ifdef KtXml_EXPORTS
281 #  define Q_XML_EXPORT Q_DECL_EXPORT
282 #else
283 #  define Q_XML_EXPORT Q_DECL_IMPORT
284 #endif
285
286 #ifdef KtScript_EXPORTS
287 #  define Q_SCRIPT_EXPORT Q_DECL_EXPORT
288 #else
289 #  define Q_SCRIPT_EXPORT Q_DECL_IMPORT
290 #endif
291
292 #ifdef KtScriptTools_EXPORTS
293 #  define Q_SCRIPTTOOLS_EXPORT Q_DECL_EXPORT
294 #else
295 #  define Q_SCRIPTTOOLS_EXPORT Q_DECL_IMPORT
296 #endif
297
298 #ifdef KtDBus_EXPORTS
299 #  define Q_DBUS_EXPORT Q_DECL_EXPORT
300 #else
301 #  define Q_DBUS_EXPORT Q_DECL_IMPORT
302 #endif
303
304 #ifdef KtUiTools_EXPORTS
305 #  define Q_UITOOLS_EXPORT Q_DECL_EXPORT
306 #else
307 #  define Q_UITOOLS_EXPORT Q_DECL_IMPORT
308 #endif
309
310 #ifdef KtDesigner_EXPORTS
311 #  define Q_DESIGNER_EXPORT Q_DECL_EXPORT
312 #else
313 #  define Q_DESIGNER_EXPORT Q_DECL_IMPORT
314 #endif
315
316 #define Q_CORE_EXPORT_INLINE Q_CORE_EXPORT inline
317 #define Q_GUI_EXPORT_INLINE Q_GUI_EXPORT inline
318
319 /*
320    No, this is not an evil backdoor. QT_BUILD_INTERNAL just exports more symbols
321    for Qt's internal unit tests. If you want slower loading times and more
322    symbols that can vanish from version to version, feel free to define QT_BUILD_INTERNAL.
323 */
324 #if defined(QT_BUILD_INTERNAL)
325 #    define Q_AUTOTEST_EXPORT Q_DECL_EXPORT
326 #else
327 #    define Q_AUTOTEST_EXPORT
328 #endif
329
330 /* These wrap try/catch so we can switch off exceptions later.
331
332    Beware - do not use the exception instance in the catch block.
333    If you can't live with that constraint, don't use these macros.
334    Use the QT_NO_EXCEPTIONS macro to protect your code instead.
335 */
336 #if !defined(QT_NO_EXCEPTIONS) && !defined(Q_COMPILER_EXCEPTIONS) && !defined(Q_MOC_RUN)
337 #  define QT_NO_EXCEPTIONS
338 #endif
339
340 #ifdef QT_NO_EXCEPTIONS
341 #  define QT_TRY if (true)
342 #  define QT_CATCH(A) else if (false)
343 #  define QT_THROW(A) {}
344 #  define QT_RETHROW {}
345 #else
346 #  define QT_TRY try
347 #  define QT_CATCH(A) catch (A)
348 #  define QT_THROW(A) throw A
349 #  define QT_RETHROW throw
350 #endif
351
352 Q_CORE_EXPORT const char *qVersion();
353
354 /*
355    Avoid "unused parameter" warnings
356 */
357 #define Q_UNUSED(x) (void)x;
358
359 class QString;
360 #define qPrintable(string) QString(string).toLocal8Bit().constData()
361
362 Q_CORE_EXPORT QString qt_error_string(int errorCode);
363
364 Q_CORE_EXPORT void qDebug(const char *, ...) /* print debug message */
365 #if !defined(__INSURE__)
366     __attribute__((format (printf, 1, 2)))
367 #endif
368 ;
369
370 Q_CORE_EXPORT void qWarning(const char *, ...) /* print warning message */
371 #if !defined(__INSURE__)
372     __attribute__((format (printf, 1, 2)))
373 #endif
374 ;
375
376 Q_CORE_EXPORT void qCritical(const char *, ...) /* print critical message */
377 #if !defined(__INSURE__)
378     __attribute__((format (printf, 1, 2)))
379 #endif
380 ;
381 Q_CORE_EXPORT void qFatal(const char *, ...) /* print fatal message and exit */
382 #if !defined(__INSURE__)
383     __attribute__((format (printf, 1, 2)))
384 #endif
385 ;
386
387 Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line);
388 Q_CORE_EXPORT void qt_assert_x(const char *where, const char *what, const char *file, int line);
389 Q_CORE_EXPORT void qt_check_pointer(const char *file, int line);
390
391 #ifndef QT_NO_DEBUG
392 #  define Q_ASSERT(cond) do { if(!(cond)) qt_assert(#cond,__FILE__,__LINE__); } while (0)
393 #  define Q_ASSERT_X(cond, where, what) do { if(!(cond)) qt_assert_x(where, what,__FILE__,__LINE__); } while (0)
394 #  define Q_CHECK_PTR(p) do { if(!p) qt_check_pointer(__FILE__,__LINE__); } while (0)
395 #else
396 #  define Q_ASSERT(cond)
397 #  define Q_ASSERT_X(cond, where, what)
398 #  define Q_CHECK_PTR(p)
399 #endif
400
401 enum QtMsgType { QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg };
402
403 Q_CORE_EXPORT void qt_message_output(QtMsgType, const char *buf);
404
405 typedef void (*QtMsgHandler)(QtMsgType, const char *);
406 Q_CORE_EXPORT QtMsgHandler qInstallMsgHandler(QtMsgHandler);
407
408
409 #if defined(QT_NO_THREAD)
410
411 template <typename T>
412 class QGlobalStatic
413 {
414 public:
415     T *pointer;
416     inline QGlobalStatic(T *p) : pointer(p) { }
417     inline ~QGlobalStatic() { pointer = nullptr; }
418 };
419
420 #define Q_GLOBAL_STATIC(TYPE, NAME)                                  \
421     static TYPE *NAME()                                              \
422     {                                                                \
423         static TYPE thisVariable;                                    \
424         static QGlobalStatic<TYPE > thisGlobalStatic(&thisVariable); \
425         return thisGlobalStatic.pointer;                             \
426     }
427
428 #define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS)                  \
429     static TYPE *NAME()                                              \
430     {                                                                \
431         static TYPE thisVariable ARGS;                               \
432         static QGlobalStatic<TYPE > thisGlobalStatic(&thisVariable); \
433         return thisGlobalStatic.pointer;                             \
434     }
435
436 #define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER)    \
437     static TYPE *NAME()                                              \
438     {                                                                \
439         static TYPE thisVariable;                                    \
440         static QGlobalStatic<TYPE > thisGlobalStatic(nullptr);     \
441         if (!thisGlobalStatic.pointer) {                             \
442             TYPE *x = thisGlobalStatic.pointer = &thisVariable;      \
443             INITIALIZER;                                             \
444         }                                                            \
445         return thisGlobalStatic.pointer;                             \
446     }
447
448 #else // QT_NO_THREAD
449
450 // Forward declaration, since qatomic.h needs qglobal.h
451 template <typename T> class QAtomicPointer;
452
453 // POD for Q_GLOBAL_STATIC
454 template <typename T>
455 class QGlobalStatic
456 {
457 public:
458     QAtomicPointer<T> pointer;
459     bool destroyed;
460 };
461
462 // Created as a function-local static to delete a QGlobalStatic<T>
463 template <typename T>
464 class QGlobalStaticDeleter
465 {
466 public:
467     QGlobalStatic<T> &globalStatic;
468     QGlobalStaticDeleter(QGlobalStatic<T> &_globalStatic)
469         : globalStatic(_globalStatic)
470     { }
471
472     inline ~QGlobalStaticDeleter()
473     {
474         delete globalStatic.pointer;
475         globalStatic.pointer = nullptr;
476         globalStatic.destroyed = true;
477     }
478 };
479
480 #define Q_GLOBAL_STATIC(TYPE, NAME)                                           \
481     static TYPE *NAME()                                                       \
482     {                                                                         \
483         static QGlobalStatic<TYPE > this__StaticVar_                          \
484             = { QAtomicPointer<TYPE>(new TYPE), false };                      \
485         static QGlobalStaticDeleter<TYPE > cleanup(this__StaticVar_);         \
486         return this__StaticVar_.pointer;                                      \
487     }
488
489 #define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS)                           \
490     static TYPE *NAME()                                                       \
491     {                                                                         \
492         static QGlobalStatic<TYPE > this__StaticVar_                          \
493             = { QAtomicPointer<TYPE>(new TYPE ARGS), false };                 \
494         static QGlobalStaticDeleter<TYPE > cleanup(this__StaticVar_);         \
495         return this__StaticVar_.pointer;                                      \
496     }
497
498 #define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER)                  \
499     static TYPE *NAME()                                                            \
500     {                                                                              \
501         static QGlobalStatic<TYPE > this__StaticVar_                               \
502             = { QAtomicPointer<TYPE>(nullptr), false };                            \
503         if (!this__StaticVar_.pointer && !this__StaticVar_.destroyed) {            \
504             QScopedPointer<TYPE > x(new TYPE);                                     \
505             INITIALIZER;                                                           \
506             if (this__StaticVar_.pointer.testAndSetOrdered(nullptr, x.data())) {   \
507                 static QGlobalStaticDeleter<TYPE > cleanup(this__StaticVar_);      \
508                 x.take();                                                          \
509             }                                                                      \
510         }                                                                          \
511         return this__StaticVar_.pointer;                                           \
512     }
513
514 #endif // QT_NO_THREAD
515
516
517 /*
518    Utility macros and inline functions
519 */
520 template <typename T>
521 constexpr inline T qAbs(const T &t)
522 {
523     return t >= 0 ? t : -t;
524 }
525
526 template <typename T>
527 constexpr inline const T &qMin(const T &a, const T &b)
528 {
529     return (a < b) ? a : b;
530 }
531
532 template <typename T>
533 constexpr inline const T &qMax(const T &a, const T &b)
534 {
535     return (a < b) ? b : a;
536 }
537
538 template <typename T>
539 constexpr inline const T &qBound(const T &min, const T &val, const T &max)
540 {
541     return qMax(min, qMin(max, val));
542 }
543
544 constexpr static inline bool qFuzzyCompare(double p1, double p2)
545 {
546     return (qAbs(p1 - p2) <= 0.000000000001 * qMin(qAbs(p1), qAbs(p2)));
547 }
548
549 constexpr static inline bool qFuzzyCompare(float p1, float p2)
550 {
551     return (qAbs(p1 - p2) <= 0.00001f * qMin(qAbs(p1), qAbs(p2)));
552 }
553
554 /*!
555   \internal
556 */
557 constexpr static inline bool qFuzzyIsNull(double d)
558 {
559     return qAbs(d) <= 0.000000000001;
560 }
561
562 /*!
563   \internal
564 */
565 constexpr static inline bool qFuzzyIsNull(float f)
566 {
567     return qAbs(f) <= 0.00001f;
568 }
569
570 /*
571    This function tests a double for a null value. It doesn't
572    check whether the actual value is 0 or close to 0, but whether
573    it is binary 0.
574 */
575 static inline bool qIsNull(double d)
576 {
577     union U {
578         double d;
579         quint64 u;
580     };
581     U val;
582     val.d = d;
583     return val.u == quint64(0);
584 }
585
586 /*
587    This function tests a float for a null value. It doesn't
588    check whether the actual value is 0 or close to 0, but whether
589    it is binary 0.
590 */
591 static inline bool qIsNull(float f)
592 {
593     union U {
594         float f;
595         quint32 u;
596     };
597     U val;
598     val.f = f;
599     return val.u == 0u;
600 }
601
602 /*
603    QTypeInfo     - type trait functionality
604 */
605 template <typename T>
606 class QTypeInfo
607 {
608 public:
609     enum {
610         isComplex = true,
611         isStatic = true,
612         isLarge = (sizeof(T) > QT_POINTER_SIZE)
613     };
614 };
615
616 template <typename T>
617 class QTypeInfo<T*>
618 {
619 public:
620     enum {
621         isComplex = false,
622         isStatic = false,
623         isLarge = false
624     };
625 };
626
627 /*
628    Specialize a specific type with:
629
630      Q_DECLARE_TYPEINFO(type, flags);
631
632    where 'type' is the name of the type to specialize and 'flags' is
633    logically-OR'ed combination of the flags below.
634 */
635 enum { /* TYPEINFO flags */
636     Q_COMPLEX_TYPE = 0,
637     Q_PRIMITIVE_TYPE = 0x1,
638     Q_STATIC_TYPE = 0,
639     Q_MOVABLE_TYPE = 0x2
640 };
641
642 #define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) \
643 class QTypeInfo<TYPE > \
644 { \
645 public: \
646     enum { \
647         isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0), \
648         isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), \
649         isLarge = (sizeof(TYPE) > QT_POINTER_SIZE), \
650     }; \
651     static inline const char *name() { return #TYPE; } \
652 }
653
654 #define Q_DECLARE_TYPEINFO(TYPE, FLAGS) \
655 template<> \
656 Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS)
657
658 template <typename T>
659 inline void qSwap(T &value1, T &value2)
660 {
661     std::swap(value1, value2);
662 }
663
664 /*
665    Specialize a shared type with:
666
667      Q_DECLARE_SHARED(type);
668
669    where 'type' is the name of the type to specialize.  NOTE: shared
670    types must declare a 'bool isDetached(void) const;' member for this
671    to work.
672 */
673 #define Q_DECLARE_SHARED(TYPE)                                          \
674 template <> inline void qSwap<TYPE>(TYPE &value1, TYPE &value2) \
675 { qSwap(value1.data_ptr(), value2.data_ptr()); } \
676 QT_END_NAMESPACE \
677 namespace std { \
678     template<> inline void swap<QT_PREPEND_NAMESPACE(TYPE)>(QT_PREPEND_NAMESPACE(TYPE) &value1, QT_PREPEND_NAMESPACE(TYPE) &value2) \
679     { swap(value1.data_ptr(), value2.data_ptr()); } \
680 } \
681 QT_BEGIN_NAMESPACE
682
683 /*
684    QTypeInfo primitive specializations
685 */
686 Q_DECLARE_TYPEINFO(bool, Q_PRIMITIVE_TYPE);
687 Q_DECLARE_TYPEINFO(char, Q_PRIMITIVE_TYPE);
688 Q_DECLARE_TYPEINFO(signed char, Q_PRIMITIVE_TYPE);
689 Q_DECLARE_TYPEINFO(uchar, Q_PRIMITIVE_TYPE);
690 Q_DECLARE_TYPEINFO(short, Q_PRIMITIVE_TYPE);
691 Q_DECLARE_TYPEINFO(ushort, Q_PRIMITIVE_TYPE);
692 Q_DECLARE_TYPEINFO(int, Q_PRIMITIVE_TYPE);
693 Q_DECLARE_TYPEINFO(uint, Q_PRIMITIVE_TYPE);
694 Q_DECLARE_TYPEINFO(long, Q_PRIMITIVE_TYPE);
695 Q_DECLARE_TYPEINFO(ulong, Q_PRIMITIVE_TYPE);
696 Q_DECLARE_TYPEINFO(qint64, Q_PRIMITIVE_TYPE);
697 Q_DECLARE_TYPEINFO(quint64, Q_PRIMITIVE_TYPE);
698 Q_DECLARE_TYPEINFO(float, Q_PRIMITIVE_TYPE);
699 Q_DECLARE_TYPEINFO(double, Q_PRIMITIVE_TYPE);
700 Q_DECLARE_TYPEINFO(long double, Q_PRIMITIVE_TYPE);
701
702 /*
703    These functions make it possible to use standard C++ functions with
704    a similar name from Qt header files (especially template classes).
705 */
706 class Q_CORE_EXPORT QFlag
707 {
708     int i;
709 public:
710     inline QFlag(int ai) : i(ai) {}
711     inline operator int() const { return i; }
712 };
713
714 class Q_CORE_EXPORT QIncompatibleFlag
715 {
716     int i;
717 public:
718     inline explicit QIncompatibleFlag(int i);
719     inline operator int() const { return i; }
720 };
721
722 inline QIncompatibleFlag::QIncompatibleFlag(int ai) : i(ai) {}
723
724 #ifndef Q_NO_TYPESAFE_FLAGS
725
726 template<typename Enum>
727 class QFlags
728 {
729     typedef void **Zero;
730     int i;
731 public:
732     typedef Enum enum_type;
733     constexpr inline QFlags(const QFlags &f) : i(f.i) {}
734     constexpr inline QFlags(Enum f) : i(f) {}
735     constexpr inline QFlags(Zero = 0) : i(0) {}
736     inline QFlags(QFlag f) : i(f) {}
737
738     inline QFlags &operator=(const QFlags &f) { i = f.i; return *this; }
739     inline QFlags &operator&=(int mask) { i &= mask; return *this; }
740     inline QFlags &operator&=(uint mask) { i &= mask; return *this; }
741     inline QFlags &operator|=(QFlags f) { i |= f.i; return *this; }
742     inline QFlags &operator|=(Enum f) { i |= f; return *this; }
743     inline QFlags &operator^=(QFlags f) { i ^= f.i; return *this; }
744     inline QFlags &operator^=(Enum f) { i ^= f; return *this; }
745
746     constexpr  inline operator int() const { return i; }
747
748     constexpr inline QFlags operator|(QFlags f) const { return QFlags(Enum(i | f.i)); }
749     constexpr inline QFlags operator|(Enum f) const { return QFlags(Enum(i | f)); }
750     constexpr inline QFlags operator^(QFlags f) const { return QFlags(Enum(i ^ f.i)); }
751     constexpr inline QFlags operator^(Enum f) const { return QFlags(Enum(i ^ f)); }
752     constexpr inline QFlags operator&(int mask) const { return QFlags(Enum(i & mask)); }
753     constexpr inline QFlags operator&(uint mask) const { return QFlags(Enum(i & mask)); }
754     constexpr inline QFlags operator&(Enum f) const { return QFlags(Enum(i & f)); }
755     constexpr inline QFlags operator~() const { return QFlags(Enum(~i)); }
756
757     constexpr inline bool operator!() const { return !i; }
758
759     inline bool testFlag(Enum f) const { return (i & f) == f && (f != 0 || i == int(f) ); }
760 };
761
762 #define Q_DECLARE_FLAGS(Flags, Enum)\
763 typedef QFlags<Enum> Flags;
764
765 #define Q_DECLARE_INCOMPATIBLE_FLAGS(Flags) \
766 inline QIncompatibleFlag operator|(Flags::enum_type f1, int f2) \
767 { return QIncompatibleFlag(int(f1) | f2); }
768
769 #define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags) \
770 constexpr inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, Flags::enum_type f2) \
771 { return QFlags<Flags::enum_type>(f1) | f2; } \
772 constexpr inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, QFlags<Flags::enum_type> f2) \
773 { return f2 | f1; } Q_DECLARE_INCOMPATIBLE_FLAGS(Flags)
774
775
776 #else /* Q_NO_TYPESAFE_FLAGS */
777
778 #define Q_DECLARE_FLAGS(Flags, Enum)\
779 typedef uint Flags;
780 #define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
781
782 #endif /* Q_NO_TYPESAFE_FLAGS */
783
784 #ifdef QT_FOREACH_COMPAT
785 template <typename T>
786 class QForeachContainer {
787 public:
788     inline QForeachContainer(const T& t) : c(t) { }
789     inline typename T::const_iterator begin() { return c.begin(); }
790     inline typename T::const_iterator end() { return c.end(); }
791 private:
792     const T c;
793 };
794
795 #define Q_FOREACH(variable, container) \
796     for (variable: QForeachContainer<Q_TYPEOF(container)>(container))
797
798 #else // QT_FOREACH_COMPAT
799
800 #define Q_FOREACH(variable, container) for (variable: container)
801
802 #endif // QT_FOREACH_COMPAT
803
804 #define Q_FOREVER for(;;)
805 #ifndef QT_NO_KEYWORDS
806 #  ifndef foreach
807 #    define foreach Q_FOREACH
808 #  endif
809 #  ifndef forever
810 #    define forever Q_FOREVER
811 #  endif
812 #endif
813
814 #define Q_UNREACHABLE() \
815     Q_ASSERT_X(false, "Q_UNREACHABLE()", "Q_UNREACHABLE was reached"); \
816     __builtin_unreachable()
817
818 template <typename T> static inline T *qGetPtrHelper(T *ptr) { return ptr; }
819 template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelper(const Wrapper &p) { return p.data(); }
820
821 #define Q_DECLARE_PRIVATE(Class) \
822     inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr)); } \
823     inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr)); } \
824     friend class Class##Private;
825
826 #define Q_DECLARE_PRIVATE_D(Dptr, Class) \
827     inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(Dptr); } \
828     inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(Dptr); } \
829     friend class Class##Private;
830
831 #define Q_DECLARE_PUBLIC(Class)                                    \
832     inline Class* q_func() { return static_cast<Class *>(q_ptr); } \
833     inline const Class* q_func() const { return static_cast<const Class *>(q_ptr); } \
834     friend class Class;
835
836 #define Q_D(Class) Class##Private * const d = d_func()
837 #define Q_Q(Class) Class * const q = q_func()
838
839 #define QT_TR_NOOP(x) (x)
840 #define QT_TR_NOOP_UTF8(x) (x)
841 #define QT_TRANSLATE_NOOP(scope, x) (x)
842 #define QT_TRANSLATE_NOOP_UTF8(scope, x) (x)
843
844 /*
845    When RTTI is not available, define this macro to force any uses of
846    dynamic_cast to cause a compile failure.
847 */
848 #ifdef QT_NO_DYNAMIC_CAST
849 #  define dynamic_cast QT_PREPEND_NAMESPACE(qt_dynamic_cast_check)
850
851   template<typename T, typename X>
852   T qt_dynamic_cast_check(X, T* = 0)
853   { return T::dynamic_cast_will_always_fail_because_rtti_is_disabled; }
854 #endif
855
856 /*
857    Some classes do not permit copies to be made of an object. These
858    classes contains a private copy constructor and assignment
859    operator to disable copying (the compiler gives an error message).
860 */
861 #define Q_DISABLE_COPY(Class) \
862     Class(const Class &) = delete; \
863     Class &operator=(const Class &) = delete;
864
865 class QByteArray;
866 Q_CORE_EXPORT QByteArray qgetenv(const char *varName);
867 Q_CORE_EXPORT bool qputenv(const char *varName, const QByteArray& value);
868
869 /*
870   Reentrant versions of basic rand() functions for random number generation
871 */
872 Q_CORE_EXPORT void qsrand(uint seed);
873 Q_CORE_EXPORT int qrand();
874
875 QT_END_NAMESPACE
876
877 #endif /* QGLOBAL_H */