summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2009-08-14 15:04:30 +0200
committerThiago Macieira <thiago.macieira@nokia.com>2009-08-14 17:33:28 +0200
commit78fbb9cf6ef5e8440f0453ef60bd7845ce418745 (patch)
treea8e784f5e6b509b79d88e6fdd4092c4f89517441
parenta931fac02fe0430439a351dacc5167ddeca1d4d0 (diff)
Reimplement qSwap and Q_DECLARE_SHARED differently.
This enables the use of Q_DECLARE_SHARED with d-pointers that are QExplicitlySharedDataPointer<PrivateClass>. Also, this enables swapping atomically QSharedPointers. Reviewed-by: Harald Fernengel
-rw-r--r--src/corelib/global/qglobal.h31
-rw-r--r--src/corelib/tools/qalgorithms.h17
-rw-r--r--src/corelib/tools/qshareddata.h14
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h19
-rw-r--r--tests/auto/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp20
-rw-r--r--tests/auto/qsharedpointer/tst_qsharedpointer.cpp32
6 files changed, 92 insertions, 41 deletions
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 5a2c329c6..92fe649ff 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1906,6 +1906,14 @@ public: \
static inline const char *name() { return #TYPE; } \
}
+template <typename T>
+inline void qSwap(T &value1, T &value2)
+{
+ const T t = value1;
+ value1 = value2;
+ value2 = t;
+}
+
/*
Specialize a shared type with:
@@ -1915,33 +1923,12 @@ public: \
types must declare a 'bool isDetached(void) const;' member for this
to work.
*/
-#if defined Q_CC_MSVC && _MSC_VER < 1300
-template <typename T>
-inline void qSwap_helper(T &value1, T &value2, T*)
-{
- T t = value1;
- value1 = value2;
- value2 = t;
-}
#define Q_DECLARE_SHARED(TYPE) \
template <> inline bool qIsDetached<TYPE>(TYPE &t) { return t.isDetached(); } \
-template <> inline void qSwap_helper<TYPE>(TYPE &value1, TYPE &value2, TYPE*) \
-{ \
- const TYPE::DataPtr t = value1.data_ptr(); \
- value1.data_ptr() = value2.data_ptr(); \
- value2.data_ptr() = t; \
-}
-#else
-#define Q_DECLARE_SHARED(TYPE) \
-template <> inline bool qIsDetached<TYPE>(TYPE &t) { return t.isDetached(); } \
-template <typename T> inline void qSwap(T &, T &); \
template <> inline void qSwap<TYPE>(TYPE &value1, TYPE &value2) \
{ \
- const TYPE::DataPtr t = value1.data_ptr(); \
- value1.data_ptr() = value2.data_ptr(); \
- value2.data_ptr() = t; \
+ qSwap<TYPE::DataPtr>(value1.data_ptr(), value2.data_ptr()); \
}
-#endif
/*
QTypeInfo primitive specializations
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h
index 6f623d9c7..3e5c3cc4a 100644
--- a/src/corelib/tools/qalgorithms.h
+++ b/src/corelib/tools/qalgorithms.h
@@ -141,23 +141,6 @@ inline void qCount(const Container &container, const T &value, Size &n)
qCount(container.constBegin(), container.constEnd(), value, n);
}
-
-#if defined Q_CC_MSVC && _MSC_VER < 1300
-template <typename T>
-inline void qSwap(T &value1, T &value2)
-{
- qSwap_helper<T>(value1, value2, (T *)0);
-}
-#else
-template <typename T>
-inline void qSwap(T &value1, T &value2)
-{
- T t = value1;
- value1 = value2;
- value2 = t;
-}
-#endif
-
#ifdef qdoc
template <typename T>
LessThan qLess()
diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h
index e13e37cd3..dde6e88c8 100644
--- a/src/corelib/tools/qshareddata.h
+++ b/src/corelib/tools/qshareddata.h
@@ -111,6 +111,9 @@ public:
inline bool operator!() const { return !d; }
+ inline void swap(QSharedDataPointer &other)
+ { qSwap(d, other.d); }
+
protected:
T *clone();
@@ -186,6 +189,9 @@ public:
inline bool operator!() const { return !d; }
+ inline void swap(QExplicitlySharedDataPointer &other)
+ { qSwap(d, other.d); }
+
protected:
T *clone();
@@ -235,6 +241,14 @@ template <class T>
Q_INLINE_TEMPLATE QExplicitlySharedDataPointer<T>::QExplicitlySharedDataPointer(T *adata) : d(adata)
{ if (d) d->ref.ref(); }
+template <class T>
+Q_INLINE_TEMPLATE void qSwap(QSharedDataPointer<T> &p1, QSharedDataPointer<T> &p2)
+{ p1.swap(p2); }
+
+template <class T>
+Q_INLINE_TEMPLATE void qSwap(QExplicitlySharedDataPointer<T> &p1, QExplicitlySharedDataPointer<T> &p2)
+{ p1.swap(p2); }
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index cbeb79ff3..1136aa9fa 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -171,8 +171,8 @@ namespace QtSharedPointer {
inline ExternalRefCountData()
{
- QBasicAtomicInt proto = Q_BASIC_ATOMIC_INITIALIZER(1);
- weakref = strongref = proto;
+ strongref = 1;
+ weakref = 1;
}
inline ExternalRefCountData(Qt::Initialization) { }
virtual inline ~ExternalRefCountData() { Q_ASSERT(!weakref); Q_ASSERT(strongref <= 0); }
@@ -385,6 +385,12 @@ namespace QtSharedPointer {
delete this->value;
}
+ inline void internalSwap(ExternalRefCount &other)
+ {
+ qSwap(d, other.d);
+ qSwap(this->value, other.value);
+ }
+
#if defined(Q_NO_TEMPLATE_FRIENDS)
public:
#else
@@ -465,6 +471,9 @@ public:
inline QSharedPointer<T> &operator=(const QWeakPointer<X> &other)
{ internalSet(other.d, other.value); return *this; }
+ inline void swap(QSharedPointer &other)
+ { internalSwap(other); }
+
template <class X>
QSharedPointer<X> staticCast() const
{
@@ -682,6 +691,12 @@ Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef() const
return QWeakPointer<T>(*this);
}
+template <class T>
+inline void qSwap(QSharedPointer<T> &p1, QSharedPointer<T> &p2)
+{
+ p1.swap(p2);
+}
+
namespace QtSharedPointer {
// helper functions:
template <class X, class T>
diff --git a/tests/auto/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp b/tests/auto/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp
index 4cdeb5c3b..97e57f171 100644
--- a/tests/auto/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp
+++ b/tests/auto/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp
@@ -61,6 +61,7 @@ private Q_SLOTS:
void clone() const;
void data() const;
void reset() const;
+ void swap() const;
};
class MyClass : public QSharedData
@@ -233,6 +234,25 @@ void tst_QExplicitlySharedDataPointer::reset() const
}
}
+void tst_QExplicitlySharedDataPointer::swap() const
+{
+ QExplicitlySharedDataPointer<MyClass> p1(0), p2(new MyClass());
+ QVERIFY(!p1.data());
+ QVERIFY(p2.data());
+
+ p1.swap(p2);
+ QVERIFY(p1.data());
+ QVERIFY(!p2.data());
+
+ p1.swap(p2);
+ QVERIFY(!p1.data());
+ QVERIFY(p2.data());
+
+ qSwap(p1, p2);
+ QVERIFY(p1.data());
+ QVERIFY(!p2.data());
+}
+
QTEST_MAIN(tst_QExplicitlySharedDataPointer)
#include "tst_qexplicitlyshareddatapointer.moc"
diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp
index 58e5401be..ab75c910b 100644
--- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp
+++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp
@@ -62,6 +62,7 @@ class tst_QSharedPointer: public QObject
private slots:
void basics_data();
void basics();
+ void swap();
void forwardDeclaration1();
void forwardDeclaration2();
void memoryManagement();
@@ -263,6 +264,37 @@ void tst_QSharedPointer::basics()
// aData is deleted here
}
+void tst_QSharedPointer::swap()
+{
+ QSharedPointer<int> p1, p2(new int(42)), control = p2;
+ QVERIFY(p1 != control);
+ QVERIFY(p1.isNull());
+ QVERIFY(p2 == control);
+ QVERIFY(!p2.isNull());
+ QVERIFY(*p2 == 42);
+
+ p1.swap(p2);
+ QVERIFY(p1 == control);
+ QVERIFY(!p1.isNull());
+ QVERIFY(p2 != control);
+ QVERIFY(p2.isNull());
+ QVERIFY(*p1 == 42);
+
+ p1.swap(p2);
+ QVERIFY(p1 != control);
+ QVERIFY(p1.isNull());
+ QVERIFY(p2 == control);
+ QVERIFY(!p2.isNull());
+ QVERIFY(*p2 == 42);
+
+ qSwap(p1, p2);
+ QVERIFY(p1 == control);
+ QVERIFY(!p1.isNull());
+ QVERIFY(p2 != control);
+ QVERIFY(p2.isNull());
+ QVERIFY(*p1 == 42);
+}
+
class ForwardDeclared;
ForwardDeclared *forwardPointer();
void externalForwardDeclaration();