20 #ifndef ITEMPAYLOADINTERNALS_P_H 
   21 #define ITEMPAYLOADINTERNALS_P_H 
   23 #include <kpimutils/supertrait.h> 
   25 #include <QtCore/QtGlobal> 
   26 #include <QtCore/QSharedPointer> 
   27 #include <QtCore/QMetaType> 
   29 #include <boost/shared_ptr.hpp> 
   30 #include <boost/type_traits/is_same.hpp> 
   31 #include <boost/mpl/eval_if.hpp> 
   32 #include <boost/mpl/identity.hpp> 
   33 #include <boost/utility/enable_if.hpp> 
   37 #include "exception.h" 
   51 struct has_clone_method {
 
   53     template <
typename S, S * (S::*)() const> 
struct sfinae
 
   63     template <
typename S> 
static No  test(...);
 
   64     template <
typename S> 
static Yes test(sfinae<S, &S::clone> *);
 
   66     static const bool value = 
sizeof (test<T>(0)) == 
sizeof (Yes) ;
 
   69 template <
typename T, 
bool b>
 
   70 struct clone_traits_helper {
 
   82 struct clone_traits_helper<T, true>
 
   86         return t ? t->clone() : 0 ;
 
   91 struct clone_traits : clone_traits_helper<T, has_clone_method<T>::value> {};
 
   94 struct shared_pointer_traits
 
   96     static const bool defined = 
false;
 
  100 struct shared_pointer_traits< boost::shared_ptr<T> >
 
  102     static const bool defined = 
true;
 
  103     typedef T element_type;
 
  104     template <
typename S>
 
  106         typedef boost::shared_ptr<S> type;
 
  111 template <
typename T>
 
  114     static const bool defined = 
true;
 
  115     typedef T element_type;
 
  116     template <
typename S>
 
  120     typedef boost::shared_ptr<T> next_shared_ptr;
 
  123 template <
typename T>
 
  124 struct is_shared_pointer
 
  126     static const bool value = shared_pointer_traits<T>::defined;
 
  129 template <
typename T>
 
  130 struct get_hierarchy_root;
 
  132 template <
typename T, 
typename S>
 
  133 struct get_hierarchy_root_recurse
 
  134     : get_hierarchy_root<S>
 
  138 template <
typename T>
 
  139 struct get_hierarchy_root_recurse<T, T>
 
  140     : boost::mpl::identity<T>
 
  144 template <
typename T>
 
  145 struct get_hierarchy_root
 
  146     : get_hierarchy_root_recurse< T, typename ::KPIMUtils::SuperClass<T>::Type >
 
  150 template <
typename T>
 
  151 struct get_hierarchy_root< boost::shared_ptr<T> >
 
  153     typedef boost::shared_ptr< typename get_hierarchy_root<T>::type > type;
 
  156 template <
typename T>
 
  168 template <
typename T> 
struct PayloadTrait
 
  171     typedef T ElementType;
 
  174     static int elementMetaTypeId()
 
  176         return qMetaTypeId<T>();
 
  180     typedef typename KPIMUtils::SuperClass<T>::Type SuperElementType;
 
  186     typedef typename KPIMUtils::SuperClass<T>::Type SuperType;
 
  189     static const bool isPolymorphic = 
false;
 
  191     static inline bool isNull(
const Type &p)
 
  198     template <
typename U> 
static inline Type castFrom(
const U &)
 
  200         throw PayloadException(
"you should never get here");
 
  203     template <
typename U> 
static inline bool canCastFrom(
const U &)
 
  208     template <
typename U> 
static inline U castTo(
const Type &)
 
  210         throw PayloadException(
"you should never get here");
 
  212     template <
typename U> 
static T clone(
const U &)
 
  214         throw PayloadException(
"clone: you should never get here");
 
  217     static const unsigned int sharedPointerId = 0;
 
  225 template <
typename T> 
struct PayloadTrait<boost::shared_ptr<T> >
 
  227     typedef T ElementType;
 
  228     static int elementMetaTypeId()
 
  230         return qMetaTypeId<T *>();
 
  232     typedef typename KPIMUtils::SuperClass<T>::Type SuperElementType;
 
  233     typedef boost::shared_ptr<ElementType> Type;
 
  234     typedef boost::shared_ptr<SuperElementType> SuperType;
 
  235     static const bool isPolymorphic = !boost::is_same<ElementType, SuperElementType>::value;
 
  236     static inline bool isNull(
const Type &p)
 
  240     template <
typename U> 
static inline Type castFrom(
const boost::shared_ptr<U> &p)
 
  242         const Type sp = boost::dynamic_pointer_cast<T, U>(p);
 
  243         if (sp.get() != 0 || p.get() == 0) {
 
  246         throw PayloadException(
"boost::dynamic_pointer_cast failed");
 
  248     template <
typename U> 
static inline bool canCastFrom(
const boost::shared_ptr<U> &p)
 
  250         const Type sp = boost::dynamic_pointer_cast<T, U>(p);
 
  251         return sp.get() != 0 || p.get() == 0;
 
  253     template <
typename U> 
static inline boost::shared_ptr<U> castTo(
const Type &p)
 
  255         const boost::shared_ptr<U> sp = boost::dynamic_pointer_cast<U>(p);
 
  259         if (T *nt = clone_traits<T>::clone(t.
data())) {
 
  260             return boost::shared_ptr<T>(nt);
 
  262             return boost::shared_ptr<T>();
 
  265     static const unsigned int sharedPointerId = 1;
 
  275     typedef T ElementType;
 
  276     static int elementMetaTypeId()
 
  278         return qMetaTypeId<T *>();
 
  280     typedef typename KPIMUtils::SuperClass<T>::Type SuperElementType;
 
  283     static const bool isPolymorphic = !boost::is_same<ElementType, SuperElementType>::value;
 
  284     static inline bool isNull(
const Type &p)
 
  290         const Type sp = qSharedPointerDynamicCast<T, U>(p);
 
  291         if (!sp.isNull() || p.
isNull()) {
 
  294         throw PayloadException(
"qSharedPointerDynamicCast failed");
 
  298         const Type sp = qSharedPointerDynamicCast<T, U>(p);
 
  299         return !sp.isNull() || p.
isNull();
 
  307         if (T *nt = clone_traits<T>::clone(t.get())) {
 
  313     static const unsigned int sharedPointerId = 2;
 
  325     virtual ~PayloadBase()
 
  328     virtual PayloadBase *clone() 
const = 0;
 
  329     virtual const char *typeName() 
const = 0;
 
  337 template <
typename T>
 
  338 struct Payload : 
public PayloadBase
 
  348     PayloadBase *clone()
 const 
  350         return new Payload<T>(
const_cast<Payload<T>* 
>(
this)->payload);
 
  353     const char *typeName()
 const 
  355         return typeid (
const_cast<Payload<T>*
>(
this)).name();
 
  365 template <
typename T>
 
  366 struct Payload<T *> : 
public PayloadBase
 
  376 template <
typename T> 
inline Payload<T> *payload_cast(PayloadBase *payloadBase)
 
  378     Payload<T> *p = 
dynamic_cast<Payload<T>*
>(payloadBase);
 
  380     if (!p && payloadBase && strcmp(payloadBase->typeName(), 
typeid (p).name()) == 0) {
 
  381         p = 
static_cast<Payload<T>*
>(payloadBase);