Update ftw classes
authorAaron Kennedy <aaron.kennedy@nokia.com>
Tue, 14 Feb 2012 11:20:32 +0000 (11:20 +0000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 20 Feb 2012 10:28:00 +0000 (11:28 +0100)
This is for the benefit of subsequent changes.

Change-Id: Ib494efb1474d069c067194008c9832653d5d8eb4
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
src/declarative/qml/ftw/ftw.pri
src/declarative/qml/ftw/qfieldlist_p.h
src/declarative/qml/ftw/qflagpointer_p.h
src/declarative/qml/ftw/qlazilyallocated_p.h [new file with mode: 0644]
src/declarative/qml/ftw/qpointervaluepair_p.h [new file with mode: 0644]

index e331c9e..2634342 100644 (file)
@@ -15,6 +15,8 @@ HEADERS +=  \
     $$PWD/qrecyclepool_p.h \
     $$PWD/qflagpointer_p.h \
     $$PWD/qdeclarativetrace_p.h \
+    $$PWD/qpointervaluepair_p.h \
+    $$PWD/qlazilyallocated_p.h \
 
 SOURCES += \
     $$PWD/qintrusivelist.cpp \
index ad70d44..4253779 100644 (file)
 
 #include <QtCore/qglobal.h>
 
+#include <private/qflagpointer_p.h>
+
+// QForwardFieldList is a super simple linked list that can only prepend
+template<class N, N *N::*nextMember>
+class QForwardFieldList
+{
+public:
+    inline QForwardFieldList();
+    inline N *first() const;
+    inline N *takeFirst();
+
+    inline void prepend(N *);
+
+    inline bool isEmpty() const;
+    inline bool isOne() const;
+    inline bool isMany() const;
+
+    static inline N *next(N *v);
+
+    inline bool flag() const;
+    inline void setFlag();
+    inline void clearFlag();
+    inline void setFlagValue(bool);
+
+    inline bool flag2() const;
+    inline void setFlag2();
+    inline void clearFlag2();
+    inline void setFlag2Value(bool);
+private:
+    QFlagPointer<N> _first;
+};
+
+// QFieldList is a simple linked list, that can append and prepend and also
+// maintains a count
 template<class N, N *N::*nextMember>
 class QFieldList 
 {
@@ -76,18 +110,128 @@ public:
     inline void insertAfter(N *, QFieldList<N, nextMember> &);
 
     inline void copyAndClear(QFieldList<N, nextMember> &);
+    inline void copyAndClearAppend(QForwardFieldList<N, nextMember> &);
+    inline void copyAndClearPrepend(QForwardFieldList<N, nextMember> &);
 
     static inline N *next(N *v);
 
+    inline bool flag() const;
+    inline void setFlag();
+    inline void clearFlag();
+    inline void setFlagValue(bool);
 private:
     N *_first;
     N *_last;
-    int _count;
+    quint32 _flag:1;
+    quint32 _count:31;
 };
 
 template<class N, N *N::*nextMember>
+QForwardFieldList<N, nextMember>::QForwardFieldList()
+{
+}
+
+template<class N, N *N::*nextMember>
+N *QForwardFieldList<N, nextMember>::first() const
+{
+    return *_first;
+}
+
+template<class N, N *N::*nextMember>
+N *QForwardFieldList<N, nextMember>::takeFirst()
+{
+    N *value = *_first;
+    if (value) {
+        _first = next(value);
+        value->*nextMember = 0;
+    }
+    return value;
+}
+
+template<class N, N *N::*nextMember>
+void QForwardFieldList<N, nextMember>::prepend(N *v)
+{
+    Q_ASSERT(v->*nextMember == 0);
+    v->*nextMember = *_first;
+    _first = v;
+}
+
+template<class N, N *N::*nextMember>
+bool QForwardFieldList<N, nextMember>::isEmpty() const
+{
+    return _first.isNull();
+}
+
+template<class N, N *N::*nextMember>
+bool QForwardFieldList<N, nextMember>::isOne() const
+{
+    return *_first && _first->*nextMember == 0;
+}
+
+template<class N, N *N::*nextMember>
+bool QForwardFieldList<N, nextMember>::isMany() const
+{
+    return *_first && _first->*nextMember != 0;
+}
+
+template<class N, N *N::*nextMember>
+N *QForwardFieldList<N, nextMember>::next(N *v)
+{
+    Q_ASSERT(v);
+    return v->*nextMember;
+}
+
+template<class N, N *N::*nextMember>
+bool QForwardFieldList<N, nextMember>::flag() const
+{
+    return _first.flag();
+}
+
+template<class N, N *N::*nextMember>
+void QForwardFieldList<N, nextMember>::setFlag()
+{
+    _first.setFlag();
+}
+
+template<class N, N *N::*nextMember>
+void QForwardFieldList<N, nextMember>::clearFlag()
+{
+    _first.clearFlag();
+}
+
+template<class N, N *N::*nextMember>
+void QForwardFieldList<N, nextMember>::setFlagValue(bool v)
+{
+    _first.setFlagValue(v);
+}
+
+template<class N, N *N::*nextMember>
+bool QForwardFieldList<N, nextMember>::flag2() const
+{
+    return _first.flag2();
+}
+
+template<class N, N *N::*nextMember>
+void QForwardFieldList<N, nextMember>::setFlag2()
+{
+    _first.setFlag2();
+}
+
+template<class N, N *N::*nextMember>
+void QForwardFieldList<N, nextMember>::clearFlag2()
+{
+    _first.clearFlag2();
+}
+
+template<class N, N *N::*nextMember>
+void QForwardFieldList<N, nextMember>::setFlag2Value(bool v)
+{
+    _first.setFlag2Value(v);
+}
+
+template<class N, N *N::*nextMember>
 QFieldList<N, nextMember>::QFieldList()
-: _first(0), _last(0), _count(0)
+: _first(0), _last(0), _flag(0), _count(0)
 {
 }
 
@@ -237,4 +381,46 @@ void QFieldList<N, nextMember>::copyAndClear(QFieldList<N, nextMember> &o)
     o._count = 0;
 }
 
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::copyAndClearAppend(QForwardFieldList<N, nextMember> &o)
+{
+    _first = 0;
+    _last = 0;
+    _count = 0;
+    while (N *n = o.takeFirst()) append(n);
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::copyAndClearPrepend(QForwardFieldList<N, nextMember> &o)
+{
+    _first = 0;
+    _last = 0;
+    _count = 0;
+    while (N *n = o.takeFirst()) prepend(n);
+}
+
+template<class N, N *N::*nextMember>
+bool QFieldList<N, nextMember>::flag() const
+{
+    return _flag;
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::setFlag()
+{
+    _flag = true;
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::clearFlag()
+{
+    _flag = false;
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::setFlagValue(bool v)
+{
+    _flag = v;
+}
+
 #endif // QFIELDLIST_P_H
index 2d50389..ac462cb 100644 (file)
@@ -69,10 +69,12 @@ public:
     inline bool flag() const;
     inline void setFlag();
     inline void clearFlag();
+    inline void setFlagValue(bool);
 
     inline bool flag2() const;
     inline void setFlag2();
     inline void clearFlag2();
+    inline void setFlag2Value(bool);
 
     inline QFlagPointer<T> &operator=(const QFlagPointer &o);
     inline QFlagPointer<T> &operator=(T *);
@@ -81,11 +83,43 @@ public:
     inline T *operator*() const;
 
 private:
-    intptr_t ptr_value;
+    quintptr ptr_value;
 
-    static const intptr_t FlagBit = 0x1;
-    static const intptr_t Flag2Bit = 0x2;
-    static const intptr_t FlagsMask = FlagBit | Flag2Bit;
+    static const quintptr FlagBit = 0x1;
+    static const quintptr Flag2Bit = 0x2;
+    static const quintptr FlagsMask = FlagBit | Flag2Bit;
+};
+
+template<typename T, typename T2>
+class QBiPointer {
+public:
+    inline QBiPointer();
+    inline QBiPointer(T *);
+    inline QBiPointer(T2 *);
+    inline QBiPointer(const QBiPointer<T, T2> &o);
+
+    inline bool isNull() const;
+    inline bool isT1() const;
+    inline bool isT2() const;
+
+    inline bool flag() const;
+    inline void setFlag();
+    inline void clearFlag();
+    inline void setFlagValue(bool);
+
+    inline QBiPointer<T, T2> &operator=(const QBiPointer<T, T2> &o);
+    inline QBiPointer<T, T2> &operator=(T *);
+    inline QBiPointer<T, T2> &operator=(T2 *);
+
+    inline T *asT1() const;
+    inline T2 *asT2() const;
+
+private:
+    quintptr ptr_value;
+
+    static const quintptr FlagBit = 0x1;
+    static const quintptr Flag2Bit = 0x2;
+    static const quintptr FlagsMask = FlagBit | Flag2Bit;
 };
 
 template<typename T>
@@ -96,7 +130,7 @@ QFlagPointer<T>::QFlagPointer()
 
 template<typename T>
 QFlagPointer<T>::QFlagPointer(T *v)
-: ptr_value(intptr_t(v))
+: ptr_value(quintptr(v))
 {
     Q_ASSERT((ptr_value & FlagsMask) == 0);
 }
@@ -132,6 +166,13 @@ void QFlagPointer<T>::clearFlag()
 }
 
 template<typename T>
+void QFlagPointer<T>::setFlagValue(bool v)
+{
+    if (v) setFlag();
+    else clearFlag();
+}
+
+template<typename T>
 bool QFlagPointer<T>::flag2() const
 {
     return ptr_value & Flag2Bit;
@@ -150,6 +191,13 @@ void QFlagPointer<T>::clearFlag2()
 }
 
 template<typename T>
+void QFlagPointer<T>::setFlag2Value(bool v)
+{
+    if (v) setFlag2();
+    else clearFlag2();
+}
+
+template<typename T>
 QFlagPointer<T> &QFlagPointer<T>::operator=(const QFlagPointer &o)
 {
     ptr_value = o.ptr_value;
@@ -159,9 +207,9 @@ QFlagPointer<T> &QFlagPointer<T>::operator=(const QFlagPointer &o)
 template<typename T>
 QFlagPointer<T> &QFlagPointer<T>::operator=(T *o)
 {
-    Q_ASSERT((intptr_t(o) & FlagsMask) == 0);
+    Q_ASSERT((quintptr(o) & FlagsMask) == 0);
 
-    ptr_value = intptr_t(o) | (ptr_value & FlagsMask);
+    ptr_value = quintptr(o) | (ptr_value & FlagsMask);
     return *this;
 }
 
@@ -177,6 +225,114 @@ T *QFlagPointer<T>::operator*() const
     return (T *)(ptr_value & ~FlagsMask);
 }
 
+template<typename T, typename T2>
+QBiPointer<T, T2>::QBiPointer()
+: ptr_value(0)
+{
+}
+
+template<typename T, typename T2>
+QBiPointer<T, T2>::QBiPointer(T *v)
+: ptr_value(quintptr(v))
+{
+    Q_ASSERT((quintptr(v) & FlagsMask) == 0);
+}
+
+template<typename T, typename T2>
+QBiPointer<T, T2>::QBiPointer(T2 *v)
+: ptr_value(quintptr(v) | Flag2Bit)
+{
+    Q_ASSERT((quintptr(v) & FlagsMask) == 0);
+}
+
+template<typename T, typename T2>
+QBiPointer<T, T2>::QBiPointer(const QBiPointer<T, T2> &o)
+: ptr_value(o.ptr_value)
+{
+}
+
+template<typename T, typename T2>
+bool QBiPointer<T, T2>::isNull() const
+{
+    return 0 == (ptr_value & (~FlagsMask));
+}
+
+template<typename T, typename T2>
+bool QBiPointer<T, T2>::isT1() const
+{
+    return !(ptr_value & Flag2Bit);
+}
+
+template<typename T, typename T2>
+bool QBiPointer<T, T2>::isT2() const
+{
+    return ptr_value & Flag2Bit;
+}
+
+template<typename T, typename T2>
+bool QBiPointer<T, T2>::flag() const
+{
+    return ptr_value & FlagBit;
+}
+
+template<typename T, typename T2>
+void QBiPointer<T, T2>::setFlag()
+{
+    ptr_value |= FlagBit;
+}
+
+template<typename T, typename T2>
+void QBiPointer<T, T2>::clearFlag()
+{
+    ptr_value &= ~FlagBit;
+}
+
+template<typename T, typename T2>
+void QBiPointer<T, T2>::setFlagValue(bool v)
+{
+    if (v) setFlag();
+    else clearFlag();
+}
+
+template<typename T, typename T2>
+QBiPointer<T, T2> &QBiPointer<T, T2>::operator=(const QBiPointer<T, T2> &o)
+{
+    ptr_value = o.ptr_value;
+    return *this;
+}
+
+template<typename T, typename T2>
+QBiPointer<T, T2> &QBiPointer<T, T2>::operator=(T *o)
+{
+    Q_ASSERT((quintptr(o) & FlagsMask) == 0);
+
+    ptr_value = quintptr(o) | (ptr_value & FlagBit);
+    return *this;
+}
+
+template<typename T, typename T2>
+QBiPointer<T, T2> &QBiPointer<T, T2>::operator=(T2 *o)
+{
+    Q_ASSERT((quintptr(o) & FlagsMask) == 0);
+
+    ptr_value = quintptr(o) | (ptr_value & FlagBit) | Flag2Bit;
+    return *this;
+}
+
+template<typename T, typename T2>
+T *QBiPointer<T, T2>::asT1() const
+{
+    Q_ASSERT(isT1());
+    return (T *)(ptr_value & ~FlagsMask);
+}
+
+template<typename T, typename T2>
+T2 *QBiPointer<T, T2>::asT2() const
+{
+    Q_ASSERT(isT2());
+    return (T2 *)(ptr_value & ~FlagsMask);
+}
+
 QT_END_NAMESPACE
 
 #endif // QFLAGPOINTER_P_H
diff --git a/src/declarative/qml/ftw/qlazilyallocated_p.h b/src/declarative/qml/ftw/qlazilyallocated_p.h
new file mode 100644 (file)
index 0000000..d5a9dcc
--- /dev/null
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLAZILYALLOCATED_P_H
+#define QLAZILYALLOCATED_P_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+#include <private/qflagpointer_p.h>
+
+QT_BEGIN_NAMESPACE
+
+template<typename T>
+class QLazilyAllocated {
+public:
+    inline QLazilyAllocated();
+    inline ~QLazilyAllocated();
+
+    inline bool isAllocated() const;
+
+    inline T *operator->() const;
+
+    inline T &value();
+    inline const T &value() const;
+
+    inline bool flag() const;
+    inline void setFlag();
+    inline void clearFlag();
+    inline void setFlagValue(bool);
+private:
+    mutable QFlagPointer<T> d;
+};
+
+template<typename T>
+QLazilyAllocated<T>::QLazilyAllocated()
+{
+}
+
+template<typename T>
+QLazilyAllocated<T>::~QLazilyAllocated()
+{
+    delete *d;
+}
+
+template<typename T>
+bool QLazilyAllocated<T>::isAllocated() const
+{
+    return !d.isNull();
+}
+
+template<typename T>
+T &QLazilyAllocated<T>::value()
+{
+    if (d.isNull()) d = new T;
+    return *(*d);
+}
+
+template<typename T>
+const T &QLazilyAllocated<T>::value() const
+{
+    if (d.isNull()) d = new T;
+    return *(*d);
+}
+
+template<typename T>
+T *QLazilyAllocated<T>::operator->() const
+{
+    return *d;
+}
+
+template<typename T>
+bool QLazilyAllocated<T>::flag() const
+{
+    return d.flag();
+}
+
+template<typename T>
+void QLazilyAllocated<T>::setFlag()
+{
+    d.setFlag();
+}
+
+template<typename T>
+void QLazilyAllocated<T>::clearFlag()
+{
+    d.clearFlag();
+}
+
+template<typename T>
+void QLazilyAllocated<T>::setFlagValue(bool v)
+{
+    d.setFlagValue(v);
+}
+
+QT_END_NAMESPACE
+
+#endif // QLAZILYALLOCATED_P_H
diff --git a/src/declarative/qml/ftw/qpointervaluepair_p.h b/src/declarative/qml/ftw/qpointervaluepair_p.h
new file mode 100644 (file)
index 0000000..fd1a770
--- /dev/null
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPOINTERVALUEPAIR_P_H
+#define QPOINTERVALUEPAIR_P_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <private/qflagpointer_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// QPointerValuePair is intended to help reduce the memory consumption of a class.
+// In the common case, QPointerValuePair behaves like a pointer.  In this mode, it
+// consumes the same memory as a regular pointer.
+// Additionally, QPointerValuePair can store an arbitrary value type in *addition*
+// to the pointer.  In this case, it uses slightly more memory than the pointer and
+// value type combined.
+// Consequently, this class is most useful in cases where a pointer is always stored
+// and a value type is rarely stored.
+template<typename P, typename V>
+class QPointerValuePair {
+public:
+    inline QPointerValuePair();
+    inline QPointerValuePair(P *);
+    inline ~QPointerValuePair();
+
+    inline bool isNull() const;
+
+    inline bool flag() const;
+    inline void setFlag();
+    inline void clearFlag();
+    inline void setFlagValue(bool);
+
+    inline QPointerValuePair<P, V> &operator=(P *);
+
+    inline P *operator->() const;
+    inline P *operator*() const;
+
+    inline bool hasValue() const;
+    inline V &value();
+    inline const V *constValue() const;
+
+private:
+    struct Value { P *pointer; V value; };
+    QBiPointer<P, Value> d;
+};
+
+template<typename P, typename V>
+QPointerValuePair<P, V>::QPointerValuePair()
+{
+}
+
+template<typename P, typename V>
+QPointerValuePair<P, V>::QPointerValuePair(P *p)
+: d(p)
+{
+}
+
+template<typename P, typename V>
+QPointerValuePair<P, V>::~QPointerValuePair()
+{
+    if (d.isT2()) delete d.asT2();
+}
+
+template<typename P, typename V>
+bool QPointerValuePair<P, V>::isNull() const
+{
+    if (d.isT1()) return 0 == d.asT1();
+    else return d.asT2()->pointer == 0;
+}
+
+template<typename P, typename V>
+bool QPointerValuePair<P, V>::flag() const
+{
+    return d.flag();
+}
+
+template<typename P, typename V>
+void QPointerValuePair<P, V>::setFlag()
+{
+    d.setFlag();
+}
+
+template<typename P, typename V>
+void QPointerValuePair<P, V>::clearFlag()
+{
+    d.clearFlag();
+}
+
+template<typename P, typename V>
+void QPointerValuePair<P, V>::setFlagValue(bool v)
+{
+    d.setFlagValue(v);
+}
+
+template<typename P, typename V>
+QPointerValuePair<P, V> &QPointerValuePair<P, V>::operator=(P *o)
+{
+    if (d.isT1()) d = o;
+    else d.asT2()->pointer = o;
+    return *this;
+}
+
+template<typename P, typename V>
+P *QPointerValuePair<P, V>::operator->() const
+{
+    if (d.isT1()) return d.asT1();
+    else return d.asT2()->pointer;
+}
+
+template<typename P, typename V>
+P *QPointerValuePair<P, V>::operator*() const
+{
+    if (d.isT1()) return d.asT1();
+    else return d.asT2()->pointer;
+}
+
+template<typename P, typename V>
+bool QPointerValuePair<P, V>::hasValue() const
+{
+    return d.isT2();
+}
+
+template<typename P, typename V>
+V &QPointerValuePair<P, V>::value()
+{
+    if (d.isT1()) {
+        P *p = d.asT1();
+        Value *value = new Value;
+        value->pointer = p;
+        d = value;
+    }
+
+    return d.asT2()->value;
+}
+
+// Will return null if hasValue() == false
+template<typename P, typename V>
+const V *QPointerValuePair<P, V>::constValue() const
+{
+    if (d.isT2()) return &d.asT2()->value;
+    else return 0;
+}
+
+QT_END_NAMESPACE
+
+#endif // QPOINTERVALUEPAIR_P_H