Make QMetaTypeInterface POD.
[profile/ivi/qtbase.git] / src / corelib / kernel / qmetatype_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QMETATYPE_P_H
43 #define QMETATYPE_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include "qmetatype.h"
57
58 QT_BEGIN_NAMESPACE
59
60 enum { /* TYPEMODULEINFO flags */
61     Q_CORE_TYPE = 1,
62     Q_GUI_TYPE = 2,
63     Q_WIDGET_TYPE = 3
64 };
65
66 template <typename T>
67 class QTypeModuleInfo
68 {
69 public:
70     enum Module {
71         IsCore = !QTypeInfo<T>::isComplex, // Primitive types are in Core
72         IsWidget = false,
73         IsGui = false,
74         IsUnknown = !IsCore
75     };
76     static inline int module() { return IsCore ? Q_CORE_TYPE : 0; }
77 };
78
79 #define QT_ASSIGN_TYPE_TO_MODULE(TYPE, MODULE) \
80 template<> \
81 class QTypeModuleInfo<TYPE > \
82 { \
83 public: \
84     enum Module { \
85         IsCore = (((MODULE) == (Q_CORE_TYPE))), \
86         IsWidget = (((MODULE) == (Q_WIDGET_TYPE))), \
87         IsGui = (((MODULE) == (Q_GUI_TYPE))), \
88         IsUnknown = !(IsCore || IsWidget || IsGui) \
89     }; \
90     static inline int module() { return MODULE; } \
91     Q_STATIC_ASSERT((IsUnknown && !(IsCore || IsWidget || IsGui)) \
92                  || (IsCore && !(IsUnknown || IsWidget || IsGui)) \
93                  || (IsWidget && !(IsUnknown || IsCore || IsGui)) \
94                  || (IsGui && !(IsUnknown || IsCore || IsWidget))); \
95 };
96
97
98 #define QT_DECLARE_CORE_MODULE_TYPES_ITER(TypeName, TypeId, Name) \
99     QT_ASSIGN_TYPE_TO_MODULE(Name, Q_CORE_TYPE);
100 #define QT_DECLARE_GUI_MODULE_TYPES_ITER(TypeName, TypeId, Name) \
101     QT_ASSIGN_TYPE_TO_MODULE(Name, Q_GUI_TYPE);
102 #define QT_DECLARE_WIDGETS_MODULE_TYPES_ITER(TypeName, TypeId, Name) \
103     QT_ASSIGN_TYPE_TO_MODULE(Name, Q_WIDGET_TYPE);
104
105 QT_FOR_EACH_STATIC_CORE_CLASS(QT_DECLARE_CORE_MODULE_TYPES_ITER)
106 QT_FOR_EACH_STATIC_CORE_TEMPLATE(QT_DECLARE_CORE_MODULE_TYPES_ITER)
107 QT_FOR_EACH_STATIC_GUI_CLASS(QT_DECLARE_GUI_MODULE_TYPES_ITER)
108 QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_DECLARE_WIDGETS_MODULE_TYPES_ITER)
109
110 #undef QT_DECLARE_CORE_MODULE_TYPES_ITER
111 #undef QT_DECLARE_GUI_MODULE_TYPES_ITER
112 #undef QT_DECLARE_WIDGETS_MODULE_TYPES_ITER
113
114 class QMetaTypeInterface
115 {
116 public:
117     template<typename T>
118     struct Impl {
119         static void *creator(const T *t)
120         {
121             if (t)
122                 return new T(*t);
123             return new T();
124         }
125
126         static void deleter(T *t) { delete t; }
127     #ifndef QT_NO_DATASTREAM
128         static void saver(QDataStream &stream, const T *t) { stream << *t; }
129         static void loader(QDataStream &stream, T *t) { stream >> *t; }
130     #endif // QT_NO_DATASTREAM
131         static void destructor(T *t)
132         {
133             Q_UNUSED(t) // Silence MSVC that warns for POD types.
134             t->~T();
135         }
136         static void *constructor(void *where, const T *t)
137         {
138             if (t)
139                 return new (where) T(*static_cast<const T*>(t));
140             return new (where) T;
141         }
142     };
143
144     QMetaType::Creator creator;
145     QMetaType::Deleter deleter;
146 #ifndef QT_NO_DATASTREAM
147     QMetaType::SaveOperator saveOp;
148     QMetaType::LoadOperator loadOp;
149 #endif
150     QMetaType::Constructor constructor;
151     QMetaType::Destructor destructor;
152     int size;
153 };
154
155 #ifndef QT_NO_DATASTREAM
156 #  define QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \
157     /*saveOp*/(reinterpret_cast<QMetaType::SaveOperator>(QMetaTypeInterface::Impl<Type>::saver)), \
158     /*loadOp*/(reinterpret_cast<QMetaType::LoadOperator>(QMetaTypeInterface::Impl<Type>::loader)),
159 #else
160 #  define QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type)
161 #endif
162
163 #define QT_METATYPE_INTERFACE_INIT(Type) \
164 { \
165     /*creator*/(reinterpret_cast<QMetaType::Creator>(QMetaTypeInterface::Impl<Type>::creator)), \
166     /*deleter*/(reinterpret_cast<QMetaType::Deleter>(QMetaTypeInterface::Impl<Type>::deleter)), \
167     QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \
168     /*constructor*/(reinterpret_cast<QMetaType::Constructor>(QMetaTypeInterface::Impl<Type>::constructor)), \
169     /*destructor*/(reinterpret_cast<QMetaType::Destructor>(QMetaTypeInterface::Impl<Type>::destructor)), \
170     /*size*/(sizeof(Type)) \
171 }
172
173 QT_END_NAMESPACE
174
175 #endif // QMETATYPE_P_H