qskinny/src/common/QskMetaFunction.hpp

191 lines
5.3 KiB
C++
Raw Normal View History

2018-03-03 15:52:42 +01: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_HPP
2020-12-11 15:16:50 +01:00
#define QSK_META_FUNCTION_HPP
2018-03-03 15:52:42 +01:00
#include "QskGlobal.h"
2018-07-19 14:10:48 +02:00
#include <qobject.h>
2018-03-03 15:52:42 +01:00
class QskMetaFunction::FunctionCall : public QtPrivate::QSlotObjectBase
{
2020-12-05 15:09:31 +01:00
public:
2018-03-03 15:52:42 +01:00
typedef void (* InvokeFunction)(
int which, QtPrivate::QSlotObjectBase*, QObject*, void**, bool* );
enum
{
TypeInfo = NumOperations + 1
};
int typeInfo() const;
int refCount() const;
inline const int* parameterTypes() const
{
return m_parameterTypes;
}
inline void setParameterTypes( const int* types )
{
m_parameterTypes = types;
}
2020-12-05 15:09:31 +01:00
protected:
2018-03-03 15:52:42 +01:00
explicit inline FunctionCall( InvokeFunction f,
const int* m_parameterTypes = nullptr ):
QSlotObjectBase( f ),
m_parameterTypes( m_parameterTypes )
{
}
2020-12-05 15:09:31 +01:00
private:
2018-03-03 15:52:42 +01:00
const int* m_parameterTypes; // static array, only needed for Qt::QueuedConnection
};
namespace QskMetaFunctionCall
{
using FunctionCall = QskMetaFunction::FunctionCall;
using namespace QtPrivate;
template< typename Function, typename Args, typename R >
class StaticFunctionCall : public FunctionCall
{
using MetaCall = StaticFunctionCall< Function, Args, R >;
2020-12-05 15:09:31 +01:00
public:
2018-03-03 15:52:42 +01:00
explicit inline StaticFunctionCall( Function function ):
FunctionCall( &invoke ),
m_function( function )
{
}
static void invoke(int which, QSlotObjectBase* functionCall,
2018-03-04 13:31:49 +01:00
QObject* object, void** args, bool* ret )
2018-03-03 15:52:42 +01:00
{
switch ( which )
{
case Destroy:
{
delete static_cast< MetaCall* >( functionCall );
break;
}
case Call:
{
typedef FunctionPointer< Function > FuncType;
FuncType::template call< Args, R >(
static_cast< MetaCall* >( functionCall )->m_function, object, args );
break;
}
2018-03-04 13:31:49 +01:00
case Compare:
{
*ret = reinterpret_cast< MetaCall* >( args )->m_function
== static_cast< MetaCall* >( functionCall )->m_function;
break;
}
2018-03-03 15:52:42 +01:00
case TypeInfo:
{
*reinterpret_cast< int* >( args ) = QskMetaFunction::StaticFunction;
2018-03-03 15:52:42 +01:00
break;
}
}
}
2020-12-05 15:09:31 +01:00
private:
2018-03-03 15:52:42 +01:00
Function m_function;
};
template< typename Function, typename Args, typename R >
class MemberFunctionCall : public FunctionCall
{
using MetaCall = MemberFunctionCall< Function, Args, R >;
2020-12-05 15:09:31 +01:00
public:
2018-03-03 15:52:42 +01:00
explicit inline MemberFunctionCall( Function function ):
FunctionCall( &invoke ),
m_function( function )
{
}
static void invoke( int which, QSlotObjectBase* functionCall,
QObject* object, void** args, bool* )
{
switch (which)
{
case Destroy:
{
delete static_cast< MetaCall* >( functionCall );
break;
}
case Call:
{
typedef FunctionPointer< Function > FuncType;
FuncType::template call< Args, R >(
static_cast< MetaCall* >( functionCall )->m_function,
static_cast< typename FuncType::Object* >( object ), args );
break;
}
case TypeInfo:
{
*reinterpret_cast< int* >( args ) = QskMetaFunction::MemberFunction;
2018-03-03 15:52:42 +01:00
break;
}
}
}
2020-12-05 15:09:31 +01:00
private:
2018-03-03 15:52:42 +01:00
Function m_function;
};
template< typename Function, int N, typename Args, typename R >
class FunctorFunctionCall : public FunctionCall
{
using MetaCall = FunctorFunctionCall< Function, N, Args, R >;
2020-12-05 15:09:31 +01:00
public:
2018-03-03 15:52:42 +01:00
explicit inline FunctorFunctionCall( Function function ):
FunctionCall( &invoke ),
m_function( function )
{
}
2018-03-04 13:31:49 +01:00
static void invoke( int which, QSlotObjectBase* functionCall,
2018-03-03 15:52:42 +01:00
QObject* object, void** args, bool* )
{
switch (which)
{
case Destroy:
{
2018-03-04 13:31:49 +01:00
delete static_cast< MetaCall* >( functionCall );
2018-03-03 15:52:42 +01:00
break;
}
case Call:
{
typedef Functor< Function, N > FuncType;
FuncType::template call< Args, R >(
2018-03-04 13:31:49 +01:00
static_cast< MetaCall* >( functionCall )->m_function, object, args );
2018-03-03 15:52:42 +01:00
break;
}
case TypeInfo:
{
*reinterpret_cast< int* >( args ) = QskMetaFunction::Functor;
break;
}
}
}
2020-12-05 15:09:31 +01:00
private:
2018-03-03 15:52:42 +01:00
Function m_function;
};
}
#endif