Index: phonondefs_p.h =================================================================== --- phonondefs_p.h (revision 770337) +++ phonondefs_p.h (working copy) @@ -21,6 +21,7 @@ #define PHONONDEFS_P_H #include +#include "medianode_p.h" #define K_D(Class) Class##Private *const d = k_func() @@ -130,11 +131,82 @@ #define pBACKEND_CALL2(methodName, varType1, var1, varType2, var2) \ QMetaObject::invokeMethod(m_backendObject, methodName, Qt::DirectConnection, Q_ARG(varType1, var1), Q_ARG(varType2, var2)) +namespace Phonon +{ + namespace + { + class NoIface; + + /// undefined result if the condition is neither true nor false + template struct If; + /// If false Else is the Result + template struct If { typedef Else Result; }; + /// If true Then is the Result + template struct If { typedef Then Result; }; + + /// All template arguments are valid + template struct IsValid { enum { Result = true }; }; + /// except NoIface + template<> struct IsValid { enum { Result = false }; }; + + template + struct iface_cast_helper + { + static inline R *help(MediaNodePrivate *d) + { + return qobject_cast(d->m_backendObject); + } + + static inline const R *help(const MediaNodePrivate *d) + { + return qobject_cast(d->m_backendObject); + } + }; + + template + struct iface_cast_helper + { + static inline R *help(const MediaNodePrivate *) + { + return 0; + } + }; + + } // anonymous namespace + + template + struct Iface + { + typedef typename If::Result, T2, typename If::Result, T1, T0>::Result>::Result Type; + static inline Type *cast(MediaNodePrivate *const d) + { + Type *ret; + ret = qobject_cast(d->m_backendObject); + if (ret) return ret; + ret = iface_cast_helper::help(d); + if (ret) return ret; + ret = iface_cast_helper::help(d); + return ret; + } + + static inline const Type *cast(const MediaNodePrivate *const d) + { + const Type *ret; + ret = qobject_cast(d->m_backendObject); + if (ret) return ret; + ret = iface_cast_helper::help(d); + if (ret) return ret; + ret = iface_cast_helper::help(d); + return ret; + } + }; +} // namespace Phonon + #define INTERFACE_CALL(function) \ -qobject_cast(d->m_backendObject)->function +Iface::cast(d)->function #define pINTERFACE_CALL(function) \ -qobject_cast(m_backendObject)->function +Iface::cast(this)->function #define PHONON_GETTER(rettype, name, retdefault) \ rettype PHONON_CLASSNAME::name() const \ @@ -153,7 +225,7 @@ const PHONON_CONCAT_HELPER(PHONON_CLASSNAME, Private) *d = k_func(); \ if (!d->m_backendObject) \ return retdefault; \ - return qobject_cast(d->m_backendObject)->name(); \ + return Iface::cast(d)->name(); \ } #define PHONON_GETTER1(rettype, name, retdefault, argtype1, argvar1) \ @@ -173,7 +245,7 @@ const PHONON_CONCAT_HELPER(PHONON_CLASSNAME, Private) *d = k_func(); \ if (!d->m_backendObject) \ return retdefault; \ - return qobject_cast(d->m_backendObject)->name(argvar1->k_ptr->backendObject()); \ + return Iface::cast(d)->name(argvar1->k_ptr->backendObject()); \ } #define PHONON_SETTER(functionname, privatevar, argtype1) \ @@ -192,7 +264,7 @@ PHONON_CONCAT_HELPER(PHONON_CLASSNAME, Private) *d = k_func(); \ d->privatevar = x; \ if (k_ptr->backendObject()) { \ - qobject_cast(d->m_backendObject)->functionname(x); \ + Iface::cast(d)->functionname(x); \ } \ }