more compile time checks, when using QskMetaFunction

This commit is contained in:
Uwe Rathmann 2018-03-14 14:45:39 +01:00
parent 0930085a64
commit 4cd45201f6
5 changed files with 118 additions and 48 deletions

View File

@ -139,8 +139,8 @@ bool QskMetaFunction::operator==( const QskMetaFunction& other ) const
if ( m_functionCall && other.m_functionCall )
{
if ( m_functionCall->typeInfo() == Function &&
other.m_functionCall->typeInfo() == Function )
if ( m_functionCall->typeInfo() == StaticFunction &&
other.m_functionCall->typeInfo() == StaticFunction )
{
// only static functions can be compared
return m_functionCall->compare(

View File

@ -8,26 +8,71 @@
#include "QskGlobal.h"
#include <QMetaType>
#include <QObject>
namespace QskMetaFunctionTraits
{
using namespace QtPrivate;
template< typename T >
using IsMemberFunction = typename std::enable_if< FunctionPointer< T >::IsPointerToMemberFunction,
std::true_type >::type;
using IsMemberFunction = typename std::enable_if<
FunctionPointer< T >::IsPointerToMemberFunction, std::true_type >::type;
template< typename T >
using IsFunctor = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction
using IsFunctor = typename std::enable_if<
!FunctionPointer< T >::IsPointerToMemberFunction
&& FunctionPointer< T >::ArgumentCount == -1, std::true_type >::type;
template< typename T >
using IsFunction = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction
using IsStaticFunction = typename std::enable_if<
!FunctionPointer< T >::IsPointerToMemberFunction
&& FunctionPointer< T >::ArgumentCount >= 0, std::true_type >::type;
template< typename T >
using IsFunction0 = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction
&& FunctionPointer< T >::ArgumentCount == 0, std::true_type >::type;
template< typename T, IsMemberFunction< T >* = nullptr >
constexpr inline int argumentCount()
{
using Traits = FunctionPointer< T >;
return Traits::ArgumentCount;
}
template< typename T, IsStaticFunction< T >* = nullptr >
constexpr inline int argumentCount()
{
using Traits = FunctionPointer< T >;
return Traits::ArgumentCount;
}
template< typename T, IsFunctor< T >* = nullptr >
constexpr inline int argumentCount()
{
using Traits = FunctionPointer< decltype( &T::operator() ) >;
return Traits::ArgumentCount;
}
template< typename T, size_t i >
constexpr typename std::enable_if< i >= argumentCount< T >(), int >::type argumentType()
{
return QMetaType::UnknownType;
}
template< typename T, size_t i, IsMemberFunction< T >* = nullptr >
constexpr typename std::enable_if < i < argumentCount< T >(), int >::type argumentType()
{
return ConnectionTypes< typename FunctionPointer< T >::Arguments >::types()[i];
}
template< typename T, size_t i, IsStaticFunction< T >* = nullptr >
constexpr typename std::enable_if < i < argumentCount< T >(), int >::type argumentType()
{
return ConnectionTypes< typename FunctionPointer< T >::Arguments >::types()[i];
}
template< typename T, size_t i, IsFunctor< T >* = nullptr >
constexpr typename std::enable_if < i < argumentCount< T >(), int >::type argumentType()
{
using Traits = FunctionPointer< decltype( &T::operator() ) >;
return ConnectionTypes< typename Traits::Arguments >::types()[i];
}
}
class QSK_EXPORT QskMetaFunction
@ -40,10 +85,10 @@ public:
Invalid = -1,
// a non static method of class
Member,
MemberFunction,
// a static function, or static method of a class
Function,
StaticFunction,
// a functor or lambda
Functor
@ -62,7 +107,7 @@ public:
template< typename T, QskMetaFunctionTraits::IsFunctor< T >* = nullptr >
QskMetaFunction( T );
template< typename T, QskMetaFunctionTraits::IsFunction< T >* = nullptr >
template< typename T, QskMetaFunctionTraits::IsStaticFunction< T >* = nullptr >
QskMetaFunction( T );
~QskMetaFunction();
@ -155,7 +200,7 @@ inline QskMetaFunction::QskMetaFunction( T functor )
ConnectionTypes< typename Traits::Arguments >::types() );
}
template< typename T, QskMetaFunctionTraits::IsFunction< T >* >
template< typename T, QskMetaFunctionTraits::IsStaticFunction< T >* >
inline QskMetaFunction::QskMetaFunction( T function )
{
using namespace QtPrivate;

View File

@ -89,7 +89,7 @@ namespace QskMetaFunctionCall
}
case TypeInfo:
{
*reinterpret_cast< int* >( args ) = QskMetaFunction::Function;
*reinterpret_cast< int* >( args ) = QskMetaFunction::StaticFunction;
break;
}
}
@ -133,7 +133,7 @@ namespace QskMetaFunctionCall
}
case TypeInfo:
{
*reinterpret_cast< int* >( args ) = QskMetaFunction::Member;
*reinterpret_cast< int* >( args ) = QskMetaFunction::MemberFunction;
break;
}
}

View File

@ -98,14 +98,11 @@ int QskShortcutHandler::insert(
return 0;
}
#if 1
// should be a compile time check for functor based slots
if ( invokable.parameterCount() > 0 )
{
qDebug() << "QskShortcutMap: invalid slot parameter count";
return 0;
}
#endif
if ( receiver )
{
@ -271,7 +268,7 @@ int QskShortcutMap::addFunction( QQuickItem* item, const QKeySequence& sequence,
bool autoRepeat, const QObject* receiver, const QskMetaFunction& function )
{
if ( ( receiver == nullptr )
&& ( function.functionType() == QskMetaFunction::Member ) )
&& ( function.functionType() == QskMetaFunction::MemberFunction ) )
{
qDebug() << "QskShortcutMap: bad receiver for shortcut:" << sequence;
return 0;

View File

@ -33,23 +33,29 @@ public:
bool autoRepeat, const QObject* receiver, const char* method );
// functor based slots
template< typename T >
static int addShortcut( const QKeySequence&,
bool autoRepeat, const QskMetaFunction& );
bool autoRepeat, T function );
template< typename T >
static int addShortcut( const QKeySequence&,
bool autoRepeat, const QObject* context, const QskMetaFunction& );
bool autoRepeat, const QObject* context, T function );
template< typename T >
static int addShortcut( QQuickItem*, const QKeySequence&,
bool autoRepeat, const QskMetaFunction& );
bool autoRepeat, T function );
template< typename T >
static int addShortcut( QQuickItem*, const QKeySequence&,
bool autoRepeat, const QObject* context, const QskMetaFunction& );
bool autoRepeat, const QObject* context, T function );
template< typename T >
static int addShortcut( QQuickWindow*, const QKeySequence&,
bool autoRepeat, const QskMetaFunction& );
bool autoRepeat, T function );
template< typename T >
static int addShortcut( QQuickWindow*, const QKeySequence&,
bool autoRepeat, const QObject* context, const QskMetaFunction& );
bool autoRepeat, const QObject* context, T function );
static bool contextMatcher( const QQuickItem*, Qt::ShortcutContext );
@ -57,6 +63,11 @@ private:
QskShortcutMap() = delete;
~QskShortcutMap() = delete;
template< typename T >
static int addFunctionT(
QQuickItem* item, const QKeySequence&, bool autoRepeat,
const QObject* receiver, T );
static int addFunction(
QQuickItem* item, const QKeySequence&, bool autoRepeat,
const QObject* receiver, const QskMetaFunction& );
@ -81,47 +92,64 @@ inline int QskShortcutMap::addShortcut(
return addMethod( item, sequence, autoRepeat, receiver, method );
}
template< typename T >
inline int QskShortcutMap::addShortcut(
const QKeySequence& sequence, bool autoRepeat, T function )
{
return addFunctionT( nullptr, sequence, autoRepeat, nullptr, function );
}
template< typename T >
inline int QskShortcutMap::addShortcut(
const QKeySequence& sequence, bool autoRepeat,
const QskMetaFunction& function )
const QObject* context, T function )
{
return addFunction( nullptr, sequence, autoRepeat, nullptr, function );
return addFunctionT( nullptr, sequence, autoRepeat, context, function );
}
template< typename T >
inline int QskShortcutMap::addShortcut(
const QKeySequence& sequence, bool autoRepeat,
const QObject* context, const QskMetaFunction& function )
QQuickItem* item, const QKeySequence& sequence,
bool autoRepeat, T function )
{
return addFunction( nullptr, sequence, autoRepeat, context, function );
return addFunctionT( item, sequence, autoRepeat, nullptr, function );
}
template< typename T >
inline int QskShortcutMap::addShortcut(
QQuickItem* item, const QKeySequence& sequence, bool autoRepeat,
const QskMetaFunction& function )
const QObject* context, T function )
{
return addFunction( item, sequence, autoRepeat, nullptr, function );
return addFunctionT( item, sequence, autoRepeat,
context, QskMetaFunction( function ) );
}
template< typename T >
inline int QskShortcutMap::addShortcut(
QQuickWindow* window, const QKeySequence& sequence,
bool autoRepeat, T function )
{
auto item = window ? window->contentItem() : nullptr;
return addFunctionT( item, sequence, autoRepeat, nullptr, function );
}
template< typename T >
inline int QskShortcutMap::addShortcut(
QQuickWindow* window, const QKeySequence& sequence,
bool autoRepeat, const QObject* context, T function )
{
auto item = window ? window->contentItem() : nullptr;
return addFunctionT( item, sequence, autoRepeat, context, function );
}
template< typename T >
inline int QskShortcutMap::addFunctionT(
QQuickItem* item, const QKeySequence& sequence, bool autoRepeat,
const QObject* context, const QskMetaFunction& function )
const QObject* context, T function )
{
return addFunction( item, sequence, autoRepeat, context, function );
}
static_assert( QskMetaFunctionTraits::argumentCount< T >() == 0,
"QskShortcutMap::addShortcut: #number of arguments need to be 0." );
inline int QskShortcutMap::addShortcut(
QQuickWindow* window, const QKeySequence& sequence, bool autoRepeat,
const QskMetaFunction& function )
{
auto item = window ? window->contentItem() : nullptr;
return addFunction( item, sequence, autoRepeat, nullptr, function );
}
inline int QskShortcutMap::addShortcut(
QQuickWindow* window, const QKeySequence& sequence, bool autoRepeat,
const QObject* context, const QskMetaFunction& function )
{
auto item = window ? window->contentItem() : nullptr;
return addFunction( item, sequence, autoRepeat, context, function );
}