b5e4f18aebd8e5ff40a265d469b0898e7c691f21
[profile/ivi/qtdeclarative.git] / src / declarative / qml / ftw / qdeclarativepool_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtDeclarative 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 QDECLARATIVEPOOL_P_H
43 #define QDECLARATIVEPOOL_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 <QtCore/qglobal.h>
57 #include <QtCore/qstring.h>
58 #include <QtCore/qurl.h>
59
60 QT_BEGIN_NAMESPACE
61
62 // Exported for QtQuick1
63 class Q_DECLARATIVE_EXPORT QDeclarativePool
64 {
65 public:
66     // The class has a destructor that needs to be called
67     class Class { 
68     public:
69         inline QDeclarativePool *pool() const;
70
71     private:
72         void *operator new(size_t);
73         void *operator new(size_t, void *m) { return m; }
74         friend class QDeclarativePool;
75
76         QDeclarativePool *_pool;
77         Class *_next;
78         void (*_destroy)(Class *);
79     };
80
81     // The class is plain old data and no destructor needs to
82     // be called
83     class POD {
84     public:
85         inline QDeclarativePool *pool() const;
86         
87     private:
88         void *operator new(size_t);
89         void *operator new(size_t, void *m) { return m; }
90         friend class QDeclarativePool;
91
92         QDeclarativePool *_pool;
93     };
94
95     inline QDeclarativePool();
96     inline ~QDeclarativePool();
97
98     void clear();
99
100     template<typename T>
101     inline T *New();
102     template<typename T>
103     inline T *NewRaw();
104     template<typename T>
105     inline T *NewRawArray(int length);
106
107     inline QString *NewString(const QString &);
108     inline QByteArray *NewByteArray(const QByteArray &);
109     inline QUrl *NewUrl(const QUrl &);
110
111     template<typename T>
112     struct List {
113         List() : m_length(0), m_data(0) {}
114         List(const List &o) : m_length(o.m_length), m_data(o.m_data) {}
115         List &operator=(const List &o) {
116             m_length = o.m_length;
117             m_data = o.m_data;
118             return *this;
119         }
120
121         int count() const {
122             return m_length;
123         }
124         int length() const { 
125             return m_length; 
126         }
127         const T &at(int index) const { 
128             Q_ASSERT(index < m_length); 
129             return m_data[index]; 
130         };
131         T &operator[](int index) {
132             Q_ASSERT(index < m_length); 
133             return m_data[index]; 
134         };
135     private:
136         friend class QDeclarativePool;
137         List(T *d, int l) : m_length(l), m_data(d) {}
138         int m_length;
139         T *m_data;
140     };
141
142     template<typename T>
143     inline List<T> NewRawList(int length);
144
145 private:
146     struct StringClass : public QString, public Class {
147     };
148     struct ByteArrayClass : public QByteArray, public Class {
149     };
150     struct UrlClass : public QUrl, public Class {
151     };
152
153     inline void *allocate(int size);
154     void newpage();
155
156     template<typename T>
157     inline void initialize(POD *);
158     template<typename T>
159     inline void initialize(Class *);
160     template<typename T>
161     static void destroy(Class *c);
162
163     struct Page {
164         struct Header {
165             Page *next;
166             char *free;
167         } header;
168
169         static const int pageSize = 4 * 4096 - sizeof(Header);
170
171         char memory[pageSize];
172     };
173
174     Page *_page;
175     Class *_classList;
176 };
177
178 QDeclarativePool::QDeclarativePool()
179 : _page(0), _classList(0)
180 {
181 }
182
183 QDeclarativePool::~QDeclarativePool()
184 {
185     clear();
186 }
187
188 template<typename T>
189 T *QDeclarativePool::New()
190 {
191     T *rv = new (allocate(sizeof(T))) T;
192     initialize<T>(rv);
193     rv->_pool = this;
194     return rv;
195 }
196
197 template<typename T>
198 T *QDeclarativePool::NewRaw()
199 {
200     return (T*)allocate(sizeof(T));
201 }
202
203 template<typename T>
204 T *QDeclarativePool::NewRawArray(int length)
205 {
206     return (T*)allocate(length * sizeof(T));
207 }
208
209 template<typename T>
210 QDeclarativePool::List<T> QDeclarativePool::NewRawList(int length)
211 {
212     return List<T>(NewRawArray<T>(length), length);
213 }
214
215 QString *QDeclarativePool::NewString(const QString &s)
216 {
217     QString *rv = New<StringClass>();
218     *rv = s;
219     return rv;
220 }
221
222 QByteArray *QDeclarativePool::NewByteArray(const QByteArray &s)
223 {
224     QByteArray *rv = New<ByteArrayClass>();
225     *rv = s;
226     return rv;
227 }
228
229 QUrl *QDeclarativePool::NewUrl(const QUrl &s)
230 {
231     QUrl *rv = New<UrlClass>();
232     *rv = s;
233     return rv;
234 }
235
236 void *QDeclarativePool::allocate(int size)
237 {
238     if (!_page || (_page->header.free + size) > (_page->memory + Page::pageSize))
239         newpage();
240
241     void *rv = _page->header.free;
242     _page->header.free += size + ((8 - size) & 7); // ensure 8 byte alignment;
243     return rv;
244 }
245
246 template<typename T>
247 void QDeclarativePool::initialize(QDeclarativePool::POD *)
248 {
249 }
250
251 template<typename T>
252 void QDeclarativePool::initialize(QDeclarativePool::Class *c)
253 {
254     c->_next = _classList;
255     c->_destroy = &destroy<T>;
256     _classList = c;
257 }
258
259 template<typename T>
260 void QDeclarativePool::destroy(Class *c)
261 {
262     static_cast<T *>(c)->~T();
263 }
264
265 QDeclarativePool *QDeclarativePool::Class::pool() const
266 {
267     return _pool;
268 }
269
270 QDeclarativePool *QDeclarativePool::POD::pool() const
271 {
272     return _pool;
273 }
274
275 QT_END_NAMESPACE
276
277 #endif // QDECLARATIVEPOOL_P_H
278