2 Copyright (C) 2009-2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
4 This library is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published
6 by the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #ifndef QGLIB_REFPOINTER_H
18 #define QGLIB_REFPOINTER_H
22 #include <boost/static_assert.hpp>
23 #include <boost/type_traits.hpp>
34 inline RefPointer(const RefPointer<T> & other);
36 inline RefPointer(const RefPointer<X> & other);
37 inline RefPointer<T> & operator=(const RefPointer<T> & other);
39 inline RefPointer<T> & operator=(const RefPointer<X> & other);
43 inline bool isNull() const;
44 inline operator bool() const;
45 inline bool operator!() const;
46 inline T *operator->() const;
47 inline operator typename T::CType*() const;
49 static RefPointer<T> wrap(typename T::CType *nativePtr, bool increaseRef = true);
52 RefPointer<X> staticCast() const;
55 RefPointer<X> dynamicCast() const;
58 template <class X> friend class RefPointer;
60 void assign(const RefPointer<X> & other);
66 class RefCountedObject
69 template <class T> friend class RefPointer;
71 virtual ~RefCountedObject() {}
73 virtual void ref() = 0;
74 virtual void unref() = 0;
81 inline RefPointer<T>::RefPointer()
87 inline RefPointer<T>::~RefPointer()
94 inline RefPointer<T>::RefPointer(const RefPointer<X> & other)
101 inline RefPointer<T>::RefPointer(const RefPointer<T> & other)
109 inline RefPointer<T> & RefPointer<T>::operator=(const RefPointer<X> & other)
117 inline RefPointer<T> & RefPointer<T>::operator=(const RefPointer<T> & other)
126 void RefPointer<T>::assign(const RefPointer<X> & other)
128 //T should be a base class of X
129 BOOST_STATIC_ASSERT((boost::is_base_of<T, X>::value));
131 if (!other.isNull()) {
133 m_class->m_object = other.m_class->m_object;
134 static_cast<RefCountedObject*>(m_class)->ref();
139 void RefPointer<T>::clear()
142 static_cast<RefCountedObject*>(m_class)->unref();
150 RefPointer<T> RefPointer<T>::wrap(typename T::CType *nativePtr, bool increaseRef)
153 if (nativePtr != NULL) {
154 ptr.m_class = new T();
155 ptr.m_class->m_object = nativePtr;
157 static_cast<RefCountedObject*>(ptr.m_class)->ref();
164 inline bool RefPointer<T>::isNull() const
166 return m_class == NULL;
170 inline RefPointer<T>::operator bool() const
172 return m_class != NULL;
176 inline bool RefPointer<T>::operator!() const
178 return m_class == NULL;
182 inline T *RefPointer<T>::operator->() const
188 inline RefPointer<T>::operator typename T::CType*() const
190 return m_class ? static_cast<typename T::CType*>(m_class->m_object) : NULL;
195 RefPointer<X> RefPointer<T>::staticCast() const
197 return isNull() ? RefPointer<X>()
198 : RefPointer<X>::wrap(static_cast<typename X::CType*>(m_class->m_object));
201 template <class T> struct GetType;
205 RefPointer<X> RefPointer<T>::dynamicCast() const
207 if (!isNull() && Type::fromInstance(m_class->m_object).isA(GetType<X>())) {
208 return RefPointer<X>::wrap(static_cast<typename X::CType*>(m_class->m_object));
210 return RefPointer<X>();