19 #ifndef QGLIB_REFPOINTER_H
20 #define QGLIB_REFPOINTER_H
26 #include <boost/type_traits.hpp>
27 #include <boost/utility/enable_if.hpp>
28 #include <QtCore/QHash>
39 template <
class T,
class X>
40 struct RefPointerEqualityCheck {};
42 template <
class T,
class X>
43 struct RefPointerEqualityCheck<T, RefPointer<X> >
45 static inline bool check(
const RefPointer<T> &
self,
const RefPointer<X> & other)
47 if (
self.m_class && other.m_class) {
48 return self.m_class->m_object == other.m_class->m_object;
50 return self.isNull() && other.isNull();
55 template <
class T,
class X>
56 struct RefPointerEqualityCheck<T, X*>
58 static inline bool check(
const RefPointer<T> &
self, X*
const & other)
60 return self.m_class ?
self.m_class->m_object == other : !other;
95 explicit inline RefPointer(T *cppClass);
98 inline RefPointer(
const RefPointer<X> & other);
99 inline RefPointer(
const RefPointer<T> & other);
102 inline RefPointer<T> & operator=(
const RefPointer<X> & other);
103 inline RefPointer<T> & operator=(
const RefPointer<T> & other);
127 inline bool isNull()
const;
128 inline bool operator!()
const;
129 inline T *operator->()
const;
137 inline operator typename T::CType*()
const;
143 static RefPointer<T>
wrap(
typename T::CType *nativePtr,
bool increaseRef =
true);
166 template <
class X>
friend class RefPointer;
167 template <
class X,
class Y>
friend struct Private::RefPointerEqualityCheck;
170 void assign(
const RefPointer<X> & other);
186 template <
class T,
class X>
friend struct Private::RefPointerEqualityCheck;
188 virtual void ref(
bool increaseRef) = 0;
189 virtual void unref() = 0;
192 inline T* object()
const;
198 inline T* RefCountedObject::object()
const
200 return static_cast<T* const
>(m_object);
205 inline RefPointer<T>::RefPointer()
211 inline RefPointer<T>::~RefPointer()
232 inline RefPointer<T>::RefPointer(
const RefPointer<T> & other)
240 inline RefPointer<T> & RefPointer<T>::operator=(
const RefPointer<X> & other)
248 inline RefPointer<T> & RefPointer<T>::operator=(
const RefPointer<T> & other)
257 void RefPointer<T>::assign(
const RefPointer<X> & other)
260 QGLIB_STATIC_ASSERT((boost::is_base_of<T, X>::value),
261 "Cannot implicitly cast a RefPointer down the hierarchy");
263 if (!other.isNull()) {
264 m_class =
static_cast<T*
>(other.m_class);
265 static_cast<RefCountedObject*
>(m_class)->ref(
true);
273 return Private::RefPointerEqualityCheck<T, X>::check(*
this, other);
280 return !Private::RefPointerEqualityCheck<T, X>::check(*
this, other);
286 template <
class T,
class X>
289 typename boost::enable_if_c<
290 boost::is_pointer<X>::value &&
291 !boost::is_same<X, typename boost::add_pointer<typename T::CType>::type>::value,
296 return Private::RefPointerEqualityCheck<T, X>::check(
self, other);
302 template <
class T,
class X>
305 typename boost::enable_if_c<
306 boost::is_pointer<X>::value &&
307 !boost::is_same<X, typename boost::add_pointer<typename T::CType>::type>::value,
312 return !Private::RefPointerEqualityCheck<T, X>::check(
self, other);
329 if (nativePtr != NULL) {
331 cppObj->ref(increaseRef);
332 ptr.m_class =
dynamic_cast<T*
>(cppObj);
333 Q_ASSERT(ptr.m_class);
341 return m_class == NULL;
345 inline bool RefPointer<T>::operator!()
const
347 return m_class == NULL;
351 inline T *RefPointer<T>::operator->()
const
353 Q_ASSERT_X(!isNull(),
"RefPointer::operator->() const",
354 "Attempted to dereference a null pointer");
361 return m_class ?
static_cast<RefCountedObject*
>(m_class)->object<typename T::CType>() : NULL;
371 result.m_class =
static_cast<X*
>(m_class);
379 template <
typename T,
typename X,
typename Enable =
void>
380 struct IfaceDynamicCastImpl
382 static inline X *doCast(
typename X::CType *obj)
391 template <
typename T,
typename X>
392 struct IfaceDynamicCastImpl<T, X,
393 typename boost::enable_if_c<
396 (boost::is_base_of<Interface, X>::value &&
397 !boost::is_base_of<Object, X>::value &&
398 boost::is_base_of<Object, T>::value)
402 static inline X *doCast(
typename X::CType *obj)
404 X *targetClass = NULL;
408 if (Type::fromInstance(obj).isA(GetType<X>()))
410 targetClass =
dynamic_cast<X*
>(Private::wrapInterface(GetType<X>(), obj));
411 Q_ASSERT(targetClass);
420 template <
typename T,
typename X>
421 struct IfaceDynamicCastImpl<T, X,
422 typename boost::enable_if_c<
425 (boost::is_base_of<Interface, T>::value &&
426 !boost::is_base_of<Object, T>::value)
430 static inline X *doCast(
typename X::CType *obj)
434 RefCountedObject *cppClass = Private::wrapObject(obj);
437 X *targetClass =
dynamic_cast<X*
>(cppClass);
444 if (boost::is_base_of<Interface, X>::value &&
445 !boost::is_base_of<Object, X>::value &&
446 Type::fromInstance(obj).isA(GetType<X>()))
448 targetClass =
dynamic_cast<X*
>(Private::wrapInterface(GetType<X>(), obj));
449 Q_ASSERT(targetClass);
466 X *targetClass =
dynamic_cast<X*
>(m_class);
470 typename X::CType *obj =
static_cast<RefCountedObject*
>(m_class)->object<typename X::CType>();
471 targetClass = Private::IfaceDynamicCastImpl<T, X>::doCast(obj);
476 result.m_class = targetClass;
487 inline operator Type() {
return GetType<T>(); }
491 template <
typename T>
494 return qHash(static_cast<typename T::CType*>(ptr));
boost::enable_if_c< boost::is_pointer< X >::value &&!boost::is_same< X, typename boost::add_pointer< typename T::CType >::type >::value, bool >::type operator==(const X &other, const RefPointer< T > &self)
static RefPointer< T > wrap(typename T::CType *nativePtr, bool increaseRef=true)
Smart pointer class for working with wrapper classes that support reference counting.
RefPointer< X > staticCast() const
boost::enable_if_c< boost::is_pointer< X >::value &&!boost::is_same< X, typename boost::add_pointer< typename T::CType >::type >::value, bool >::type operator!=(const X &other, const RefPointer< T > &self)
Base class for all the reference-counted object wrappers.
RefPointer< X > dynamicCast() const
bool operator!=(const X &other) const
uint qHash(const RefPointer< T > &ptr)
bool operator==(const X &other) const