Merge remote-tracking branch 'origin/master' into api_changes
[profile/ivi/qtbase.git] / src / corelib / tools / qarraydatapointer.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QARRAYDATAPOINTER_H
43 #define QARRAYDATAPOINTER_H
44
45 #include <QtCore/qarraydataops.h>
46
47 QT_BEGIN_HEADER
48
49 QT_BEGIN_NAMESPACE
50
51 template <class T>
52 struct QArrayDataPointer
53 {
54 private:
55     typedef QTypedArrayData<T> Data;
56     typedef QArrayDataOps<T> DataOps;
57
58 public:
59     QArrayDataPointer()
60         : d(Data::sharedNull())
61     {
62     }
63
64     QArrayDataPointer(const QArrayDataPointer &other)
65         : d(other.d->ref.ref()
66             ? other.d
67             : other.clone(other.d->cloneFlags()))
68     {
69     }
70
71     explicit QArrayDataPointer(QTypedArrayData<T> *ptr)
72         : d(ptr)
73     {
74         Q_CHECK_PTR(ptr);
75     }
76
77     QArrayDataPointer(QArrayDataPointerRef<T> ref)
78         : d(ref.ptr)
79     {
80     }
81
82     QArrayDataPointer &operator=(const QArrayDataPointer &other)
83     {
84         QArrayDataPointer tmp(other);
85         this->swap(tmp);
86         return *this;
87     }
88
89 #ifdef Q_COMPILER_RVALUE_REFS
90     QArrayDataPointer(QArrayDataPointer &&other)
91         : d(other.d)
92     {
93         other.d = Data::sharedNull();
94     }
95
96     QArrayDataPointer &operator=(QArrayDataPointer &&other)
97     {
98         this->swap(other);
99         return *this;
100     }
101 #endif
102
103     DataOps &operator*() const
104     {
105         Q_ASSERT(d);
106         return *static_cast<DataOps *>(d);
107     }
108
109     DataOps *operator->() const
110     {
111         Q_ASSERT(d);
112         return static_cast<DataOps *>(d);
113     }
114
115     ~QArrayDataPointer()
116     {
117         if (!d->ref.deref()) {
118             (*this)->destroyAll();
119             Data::deallocate(d);
120         }
121     }
122
123     bool isNull() const
124     {
125         return d == Data::sharedNull();
126     }
127
128     Data *data() const
129     {
130         return d;
131     }
132
133     bool needsDetach() const
134     {
135         return (!d->isMutable() || d->ref.isShared());
136     }
137
138     void setSharable(bool sharable)
139     {
140         if (needsDetach()) {
141             Data *detached = clone(sharable
142                     ? d->detachFlags() & ~QArrayData::Unsharable
143                     : d->detachFlags() | QArrayData::Unsharable);
144             QArrayDataPointer old(d);
145             d = detached;
146         } else {
147             d->ref.setSharable(sharable);
148         }
149     }
150
151     void swap(QArrayDataPointer &other)
152     {
153         qSwap(d, other.d);
154     }
155
156     void clear()
157     {
158         QArrayDataPointer tmp(d);
159         d = Data::sharedNull();
160     }
161
162     bool detach()
163     {
164         if (needsDetach()) {
165             Data *copy = clone(d->detachFlags());
166             QArrayDataPointer old(d);
167             d = copy;
168             return true;
169         }
170
171         return false;
172     }
173
174 private:
175     Data *clone(QArrayData::AllocationOptions options) const Q_REQUIRED_RESULT
176     {
177         QArrayDataPointer copy(Data::allocate(d->detachCapacity(d->size),
178                     options));
179         if (d->size)
180             copy->copyAppend(d->begin(), d->end());
181
182         Data *result = copy.d;
183         copy.d = Data::sharedNull();
184         return result;
185     }
186
187     Data *d;
188 };
189
190 template <class T>
191 inline bool operator==(const QArrayDataPointer<T> &lhs, const QArrayDataPointer<T> &rhs)
192 {
193     return lhs.data() == rhs.data();
194 }
195
196 template <class T>
197 inline bool operator!=(const QArrayDataPointer<T> &lhs, const QArrayDataPointer<T> &rhs)
198 {
199     return lhs.data() != rhs.data();
200 }
201
202 template <class T>
203 inline void qSwap(QArrayDataPointer<T> &p1, QArrayDataPointer<T> &p2)
204 {
205     p1.swap(p2);
206 }
207
208 QT_END_NAMESPACE
209
210 namespace std
211 {
212     template <class T>
213     inline void swap(
214             QT_PREPEND_NAMESPACE(QArrayDataPointer)<T> &p1,
215             QT_PREPEND_NAMESPACE(QArrayDataPointer)<T> &p2)
216     {
217         p1.swap(p2);
218     }
219 }
220
221 QT_END_HEADER
222
223 #endif // include guard