• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • KDE Home
  • Contact Us
 

akonadi

itempayloadinternals_p.h
00001 /*
00002     Copyright (c) 2007 Till Adam <adam@kde.org>
00003 
00004     This library is free software; you can redistribute it and/or modify it
00005     under the terms of the GNU Library General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or (at your
00007     option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful, but WITHOUT
00010     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00011     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00012     License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to the
00016     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017     02110-1301, USA.
00018 */
00019 
00020 #ifndef ITEMPAYLOADINTERNALS_P_H
00021 #define ITEMPAYLOADINTERNALS_P_H
00022 
00023 #include <kpimutils/supertrait.h>
00024 
00025 #include <QtCore/QtGlobal>
00026 #include <QtCore/QSharedPointer>
00027 #include <QtCore/QMetaType>
00028 
00029 #include <boost/shared_ptr.hpp>
00030 #include <boost/type_traits/is_same.hpp>
00031 #include <boost/mpl/eval_if.hpp>
00032 #include <boost/mpl/identity.hpp>
00033 #include <boost/utility/enable_if.hpp>
00034 
00035 #include <typeinfo>
00036 
00037 #include "exception.h"
00038 
00039 //@cond PRIVATE Doxygen 1.7.1 hangs processing this file. so skip it.
00040 //for more info, see https://bugzilla.gnome.org/show_bug.cgi?id=531637
00041 
00042 /* WARNING
00043  * The below is an implementation detail of the Item class. It is not to be
00044  * considered public API, and subject to change without notice
00045  */
00046 
00047 namespace Akonadi {
00048 namespace Internal {
00049 
00050 template <typename T>
00051 struct has_clone_method {
00052 private:
00053     template <typename S, S * (S::*)() const> struct sfinae {};
00054     struct No {};
00055     struct Yes { No no[2]; };
00056     template <typename S> static No  test( ... );
00057     template <typename S> static Yes test( sfinae<S,&S::clone> * );
00058 public:
00059     static const bool value = sizeof( test<T>(0) ) == sizeof( Yes ) ;
00060 };
00061 
00062 template <typename T, bool b>
00063 struct clone_traits_helper {
00064     // runtime error (commented in) or compiletime error (commented out)?
00065     // ### runtime error, until we check has_clone_method in the
00066     // ### Item::payload<T> impl directly...
00067     template <typename U>
00068     static T * clone( U ) { return 0; }
00069 };
00070 
00071 template <typename T>
00072 struct clone_traits_helper<T,true> {
00073     static T * clone( T * t ) { return t ? t->clone() : 0 ; }
00074 };
00075 
00076 template <typename T>
00077 struct clone_traits : clone_traits_helper<T, has_clone_method<T>::value> {};
00078 
00079 template <typename T>
00080 struct shared_pointer_traits {
00081     static const bool defined = false;
00082 };
00083 
00084 template <typename T>
00085 struct shared_pointer_traits< boost::shared_ptr<T> > {
00086     static const bool defined = true;
00087     typedef T element_type;
00088     template <typename S>
00089     struct make { typedef boost::shared_ptr<S> type; };
00090     typedef QSharedPointer<T> next_shared_ptr;
00091 };
00092 
00093 template <typename T>
00094 struct shared_pointer_traits< QSharedPointer<T> > {
00095     static const bool defined = true;
00096     typedef T element_type;
00097     template <typename S>
00098     struct make { typedef QSharedPointer<S> type; };
00099     typedef boost::shared_ptr<T> next_shared_ptr;
00100 };
00101 
00102 template <typename T>
00103 struct is_shared_pointer {
00104     static const bool value = shared_pointer_traits<T>::defined;
00105 };
00106 
00107 template <typename T>
00108 struct get_hierarchy_root;
00109 
00110 template <typename T, typename S>
00111 struct get_hierarchy_root_recurse
00112     : get_hierarchy_root<S> {};
00113 
00114 template <typename T>
00115 struct get_hierarchy_root_recurse<T,T>
00116     : boost::mpl::identity<T> {};
00117 
00118 template <typename T>
00119 struct get_hierarchy_root
00120     : get_hierarchy_root_recurse< T, typename ::KPIMUtils::SuperClass<T>::Type > {};
00121 
00122 template <typename T>
00123 struct get_hierarchy_root< boost::shared_ptr<T> > {
00124     typedef boost::shared_ptr< typename get_hierarchy_root<T>::type > type;
00125 };
00126 
00127 template <typename T>
00128 struct get_hierarchy_root< QSharedPointer<T> > {
00129     typedef QSharedPointer< typename get_hierarchy_root<T>::type > type;
00130 };
00131 
00132 
00139 template <typename T> struct PayloadTrait
00140 {
00142   typedef T ElementType;
00143   // the metatype id for the element type, or for pointer-to-element
00144   // type, if in a shared pointer
00145   static int elementMetaTypeId() { return qMetaTypeId<T>(); }
00148   typedef typename KPIMUtils::SuperClass<T>::Type SuperElementType;
00150   typedef T Type;
00154   typedef typename KPIMUtils::SuperClass<T>::Type SuperType;
00157   static const bool isPolymorphic = false;
00159   static inline bool isNull( const Type & ) { return true; }
00162   template <typename U> static inline Type castFrom( const U& )
00163   {
00164     throw PayloadException( "you should never get here" );
00165   }
00167   template <typename U> static inline bool canCastFrom( const U& )
00168   {
00169     return false;
00170   }
00172   template <typename U> static inline U castTo( const Type& )
00173   {
00174     throw PayloadException( "you should never get here" );
00175   }
00176   template <typename U> static T clone( const U & )
00177   {
00178     throw PayloadException( "clone: you should never get here" );
00179   }
00181   static const unsigned int sharedPointerId = 0;
00182 };
00183 
00189 template <typename T> struct PayloadTrait<boost::shared_ptr<T> >
00190 {
00191   typedef T ElementType;
00192   static int elementMetaTypeId() { return qMetaTypeId<T*>(); }
00193   typedef typename KPIMUtils::SuperClass<T>::Type SuperElementType;
00194   typedef boost::shared_ptr<ElementType> Type;
00195   typedef boost::shared_ptr<SuperElementType> SuperType;
00196   static const bool isPolymorphic = !boost::is_same<ElementType, SuperElementType>::value;
00197   static inline bool isNull( const Type &p ) { return p.get() == 0; }
00198   template <typename U> static inline Type castFrom( const boost::shared_ptr<U> &p )
00199   {
00200     const Type sp = boost::dynamic_pointer_cast<T,U>( p );
00201     if ( sp.get() != 0 || p.get() == 0 )
00202       return sp;
00203     throw PayloadException( "boost::dynamic_pointer_cast failed" );
00204   }
00205   template <typename U> static inline bool canCastFrom( const boost::shared_ptr<U> &p )
00206   {
00207     const Type sp = boost::dynamic_pointer_cast<T,U>( p );
00208     return sp.get() != 0 || p.get() == 0;
00209   }
00210   template <typename U> static inline boost::shared_ptr<U> castTo( const Type &p )
00211   {
00212     const boost::shared_ptr<U> sp = boost::dynamic_pointer_cast<U>( p );
00213     return sp;
00214   }
00215   static boost::shared_ptr<T> clone( const QSharedPointer<T> & t ) {
00216       if ( T * nt = clone_traits<T>::clone( t.data() ) )
00217           return boost::shared_ptr<T>( nt );
00218       else
00219           return boost::shared_ptr<T>();
00220   }
00221   static const unsigned int sharedPointerId = 1;
00222 };
00223 
00229 template <typename T> struct PayloadTrait<QSharedPointer<T> >
00230 {
00231   typedef T ElementType;
00232   static int elementMetaTypeId() { return qMetaTypeId<T*>(); }
00233   typedef typename KPIMUtils::SuperClass<T>::Type SuperElementType;
00234   typedef QSharedPointer<T> Type;
00235   typedef QSharedPointer<SuperElementType> SuperType;
00236   static const bool isPolymorphic = !boost::is_same<ElementType, SuperElementType>::value;
00237   static inline bool isNull( const Type &p ) { return p.isNull(); }
00238   template <typename U> static inline Type castFrom( const QSharedPointer<U> &p )
00239   {
00240     const Type sp = qSharedPointerDynamicCast<T,U>( p );
00241     if ( !sp.isNull() || p.isNull() )
00242       return sp;
00243     throw PayloadException( "qSharedPointerDynamicCast failed" );
00244   }
00245   template <typename U> static inline bool canCastFrom( const QSharedPointer<U> &p )
00246   {
00247     const Type sp = qSharedPointerDynamicCast<T,U>( p );
00248     return !sp.isNull() || p.isNull();
00249   }
00250   template <typename U> static inline QSharedPointer<U> castTo( const Type &p )
00251   {
00252     const QSharedPointer<U> sp = qSharedPointerDynamicCast<U,T>( p );
00253     return sp;
00254   }
00255   static QSharedPointer<T> clone( const boost::shared_ptr<T> & t ) {
00256       if ( T * nt = clone_traits<T>::clone( t.get() ) )
00257           return QSharedPointer<T>( nt );
00258       else
00259           return QSharedPointer<T>();
00260   }
00261   static const unsigned int sharedPointerId = 2;
00262 };
00263 
00264 
00265 }
00266 
00272 struct PayloadBase
00273 {
00274     virtual ~PayloadBase() { }
00275     virtual PayloadBase * clone() const = 0;
00276     virtual const char* typeName() const = 0;
00277 };
00278 
00284 template <typename T>
00285 struct Payload : public PayloadBase
00286 {
00287     Payload() {};
00288     Payload( const T& p ) : payload( p ) {}
00289 
00290     PayloadBase * clone() const
00291     {
00292         return new Payload<T>( const_cast<Payload<T>* >(this)->payload);
00293     }
00294 
00295     const char* typeName() const
00296     {
00297       return typeid(const_cast<Payload<T>*> (this)).name();
00298     }
00299 
00300     T payload;
00301 };
00302 
00307 template <typename T>
00308 struct Payload<T*> : public PayloadBase
00309 {
00310 };
00311 
00312 namespace Internal {
00313 
00318 template <typename T> inline Payload<T>* payload_cast( PayloadBase* payloadBase )
00319 {
00320   Payload<T> *p = dynamic_cast<Payload<T>*>( payloadBase );
00321   // try harder to cast, workaround for some gcc issue with template instances in multiple DSO's
00322   if ( !p && payloadBase && strcmp( payloadBase->typeName(), typeid(p).name() ) == 0 ) {
00323     p = static_cast<Payload<T>*>( payloadBase );
00324   }
00325   return p;
00326 }
00327 
00328 }
00329 
00330 }
00331 //@endcond
00332 
00333 #endif
00334 

akonadi

Skip menu "akonadi"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.7.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal