qskinny/src/common/QskMetaFunction.h

177 lines
4.8 KiB
C
Raw Normal View History

/******************************************************************************
* 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"
#include <QMetaType>
2018-02-28 09:43:15 +00:00
namespace QskMetaFunctionTraits
{
using namespace QtPrivate;
template< typename T >
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
&& FunctionPointer< T >::ArgumentCount == -1, std::true_type >::type;
2018-03-02 05:57:08 +00:00
template< typename T >
using IsFunction = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction
&& FunctionPointer< T >::ArgumentCount >= 0, std::true_type >::type;
2018-03-02 06:07:19 +00:00
template< typename T >
using IsFunction0 = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction
&& FunctionPointer< T >::ArgumentCount == 0, std::true_type >::type;
2018-02-28 09:43:15 +00:00
}
class QSK_EXPORT QskMetaFunction
{
Q_GADGET
public:
enum Type
{
Invalid = -1,
// a non static method of class
Member,
// a static function, or static method of a class
Function,
// 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 >
QskMetaFunction( T );
2018-03-02 05:57:08 +00:00
template< typename T, QskMetaFunctionTraits::IsFunctor< T >* = nullptr >
QskMetaFunction( T );
2018-03-02 05:57:08 +00:00
template< typename T, QskMetaFunctionTraits::IsFunction< T >* = nullptr >
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;
size_t parameterCount() const;
2018-03-08 07:37:44 +00:00
const int* parameterTypes() const;
void invoke( QObject*, void* args[],
Qt::ConnectionType = Qt::AutoConnection );
Type functionType() const;
2018-03-04 12:31:49 +00:00
bool isNull() const;
2018-03-03 14:52:42 +00:00
class FunctionCall;
FunctionCall* functionCall() const;
2018-02-28 15:48:46 +00:00
2018-03-03 14:52:42 +00:00
protected:
QskMetaFunction( FunctionCall* );
2018-02-28 15:48:46 +00:00
private:
2018-03-03 14:52:42 +00:00
FunctionCall* m_functionCall;
};
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-28 09:43:15 +00:00
template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* >
inline QskMetaFunction::QskMetaFunction( T function )
{
using namespace QtPrivate;
2018-03-03 14:52:42 +00:00
using namespace QskMetaFunctionCall;
using Traits = FunctionPointer< T >;
constexpr int Argc = Traits::ArgumentCount;
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-03-02 05:57:08 +00:00
template< typename T, QskMetaFunctionTraits::IsFunctor< T >* >
inline QskMetaFunction::QskMetaFunction( T functor )
{
using namespace QtPrivate;
2018-03-03 14:52:42 +00:00
using namespace QskMetaFunctionCall;
2018-03-02 05:57:08 +00:00
using Traits = FunctionPointer< decltype( &T::operator() ) >;
constexpr int Argc = Traits::ArgumentCount;
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-03-02 05:57:08 +00:00
template< typename T, QskMetaFunctionTraits::IsFunction< T >* >
inline QskMetaFunction::QskMetaFunction( T function )
{
using namespace QtPrivate;
2018-03-03 14:52:42 +00:00
using namespace QskMetaFunctionCall;
2018-03-02 05:57:08 +00:00
using Traits = FunctionPointer< T >;
constexpr int Argc = Traits::ArgumentCount;
using Args = typename List_Left< typename Traits::Arguments, Argc >::Value;
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() );
}
Q_DECLARE_METATYPE( QskMetaFunction )
#endif