Advertisement
Guest User

qsharedpointer_impl.h Qt5.2 iOS/OSX

a guest
Feb 22nd, 2014
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 28.93 KB | None | 0 0
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
  4. ** Contact: http://www.qt-project.org/legal
  5. **
  6. ** This file is part of the QtCore module of the Qt Toolkit.
  7. **
  8. ** $QT_BEGIN_LICENSE:LGPL$
  9. ** Commercial License Usage
  10. ** Licensees holding valid commercial Qt licenses may use this file in
  11. ** accordance with the commercial license agreement provided with the
  12. ** Software or, alternatively, in accordance with the terms contained in
  13. ** a written agreement between you and Digia.  For licensing terms and
  14. ** conditions see http://qt.digia.com/licensing.  For further information
  15. ** use the contact form at http://qt.digia.com/contact-us.
  16. **
  17. ** GNU Lesser General Public License Usage
  18. ** Alternatively, this file may be used under the terms of the GNU Lesser
  19. ** General Public License version 2.1 as published by the Free Software
  20. ** Foundation and appearing in the file LICENSE.LGPL included in the
  21. ** packaging of this file.  Please review the following information to
  22. ** ensure the GNU Lesser General Public License version 2.1 requirements
  23. ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  24. **
  25. ** In addition, as a special exception, Digia gives you certain additional
  26. ** rights.  These rights are described in the Digia Qt LGPL Exception
  27. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  28. **
  29. ** GNU General Public License Usage
  30. ** Alternatively, this file may be used under the terms of the GNU
  31. ** General Public License version 3.0 as published by the Free Software
  32. ** Foundation and appearing in the file LICENSE.GPL included in the
  33. ** packaging of this file.  Please review the following information to
  34. ** ensure the GNU General Public License version 3.0 requirements will be
  35. ** met: http://www.gnu.org/copyleft/gpl.html.
  36. **
  37. **
  38. ** $QT_END_LICENSE$
  39. **
  40. ****************************************************************************/
  41.  
  42. #ifndef Q_QDOC
  43.  
  44. #ifndef QSHAREDPOINTER_H
  45. #error Do not include qsharedpointer_impl.h directly
  46. #endif
  47.  
  48. #if 0
  49. #pragma qt_sync_skip_header_check
  50. #pragma qt_sync_stop_processing
  51. #endif
  52.  
  53. #if 0
  54. // These macros are duplicated here to make syncqt not complain a about
  55. // this header, as we have a "qt_sync_stop_processing" below, which in turn
  56. // is here because this file contains a template mess and duplicates the
  57. // classes found in qsharedpointer.h
  58. QT_BEGIN_NAMESPACE
  59. QT_END_NAMESPACE
  60. #pragma qt_sync_stop_processing
  61. #endif
  62.  
  63. #include <new>
  64. #include <QtCore/qatomic.h>
  65. #include <QtCore/qobject.h>    // for qobject_cast
  66. #include <QtCore/qhash.h>    // for qHash
  67.  
  68. #if defined(Q_COMPILER_RVALUE_REFS) && defined(Q_COMPILER_VARIADIC_TEMPLATES)
  69. #  include <utility>           // for std::forward
  70. #endif
  71.  
  72. QT_BEGIN_NAMESPACE
  73.  
  74.  
  75. // Macro QSHAREDPOINTER_VERIFY_AUTO_CAST
  76. //  generates a compiler error if the following construct isn't valid:
  77. //    T *ptr1;
  78. //    X *ptr2 = ptr1;
  79. //
  80. #ifdef QT_NO_DEBUG
  81. # define QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X)          qt_noop()
  82. #else
  83.  
  84. template<typename T> inline void qt_sharedpointer_cast_check(T *) { }
  85. # define QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X)          \
  86.     qt_sharedpointer_cast_check<T>(static_cast<X *>(0))
  87. #endif
  88.  
  89. //
  90. // forward declarations
  91. //
  92. template <class T> class QWeakPointer;
  93. template <class T> class QSharedPointer;
  94.  
  95. class QVariant;
  96.  
  97. template <class X, class T>
  98. QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &ptr);
  99. template <class X, class T>
  100. QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &ptr);
  101. template <class X, class T>
  102. QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &ptr);
  103.  
  104. #ifndef QT_NO_QOBJECT
  105. template <class X, class T>
  106. QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &ptr);
  107. #endif
  108.  
  109. namespace QtSharedPointer {
  110.     template <class T> class ExternalRefCount;
  111.  
  112.     template <class X, class Y> QSharedPointer<X> copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
  113.  
  114.     // used in debug mode to verify the reuse of pointers
  115.     Q_CORE_EXPORT void internalSafetyCheckAdd(const void *, const volatile void *);
  116.     Q_CORE_EXPORT void internalSafetyCheckRemove(const void *);
  117.  
  118.     template <class T, typename Klass, typename RetVal>
  119.     inline void executeDeleter(T *t, RetVal (Klass:: *memberDeleter)())
  120.     { (t->*memberDeleter)(); }
  121.     template <class T, typename Deleter>
  122.     inline void executeDeleter(T *t, Deleter d)
  123.     { d(t); }
  124.     struct NormalDeleter {};
  125.  
  126.     // this uses partial template specialization
  127.     template <class T> struct RemovePointer;
  128.     template <class T> struct RemovePointer<T *> { typedef T Type; };
  129.     template <class T> struct RemovePointer<QSharedPointer<T> > { typedef T Type; };
  130.     template <class T> struct RemovePointer<QWeakPointer<T> > { typedef T Type; };
  131.  
  132.     // This class is the d-pointer of QSharedPointer and QWeakPointer.
  133.     //
  134.     // It is a reference-counted reference counter. "strongref" is the inner
  135.     // reference counter, and it tracks the lifetime of the pointer itself.
  136.     // "weakref" is the outer reference counter and it tracks the lifetime of
  137.     // the ExternalRefCountData object.
  138.     //
  139.     // The deleter is stored in the destroyer member and is always a pointer to
  140.     // a static function in ExternalRefCountWithCustomDeleter or in
  141.     // ExternalRefCountWithContiguousData
  142.     struct ExternalRefCountData
  143.     {
  144.         typedef void (*DestroyerFn)(ExternalRefCountData *);
  145.         QBasicAtomicInt weakref;
  146.         QBasicAtomicInt strongref;
  147.         DestroyerFn destroyer;
  148.  
  149.         inline ExternalRefCountData(DestroyerFn d)
  150.             : destroyer(d)
  151.         {
  152.             strongref.store(1);
  153.             weakref.store(1);
  154.         }
  155.         inline ExternalRefCountData(Qt::Initialization) { }
  156.         ~ExternalRefCountData() { Q_ASSERT(!weakref.load()); Q_ASSERT(strongref.load() <= 0); }
  157.  
  158.         void destroy() { destroyer(this); }
  159.  
  160. #ifndef QT_NO_QOBJECT
  161.         Q_CORE_EXPORT static ExternalRefCountData *getAndRef(const QObject *);
  162.         Q_CORE_EXPORT void setQObjectShared(const QObject *, bool enable);
  163.         Q_CORE_EXPORT void checkQObjectShared(const QObject *);
  164. #endif
  165.         inline void checkQObjectShared(...) { }
  166.         inline void setQObjectShared(...) { }
  167.  
  168.         inline void operator delete(void *ptr) { ::operator delete(ptr); }
  169.         inline void operator delete(void *, void *) { }
  170.     };
  171.     // sizeof(ExternalRefCountData) = 12 (32-bit) / 16 (64-bit)
  172.  
  173.     template <class T, typename Deleter>
  174.     struct CustomDeleter
  175.     {
  176.         Deleter deleter;
  177.         T *ptr;
  178.  
  179.         CustomDeleter(T *p, Deleter d) : deleter(d), ptr(p) {}
  180.         void execute() { executeDeleter(ptr, deleter); }
  181.     };
  182.     // sizeof(CustomDeleter) = sizeof(Deleter) + sizeof(void*) + padding
  183.     // for Deleter = stateless functor: 8 (32-bit) / 16 (64-bit) due to padding
  184.     // for Deleter = function pointer:  8 (32-bit) / 16 (64-bit)
  185.     // for Deleter = PMF: 12 (32-bit) / 24 (64-bit)  (GCC)
  186.  
  187.     // This specialization of CustomDeleter for a deleter of type NormalDeleter
  188.     // is an optimization: instead of storing a pointer to a function that does
  189.     // the deleting, we simply delete the pointer ourselves.
  190.     template <class T>
  191.     struct CustomDeleter<T, NormalDeleter>
  192.     {
  193.         T *ptr;
  194.  
  195.         CustomDeleter(T *p, NormalDeleter) : ptr(p) {}
  196.         void execute() { delete ptr; }
  197.     };
  198.     // sizeof(CustomDeleter specialization) = sizeof(void*)
  199.  
  200.     // This class extends ExternalRefCountData and implements
  201.     // the static function that deletes the object. The pointer and the
  202.     // custom deleter are kept in the "extra" member so we can construct
  203.     // and destruct it independently of the full structure.
  204.     template <class T, typename Deleter>
  205.     struct ExternalRefCountWithCustomDeleter: public ExternalRefCountData
  206.     {
  207.         typedef ExternalRefCountWithCustomDeleter Self;
  208.         typedef ExternalRefCountData BaseClass;
  209.         CustomDeleter<T, Deleter> extra;
  210.  
  211.         static inline void deleter(ExternalRefCountData *self)
  212.         {
  213.             Self *realself = static_cast<Self *>(self);
  214.             realself->extra.execute();
  215.  
  216.             // delete the deleter too
  217.             realself->extra.~CustomDeleter<T, Deleter>();
  218.         }
  219.         static void safetyCheckDeleter(ExternalRefCountData *self)
  220.         {
  221.             internalSafetyCheckRemove(self);
  222.             deleter(self);
  223.         }
  224.  
  225.         static inline Self *create(T *ptr, Deleter userDeleter, DestroyerFn actualDeleter)
  226.         {
  227.             Self *d = static_cast<Self *>(::operator new(sizeof(Self)));
  228.  
  229.             // initialize the two sub-objects
  230.             new (&d->extra) CustomDeleter<T, Deleter>(ptr, userDeleter);
  231.             new (d) BaseClass(actualDeleter); // can't throw
  232.  
  233.             return d;
  234.         }
  235.     private:
  236.         // prevent construction
  237.         ExternalRefCountWithCustomDeleter() Q_DECL_EQ_DELETE;
  238.         ~ExternalRefCountWithCustomDeleter() Q_DECL_EQ_DELETE;
  239.         Q_DISABLE_COPY(ExternalRefCountWithCustomDeleter)
  240.     };
  241.  
  242.     // This class extends ExternalRefCountData and adds a "T"
  243.     // member. That way, when the create() function is called, we allocate
  244.     // memory for both QSharedPointer's d-pointer and the actual object being
  245.     // tracked.
  246.     template <class T>
  247.     struct ExternalRefCountWithContiguousData: public ExternalRefCountData
  248.     {
  249.         typedef ExternalRefCountData Parent;
  250.         T data;
  251.  
  252.         static void deleter(ExternalRefCountData *self)
  253.         {
  254.             ExternalRefCountWithContiguousData *that =
  255.                     static_cast<ExternalRefCountWithContiguousData *>(self);
  256.             that->data.~T();
  257.         }
  258.         static void safetyCheckDeleter(ExternalRefCountData *self)
  259.         {
  260.             internalSafetyCheckRemove(self);
  261.             deleter(self);
  262.         }
  263.  
  264.         static inline ExternalRefCountData *create(T **ptr, DestroyerFn destroy)
  265.         {
  266.             ExternalRefCountWithContiguousData *d =
  267.                 static_cast<ExternalRefCountWithContiguousData *>(::operator new(sizeof(ExternalRefCountWithContiguousData)));
  268.  
  269.             // initialize the d-pointer sub-object
  270.             // leave d->data uninitialized
  271.             new (d) Parent(destroy); // can't throw
  272.  
  273.             *ptr = &d->data;
  274.             return d;
  275.         }
  276.  
  277.     private:
  278.         // prevent construction
  279.         ExternalRefCountWithContiguousData() Q_DECL_EQ_DELETE;
  280.         ~ExternalRefCountWithContiguousData() Q_DECL_EQ_DELETE;
  281.         Q_DISABLE_COPY(ExternalRefCountWithContiguousData)
  282.     };
  283.  
  284. #ifndef QT_NO_QOBJECT
  285.     Q_CORE_EXPORT QWeakPointer<QObject> weakPointerFromVariant_internal(const QVariant &variant);
  286.     Q_CORE_EXPORT QSharedPointer<QObject> sharedPointerFromVariant_internal(const QVariant &variant);
  287. #endif
  288. } // namespace QtSharedPointer
  289.  
  290. template <class T> class QSharedPointer
  291. {
  292.     typedef T *QSharedPointer:: *RestrictedBool;
  293.     typedef QtSharedPointer::ExternalRefCountData Data;
  294. public:
  295.     typedef T Type;
  296.     typedef T element_type;
  297.     typedef T value_type;
  298.     typedef value_type *pointer;
  299.     typedef const value_type *const_pointer;
  300.     typedef value_type &reference;
  301.     typedef const value_type &const_reference;
  302.     typedef qptrdiff difference_type;
  303.  
  304.     inline T *matrixData() const { return value; }
  305.     inline bool isNull() const { return !matrixData(); }
  306.     inline operator RestrictedBool() const { return isNull() ? 0 : &QSharedPointer::value; }
  307.     inline bool operator !() const { return isNull(); }
  308.     inline T &operator*() const { return *matrixData(); }
  309.     inline T *operator->() const { return matrixData(); }
  310.  
  311.     QSharedPointer() : value(0), d(0) { }
  312.     ~QSharedPointer() { deref(); }
  313.  
  314.     inline explicit QSharedPointer(T *ptr) : value(ptr) // noexcept
  315.     { internalConstruct(ptr, QtSharedPointer::NormalDeleter()); }
  316.  
  317.     template <typename Deleter>
  318.     inline QSharedPointer(T *ptr, Deleter deleter) : value(ptr) // throws
  319.     { internalConstruct(ptr, deleter); }
  320.  
  321.     inline QSharedPointer(const QSharedPointer<T> &other) : value(other.value), d(other.d)
  322.     { if (d) ref(); }
  323.     inline QSharedPointer<T> &operator=(const QSharedPointer<T> &other)
  324.     {
  325.         QSharedPointer copy(other);
  326.         swap(copy);
  327.         return *this;
  328.     }
  329. #ifdef Q_COMPILER_RVALUE_REFS
  330.     inline QSharedPointer<T> &operator=(QSharedPointer<T> &&other)
  331.     {
  332.         swap(other);
  333.         return *this;
  334.     }
  335. #endif
  336.  
  337.     template <class X>
  338.     inline QSharedPointer(const QSharedPointer<X> &other) : value(other.value), d(other.d)
  339.     { if (d) ref(); }
  340.  
  341.     template <class X>
  342.     inline QSharedPointer<T> &operator=(const QSharedPointer<X> &other)
  343.     {
  344.         QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X); // if you get an error in this line, the cast is invalid
  345.         internalCopy(other);
  346.         return *this;
  347.     }
  348.  
  349.     template <class X>
  350.     inline QSharedPointer(const QWeakPointer<X> &other) : value(0), d(0)
  351.     { *this = other; }
  352.  
  353.     template <class X>
  354.     inline QSharedPointer<T> &operator=(const QWeakPointer<X> &other)
  355.     { internalSet(other.d, other.value); return *this; }
  356.  
  357.     inline void swap(QSharedPointer &other)
  358.     { QSharedPointer<T>::internalSwap(other); }
  359.  
  360.     inline void reset() { clear(); }
  361.     inline void reset(T *t)
  362.     { QSharedPointer copy(t); swap(copy); }
  363.     template <typename Deleter>
  364.     inline void reset(T *t, Deleter deleter)
  365.     { QSharedPointer copy(t, deleter); swap(copy); }
  366.  
  367.     template <class X>
  368.     QSharedPointer<X> staticCast() const
  369.     {
  370.         return qSharedPointerCast<X, T>(*this);
  371.     }
  372.  
  373.     template <class X>
  374.     QSharedPointer<X> dynamicCast() const
  375.     {
  376.         return qSharedPointerDynamicCast<X, T>(*this);
  377.     }
  378.  
  379.     template <class X>
  380.     QSharedPointer<X> constCast() const
  381.     {
  382.         return qSharedPointerConstCast<X, T>(*this);
  383.     }
  384.  
  385. #ifndef QT_NO_QOBJECT
  386.     template <class X>
  387.     QSharedPointer<X> objectCast() const
  388.     {
  389.         return qSharedPointerObjectCast<X, T>(*this);
  390.     }
  391. #endif
  392.  
  393.     inline void clear() { QSharedPointer copy; swap(copy); }
  394.  
  395.     QWeakPointer<T> toWeakRef() const;
  396.  
  397. #if defined(Q_COMPILER_RVALUE_REFS) && defined(Q_COMPILER_VARIADIC_TEMPLATES)
  398.     template <typename... Args>
  399.     static QSharedPointer<T> create(Args && ...arguments)
  400.     {
  401.         typedef QtSharedPointer::ExternalRefCountWithContiguousData<T> Private;
  402. # ifdef QT_SHAREDPOINTER_TRACK_POINTERS
  403.         typename Private::DestroyerFn destroy = &Private::safetyCheckDeleter;
  404. # else
  405.         typename Private::DestroyerFn destroy = &Private::deleter;
  406. # endif
  407.         QSharedPointer<T> result(Qt::Uninitialized);
  408.         result.d = Private::create(&result.value, destroy);
  409.  
  410.         // now initialize the data
  411.         new (result.data()) T(std::forward<Args>(arguments)...);
  412.         result.d->setQObjectShared(result.value, true);
  413. # ifdef QT_SHAREDPOINTER_TRACK_POINTERS
  414.         internalSafetyCheckAdd(result.d, result.value);
  415. # endif
  416.         return result;
  417.     }
  418. #else
  419.     static inline QSharedPointer<T> create()
  420.     {
  421.         typedef QtSharedPointer::ExternalRefCountWithContiguousData<T> Private;
  422. # ifdef QT_SHAREDPOINTER_TRACK_POINTERS
  423.         typename Private::DestroyerFn destroy = &Private::safetyCheckDeleter;
  424. # else
  425.         typename Private::DestroyerFn destroy = &Private::deleter;
  426. # endif
  427.         QSharedPointer<T> result(Qt::Uninitialized);
  428.         result.d = Private::create(&result.value, destroy);
  429.  
  430.         // now initialize the data
  431.         new (result.matrixData()) T();
  432. # ifdef QT_SHAREDPOINTER_TRACK_POINTERS
  433.         internalSafetyCheckAdd(result.d, result.value);
  434. # endif
  435.         result.d->setQObjectShared(result.value, true);
  436.         return result;
  437.     }
  438. #endif
  439.  
  440. private:
  441.     explicit QSharedPointer(Qt::Initialization) {}
  442.  
  443.     inline void deref()
  444.     { deref(d); }
  445.     static inline void deref(Data *d)
  446.     {
  447.         if (!d) return;
  448.         if (!d->strongref.deref()) {
  449.             d->destroy();
  450.         }
  451.         if (!d->weakref.deref())
  452.             delete d;
  453.     }
  454.  
  455.     template <typename Deleter>
  456.     inline void internalConstruct(T *ptr, Deleter deleter)
  457.     {
  458.         if (!ptr) {
  459.             d = 0;
  460.             return;
  461.         }
  462.  
  463.         typedef QtSharedPointer::ExternalRefCountWithCustomDeleter<T, Deleter> Private;
  464. # ifdef QT_SHAREDPOINTER_TRACK_POINTERS
  465.         typename Private::DestroyerFn actualDeleter = &Private::safetyCheckDeleter;
  466. # else
  467.         typename Private::DestroyerFn actualDeleter = &Private::deleter;
  468. # endif
  469.         d = Private::create(ptr, deleter, actualDeleter);
  470.  
  471. #ifdef QT_SHAREDPOINTER_TRACK_POINTERS
  472.         internalSafetyCheckAdd(d, ptr);
  473. #endif
  474.         d->setQObjectShared(ptr, true);
  475.     }
  476.  
  477.     template <class X>
  478.     inline void internalCopy(const QSharedPointer<X> &other)
  479.     {
  480.         Data *o = other.d;
  481.         T *actual = other.value;
  482.         if (o)
  483.             other.ref();
  484.         qSwap(d, o);
  485.         qSwap(this->value, actual);
  486.         deref(o);
  487.     }
  488.  
  489.     inline void internalSwap(QSharedPointer &other)
  490.     {
  491.         qSwap(d, other.d);
  492.         qSwap(this->value, other.value);
  493.     }
  494.  
  495. #if defined(Q_NO_TEMPLATE_FRIENDS)
  496. public:
  497. #else
  498.     template <class X> friend class QSharedPointer;
  499.     template <class X> friend class QWeakPointer;
  500.     template <class X, class Y> friend QSharedPointer<X> QtSharedPointer::copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
  501. #endif
  502.     inline void ref() const { d->weakref.ref(); d->strongref.ref(); }
  503.  
  504.     inline void internalSet(Data *o, T *actual)
  505.     {
  506.         if (o) {
  507.             // increase the strongref, but never up from zero
  508.             // or less (-1 is used by QWeakPointer on untracked QObject)
  509.             int tmp = o->strongref.load();
  510.             while (tmp > 0) {
  511.                 // try to increment from "tmp" to "tmp + 1"
  512.                 if (o->strongref.testAndSetRelaxed(tmp, tmp + 1))
  513.                     break;   // succeeded
  514.                 tmp = o->strongref.load();  // failed, try again
  515.             }
  516.  
  517.             if (tmp > 0) {
  518.                 o->weakref.ref();
  519.             } else {
  520.                 o->checkQObjectShared(actual);
  521.                 o = 0;
  522.             }
  523.         }
  524.  
  525.         qSwap(d, o);
  526.         qSwap(this->value, actual);
  527.         if (!d || d->strongref.load() == 0)
  528.             this->value = 0;
  529.  
  530.         // dereference saved data
  531.         deref(o);
  532.     }
  533.  
  534.     Type *value;
  535.     Data *d;
  536. };
  537.  
  538. template <class T>
  539. class QWeakPointer
  540. {
  541.     typedef T *QWeakPointer:: *RestrictedBool;
  542.     typedef QtSharedPointer::ExternalRefCountData Data;
  543.  
  544. public:
  545.     typedef T element_type;
  546.     typedef T value_type;
  547.     typedef value_type *pointer;
  548.     typedef const value_type *const_pointer;
  549.     typedef value_type &reference;
  550.     typedef const value_type &const_reference;
  551.     typedef qptrdiff difference_type;
  552.  
  553.     inline bool isNull() const { return d == 0 || d->strongref.load() == 0 || value == 0; }
  554.     inline operator RestrictedBool() const { return isNull() ? 0 : &QWeakPointer::value; }
  555.     inline bool operator !() const { return isNull(); }
  556.     inline T *data() const { return d == 0 || d->strongref.load() == 0 ? 0 : value; }
  557.  
  558.     inline QWeakPointer() : d(0), value(0) { }
  559.     inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; }
  560.  
  561. #ifndef QT_NO_QOBJECT
  562.     // special constructor that is enabled only if X derives from QObject
  563. #if QT_DEPRECATED_SINCE(5, 0)
  564.     template <class X>
  565.     QT_DEPRECATED inline QWeakPointer(X *ptr) : d(ptr ? Data::getAndRef(ptr) : 0), value(ptr)
  566.     { }
  567. #endif
  568. #endif
  569.  
  570. #if QT_DEPRECATED_SINCE(5, 0)
  571.     template <class X>
  572.     QT_DEPRECATED inline QWeakPointer &operator=(X *ptr)
  573.     { return *this = QWeakPointer(ptr); }
  574. #endif
  575.  
  576.     inline QWeakPointer(const QWeakPointer<T> &o) : d(o.d), value(o.value)
  577.     { if (d) d->weakref.ref(); }
  578.     inline QWeakPointer<T> &operator=(const QWeakPointer<T> &o)
  579.     {
  580.         internalSet(o.d, o.value);
  581.         return *this;
  582.     }
  583.  
  584.     inline QWeakPointer(const QSharedPointer<T> &o) : d(o.d), value(o.matrixData())
  585.     { if (d) d->weakref.ref();}
  586.     inline QWeakPointer<T> &operator=(const QSharedPointer<T> &o)
  587.     {
  588.         internalSet(o.d, o.value);
  589.         return *this;
  590.     }
  591.  
  592.     template <class X>
  593.     inline QWeakPointer(const QWeakPointer<X> &o) : d(0), value(0)
  594.     { *this = o; }
  595.  
  596.     template <class X>
  597.     inline QWeakPointer<T> &operator=(const QWeakPointer<X> &o)
  598.     {
  599.         // conversion between X and T could require access to the virtual table
  600.         // so force the operation to go through QSharedPointer
  601.         *this = o.toStrongRef();
  602.         return *this;
  603.     }
  604.  
  605.     template <class X>
  606.     inline bool operator==(const QWeakPointer<X> &o) const
  607.     { return d == o.d && value == static_cast<const T *>(o.value); }
  608.  
  609.     template <class X>
  610.     inline bool operator!=(const QWeakPointer<X> &o) const
  611.     { return !(*this == o); }
  612.  
  613.     template <class X>
  614.     inline QWeakPointer(const QSharedPointer<X> &o) : d(0), value(0)
  615.     { *this = o; }
  616.  
  617.     template <class X>
  618.     inline QWeakPointer<T> &operator=(const QSharedPointer<X> &o)
  619.     {
  620.         QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X); // if you get an error in this line, the cast is invalid
  621.         internalSet(o.d, o.matrixData());
  622.         return *this;
  623.     }
  624.  
  625.     template <class X>
  626.     inline bool operator==(const QSharedPointer<X> &o) const
  627.     { return d == o.d; }
  628.  
  629.     template <class X>
  630.     inline bool operator!=(const QSharedPointer<X> &o) const
  631.     { return !(*this == o); }
  632.  
  633.     inline void clear() { *this = QWeakPointer<T>(); }
  634.  
  635.     inline QSharedPointer<T> toStrongRef() const { return QSharedPointer<T>(*this); }
  636.  
  637. #if defined(QWEAKPOINTER_ENABLE_ARROW)
  638.     inline T *operator->() const { return data(); }
  639. #endif
  640.  
  641. private:
  642.  
  643. #if defined(Q_NO_TEMPLATE_FRIENDS)
  644. public:
  645. #else
  646.     template <class X> friend class QSharedPointer;
  647.     template <class X> friend class QPointer;
  648. #endif
  649.  
  650.     template <class X>
  651.     inline QWeakPointer &assign(X *ptr)
  652.     { return *this = QWeakPointer<X>(ptr, true); }
  653.  
  654. #ifndef QT_NO_QOBJECT
  655.     template <class X>
  656.     inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : 0), value(ptr)
  657.     { }
  658. #endif
  659.  
  660.     inline void internalSet(Data *o, T *actual)
  661.     {
  662.         if (d == o) return;
  663.         if (o)
  664.             o->weakref.ref();
  665.         if (d && !d->weakref.deref())
  666.             delete d;
  667.         d = o;
  668.         value = actual;
  669.     }
  670.  
  671.     Data *d;
  672.     T *value;
  673. };
  674.  
  675. //
  676. // operator== and operator!=
  677. //
  678. template <class T, class X>
  679. bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
  680. {
  681.     return ptr1.matrixData() == ptr2.matrixData();
  682. }
  683. template <class T, class X>
  684. bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
  685. {
  686.     return ptr1.matrixData() != ptr2.matrixData();
  687. }
  688.  
  689. template <class T, class X>
  690. bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2)
  691. {
  692.     return ptr1.matrixData() == ptr2;
  693. }
  694. template <class T, class X>
  695. bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2)
  696. {
  697.     return ptr1 == ptr2.matrixData();
  698. }
  699. template <class T, class X>
  700. bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2)
  701. {
  702.     return !(ptr1 == ptr2);
  703. }
  704. template <class T, class X>
  705. bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2)
  706. {
  707.     return !(ptr2 == ptr1);
  708. }
  709.  
  710. template <class T, class X>
  711. bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
  712. {
  713.     return ptr2 == ptr1;
  714. }
  715. template <class T, class X>
  716. bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
  717. {
  718.     return ptr2 != ptr1;
  719. }
  720.  
  721. //
  722. // operator-
  723. //
  724. template <class T, class X>
  725. Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
  726. {
  727.     return ptr1.matrixData() - ptr2.matrixData();
  728. }
  729. template <class T, class X>
  730. Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, X *ptr2)
  731. {
  732.     return ptr1.matrixData() - ptr2;
  733. }
  734. template <class T, class X>
  735. Q_INLINE_TEMPLATE typename QSharedPointer<X>::difference_type operator-(T *ptr1, const QSharedPointer<X> &ptr2)
  736. {
  737.     return ptr1 - ptr2.matrixData();
  738. }
  739.  
  740. //
  741. // operator<
  742. //
  743. template <class T, class X>
  744. Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
  745. {
  746.     return ptr1.matrixData() < ptr2.matrixData();
  747. }
  748. template <class T, class X>
  749. Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, X *ptr2)
  750. {
  751.     return ptr1.matrixData() < ptr2;
  752. }
  753. template <class T, class X>
  754. Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer<X> &ptr2)
  755. {
  756.     return ptr1 < ptr2.matrixData();
  757. }
  758.  
  759. //
  760. // qHash
  761. //
  762. template <class T>
  763. Q_INLINE_TEMPLATE uint qHash(const QSharedPointer<T> &ptr, uint seed = 0)
  764. {
  765.     return QT_PREPEND_NAMESPACE(qHash)(ptr.matrixData(), seed);
  766. }
  767.  
  768.  
  769. template <class T>
  770. Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef() const
  771. {
  772.     return QWeakPointer<T>(*this);
  773. }
  774.  
  775. template <class T>
  776. inline void qSwap(QSharedPointer<T> &p1, QSharedPointer<T> &p2)
  777. {
  778.     p1.swap(p2);
  779. }
  780.  
  781. QT_END_NAMESPACE
  782. namespace std {
  783.     template <class T>
  784.     inline void swap(QT_PREPEND_NAMESPACE(QSharedPointer)<T> &p1, QT_PREPEND_NAMESPACE(QSharedPointer)<T> &p2)
  785.     { p1.swap(p2); }
  786. }
  787. QT_BEGIN_NAMESPACE
  788.  
  789. namespace QtSharedPointer {
  790. // helper functions:
  791.     template <class X, class T>
  792.     Q_INLINE_TEMPLATE QSharedPointer<X> copyAndSetPointer(X *ptr, const QSharedPointer<T> &src)
  793.     {
  794.         QSharedPointer<X> result;
  795.         result.internalSet(src.d, ptr);
  796.         return result;
  797.     }
  798. }
  799.  
  800. // cast operators
  801. template <class X, class T>
  802. Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &src)
  803. {
  804.     X *ptr = static_cast<X *>(src.matrixData()); // if you get an error in this line, the cast is invalid
  805.     return QtSharedPointer::copyAndSetPointer(ptr, src);
  806. }
  807. template <class X, class T>
  808. Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &src)
  809. {
  810.     return qSharedPointerCast<X, T>(src.toStrongRef());
  811. }
  812.  
  813. template <class X, class T>
  814. Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src)
  815. {
  816.     X *ptr = dynamic_cast<X *>(src.matrixData()); // if you get an error in this line, the cast is invalid
  817.     if (!ptr)
  818.         return QSharedPointer<X>();
  819.     return QtSharedPointer::copyAndSetPointer(ptr, src);
  820. }
  821. template <class X, class T>
  822. Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &src)
  823. {
  824.     return qSharedPointerDynamicCast<X, T>(src.toStrongRef());
  825. }
  826.  
  827. template <class X, class T>
  828. Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src)
  829. {
  830.     X *ptr = const_cast<X *>(src.matrixData()); // if you get an error in this line, the cast is invalid
  831.     return QtSharedPointer::copyAndSetPointer(ptr, src);
  832. }
  833. template <class X, class T>
  834. Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &src)
  835. {
  836.     return qSharedPointerConstCast<X, T>(src.toStrongRef());
  837. }
  838.  
  839. template <class X, class T>
  840. Q_INLINE_TEMPLATE
  841. QWeakPointer<X> qWeakPointerCast(const QSharedPointer<T> &src)
  842. {
  843.     return qSharedPointerCast<X, T>(src).toWeakRef();
  844. }
  845.  
  846. #ifndef QT_NO_QOBJECT
  847. template <class X, class T>
  848. Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &src)
  849. {
  850.     X *ptr = qobject_cast<X *>(src.matrixData());
  851.     return QtSharedPointer::copyAndSetPointer(ptr, src);
  852. }
  853. template <class X, class T>
  854. Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer<T> &src)
  855. {
  856.     return qSharedPointerObjectCast<X>(src.toStrongRef());
  857. }
  858.  
  859. template <class X, class T>
  860. inline QSharedPointer<typename QtSharedPointer::RemovePointer<X>::Type>
  861. qobject_cast(const QSharedPointer<T> &src)
  862. {
  863.     return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src);
  864. }
  865. template <class X, class T>
  866. inline QSharedPointer<typename QtSharedPointer::RemovePointer<X>::Type>
  867. qobject_cast(const QWeakPointer<T> &src)
  868. {
  869.     return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src);
  870. }
  871.  
  872. template<typename T>
  873. QWeakPointer<typename QtPrivate::QEnableIf<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::Type>
  874. qWeakPointerFromVariant(const QVariant &variant)
  875. {
  876.     return QWeakPointer<T>(qobject_cast<T*>(QtSharedPointer::weakPointerFromVariant_internal(variant).data()));
  877. }
  878. template<typename T>
  879. QSharedPointer<typename QtPrivate::QEnableIf<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::Type>
  880. qSharedPointerFromVariant(const QVariant &variant)
  881. {
  882.     return qSharedPointerObjectCast<T>(QtSharedPointer::sharedPointerFromVariant_internal(variant));
  883. }
  884.  
  885. #endif
  886.  
  887. template<typename T> Q_DECLARE_TYPEINFO_BODY(QWeakPointer<T>, Q_MOVABLE_TYPE);
  888. template<typename T> Q_DECLARE_TYPEINFO_BODY(QSharedPointer<T>, Q_MOVABLE_TYPE);
  889.  
  890.  
  891. QT_END_NAMESPACE
  892.  
  893. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement