2018-02-26 08:09:21 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
|
|
|
* This file may be used under the terms of the QSkinny License, Version 1.0
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#ifndef QSK_META_FUNCTION_H
|
|
|
|
#define QSK_META_FUNCTION_H 1
|
|
|
|
|
|
|
|
#include "QskGlobal.h"
|
2018-07-19 12:10:48 +00:00
|
|
|
|
|
|
|
#include <qmetatype.h>
|
|
|
|
#include <qobject.h>
|
2018-02-26 08:09:21 +00:00
|
|
|
|
2018-02-28 09:43:15 +00:00
|
|
|
namespace QskMetaFunctionTraits
|
|
|
|
{
|
|
|
|
using namespace QtPrivate;
|
|
|
|
|
|
|
|
template< typename T >
|
2018-03-14 13:45:39 +00:00
|
|
|
using IsMemberFunction = typename std::enable_if<
|
|
|
|
FunctionPointer< T >::IsPointerToMemberFunction, std::true_type >::type;
|
2018-02-28 09:43:15 +00:00
|
|
|
|
2018-11-03 16:13:47 +00:00
|
|
|
template< typename T >
|
|
|
|
using IsFunctorOrStaticFunction = typename std::enable_if<
|
|
|
|
!FunctionPointer< T >::IsPointerToMemberFunction, std::true_type >::type;
|
|
|
|
|
2018-02-28 09:43:15 +00:00
|
|
|
template< typename T >
|
2018-03-14 13:45:39 +00:00
|
|
|
using IsFunctor = typename std::enable_if<
|
|
|
|
!FunctionPointer< T >::IsPointerToMemberFunction
|
2018-02-28 09:43:15 +00:00
|
|
|
&& FunctionPointer< T >::ArgumentCount == -1, std::true_type >::type;
|
2018-03-02 05:57:08 +00:00
|
|
|
|
|
|
|
template< typename T >
|
2018-03-14 13:45:39 +00:00
|
|
|
using IsStaticFunction = typename std::enable_if<
|
|
|
|
!FunctionPointer< T >::IsPointerToMemberFunction
|
2018-03-02 05:57:08 +00:00
|
|
|
&& FunctionPointer< T >::ArgumentCount >= 0, std::true_type >::type;
|
2018-03-02 06:07:19 +00:00
|
|
|
|
2018-03-14 13:45:39 +00:00
|
|
|
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()
|
|
|
|
{
|
2018-08-03 06:15:28 +00:00
|
|
|
return ConnectionTypes< typename FunctionPointer< T >::Arguments >::types()[ i ];
|
2018-03-14 13:45:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T, size_t i, IsStaticFunction< T >* = nullptr >
|
|
|
|
constexpr typename std::enable_if < i < argumentCount< T >(), int >::type argumentType()
|
|
|
|
{
|
2018-08-03 06:15:28 +00:00
|
|
|
return ConnectionTypes< typename FunctionPointer< T >::Arguments >::types()[ i ];
|
2018-03-14 13:45:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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() ) >;
|
2018-08-03 06:15:28 +00:00
|
|
|
return ConnectionTypes< typename Traits::Arguments >::types()[ i ];
|
2018-03-14 13:45:39 +00:00
|
|
|
}
|
2018-02-28 09:43:15 +00:00
|
|
|
}
|
|
|
|
|
2018-02-26 08:09:21 +00:00
|
|
|
class QSK_EXPORT QskMetaFunction
|
|
|
|
{
|
|
|
|
Q_GADGET
|
|
|
|
|
2018-08-03 06:15:28 +00:00
|
|
|
public:
|
2018-02-26 08:09:21 +00:00
|
|
|
enum Type
|
|
|
|
{
|
|
|
|
Invalid = -1,
|
|
|
|
|
|
|
|
// a non static method of class
|
2018-03-14 13:45:39 +00:00
|
|
|
MemberFunction,
|
2018-02-26 08:09:21 +00:00
|
|
|
|
|
|
|
// a static function, or static method of a class
|
2018-03-14 13:45:39 +00:00
|
|
|
StaticFunction,
|
2018-02-26 08:09:21 +00:00
|
|
|
|
|
|
|
// a functor or lambda
|
|
|
|
Functor
|
|
|
|
};
|
|
|
|
|
|
|
|
Q_ENUM( Type )
|
|
|
|
|
|
|
|
QskMetaFunction();
|
|
|
|
|
|
|
|
QskMetaFunction( const QskMetaFunction& );
|
|
|
|
QskMetaFunction( QskMetaFunction&& );
|
|
|
|
|
2018-02-28 09:43:15 +00:00
|
|
|
template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* = nullptr >
|
2018-02-26 08:09:21 +00:00
|
|
|
QskMetaFunction( T );
|
|
|
|
|
2018-03-02 05:57:08 +00:00
|
|
|
template< typename T, QskMetaFunctionTraits::IsFunctor< T >* = nullptr >
|
2018-02-26 08:09:21 +00:00
|
|
|
QskMetaFunction( T );
|
|
|
|
|
2018-03-14 13:45:39 +00:00
|
|
|
template< typename T, QskMetaFunctionTraits::IsStaticFunction< T >* = nullptr >
|
2018-02-26 08:09:21 +00:00
|
|
|
QskMetaFunction( T );
|
|
|
|
|
|
|
|
~QskMetaFunction();
|
|
|
|
|
|
|
|
QskMetaFunction& operator=( const QskMetaFunction& );
|
|
|
|
QskMetaFunction& operator=( QskMetaFunction&& );
|
|
|
|
|
2018-03-04 12:31:49 +00:00
|
|
|
bool operator==( const QskMetaFunction& ) const;
|
|
|
|
bool operator!=( const QskMetaFunction& ) const;
|
|
|
|
|
|
|
|
explicit operator bool() const;
|
|
|
|
|
2018-03-08 07:37:44 +00:00
|
|
|
int returnType() const;
|
2018-02-26 08:09:21 +00:00
|
|
|
|
2018-02-27 16:47:23 +00:00
|
|
|
size_t parameterCount() const;
|
2018-03-08 07:37:44 +00:00
|
|
|
const int* parameterTypes() const;
|
2018-02-27 16:47:23 +00:00
|
|
|
|
2018-02-26 08:09:21 +00:00
|
|
|
void invoke( QObject*, void* args[],
|
|
|
|
Qt::ConnectionType = Qt::AutoConnection );
|
|
|
|
|
|
|
|
Type functionType() const;
|
2018-03-04 12:31:49 +00:00
|
|
|
bool isNull() const;
|
2018-02-26 08:09:21 +00:00
|
|
|
|
2018-03-03 14:52:42 +00:00
|
|
|
class FunctionCall;
|
|
|
|
FunctionCall* functionCall() const;
|
2018-02-28 15:48:46 +00:00
|
|
|
|
2018-08-03 06:15:28 +00:00
|
|
|
protected:
|
2018-03-03 14:52:42 +00:00
|
|
|
QskMetaFunction( FunctionCall* );
|
2018-02-28 15:48:46 +00:00
|
|
|
|
2018-08-03 06:15:28 +00:00
|
|
|
private:
|
2018-03-03 14:52:42 +00:00
|
|
|
FunctionCall* m_functionCall;
|
2018-02-26 08:09:21 +00:00
|
|
|
};
|
|
|
|
|
2018-03-04 12:31:49 +00:00
|
|
|
inline bool QskMetaFunction::operator!=( const QskMetaFunction& other ) const
|
|
|
|
{
|
|
|
|
return !( *this == other );
|
|
|
|
}
|
|
|
|
|
|
|
|
inline QskMetaFunction::operator bool() const
|
|
|
|
{
|
|
|
|
return !isNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool QskMetaFunction::isNull() const
|
|
|
|
{
|
|
|
|
return m_functionCall == nullptr;
|
|
|
|
}
|
2018-03-03 14:52:42 +00:00
|
|
|
|
|
|
|
inline QskMetaFunction::FunctionCall* QskMetaFunction::functionCall() const
|
2018-02-28 15:48:46 +00:00
|
|
|
{
|
2018-03-03 14:52:42 +00:00
|
|
|
return m_functionCall;
|
2018-02-28 15:48:46 +00:00
|
|
|
}
|
|
|
|
|
2018-03-04 12:31:49 +00:00
|
|
|
#include "QskMetaFunction.hpp"
|
|
|
|
|
2018-02-28 15:48:46 +00:00
|
|
|
inline const int* QskMetaFunction::parameterTypes() const
|
|
|
|
{
|
2018-03-03 14:52:42 +00:00
|
|
|
return m_functionCall ? m_functionCall->parameterTypes() : nullptr;
|
2018-02-28 15:48:46 +00:00
|
|
|
}
|
2018-02-26 08:09:21 +00:00
|
|
|
|
2018-02-28 09:43:15 +00:00
|
|
|
template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* >
|
2018-02-26 08:09:21 +00:00
|
|
|
inline QskMetaFunction::QskMetaFunction( T function )
|
|
|
|
{
|
|
|
|
using namespace QtPrivate;
|
2018-03-03 14:52:42 +00:00
|
|
|
using namespace QskMetaFunctionCall;
|
2018-02-26 08:09:21 +00:00
|
|
|
|
|
|
|
using Traits = FunctionPointer< T >;
|
|
|
|
|
2018-03-01 14:13:55 +00:00
|
|
|
constexpr int Argc = Traits::ArgumentCount;
|
2018-02-26 08:09:21 +00:00
|
|
|
using Args = typename List_Left< typename Traits::Arguments, Argc >::Value;
|
2018-03-01 11:18:58 +00:00
|
|
|
|
2018-03-03 14:52:42 +00:00
|
|
|
m_functionCall = new MemberFunctionCall< T, Args, void >( function );
|
|
|
|
m_functionCall->setParameterTypes(
|
2018-03-02 10:26:25 +00:00
|
|
|
ConnectionTypes< typename Traits::Arguments >::types() );
|
2018-02-26 08:09:21 +00:00
|
|
|
}
|
|
|
|
|
2018-03-02 05:57:08 +00:00
|
|
|
template< typename T, QskMetaFunctionTraits::IsFunctor< T >* >
|
|
|
|
inline QskMetaFunction::QskMetaFunction( T functor )
|
2018-02-26 08:09:21 +00:00
|
|
|
{
|
|
|
|
using namespace QtPrivate;
|
2018-03-03 14:52:42 +00:00
|
|
|
using namespace QskMetaFunctionCall;
|
2018-02-26 08:09:21 +00:00
|
|
|
|
2018-03-02 05:57:08 +00:00
|
|
|
using Traits = FunctionPointer< decltype( &T::operator() ) >;
|
2018-02-26 08:09:21 +00:00
|
|
|
|
2018-03-01 14:13:55 +00:00
|
|
|
constexpr int Argc = Traits::ArgumentCount;
|
2018-02-26 08:09:21 +00:00
|
|
|
using Args = typename List_Left< typename Traits::Arguments, Argc >::Value;
|
|
|
|
|
2018-03-03 14:52:42 +00:00
|
|
|
m_functionCall = new FunctorFunctionCall< T, Argc, Args, void >( functor );
|
|
|
|
m_functionCall->setParameterTypes(
|
2018-03-02 10:26:25 +00:00
|
|
|
ConnectionTypes< typename Traits::Arguments >::types() );
|
2018-02-26 08:09:21 +00:00
|
|
|
}
|
|
|
|
|
2018-03-14 13:45:39 +00:00
|
|
|
template< typename T, QskMetaFunctionTraits::IsStaticFunction< T >* >
|
2018-03-02 05:57:08 +00:00
|
|
|
inline QskMetaFunction::QskMetaFunction( T function )
|
2018-02-26 08:09:21 +00:00
|
|
|
{
|
|
|
|
using namespace QtPrivate;
|
2018-03-03 14:52:42 +00:00
|
|
|
using namespace QskMetaFunctionCall;
|
2018-02-26 08:09:21 +00:00
|
|
|
|
2018-03-02 05:57:08 +00:00
|
|
|
using Traits = FunctionPointer< T >;
|
2018-02-26 08:09:21 +00:00
|
|
|
|
2018-03-01 14:13:55 +00:00
|
|
|
constexpr int Argc = Traits::ArgumentCount;
|
2018-02-26 08:09:21 +00:00
|
|
|
using Args = typename List_Left< typename Traits::Arguments, Argc >::Value;
|
2018-03-02 13:58:43 +00:00
|
|
|
|
2018-03-03 14:52:42 +00:00
|
|
|
m_functionCall = new StaticFunctionCall< T, Args, void >( function );
|
|
|
|
m_functionCall->setParameterTypes(
|
2018-03-02 10:26:25 +00:00
|
|
|
ConnectionTypes< typename Traits::Arguments >::types() );
|
2018-02-26 08:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Q_DECLARE_METATYPE( QskMetaFunction )
|
|
|
|
|
|
|
|
#endif
|