19 #ifndef QGLIB_REFPOINTER_H
20 #define QGLIB_REFPOINTER_H
27 #include <boost/type_traits.hpp>
29 #include <boost/utility/enable_if.hpp>
30 #include <QtCore/QHash>
41 template <
class T,
class X>
42 struct RefPointerEqualityCheck {};
44 template <
class T,
class X>
45 struct RefPointerEqualityCheck<T, RefPointer<X> >
47 static inline bool check(
const RefPointer<T> &
self,
const RefPointer<X> & other)
49 if (
self.m_class && other.m_class) {
50 return self.m_class->m_object == other.m_class->m_object;
52 return self.isNull() && other.isNull();
57 template <
class T,
class X>
58 struct RefPointerEqualityCheck<T, X*>
60 static inline bool check(
const RefPointer<T> &
self, X*
const & other)
62 return self.m_class ?
self.m_class->m_object == other : !other;
129 inline bool isNull()
const;
130 inline bool operator!()
const;
131 inline T *operator->()
const;
139 inline operator typename T::CType*()
const;
169 template <
class X,
class Y>
friend struct Private::RefPointerEqualityCheck;
188 template <
class T,
class X>
friend struct Private::RefPointerEqualityCheck;
190 virtual void ref(
bool increaseRef) = 0;
191 virtual void unref() = 0;
194 inline T* object()
const;
200 inline T* RefCountedObject::object()
const
202 return static_cast<T* const
>(m_object);
207 inline RefPointer<T>::RefPointer()
213 inline RefPointer<T>::~RefPointer()
234 inline RefPointer<T>::RefPointer(
const RefPointer<T> & other)
242 inline RefPointer<T> & RefPointer<T>::operator=(
const RefPointer<X> & other)
250 inline RefPointer<T> & RefPointer<T>::operator=(
const RefPointer<T> & other)
259 void RefPointer<T>::assign(
const RefPointer<X> & other)
262 QGLIB_STATIC_ASSERT((boost::is_base_of<T, X>::value),
263 "Cannot implicitly cast a RefPointer down the hierarchy");
265 if (!other.isNull()) {
266 m_class =
static_cast<T*
>(other.m_class);
267 static_cast<RefCountedObject*
>(m_class)->ref(
true);
275 return Private::RefPointerEqualityCheck<T, X>::check(*
this, other);
282 return !Private::RefPointerEqualityCheck<T, X>::check(*
this, other);
288 template <
class T,
class X>
291 typename boost::enable_if_c<
292 boost::is_pointer<X>::value &&
293 !boost::is_same<X, typename boost::add_pointer<typename T::CType>::type>::value,
298 return Private::RefPointerEqualityCheck<T, X>::check(
self, other);
304 template <
class T,
class X>
307 typename boost::enable_if_c<
308 boost::is_pointer<X>::value &&
309 !boost::is_same<X, typename boost::add_pointer<typename T::CType>::type>::value,
314 return !Private::RefPointerEqualityCheck<T, X>::check(
self, other);
331 if (nativePtr != NULL) {
333 cppObj->ref(increaseRef);
334 ptr.m_class =
dynamic_cast<T*
>(cppObj);
335 Q_ASSERT(ptr.m_class);
343 return m_class == NULL;
347 inline bool RefPointer<T>::operator!()
const
349 return m_class == NULL;
353 inline T *RefPointer<T>::operator->()
const
355 Q_ASSERT_X(!isNull(),
"RefPointer::operator->() const",
356 "Attempted to dereference a null pointer");
363 return m_class ?
static_cast<RefCountedObject*
>(m_class)->object<typename T::CType>() : NULL;
373 result.m_class =
static_cast<X*
>(m_class);
381 template <
typename T,
typename X,
typename Enable =
void>
382 struct IfaceDynamicCastImpl
384 static inline X *doCast(
typename X::CType *obj)
393 template <
typename T,
typename X>
394 struct IfaceDynamicCastImpl<T, X,
395 typename boost::enable_if_c<
398 (boost::is_base_of<Interface, X>::value &&
399 !boost::is_base_of<Object, X>::value &&
400 boost::is_base_of<Object, T>::value)
404 static inline X *doCast(
typename X::CType *obj)
406 X *targetClass = NULL;
410 if (Type::fromInstance(obj).isA(GetType<X>()))
412 targetClass =
dynamic_cast<X*
>(Private::wrapInterface(GetType<X>(), obj));
413 Q_ASSERT(targetClass);
422 template <
typename T,
typename X>
423 struct IfaceDynamicCastImpl<T, X,
424 typename boost::enable_if_c<
427 (boost::is_base_of<Interface, T>::value &&
428 !boost::is_base_of<Object, T>::value)
432 static inline X *doCast(
typename X::CType *obj)
436 RefCountedObject *cppClass = Private::wrapObject(obj);
439 X *targetClass =
dynamic_cast<X*
>(cppClass);
446 if (boost::is_base_of<Interface, X>::value &&
447 !boost::is_base_of<Object, X>::value &&
448 Type::fromInstance(obj).isA(GetType<X>()))
450 targetClass =
dynamic_cast<X*
>(Private::wrapInterface(GetType<X>(), obj));
451 Q_ASSERT(targetClass);
468 X *targetClass =
dynamic_cast<X*
>(m_class);
472 typename X::CType *obj =
static_cast<RefCountedObject*
>(m_class)->object<typename X::CType>();
473 targetClass = Private::IfaceDynamicCastImpl<T, X>::doCast(obj);
478 result.m_class = targetClass;
489 inline operator Type() {
return GetType<T>(); }
493 template <
typename T>
494 inline uint qHash(
const RefPointer<T> & ptr)
496 return qHash(
static_cast<typename T::CType*
>(ptr));
Base class for all the reference-counted object wrappers.
Smart pointer class for working with wrapper classes that support reference counting.
RefPointer< X > staticCast() const
RefPointer< X > dynamicCast() const
static RefPointer< T > wrap(typename T::CType *nativePtr, bool increaseRef=true)
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)
bool operator==(const X &other) 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)
bool operator!=(const X &other) const
Wrappers for Glib and GObject classes.