more compile time checks, when using QskMetaFunction
This commit is contained in:
parent
0930085a64
commit
4cd45201f6
@ -139,8 +139,8 @@ bool QskMetaFunction::operator==( const QskMetaFunction& other ) const
|
|||||||
|
|
||||||
if ( m_functionCall && other.m_functionCall )
|
if ( m_functionCall && other.m_functionCall )
|
||||||
{
|
{
|
||||||
if ( m_functionCall->typeInfo() == Function &&
|
if ( m_functionCall->typeInfo() == StaticFunction &&
|
||||||
other.m_functionCall->typeInfo() == Function )
|
other.m_functionCall->typeInfo() == StaticFunction )
|
||||||
{
|
{
|
||||||
// only static functions can be compared
|
// only static functions can be compared
|
||||||
return m_functionCall->compare(
|
return m_functionCall->compare(
|
||||||
|
@ -8,26 +8,71 @@
|
|||||||
|
|
||||||
#include "QskGlobal.h"
|
#include "QskGlobal.h"
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
namespace QskMetaFunctionTraits
|
namespace QskMetaFunctionTraits
|
||||||
{
|
{
|
||||||
using namespace QtPrivate;
|
using namespace QtPrivate;
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
using IsMemberFunction = typename std::enable_if< FunctionPointer< T >::IsPointerToMemberFunction,
|
using IsMemberFunction = typename std::enable_if<
|
||||||
std::true_type >::type;
|
FunctionPointer< T >::IsPointerToMemberFunction, std::true_type >::type;
|
||||||
|
|
||||||
template< typename T >
|
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;
|
&& FunctionPointer< T >::ArgumentCount == -1, std::true_type >::type;
|
||||||
|
|
||||||
template< typename T >
|
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;
|
&& FunctionPointer< T >::ArgumentCount >= 0, std::true_type >::type;
|
||||||
|
|
||||||
template< typename T >
|
template< typename T, IsMemberFunction< T >* = nullptr >
|
||||||
using IsFunction0 = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction
|
constexpr inline int argumentCount()
|
||||||
&& FunctionPointer< T >::ArgumentCount == 0, std::true_type >::type;
|
{
|
||||||
|
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
|
class QSK_EXPORT QskMetaFunction
|
||||||
@ -40,10 +85,10 @@ public:
|
|||||||
Invalid = -1,
|
Invalid = -1,
|
||||||
|
|
||||||
// a non static method of class
|
// a non static method of class
|
||||||
Member,
|
MemberFunction,
|
||||||
|
|
||||||
// a static function, or static method of a class
|
// a static function, or static method of a class
|
||||||
Function,
|
StaticFunction,
|
||||||
|
|
||||||
// a functor or lambda
|
// a functor or lambda
|
||||||
Functor
|
Functor
|
||||||
@ -62,7 +107,7 @@ public:
|
|||||||
template< typename T, QskMetaFunctionTraits::IsFunctor< T >* = nullptr >
|
template< typename T, QskMetaFunctionTraits::IsFunctor< T >* = nullptr >
|
||||||
QskMetaFunction( T );
|
QskMetaFunction( T );
|
||||||
|
|
||||||
template< typename T, QskMetaFunctionTraits::IsFunction< T >* = nullptr >
|
template< typename T, QskMetaFunctionTraits::IsStaticFunction< T >* = nullptr >
|
||||||
QskMetaFunction( T );
|
QskMetaFunction( T );
|
||||||
|
|
||||||
~QskMetaFunction();
|
~QskMetaFunction();
|
||||||
@ -155,7 +200,7 @@ inline QskMetaFunction::QskMetaFunction( T functor )
|
|||||||
ConnectionTypes< typename Traits::Arguments >::types() );
|
ConnectionTypes< typename Traits::Arguments >::types() );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T, QskMetaFunctionTraits::IsFunction< T >* >
|
template< typename T, QskMetaFunctionTraits::IsStaticFunction< T >* >
|
||||||
inline QskMetaFunction::QskMetaFunction( T function )
|
inline QskMetaFunction::QskMetaFunction( T function )
|
||||||
{
|
{
|
||||||
using namespace QtPrivate;
|
using namespace QtPrivate;
|
||||||
|
@ -89,7 +89,7 @@ namespace QskMetaFunctionCall
|
|||||||
}
|
}
|
||||||
case TypeInfo:
|
case TypeInfo:
|
||||||
{
|
{
|
||||||
*reinterpret_cast< int* >( args ) = QskMetaFunction::Function;
|
*reinterpret_cast< int* >( args ) = QskMetaFunction::StaticFunction;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,7 +133,7 @@ namespace QskMetaFunctionCall
|
|||||||
}
|
}
|
||||||
case TypeInfo:
|
case TypeInfo:
|
||||||
{
|
{
|
||||||
*reinterpret_cast< int* >( args ) = QskMetaFunction::Member;
|
*reinterpret_cast< int* >( args ) = QskMetaFunction::MemberFunction;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,14 +98,11 @@ int QskShortcutHandler::insert(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
|
||||||
// should be a compile time check for functor based slots
|
|
||||||
if ( invokable.parameterCount() > 0 )
|
if ( invokable.parameterCount() > 0 )
|
||||||
{
|
{
|
||||||
qDebug() << "QskShortcutMap: invalid slot parameter count";
|
qDebug() << "QskShortcutMap: invalid slot parameter count";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( receiver )
|
if ( receiver )
|
||||||
{
|
{
|
||||||
@ -271,7 +268,7 @@ int QskShortcutMap::addFunction( QQuickItem* item, const QKeySequence& sequence,
|
|||||||
bool autoRepeat, const QObject* receiver, const QskMetaFunction& function )
|
bool autoRepeat, const QObject* receiver, const QskMetaFunction& function )
|
||||||
{
|
{
|
||||||
if ( ( receiver == nullptr )
|
if ( ( receiver == nullptr )
|
||||||
&& ( function.functionType() == QskMetaFunction::Member ) )
|
&& ( function.functionType() == QskMetaFunction::MemberFunction ) )
|
||||||
{
|
{
|
||||||
qDebug() << "QskShortcutMap: bad receiver for shortcut:" << sequence;
|
qDebug() << "QskShortcutMap: bad receiver for shortcut:" << sequence;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -33,23 +33,29 @@ public:
|
|||||||
bool autoRepeat, const QObject* receiver, const char* method );
|
bool autoRepeat, const QObject* receiver, const char* method );
|
||||||
|
|
||||||
// functor based slots
|
// functor based slots
|
||||||
|
template< typename T >
|
||||||
static int addShortcut( const QKeySequence&,
|
static int addShortcut( const QKeySequence&,
|
||||||
bool autoRepeat, const QskMetaFunction& );
|
bool autoRepeat, T function );
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
static int addShortcut( const QKeySequence&,
|
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&,
|
static int addShortcut( QQuickItem*, const QKeySequence&,
|
||||||
bool autoRepeat, const QskMetaFunction& );
|
bool autoRepeat, T function );
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
static int addShortcut( QQuickItem*, const QKeySequence&,
|
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&,
|
static int addShortcut( QQuickWindow*, const QKeySequence&,
|
||||||
bool autoRepeat, const QskMetaFunction& );
|
bool autoRepeat, T function );
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
static int addShortcut( QQuickWindow*, const QKeySequence&,
|
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 );
|
static bool contextMatcher( const QQuickItem*, Qt::ShortcutContext );
|
||||||
|
|
||||||
@ -57,6 +63,11 @@ private:
|
|||||||
QskShortcutMap() = delete;
|
QskShortcutMap() = delete;
|
||||||
~QskShortcutMap() = delete;
|
~QskShortcutMap() = delete;
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
static int addFunctionT(
|
||||||
|
QQuickItem* item, const QKeySequence&, bool autoRepeat,
|
||||||
|
const QObject* receiver, T );
|
||||||
|
|
||||||
static int addFunction(
|
static int addFunction(
|
||||||
QQuickItem* item, const QKeySequence&, bool autoRepeat,
|
QQuickItem* item, const QKeySequence&, bool autoRepeat,
|
||||||
const QObject* receiver, const QskMetaFunction& );
|
const QObject* receiver, const QskMetaFunction& );
|
||||||
@ -81,47 +92,64 @@ inline int QskShortcutMap::addShortcut(
|
|||||||
return addMethod( item, sequence, autoRepeat, receiver, method );
|
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(
|
inline int QskShortcutMap::addShortcut(
|
||||||
const QKeySequence& sequence, bool autoRepeat,
|
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(
|
inline int QskShortcutMap::addShortcut(
|
||||||
const QKeySequence& sequence, bool autoRepeat,
|
QQuickItem* item, const QKeySequence& sequence,
|
||||||
const QObject* context, const QskMetaFunction& function )
|
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(
|
inline int QskShortcutMap::addShortcut(
|
||||||
QQuickItem* item, const QKeySequence& sequence, bool autoRepeat,
|
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(
|
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,
|
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 );
|
return addFunction( item, sequence, autoRepeat, context, function );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user