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 {};
55 struct Yes { No no[2]; };
56 template <
typename S>
static No test( ... );
57 template <
typename S>
static Yes test( sfinae<S,&S::clone> * );
59 static const bool value =
sizeof( test<T>(0) ) ==
sizeof( Yes ) ;
62 template <
typename T,
bool b>
63 struct clone_traits_helper {
68 static T * clone( U ) {
return 0; }
72 struct clone_traits_helper<T,true> {
73 static T * clone( T * t ) {
return t ? t->clone() : 0 ; }
77 struct clone_traits : clone_traits_helper<T, has_clone_method<T>::value> {};
80 struct shared_pointer_traits {
81 static const bool defined =
false;
85 struct shared_pointer_traits< boost::shared_ptr<T> > {
86 static const bool defined =
true;
87 typedef T element_type;
89 struct make {
typedef boost::shared_ptr<S> type; };
90 typedef QSharedPointer<T> next_shared_ptr;
94 struct shared_pointer_traits< QSharedPointer<T> > {
95 static const bool defined =
true;
96 typedef T element_type;
98 struct make {
typedef QSharedPointer<S> type; };
99 typedef boost::shared_ptr<T> next_shared_ptr;
102 template <
typename T>
103 struct is_shared_pointer {
104 static const bool value = shared_pointer_traits<T>::defined;
107 template <
typename T>
108 struct get_hierarchy_root;
110 template <
typename T,
typename S>
111 struct get_hierarchy_root_recurse
112 : get_hierarchy_root<S> {};
114 template <
typename T>
115 struct get_hierarchy_root_recurse<T,T>
116 : boost::mpl::identity<T> {};
118 template <
typename T>
119 struct get_hierarchy_root
120 : get_hierarchy_root_recurse< T, typename ::KPIMUtils::SuperClass<T>::Type > {};
122 template <
typename T>
123 struct get_hierarchy_root< boost::shared_ptr<T> > {
124 typedef boost::shared_ptr< typename get_hierarchy_root<T>::type > type;
127 template <
typename T>
128 struct get_hierarchy_root< QSharedPointer<T> > {
129 typedef QSharedPointer< typename get_hierarchy_root<T>::type > type;
138 template <
typename T>
struct PayloadTrait
141 typedef T ElementType;
144 static int elementMetaTypeId() {
return qMetaTypeId<T>(); }
147 typedef typename KPIMUtils::SuperClass<T>::Type SuperElementType;
153 typedef typename KPIMUtils::SuperClass<T>::Type SuperType;
156 static const bool isPolymorphic =
false;
158 static inline bool isNull(
const Type & ) {
return true; }
161 template <
typename U>
static inline Type castFrom(
const U& )
163 throw PayloadException(
"you should never get here" );
166 template <
typename U>
static inline bool canCastFrom(
const U& )
171 template <
typename U>
static inline U castTo(
const Type& )
173 throw PayloadException(
"you should never get here" );
175 template <
typename U>
static T clone(
const U & )
177 throw PayloadException(
"clone: you should never get here" );
180 static const unsigned int sharedPointerId = 0;
188 template <
typename T>
struct PayloadTrait<boost::shared_ptr<T> >
190 typedef T ElementType;
191 static int elementMetaTypeId() {
return qMetaTypeId<T*>(); }
192 typedef typename KPIMUtils::SuperClass<T>::Type SuperElementType;
193 typedef boost::shared_ptr<ElementType> Type;
194 typedef boost::shared_ptr<SuperElementType> SuperType;
195 static const bool isPolymorphic = !boost::is_same<ElementType, SuperElementType>::value;
196 static inline bool isNull(
const Type &p ) {
return p.get() == 0; }
197 template <
typename U>
static inline Type castFrom(
const boost::shared_ptr<U> &p )
199 const Type sp = boost::dynamic_pointer_cast<T,U>( p );
200 if ( sp.get() != 0 || p.get() == 0 )
202 throw PayloadException(
"boost::dynamic_pointer_cast failed" );
204 template <
typename U>
static inline bool canCastFrom(
const boost::shared_ptr<U> &p )
206 const Type sp = boost::dynamic_pointer_cast<T,U>( p );
207 return sp.get() != 0 || p.get() == 0;
209 template <
typename U>
static inline boost::shared_ptr<U> castTo(
const Type &p )
211 const boost::shared_ptr<U> sp = boost::dynamic_pointer_cast<U>( p );
214 static boost::shared_ptr<T> clone(
const QSharedPointer<T> & t ) {
215 if ( T * nt = clone_traits<T>::clone( t.data() ) )
216 return boost::shared_ptr<T>( nt );
218 return boost::shared_ptr<T>();
220 static const unsigned int sharedPointerId = 1;
228 template <
typename T>
struct PayloadTrait<QSharedPointer<T> >
230 typedef T ElementType;
231 static int elementMetaTypeId() {
return qMetaTypeId<T*>(); }
232 typedef typename KPIMUtils::SuperClass<T>::Type SuperElementType;
233 typedef QSharedPointer<T> Type;
234 typedef QSharedPointer<SuperElementType> SuperType;
235 static const bool isPolymorphic = !boost::is_same<ElementType, SuperElementType>::value;
236 static inline bool isNull(
const Type &p ) {
return p.isNull(); }
237 template <
typename U>
static inline Type castFrom(
const QSharedPointer<U> &p )
239 const Type sp = qSharedPointerDynamicCast<T,U>( p );
240 if ( !sp.isNull() || p.isNull() )
242 throw PayloadException(
"qSharedPointerDynamicCast failed" );
244 template <
typename U>
static inline bool canCastFrom(
const QSharedPointer<U> &p )
246 const Type sp = qSharedPointerDynamicCast<T,U>( p );
247 return !sp.isNull() || p.isNull();
249 template <
typename U>
static inline QSharedPointer<U> castTo(
const Type &p )
251 const QSharedPointer<U> sp = qSharedPointerDynamicCast<U,T>( p );
254 static QSharedPointer<T> clone(
const boost::shared_ptr<T> & t ) {
255 if ( T * nt = clone_traits<T>::clone( t.get() ) )
256 return QSharedPointer<T>( nt );
258 return QSharedPointer<T>();
260 static const unsigned int sharedPointerId = 2;
272 virtual ~PayloadBase() { }
273 virtual PayloadBase * clone()
const = 0;
274 virtual const char* typeName()
const = 0;
282 template <
typename T>
283 struct Payload :
public PayloadBase
286 Payload(
const T& p ) : payload( p ) {}
288 PayloadBase * clone()
const
290 return new Payload<T>(
const_cast<Payload<T>*
>(
this)->payload);
293 const char* typeName()
const
295 return typeid(
const_cast<Payload<T>*
> (
this)).name();
305 template <
typename T>
306 struct Payload<T*> :
public PayloadBase
316 template <
typename T>
inline Payload<T>* payload_cast( PayloadBase* payloadBase )
318 Payload<T> *p =
dynamic_cast<Payload<T>*
>( payloadBase );
320 if ( !p && payloadBase && strcmp( payloadBase->typeName(),
typeid(p).name() ) == 0 ) {
321 p =
static_cast<Payload<T>*
>( payloadBase );