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);