QtGStreamer  0.10.2
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
type.h
00001 /*
00002     Copyright (C) 2009-2010  George Kiagiadakis <kiagiadakis.george@gmail.com>
00003     Copyright (C) 2010 Collabora Ltd.
00004       @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
00005 
00006     This library is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU Lesser General Public License as published
00008     by the Free Software Foundation; either version 2.1 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU Lesser General Public License for more details.
00015 
00016     You should have received a copy of the GNU Lesser General Public License
00017     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 #ifndef QGLIB_TYPE_H
00020 #define QGLIB_TYPE_H
00021 
00022 #include "global.h"
00023 #include <QtCore/QList>
00024 #include <boost/mpl/if.hpp>
00025 
00026 /*
00027  * This is a re-definition of GType inside the QGlib::Private namespace.
00028  * It is used in the headers to avoid including <glib-object.h>.
00029  *
00030  * According to gtype.h, GType is ulong in C++ for historic reasons,
00031  * but only if sizeof(size_t) == sizeof(ulong). This template trick
00032  * here attempts to express the same logic wigh C++ templates.
00033  */
00034 namespace QGlib {
00035 namespace Private {
00036     typedef boost::mpl::if_c<
00037         sizeof(size_t) == sizeof(unsigned long),
00038         unsigned long,
00039         QIntegerForSizeof<size_t>::Unsigned
00040     >::type GType;
00041 } //namespace Private
00042 } //namespace QGlib
00043 
00044 namespace QGlib { //closing and re-opening namespace QGlib is required to trick codegen
00045 
00063 class QTGLIB_EXPORT Type
00064 {
00065 public:
00066     enum FundamentalType {
00067         Invalid = 0,
00068         None = 1<<2,
00069         Interface = 2<<2,
00070         Char = 3<<2,
00071         Uchar = 4<<2,
00072         Boolean = 5<<2,
00073         Int = 6<<2,
00074         Uint = 7<<2,
00075         Long = 8<<2,
00076         Ulong = 9<<2,
00077         Int64 = 10<<2,
00078         Uint64 = 11<<2,
00079         Enum = 12<<2,
00080         Flags = 13<<2,
00081         Float = 14<<2,
00082         Double = 15<<2,
00083         String = 16<<2,
00084         Pointer = 17<<2,
00085         Boxed = 18<<2,
00086         Param = 19<<2,
00087         Object = 20<<2
00088     };
00089 
00090     inline Type() : m_type(0) {}
00091     inline Type(Private::GType gtype) : m_type(gtype) {}
00092     inline Type(FundamentalType ftype) : m_type(ftype) {}
00093     inline Type(const Type & other) : m_type(other.m_type) {}
00094 
00095     inline Type & operator=(Type other);
00096     inline bool operator==(Type other) const;
00097     inline operator Private::GType() const { return m_type; }
00098 
00099     static Type fromInstance(void *nativeInstance);
00100     static Type fromName(const char *name);
00101 
00102     QString name() const;
00103     Quark nameQuark() const;
00104 
00105     bool isValid() const;
00106     bool isAbstract() const;
00107     bool isDerived() const;
00108     bool isFundamental() const;
00109     bool isValueType() const;
00110     bool hasValueTable() const;
00111     bool isClassed() const;
00112     bool isInstantiatable() const;
00113     bool isDerivable() const;
00114     bool isDeepDerivable() const;
00115     bool isInterface() const;
00116 
00117     Type fundamental() const;
00118     Type parent() const;
00119     uint depth() const;
00120     Type nextBase(Type rootType) const;
00121     bool isA(Type is_a_type) const;
00122 
00123     template <typename T>
00124     inline bool isA() const;
00125 
00126     QList<Type> children() const;
00127     QList<Type> interfaces() const;
00128     QList<Type> interfacePrerequisites() const;
00129 
00130     void *quarkData(const Quark & qname) const;
00131     void setQuarkData(const Quark & qname, void *data);
00132 
00133 private:
00134     Private::GType m_type;
00135 };
00136 
00137 inline Type & Type::operator=(Type other)
00138 {
00139     m_type = other.m_type;
00140     return *this;
00141 }
00142 
00143 inline bool Type::operator==(Type other) const
00144 {
00145     return m_type == other.m_type;
00146 }
00147 
00148 template <class T>
00149 inline Type GetType(); //forward-declaration, defined below
00150 
00151 template <typename T>
00152 inline bool Type::isA() const
00153 {
00154     return isA(GetType<T>());
00155 }
00156 
00157 //***************
00158 // -- GetType --
00159 //***************
00160 
00161 /* Used to provide the implementation for GetType() */
00162 template <class T>
00163 struct GetTypeImpl
00164 {
00165 //If we have static_assert(), use it to show a more friendly error message to the developer.
00166 //The check is dummy and is expected to evaluate to false. It is just used to trick the
00167 //compiler to delay the evaluation of the expression until the instantiation of this template
00168 //(where T becomes a known type). static_assert(false, "foo"); fails even before instantiation.
00169 #if defined(QGLIB_HAVE_CXX0X_STATIC_ASSERT)
00170 private:
00171     template <class X> struct FailStruct { static const bool value = false; };
00172     static_assert(FailStruct<T>::value, "Type T has not been registered with the QGlib type system");
00173 #endif
00174 };
00175 
00179 template <class T>
00180 inline Type GetType()
00181 {
00182     return GetTypeImpl<T>();
00183 }
00184 
00185 } //namespace QGlib
00186 
00187 /* This is to be used to define new Q*_REGISTER_TYPE(T) macros in
00188  * other bindings libraries that are based on QtGLib.
00189  */
00190 #define QGLIB_REGISTER_TYPE_WITH_EXPORT_MACRO(T, EXPORT_MACRO) \
00191     namespace QGlib { \
00192         template <> \
00193         struct EXPORT_MACRO GetTypeImpl<T> { operator Type(); }; \
00194     }
00195 
00196 /* This macro is used to register a class with the QtGLib type system. It forward-declares
00197  * a specialization for struct GetTypeImpl and serves as a keyword for codegen,
00198  * our code generator, which provides the compiled implementation. This specific macro
00199  * is meant to be used only inside QtGLib, for other libraries, define a new macro
00200  * using QGLIB_REGISTER_TYPE_WITH_EXPORT_MACRO.
00201  * Note: this macro must be used outside of any namespace scope
00202  */
00203 #define QGLIB_REGISTER_TYPE(T) \
00204     QGLIB_REGISTER_TYPE_WITH_EXPORT_MACRO(T, QTGLIB_EXPORT)
00205 
00206 //**************************
00207 // -- type registrations --
00208 //**************************
00209 
00210 #define QGLIB_REGISTER_NATIVE_TYPE(T, GTYPE) \
00211     namespace QGlib { \
00212         template <> \
00213         struct GetTypeImpl<T> { \
00214             inline operator Type() { return (GTYPE); }; \
00215         }; \
00216     }
00217 
00218 QGLIB_REGISTER_NATIVE_TYPE(bool, Type::Boolean)
00219 QGLIB_REGISTER_NATIVE_TYPE(char, Type::Char)
00220 QGLIB_REGISTER_NATIVE_TYPE(unsigned char, Type::Uchar)
00221 QGLIB_REGISTER_NATIVE_TYPE(int, Type::Int)
00222 QGLIB_REGISTER_NATIVE_TYPE(unsigned int, Type::Uint)
00223 QGLIB_REGISTER_NATIVE_TYPE(long, Type::Long)
00224 QGLIB_REGISTER_NATIVE_TYPE(unsigned long, Type::Ulong)
00225 QGLIB_REGISTER_NATIVE_TYPE(qint64, Type::Int64)
00226 QGLIB_REGISTER_NATIVE_TYPE(quint64, Type::Uint64)
00227 QGLIB_REGISTER_NATIVE_TYPE(float, Type::Float)
00228 QGLIB_REGISTER_NATIVE_TYPE(double, Type::Double)
00229 QGLIB_REGISTER_NATIVE_TYPE(void*, Type::Pointer)
00230 QGLIB_REGISTER_NATIVE_TYPE(const char*, Type::String)
00231 QGLIB_REGISTER_NATIVE_TYPE(QByteArray, Type::String)
00232 QGLIB_REGISTER_NATIVE_TYPE(QString, Type::String)
00233 
00234 //partial specializations for string literals
00235 namespace QGlib {
00236     template <int N>
00237     struct GetTypeImpl<const char[N]> { //ISO C++ string literals are const char[]
00238         inline operator Type() { return Type::String; };
00239     };
00240 }
00241 
00242 namespace QGlib {
00243     template <int N>
00244     struct GetTypeImpl<char[N]> { //gcc string literals are char[]
00245         inline operator Type() { return Type::String; };
00246     };
00247 }
00248 
00249 #undef QGLIB_REGISTER_NATIVE_TYPE
00250 
00251 QGLIB_REGISTER_TYPE(QGlib::Type) //codegen: GType=G_TYPE_GTYPE
00252 
00253 #endif // QGLIB_TYPE_H