src/messaging/win32wce/qprivateimplementation.h
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #ifndef QPRIVATEIMPLEMENTATION_H
       
    43 #define QPRIVATEIMPLEMENTATION_H
       
    44 
       
    45 //
       
    46 //  W A R N I N G
       
    47 //  -------------
       
    48 //
       
    49 // This file is not part of the Qt Extended 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 /* Rationale:
       
    57 
       
    58 QSharedDataPointer has some deficiencies when used for implementation hiding,
       
    59 which are exposed by its use in the messaging library:
       
    60 1. It cannot easily be used with incomplete classes, requiring client classes
       
    61    to unnecessarily define destructors, copy constructors and assignment
       
    62    operators.
       
    63 2. It is not polymorphic, and must be reused redundantly where a class with
       
    64    a hidden implementation is derived from another class with a hidden
       
    65    implementation.
       
    66 3. Type-bridging functions are required to provide a supertype with access
       
    67    to the supertype data allocated within a subtype object.
       
    68 
       
    69 The QPrivateImplementation class stores a pointer to the correct destructor
       
    70 and copy-constructor, given the type of the actual object instantiated.
       
    71 This allows it to be copied and deleted in contexts where the true type of
       
    72 the implementation object is not recorded.
       
    73 
       
    74 The QPrivateImplementationPointer provides QSharedDataPointer semantics,
       
    75 providing the pointee type with necessary derived-type information. The
       
    76 pointee type must derive from QPrivateImplementation.
       
    77 
       
    78 The QPrivatelyImplemented<> template provides correct copy and assignment
       
    79 functions, and allows the shared implementation object to be cast to the
       
    80 different object types in the implementation type hierarchy.
       
    81 
       
    82 */
       
    83 
       
    84 #include "qmailglobal.h"
       
    85 #include <QtCore/qglobal.h>
       
    86 #include <QtCore/qatomic.h>
       
    87 
       
    88 class QPrivateImplementationBase
       
    89 {
       
    90 public:
       
    91     template<typename Subclass>
       
    92     inline QPrivateImplementationBase(Subclass* p)
       
    93         : ref_count(0),
       
    94           self(p),
       
    95           delete_function(&QPrivateImplementationBase::typed_delete<Subclass>),
       
    96           copy_function(&QPrivateImplementationBase::typed_copy_construct<Subclass>)
       
    97     {
       
    98     }
       
    99 
       
   100     inline QPrivateImplementationBase(const QPrivateImplementationBase& other)
       
   101         : ref_count(0),
       
   102           self(other.self),
       
   103           delete_function(other.delete_function),
       
   104           copy_function(other.copy_function)
       
   105     {
       
   106     }
       
   107 
       
   108     inline void ref()
       
   109     {
       
   110         ref_count.ref();
       
   111     }
       
   112 
       
   113     inline bool deref()
       
   114     {
       
   115         if (ref_count.deref() == 0 && delete_function && self) {
       
   116             (*delete_function)(self);
       
   117             return true;
       
   118         } else  {
       
   119             return false;
       
   120         }
       
   121     }
       
   122 
       
   123     inline void* detach()
       
   124     {
       
   125         if (copy_function && self && ref_count != 1) {
       
   126             void* copy = (*copy_function)(self);
       
   127             reinterpret_cast<QPrivateImplementationBase*>(copy)->self = copy;
       
   128             return copy;
       
   129         } else {
       
   130             return 0;
       
   131         }
       
   132     }
       
   133 
       
   134 private:
       
   135     QAtomicInt ref_count;
       
   136 
       
   137     void *self;
       
   138     void (*delete_function)(void *p);
       
   139     void *(*copy_function)(const void *p);
       
   140 
       
   141     template<class T>
       
   142     static inline void typed_delete(void *p)
       
   143     {
       
   144         delete static_cast<T*>(p);
       
   145     }
       
   146 
       
   147     template<class T>
       
   148     static inline void* typed_copy_construct(const void *p)
       
   149     {
       
   150         return new T(*static_cast<const T*>(p));
       
   151     }
       
   152 
       
   153     // using the assignment operator would lead to corruption in the ref-counting
       
   154     QPrivateImplementationBase &operator=(const QPrivateImplementationBase &);
       
   155 };
       
   156 
       
   157 template <class T> class QPrivateImplementationPointer
       
   158 {
       
   159 public:
       
   160     inline T &operator*() { return *detach(); }
       
   161     inline const T &operator*() const { return *d; }
       
   162 
       
   163     inline T *operator->() { return detach(); }
       
   164     inline const T *operator->() const { return d; }
       
   165 
       
   166     inline operator T *() { return detach(); }
       
   167     inline operator const T *() const { return d; }
       
   168 
       
   169     inline T *data() { return detach(); }
       
   170     inline const T *data() const { return d; }
       
   171 
       
   172     inline const T *constData() const { return d; }
       
   173 
       
   174     inline bool operator==(const QPrivateImplementationPointer<T> &other) const { return d == other.d; }
       
   175     inline bool operator!=(const QPrivateImplementationPointer<T> &other) const { return d != other.d; }
       
   176 
       
   177     inline QPrivateImplementationPointer()
       
   178         : d(0)
       
   179     {
       
   180     }
       
   181 
       
   182     inline explicit QPrivateImplementationPointer(T *p)
       
   183         : d(p)
       
   184     {
       
   185         increment(d);
       
   186     }
       
   187 
       
   188     template<typename U>
       
   189     inline explicit QPrivateImplementationPointer(U *p)
       
   190         : d(static_cast<T*>(p))
       
   191     {
       
   192         increment(d);
       
   193     }
       
   194 
       
   195     inline QPrivateImplementationPointer(const QPrivateImplementationPointer<T> &o)
       
   196         : d(o.d)
       
   197     {
       
   198         increment(d);
       
   199     }
       
   200 
       
   201     inline ~QPrivateImplementationPointer()
       
   202     {
       
   203         decrement(d);
       
   204     }
       
   205 
       
   206     inline QPrivateImplementationPointer<T> &operator=(T *p)
       
   207     {
       
   208         assign_helper(p);
       
   209         return *this;
       
   210     }
       
   211 
       
   212     inline QPrivateImplementationPointer<T> &operator=(const QPrivateImplementationPointer<T> &o)
       
   213     {
       
   214         assign_helper(o.d);
       
   215         return *this;
       
   216     }
       
   217 
       
   218     inline bool operator!() const { return !d; }
       
   219 
       
   220 private:
       
   221     void increment(T*& p);
       
   222 
       
   223     void decrement(T*& p);
       
   224 
       
   225     inline T* assign_helper(T *p)
       
   226     {
       
   227         if (p != d) {
       
   228             increment(p);
       
   229             decrement(d);
       
   230             d = p;
       
   231         }
       
   232         return d;
       
   233     }
       
   234 
       
   235     inline T* detach()
       
   236     {
       
   237         if (!d) return 0;
       
   238 
       
   239         if (T* detached = static_cast<T*>(d->detach())) {
       
   240             return assign_helper(detached);
       
   241         } else {
       
   242             return d;
       
   243         }
       
   244     }
       
   245 
       
   246 public:
       
   247     T *d;
       
   248 };
       
   249 
       
   250 template<typename ImplementationType>
       
   251 class QTOPIAMAIL_EXPORT QPrivatelyImplemented
       
   252 {
       
   253 public:
       
   254     QPrivatelyImplemented(ImplementationType* p);
       
   255     QPrivatelyImplemented(const QPrivatelyImplemented& other);
       
   256 
       
   257     template<typename A1>
       
   258     QTOPIAMAIL_EXPORT QPrivatelyImplemented(ImplementationType* p, A1 a1);
       
   259 
       
   260     virtual ~QPrivatelyImplemented();
       
   261 
       
   262     const QPrivatelyImplemented<ImplementationType>& operator=(const QPrivatelyImplemented<ImplementationType>& other);
       
   263 
       
   264     template<typename ImplementationSubclass>
       
   265     inline ImplementationSubclass* impl()
       
   266     {
       
   267         return static_cast<ImplementationSubclass*>(static_cast<ImplementationType*>(d));
       
   268     }
       
   269 
       
   270     template<typename InterfaceType>
       
   271     inline typename InterfaceType::ImplementationType* impl(InterfaceType*)
       
   272     {
       
   273         return impl<typename InterfaceType::ImplementationType>();
       
   274     }
       
   275 
       
   276     template<typename ImplementationSubclass>
       
   277     inline const ImplementationSubclass* impl() const
       
   278     {
       
   279         return static_cast<const ImplementationSubclass*>(static_cast<const ImplementationType*>(d));
       
   280     }
       
   281 
       
   282     template<typename InterfaceType>
       
   283     inline const typename InterfaceType::ImplementationType* impl(const InterfaceType*) const
       
   284     {
       
   285         return impl<const typename InterfaceType::ImplementationType>();
       
   286     }
       
   287 
       
   288 protected:
       
   289     QPrivateImplementationPointer<ImplementationType> d;
       
   290 };
       
   291 
       
   292 
       
   293 class QPrivateNoncopyableBase
       
   294 {
       
   295 public:
       
   296     template<typename Subclass>
       
   297     inline QPrivateNoncopyableBase(Subclass* p)
       
   298         : self(p),
       
   299           delete_function(&QPrivateNoncopyableBase::typed_delete<Subclass>)
       
   300     {
       
   301     }
       
   302 
       
   303     inline void delete_self()
       
   304     {
       
   305         if (delete_function && self) {
       
   306             (*delete_function)(self);
       
   307         }
       
   308     }
       
   309 
       
   310 private:
       
   311     void *self;
       
   312     void (*delete_function)(void *p);
       
   313 
       
   314     template<class T>
       
   315     static inline void typed_delete(void *p)
       
   316     {
       
   317         delete static_cast<T*>(p);
       
   318     }
       
   319 
       
   320     // do not permit copying
       
   321     QPrivateNoncopyableBase(const QPrivateNoncopyableBase &);
       
   322 
       
   323     QPrivateNoncopyableBase &operator=(const QPrivateNoncopyableBase &);
       
   324 };
       
   325 
       
   326 template <class T> class QPrivateNoncopyablePointer
       
   327 {
       
   328 public:
       
   329     inline T &operator*() { return *d; }
       
   330     inline const T &operator*() const { return *d; }
       
   331 
       
   332     inline T *operator->() { return d; }
       
   333     inline const T *operator->() const { return d; }
       
   334 
       
   335     inline operator T *() { return d; }
       
   336     inline operator const T *() const { return d; }
       
   337 
       
   338     inline T *data() { return d; }
       
   339     inline const T *data() const { return d; }
       
   340 
       
   341     inline const T *constData() const { return d; }
       
   342 
       
   343     inline bool operator==(const QPrivateNoncopyablePointer<T> &other) const { return d == other.d; }
       
   344     inline bool operator!=(const QPrivateNoncopyablePointer<T> &other) const { return d != other.d; }
       
   345 
       
   346     inline QPrivateNoncopyablePointer()
       
   347         : d(0)
       
   348     {
       
   349     }
       
   350 
       
   351     inline explicit QPrivateNoncopyablePointer(T *p)
       
   352         : d(p)
       
   353     {
       
   354     }
       
   355 
       
   356     template<typename U>
       
   357     inline explicit QPrivateNoncopyablePointer(U *p)
       
   358         : d(static_cast<T*>(p))
       
   359     {
       
   360     }
       
   361 
       
   362     ~QPrivateNoncopyablePointer();
       
   363 
       
   364     inline bool operator!() const { return !d; }
       
   365 
       
   366 private:
       
   367     inline QPrivateNoncopyablePointer<T> &operator=(T *) { return *this; }
       
   368 
       
   369     inline QPrivateNoncopyablePointer<T> &operator=(const QPrivateNoncopyablePointer<T> &) { return *this; }
       
   370 
       
   371 public:
       
   372     T *d;
       
   373 };
       
   374 
       
   375 template<typename ImplementationType>
       
   376 class QTOPIAMAIL_EXPORT QPrivatelyNoncopyable
       
   377 {
       
   378 public:
       
   379     QPrivatelyNoncopyable(ImplementationType* p);
       
   380 
       
   381     template<typename A1>
       
   382     QTOPIAMAIL_EXPORT QPrivatelyNoncopyable(ImplementationType* p, A1 a1);
       
   383 
       
   384     virtual ~QPrivatelyNoncopyable();
       
   385 
       
   386     template<typename ImplementationSubclass>
       
   387     inline ImplementationSubclass* impl()
       
   388     {
       
   389         return static_cast<ImplementationSubclass*>(static_cast<ImplementationType*>(d));
       
   390     }
       
   391 
       
   392     template<typename InterfaceType>
       
   393     inline typename InterfaceType::ImplementationType* impl(InterfaceType*)
       
   394     {
       
   395         return impl<typename InterfaceType::ImplementationType>();
       
   396     }
       
   397 
       
   398     template<typename ImplementationSubclass>
       
   399     inline const ImplementationSubclass* impl() const
       
   400     {
       
   401         return static_cast<const ImplementationSubclass*>(static_cast<const ImplementationType*>(d));
       
   402     }
       
   403 
       
   404     template<typename InterfaceType>
       
   405     inline const typename InterfaceType::ImplementationType* impl(const InterfaceType*) const
       
   406     {
       
   407         return impl<const typename InterfaceType::ImplementationType>();
       
   408     }
       
   409 
       
   410 protected:
       
   411     QPrivateNoncopyablePointer<ImplementationType> d;
       
   412 };
       
   413 
       
   414 #endif