1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-08 23:26:40 +02:00

Fix QxtFifo and move qxtweb modules in their respective folder

This commit is contained in:
Uwe L. Korn
2013-04-09 10:35:08 +02:00
parent fd60cf4a5b
commit bf2067c414
70 changed files with 75 additions and 1547 deletions

View File

@@ -0,0 +1,639 @@
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#ifndef QXTBOUNDCFUNCTION_H
#define QXTBOUNDCFUNCTION_H
#include <qxtboundfunctionbase.h>
#include <qxtmetatype.h>
#include <qxtglobal.h>
#include <QtDebug>
#ifndef QXT_DOXYGEN_RUN
#define QXT_RETURN(fp) *reinterpret_cast<RETURN*>(returnValue.data()) = (*reinterpret_cast<FUNCTION>(fp))
#define QXT_INVOKE(fp) (*reinterpret_cast<FUNCTION>(fp))
#define QXT_PARAM(i) *reinterpret_cast<T ## i *>(p ## i .data())
template < typename RETURN, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void, typename T5 = void,
typename T6 = void, typename T7 = void, typename T8 = void, typename T9 = void, typename T10 = void >
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return : public QxtGenericFunctionPointer
{
public:
typedef RETURN(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7), QXT_PARAM(8), QXT_PARAM(9), QXT_PARAM(10));
return true;
}
private:
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename RETURN>
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, void, void, void, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef RETURN(*FUNCTION)();
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_RETURN(funcPtr)();
return true;
}
private:
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename RETURN, typename T1>
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, void, void, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef RETURN(*FUNCTION)(T1);
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_RETURN(funcPtr)(QXT_PARAM(1));
return true;
}
private:
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename RETURN, typename T1, typename T2>
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, void, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef RETURN(*FUNCTION)(T1, T2);
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2));
return true;
}
private:
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename RETURN, typename T1, typename T2, typename T3>
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef RETURN(*FUNCTION)(T1, T2, T3);
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3));
return true;
}
private:
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename RETURN, typename T1, typename T2, typename T3, typename T4>
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, T4, void, void, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef RETURN(*FUNCTION)(T1, T2, T3, T4);
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4));
return true;
}
private:
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5>
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, void, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef RETURN(*FUNCTION)(T1, T2, T3, T4, T5);
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5));
return true;
}
private:
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, T6, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef RETURN(*FUNCTION)(T1, T2, T3, T4, T5, T6);
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6));
return true;
}
private:
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, T6, T7, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef RETURN(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7);
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7));
return true;
}
};
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, void, void> : public QxtGenericFunctionPointer
{
public:
typedef RETURN(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7, T8);
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7), QXT_PARAM(8));
return true;
}
private:
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
class /*QXT_CORE_EXPORT*/ qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, void> : public QxtGenericFunctionPointer
{
public:
typedef RETURN(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7, T8, T9);
bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_RETURN(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7), QXT_PARAM(8), QXT_PARAM(9));
return true;
}
private:
qxt_cfunction_return(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template < typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void, typename T5 = void,
typename T6 = void, typename T7 = void, typename T8 = void, typename T9 = void, typename T10 = void >
class /*QXT_CORE_EXPORT*/ qxt_cfunction : public QxtGenericFunctionPointer
{
public:
typedef void(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7), QXT_PARAM(8), QXT_PARAM(9), QXT_PARAM(10));
return true;
}
private:
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <>
class /*QXT_CORE_EXPORT*/ qxt_cfunction<void, void, void, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef void(*FUNCTION)();
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_INVOKE(funcPtr)();
return true;
}
private:
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename T1>
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, void, void, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef void(*FUNCTION)(T1);
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_INVOKE(funcPtr)(QXT_PARAM(1));
return true;
}
private:
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename T1, typename T2>
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, void, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef void(*FUNCTION)(T1, T2);
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2));
return true;
}
private:
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename T1, typename T2, typename T3>
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, void, void, void, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef void(*FUNCTION)(T1, T2, T3);
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3));
return true;
}
private:
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename T1, typename T2, typename T3, typename T4>
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, T4, void, void, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef void(*FUNCTION)(T1, T2, T3, T4);
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4));
return true;
}
private:
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename T1, typename T2, typename T3, typename T4, typename T5>
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, T4, T5, void, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef void(*FUNCTION)(T1, T2, T3, T4, T5);
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5));
return true;
}
private:
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, T4, T5, T6, void, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef void(*FUNCTION)(T1, T2, T3, T4, T5, T6);
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6));
return true;
}
private:
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, T4, T5, T6, T7, void, void, void> : public QxtGenericFunctionPointer
{
public:
typedef void(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7);
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7));
return true;
}
private:
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, T4, T5, T6, T7, T8, void, void> : public QxtGenericFunctionPointer
{
public:
typedef void(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7, T8);
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7), QXT_PARAM(8));
return true;
}
private:
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
class /*QXT_CORE_EXPORT*/ qxt_cfunction<T1, T2, T3, T4, T5, T6, T7, T8, T9, void> : public QxtGenericFunctionPointer
{
public:
typedef void(*FUNCTION)(T1, T2, T3, T4, T5, T6, T7, T8, T9);
bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
{
QXT_10_UNUSED;
QXT_INVOKE(funcPtr)(QXT_PARAM(1), QXT_PARAM(2), QXT_PARAM(3), QXT_PARAM(4), QXT_PARAM(5), QXT_PARAM(6), QXT_PARAM(7), QXT_PARAM(8), QXT_PARAM(9));
return true;
}
private:
qxt_cfunction(voidFunc* ptr, const QByteArray& typeIdName) : QxtGenericFunctionPointer(ptr, typeIdName) {}
};
template < typename RETURN = void, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void, typename T5 = void,
typename T6 = void, typename T7 = void, typename T8 = void, typename T9 = void, typename T10 = void >
class /*QXT_CORE_EXPORT*/ QxtBoundCFunction : public QxtBoundFunctionBase
{
public:
QxtGenericFunctionPointer funcPtr;
QxtBoundCFunction(QObject* parent, QxtGenericFunctionPointer funcPointer, QGenericArgument* params[10], QByteArray types[10]) : QxtBoundFunctionBase(parent, params, types), funcPtr(funcPointer)
{
// initializers only, thanks to template magic
}
virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument))
{
if (type != Qt::AutoConnection && type != Qt::DirectConnection)
{
qWarning() << "QxtBoundCFunction::invoke: Cannot invoke non-Qt functions using a queued connection";
return false;
}
return reinterpret_cast<qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>*>(&funcPtr)->invoke(returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
}
};
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
class /*QXT_CORE_EXPORT*/ QxtBoundCFunction<void, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : public QxtBoundFunctionBase
{
public:
QxtGenericFunctionPointer funcPtr;
QxtBoundCFunction(QObject* parent, QxtGenericFunctionPointer funcPointer, QGenericArgument* params[10], QByteArray types[10]) : QxtBoundFunctionBase(parent, params, types), funcPtr(funcPointer)
{
// initializers only, thanks to template magic
}
virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument))
{
Q_UNUSED(returnValue);
if (type != Qt::AutoConnection && type != Qt::DirectConnection)
{
qWarning() << "QxtBoundCFunction::invoke: Cannot invoke non-Qt functions using a queued connection";
return false;
}
return reinterpret_cast<qxt_cfunction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>*>(&funcPtr)->invoke(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
}
};
#undef QXT_RETURN
#undef QXT_INVOKE
#undef QXT_PARAM
#endif
namespace QxtMetaObject
{
/*!
* \relates QxtMetaObject
* \sa QxtMetaObject::connect
* \sa qxtFuncPtr
* \sa QxtBoundFunction
* \sa QXT_BIND
*
* Creates a binding to the provided C/C++ function using the provided parameter list.
* Use the qxtFuncPtr function to wrap a bare function pointer for use in this function.
* Use the Q_ARG macro to specify constant parameters, or use the QXT_BIND macro to
* relay a parameter from a connected signal or passed via the QxtBoundFunction::invoke()
* method.
*
* The first template parameter must match the return type of the function, or
* void if the function does not return a value. The remaining template parameters must
* match the types of the function's parameters. If any type does not match, this
* function returns NULL.
*
* The returned QxtBoundFunction will not have a parent. Assigning a parent using
* QObject::setParent() is strongly recommended to avoid memory leaks.
*/
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QXT_IMPL_10ARGS(QGenericArgument))
{
// Make sure the template parameters make a function pointer equivalent to the one passed in
if (funcPointer.typeName != typeid(typename qxt_cfunction_return<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::FUNCTION).name())
{
qWarning() << "QxtMetaObject::bind: parameter list mismatch, check template arguments";
return 0;
}
QGenericArgument* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 };
for (int i = 0; i < 10; i++)
{
if (args[i]->name() == 0) break; // done
if (QByteArray(args[i]->name()) == "QxtBoundArgument")
{
Q_ASSERT_X((quintptr)(args[i]->data()) > 0 && (quintptr)(args[i]->data()) <= 10, "QXT_BIND", "invalid argument number");
}
}
QByteArray types[10];
types[0] = QxtMetaType<T1>::name();
types[1] = QxtMetaType<T2>::name();
types[2] = QxtMetaType<T3>::name();
types[3] = QxtMetaType<T4>::name();
types[4] = QxtMetaType<T5>::name();
types[5] = QxtMetaType<T6>::name();
types[6] = QxtMetaType<T7>::name();
types[7] = QxtMetaType<T8>::name();
types[8] = QxtMetaType<T9>::name();
types[9] = QxtMetaType<T10>::name();
return new QxtBoundCFunction<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(0, funcPointer, args, types);
}
/*!
* \relates QxtMetaObject
* \sa QxtMetaObject::connect
* \sa qxtFuncPtr
* \sa QxtBoundFunction
*
* Creates a binding to the provided C/C++ function using the provided parameter list.
* Use the qxtFuncPtr function to wrap a bare function pointer for use in this function.
* The type of each argument is deduced from the type of the QVariant. This function
* cannot bind positional arguments; see the overload using QGenericArgument.
*
* The first template parameter must match the return type of the function, or
* void if the function does not return a value. The remaining template parameters must
* match the types of the function's parameters. If any type does not match, this
* function returns NULL.
*
* The returned QxtBoundFunction will not have a parent. Assigning a parent using
* QObject::setParent() is strongly recommended to avoid memory leaks.
*/
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QXT_IMPL_10ARGS(QVariant))
{
QVariant* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 };
return QxtMetaObject::bind<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(funcPointer, QXT_VAR_ARG(1), QXT_VAR_ARG(2), QXT_VAR_ARG(3), QXT_VAR_ARG(4),
QXT_VAR_ARG(5), QXT_VAR_ARG(6), QXT_VAR_ARG(7), QXT_VAR_ARG(8), QXT_VAR_ARG(9), QXT_VAR_ARG(10));
}
// The following overloads exist because C++ doesn't support default parameters in function templates
#ifndef QXT_DOXYGEN_RUN
template <typename RETURN>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer)
{
return bind<RETURN, void, void, void, void, void, void, void, void, void, void>(funcPointer,
QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
}
template <typename RETURN, typename T1>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1)
{
return bind<RETURN, T1, void, void, void, void, void, void, void, void, void>(funcPointer,
p1, QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
}
template <typename RETURN, typename T1, typename T2>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2)
{
return bind<RETURN, T1, T2, void, void, void, void, void, void, void, void>(funcPointer,
p1, p2, QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
}
template <typename RETURN, typename T1, typename T2, typename T3>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3)
{
return bind<RETURN, T1, T2, T3, void, void, void, void, void, void, void>(funcPointer,
p1, p2, p3, QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
}
template <typename RETURN, typename T1, typename T2, typename T3, typename T4>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3, QGenericArgument p4)
{
return bind<RETURN, T1, T2, T3, T4, void, void, void, void, void, void>(funcPointer,
p1, p2, p3, p4, QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
}
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3, QGenericArgument p4, QGenericArgument p5)
{
return bind<RETURN, T1, T2, T3, T4, T5, void, void, void, void, void>(funcPointer,
p1, p2, p3, p4, p5, QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
}
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3, QGenericArgument p4, QGenericArgument p5, QGenericArgument p6)
{
return bind<RETURN, T1, T2, T3, T4, T5, T6, void, void, void, void>(funcPointer,
p1, p2, p3, p4, p5, p6, QGenericArgument(), QGenericArgument(), QGenericArgument(), QGenericArgument());
}
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3, QGenericArgument p4, QGenericArgument p5, QGenericArgument p6, QGenericArgument p7)
{
return bind<RETURN, T1, T2, T3, T4, T5, T6, T7, void, void, void>(funcPointer,
p1, p2, p3, p4, p5, p6, p7, QGenericArgument(), QGenericArgument(), QGenericArgument());
}
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3, QGenericArgument p4, QGenericArgument p5,
QGenericArgument p6, QGenericArgument p7, QGenericArgument p8)
{
return bind<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, void, void>(funcPointer, p1, p2, p3, p4, p5, p6, p7, p8, QGenericArgument(), QGenericArgument());
}
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QGenericArgument p1, QGenericArgument p2, QGenericArgument p3, QGenericArgument p4, QGenericArgument p5,
QGenericArgument p6, QGenericArgument p7, QGenericArgument p8, QGenericArgument p9)
{
return bind<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, void>(funcPointer, p1, p2, p3, p4, p5, p6, p7, p8, p9, QGenericArgument());
}
template <typename RETURN, typename T1>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1)
{
return bind<RETURN, T1, void, void, void, void, void, void, void, void, void>(funcPointer, p1, QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant());
}
template <typename RETURN, typename T1, typename T2>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2)
{
return bind<RETURN, T1, T2, void, void, void, void, void, void, void, void>(funcPointer, p1, p2, QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant());
}
template <typename RETURN, typename T1, typename T2, typename T3>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3)
{
return bind<RETURN, T1, T2, T3, void, void, void, void, void, void, void>(funcPointer, p1, p2, p3, QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant());
}
template <typename RETURN, typename T1, typename T2, typename T3, typename T4>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3, QVariant p4)
{
return bind<RETURN, T1, T2, T3, T4, void, void, void, void, void, void>(funcPointer, p1, p2, p3, p4, QVariant(), QVariant(), QVariant(), QVariant(), QVariant(), QVariant());
}
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5)
{
return bind<RETURN, T1, T2, T3, T4, T5, void, void, void, void, void>(funcPointer, p1, p2, p3, p4, p5, QVariant(), QVariant(), QVariant(), QVariant(), QVariant());
}
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6)
{
return bind<RETURN, T1, T2, T3, T4, T5, T6, void, void, void, void>(funcPointer, p1, p2, p3, p4, p5, p6, QVariant(), QVariant(), QVariant(), QVariant());
}
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7)
{
return bind<RETURN, T1, T2, T3, T4, T5, T6, T7, void, void, void>(funcPointer, p1, p2, p3, p4, p5, p6, p7, QVariant(), QVariant(), QVariant());
}
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8)
{
return bind<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, void, void>(funcPointer, p1, p2, p3, p4, p5, p6, p7, p8, QVariant(), QVariant());
}
template <typename RETURN, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
inline QxtBoundFunction* bind(QxtGenericFunctionPointer funcPointer, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8, QVariant p9)
{
return bind<RETURN, T1, T2, T3, T4, T5, T6, T7, T8, T9, void>(funcPointer, p1, p2, p3, p4, p5, p6, p7, p8, p9, QVariant());
}
#endif
}
#endif

View File

@@ -0,0 +1,274 @@
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#ifndef QXTBOUNDFUNCTION_H
#define QXTBOUNDFUNCTION_H
#include <QObject>
#include <QMetaObject>
#include <QGenericArgument>
#include <qxtmetaobject.h>
#include <qxtnull.h>
#include <QThread>
#include <QtDebug>
/*!
\class QxtBoundFunction
\inmodule QxtCore
\brief Binds parameters to a function call
* A bound function is very similar to what the C++ FAQ Lite refers to as "functionoids."
* (http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.10)
* It is similar in use to a function pointer, but allows any or all parameters to be
* pre-filled with constant values. The remaining parameters are specified when the
* function is invoked, for instance, by a Qt signal connection.
*
* By far, the most common expected use is to provide a parameter to a slot when the
* signal doesn't have offer one. Many developers new to Qt try to write code like this:
* \code
* connect(button, SIGNAL(clicked()), lineEdit, SLOT(setText("Hello, world")));
* \endcode
* Experienced Qt developers will immediately spot the flaw here. The typical solution
* is to create a short, one-line wrapper slot that invokes the desired function. Some
* clever developers may even use QSignalMapper to handle slots that only need one
* int or QString parameter.
*
* QxtBoundFunction enables the previous connect statement to be written like this:
* \code
* connect(button, SIGNAL(clicked()), QxtMetaObject::bind(lineEdit, SLOT(setText(QString)), Q_ARG(QString, "Hello, world!")));
* \code
* This accomplishes the same result without having to create a new slot, or worse,
* an entire object, just to pass a constant value.
*
* Additionally, through the use of the QXT_BIND macro, parameters from the signal
* can be rearranged, skipped, or passed alongside constant arguments provided
* with the Q_ARG macro. This can be used to provide stateful callbacks to a
* generic function, for example.
*
* Many kinds of functions can be bound. The most common binding applies to
* Qt signals and slots, but standard C/C++ functions can be bound as well.
* Future development may add the ability to bind to C++ member functions,
* and developers can make custom QxtBoundFunction subclasses for even more
* flexibility if necessary.
*
*
*/
class QXT_CORE_EXPORT QxtBoundFunction : public QObject
{
Q_OBJECT
public:
#ifndef QXT_DOXYGEN_RUN
virtual ~QxtBoundFunction() {};
#endif
/*!
* Invokes the bound function and returns a value.
*
* The template parameter should be the return type of the invoked function. This overload accepts
* QVariant parameters and will guess the data type of each parameter based on the type of the QVariant.
*/
template <class T>
inline QxtNullable<T> invoke(QXT_PROTO_10ARGS(QVariant))
{
if (!parent() || QThread::currentThread() == parent()->thread())
return invoke<T>(Qt::DirectConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
#if QT_VERSION >= 0x040300
return invoke<T>(Qt::BlockingQueuedConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
#else
qWarning() << "QxtBoundFunction::invoke: Cannot return a value using a queued connection";
return QxtNull();
#endif
}
/*!
* Invokes the bound function and returns a value.
*
* The template parameter should be the return type of the invoked function. This overload accepts
* QGenericArgument parameters, expressed using the Q_ARG() macro.
*/
template <class T>
QxtNullable<T> invoke(Qt::ConnectionType type, QVariant p1, QXT_PROTO_9ARGS(QVariant))
{
if (type == Qt::QueuedConnection)
{
qWarning() << "QxtBoundFunction::invoke: Cannot return a value using a queued connection";
return QxtNull();
}
T retval;
// I know this is a totally ugly function call
if (invoke(type, QGenericReturnArgument(qVariantFromValue<T>(*reinterpret_cast<T*>(0)).typeName(), reinterpret_cast<void*>(&retval)),
p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))
{
return retval;
}
else
{
return QxtNull();
}
}
/*!
* Invokes the bound function, discarding the return value.
*
* This overload accepts QVariant parameters and will guess the data type of each
* parameter based on the type of the QVariant.
*
* This function returns true if the invocation was successful, otherwise it
* returns false.
*/
inline bool invoke(QVariant p1, QXT_PROTO_9ARGS(QVariant))
{
return invoke(Qt::AutoConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
}
/*!
* Invokes the bound function, discarding the return value.
*
* This overload accepts QVariant parameters and will guess the data type of each
* parameter based on the type of the QVariant. It also allows you to specify the
* connection type, allowing the bound function to be invoked across threads using
* the Qt event loop.
*
* This function returns true if the invocation was successful, otherwise it
* returns false.
*/
bool invoke(Qt::ConnectionType, QVariant p1, QXT_PROTO_9ARGS(QVariant));
/*!
* Invokes the bound function, discarding the return value.
*
* This overload accepts QGenericArgument parameters, expressed using the Q_ARG()
* macro.
*
* This function returns true if the invocation was successful, otherwise it
* returns false.
*/
inline bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
{
return invoke(Qt::AutoConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
}
/*!
* Invokes the bound function, discarding the return value.
*
* This overload accepts QGenericArgument parameters, expressed using the Q_ARG()
* macro. It also allows you to specify the connection type, allowing the bound
* function to be invoked across threads using the Qt event loop.
*
* This function returns true if the invocation was successful, otherwise it
* returns false.
*/
inline bool invoke(Qt::ConnectionType type, QXT_PROTO_10ARGS(QGenericArgument))
{
return invoke(type, QGenericReturnArgument(), p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
}
/*!
* Invokes the bound function and assigns the return value to a parameter passed by reference.
*
* Use the Q_RETURN_ARG() macro to pass a reference to an assignable object of the function's
* return type. When the function completes, its return value will be stored in that object.
*
* This overload accepts QVariant parameters and will guess the data type of each
* parameter based on the type of the QVariant.
*
* This function returns true if the invocation was successful, otherwise it
* returns false.
*/
inline bool invoke(QGenericReturnArgument returnValue, QVariant p1, QXT_PROTO_9ARGS(QVariant))
{
return invoke(Qt::AutoConnection, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
}
/*!
* Invokes the bound function and assigns the return value to a parameter passed by reference.
*
* Use the Q_RETURN_ARG() macro to pass a reference to an assignable object of the function's
* return type. When the function completes, its return value will be stored in that object.
*
* This overload accepts QVariant parameters and will guess the data type of each
* parameter based on the type of the QVariant. It also allows you to specify the
* connection type, allowing the bound function to be invoked across threads using
* the Qt event loop.
*
* This function returns true if the invocation was successful, otherwise it
* returns false.
*/
bool invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QVariant p1, QXT_PROTO_9ARGS(QVariant));
/*!
* Invokes the bound function and assigns the return value to a parameter passed by reference.
*
* Use the Q_RETURN_ARG() macro to pass a reference to an assignable object of the function's
* return type. When the function completes, its return value will be stored in that object.
*
* This overload accepts QGenericArgument parameters, expressed using the Q_ARG()
* macro.
*
* This function returns true if the invocation was successful, otherwise it
* returns false.
*/
inline bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
{
return invoke(Qt::AutoConnection, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
}
/*!
* Invokes the bound function and assigns the return value to a parameter passed by reference.
*
* Use the Q_RETURN_ARG() macro to pass a reference to an assignable object of the function's
* return type. When the function completes, its return value will be stored in that object.
*
* This overload accepts QGenericArgument parameters, expressed using the Q_ARG()
* macro. It also allows you to specify the connection type, allowing the bound
* function to be invoked across threads using the Qt event loop.
*
* This function returns true if the invocation was successful, otherwise it
* returns false.
*/
bool invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument));
protected:
#ifndef QXT_DOXYGEN_RUN
QxtBoundFunction(QObject* parent = 0);
#endif
/*!
* Performs the work of invoking the bound function.
*
* This function is pure virtual. The various QxtMetaObject::bind() functions return opaque subclasses
* of QxtBoundFunction. If you wish to create a new kind of bound function, reimplement this function to
* perform the invocation and assign the function's return value, if any, to the returnValue parameter.
*
* This function should return true if the invocation is successful and false if an error occurs.
*/
virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument)) = 0;
};
#endif

View File

@@ -0,0 +1,67 @@
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
// This file exists for the convenience of QxtBoundCFunction.
// It is not part of the public API and is subject to change.
//
// We mean it.
#ifndef QXTBOUNDFUNCTIONBASE_H
#define QXTBOUNDFUNCTIONBASE_H
#include <QObject>
#include <QMetaObject>
#include <QGenericArgument>
#include <qxtmetaobject.h>
#include <qxtboundfunction.h>
#ifndef QXT_DOXYGEN_RUN
#define QXT_10_UNUSED Q_UNUSED(p1) Q_UNUSED(p2) Q_UNUSED(p3) Q_UNUSED(p4) Q_UNUSED(p5) Q_UNUSED(p6) Q_UNUSED(p7) Q_UNUSED(p8) Q_UNUSED(p9) Q_UNUSED(p10)
class QXT_CORE_EXPORT QxtBoundFunctionBase : public QxtBoundFunction
{
public:
QByteArray bindTypes[10];
QGenericArgument arg[10], p[10];
void* data[10];
QxtBoundFunctionBase(QObject* parent, QGenericArgument* params[10], QByteArray types[10]);
virtual ~QxtBoundFunctionBase();
int qt_metacall(QMetaObject::Call _c, int _id, void **_a);
bool invokeBase(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument));
};
#define QXT_ARG(i) ((argCount>i)?QGenericArgument(p ## i .typeName(), p ## i .constData()):QGenericArgument())
#define QXT_VAR_ARG(i) (p ## i .isValid())?QGenericArgument(p ## i .typeName(), p ## i .constData()):QGenericArgument()
#endif
#endif

View File

@@ -0,0 +1,269 @@
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
/*!
\class QxtFifo
\inmodule QxtCore
\brief The QxtFifo class provides a simple loopback QIODevice.
read and write to the same object
emits a readyRead Signal.
useful for loopback tests where QBuffer does not work.
\code
QxtFifo fifo;
QTextStream (&fifo)<<QString("foo");
QString a;
QTextStream(&fifo)>>a;
qDebug()<<a;
\endcode
*/
#include "qxtfifo.h"
#include <string.h>
#include <limits.h>
#include <QDebug>
#include <QQueue>
#include <qatomic.h>
#if QT_VERSION >= 0x50000
# define QXT_EXCHANGE(x) fetchAndStoreOrdered(x)
# define QXT_EXCHANGE_(x) fetchAndStoreOrdered(x.load())
# define QXT_ADD fetchAndAddOrdered
#elif QT_VERSION >= 0x040400
# include <qbasicatomic.h>
# define QXT_EXCHANGE fetchAndStoreOrdered
# define QXT_EXCHANGE_ QXT_EXCHANGE
# define QXT_ADD fetchAndAddOrdered
#else
typedef QBasicAtomic QBasicAtomicInt;
# define QXT_EXCHANGE exchange
# define QXT_EXCHANGE_ QXT_EXCHANGE
# define QXT_ADD fetchAndAdd
#endif
struct QxtFifoNode {
QxtFifoNode(const char* data, int size) : content(data, size) {
#if QT_VERSION >= 0x50000
next.store(0);
#else
next = NULL;
#endif
}
QxtFifoNode(const QByteArray &data) : content(data) {
#if QT_VERSION >= 0x50000
next.store(0);
#else
next = NULL;
#endif
}
QByteArray content;
QBasicAtomicPointer<QxtFifoNode> next;
};
class QxtFifoPrivate : public QxtPrivate<QxtFifo> {
public:
QXT_DECLARE_PUBLIC(QxtFifo)
QxtFifoPrivate() {
QxtFifoNode *n = new QxtFifoNode(NULL, 0);
#if QT_VERSION >= 0x50000
head.store(n);
tail.store(n);
#else
head = n;
tail = n;
#endif
#if QT_VERSION >= 0x50000
available.store(0);
#else
available = 0;
#endif
}
QBasicAtomicPointer<QxtFifoNode> head, tail;
QBasicAtomicInt available;
};
/*!
Constructs a new QxtFifo with \a parent.
*/
QxtFifo::QxtFifo(QObject *parent) : QIODevice(parent)
{
QXT_INIT_PRIVATE(QxtFifo);
setOpenMode(QIODevice::ReadWrite);
}
/*!
Constructs a new QxtFifo with \a parent and initial content from \a prime.
*/
QxtFifo::QxtFifo(const QByteArray &prime, QObject *parent) : QIODevice(parent)
{
QXT_INIT_PRIVATE(QxtFifo);
setOpenMode(QIODevice::ReadWrite);
// Since we're being constructed, access to the internals is safe
QxtFifoNode* node;
#if QT_VERSION >= 0x50000
node = qxt_d().head.load();
#else
node = qxt_d().head;
#endif
node->content = prime;
qxt_d().available.QXT_ADD( prime.size() );
}
/*!
\reimp
*/
qint64 QxtFifo::readData ( char * data, qint64 maxSize )
{
int bytes, step;
#if QT_VERSION >= 0x50000
bytes = qxt_d().available.load();
#else
bytes = qxt_d().available;
#endif
if(!bytes) return 0;
if(bytes > maxSize) bytes = maxSize;
int written = bytes;
char* writePos = data;
QxtFifoNode* node;
while(bytes > 0) {
#if QT_VERSION >= 0x50000
node = qxt_d().head.load();
#else
node = qxt_d().head;
#endif
step = node->content.size();
if(step >= bytes) {
int rem = step - bytes;
memcpy(writePos, node->content.constData(), bytes);
step = bytes;
node->content = node->content.right(rem);
} else {
memcpy(writePos, node->content.constData(), step);
qxt_d().head.QXT_EXCHANGE_(node->next);
delete node;
#if QT_VERSION >= 0x50000
node = qxt_d().head.load();
#else
node = qxt_d().head;
#endif
}
writePos += step;
bytes -= step;
}
qxt_d().available.QXT_ADD(-written);
return written;
}
/*!
\reimp
*/
qint64 QxtFifo::writeData ( const char * data, qint64 maxSize )
{
if(maxSize > 0) {
if(maxSize > INT_MAX) maxSize = INT_MAX; // qint64 could easily exceed QAtomicInt, so let's play it safe
QxtFifoNode* newData = new QxtFifoNode(data, maxSize);
#if QT_VERSION >= 0x50000
qxt_d().tail.load()->next.QXT_EXCHANGE(newData);
#else
qxt_d().tail->next.QXT_EXCHANGE(newData);
#endif
qxt_d().tail.QXT_EXCHANGE(newData);
qxt_d().available.QXT_ADD(maxSize);
QMetaObject::invokeMethod(this, "bytesWritten", Qt::QueuedConnection, Q_ARG(qint64, maxSize));
QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
}
return maxSize;
}
/*!
\reimp
*/
bool QxtFifo::isSequential () const
{
return true;
}
/*!
\reimp
*/
qint64 QxtFifo::bytesAvailable () const
{
#if QT_VERSION >= 0x50000
return qxt_d().available.load() + QIODevice::bytesAvailable();
#else
return qxt_d().available + QIODevice::bytesAvailable();
#endif
}
/*!
*/
void QxtFifo::clear()
{
qxt_d().available.QXT_EXCHANGE(0);
qxt_d().tail.QXT_EXCHANGE_(qxt_d().head);
#if QT_VERSION >= 0x50000
QxtFifoNode* node = qxt_d().head.load()->next.QXT_EXCHANGE(NULL);
#else
QxtFifoNode* node = qxt_d().head->next.QXT_EXCHANGE(NULL);
#endif
#if QT_VERSION >= 0x50000
while (node && node->next.load())
#else
while (node && node->next)
#endif
{
QxtFifoNode* next = node->next.QXT_EXCHANGE(NULL);
delete node;
node = next;
}
#if QT_VERSION >= 0x50000
qxt_d().head.load()->content = QByteArray();
#else
qxt_d().head->content = QByteArray();
#endif
}

View File

@@ -0,0 +1,57 @@
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#ifndef QXTFIFO_H
#define QXTFIFO_H
#include "qxtglobal.h"
#include <QIODevice>
class QxtFifoPrivate;
class QXT_CORE_EXPORT QxtFifo : public QIODevice
{
Q_OBJECT
public:
QxtFifo(QObject * parent = 0);
virtual bool isSequential() const;
virtual qint64 bytesAvailable() const;
void clear();
protected:
explicit QxtFifo(const QByteArray &prime, QObject * parent = 0);
virtual qint64 readData(char * data, qint64 maxSize);
virtual qint64 writeData(const char * data, qint64 maxSize);
private:
QXT_DECLARE_PRIVATE(QxtFifo)
};
#endif // QXTFIFO_H

View File

@@ -0,0 +1,233 @@
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#ifndef QXTGLOBAL_H
#define QXTGLOBAL_H
#include <QtGlobal>
#define QXT_VERSION 0x000700
#define QXT_VERSION_STR "0.7.0"
//--------------------------global macros------------------------------
#ifndef QXT_NO_MACROS
#ifndef _countof
#define _countof(x) (sizeof(x)/sizeof(*x))
#endif
#endif // QXT_NO_MACROS
//--------------------------export macros------------------------------
#define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_CORE)
# define QXT_CORE_EXPORT Q_DECL_EXPORT
# else
# define QXT_CORE_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_CORE_EXPORT
#endif // BUILD_QXT_CORE
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_GUI)
# define QXT_GUI_EXPORT Q_DECL_EXPORT
# else
# define QXT_GUI_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_GUI_EXPORT
#endif // BUILD_QXT_GUI
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_NETWORK)
# define QXT_NETWORK_EXPORT Q_DECL_EXPORT
# else
# define QXT_NETWORK_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_NETWORK_EXPORT
#endif // BUILD_QXT_NETWORK
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_SQL)
# define QXT_SQL_EXPORT Q_DECL_EXPORT
# else
# define QXT_SQL_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_SQL_EXPORT
#endif // BUILD_QXT_SQL
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_WEB)
# define QXT_WEB_EXPORT Q_DECL_EXPORT
# else
# define QXT_WEB_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_WEB_EXPORT
#endif // BUILD_QXT_WEB
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_BERKELEY)
# define QXT_BERKELEY_EXPORT Q_DECL_EXPORT
# else
# define QXT_BERKELEY_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_BERKELEY_EXPORT
#endif // BUILD_QXT_BERKELEY
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_ZEROCONF)
# define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT
# else
# define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT
# endif
#else
# define QXT_ZEROCONF_EXPORT
#endif // QXT_ZEROCONF_EXPORT
#if defined(BUILD_QXT_CORE) || defined(BUILD_QXT_GUI) || defined(BUILD_QXT_SQL) || defined(BUILD_QXT_NETWORK) || defined(BUILD_QXT_WEB) || defined(BUILD_QXT_BERKELEY) || defined(BUILD_QXT_ZEROCONF)
# define BUILD_QXT
#endif
QXT_CORE_EXPORT const char* qxtVersion();
#ifndef QT_BEGIN_NAMESPACE
#define QT_BEGIN_NAMESPACE
#endif
#ifndef QT_END_NAMESPACE
#define QT_END_NAMESPACE
#endif
#ifndef QT_FORWARD_DECLARE_CLASS
#define QT_FORWARD_DECLARE_CLASS(Class) class Class;
#endif
/****************************************************************************
** This file is derived from code bearing the following notice:
** The sole author of this file, Adam Higerd, has explicitly disclaimed all
** copyright interest and protection for the content within. This file has
** been placed in the public domain according to United States copyright
** statute and case law. In jurisdictions where this public domain dedication
** is not legally recognized, anyone who receives a copy of this file is
** permitted to use, modify, duplicate, and redistribute this file, in whole
** or in part, with no restrictions or conditions. In these jurisdictions,
** this file shall be copyright (C) 2006-2008 by Adam Higerd.
****************************************************************************/
#define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface<PUB, PUB##Private> qxt_d;
#define QXT_DECLARE_PUBLIC(PUB) friend class PUB;
#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);
#define QXT_D(PUB) PUB##Private& d = qxt_d()
#define QXT_P(PUB) PUB& p = qxt_p()
template <typename PUB>
class QxtPrivate
{
public:
virtual ~QxtPrivate()
{}
inline void QXT_setPublic(PUB* pub)
{
qxt_p_ptr = pub;
}
protected:
inline PUB& qxt_p()
{
return *qxt_p_ptr;
}
inline const PUB& qxt_p() const
{
return *qxt_p_ptr;
}
inline PUB* qxt_ptr()
{
return qxt_p_ptr;
}
inline const PUB* qxt_ptr() const
{
return qxt_p_ptr;
}
private:
PUB* qxt_p_ptr;
};
template <typename PUB, typename PVT>
class QxtPrivateInterface
{
friend class QxtPrivate<PUB>;
public:
QxtPrivateInterface()
{
pvt = new PVT;
}
~QxtPrivateInterface()
{
delete pvt;
}
inline void setPublic(PUB* pub)
{
pvt->QXT_setPublic(pub);
}
inline PVT& operator()()
{
return *static_cast<PVT*>(pvt);
}
inline const PVT& operator()() const
{
return *static_cast<PVT*>(pvt);
}
inline PVT * operator->()
{
return static_cast<PVT*>(pvt);
}
inline const PVT * operator->() const
{
return static_cast<PVT*>(pvt);
}
private:
QxtPrivateInterface(const QxtPrivateInterface&) { }
QxtPrivateInterface& operator=(const QxtPrivateInterface&) { }
QxtPrivate<PUB>* pvt;
};
#endif // QXT_GLOBAL

View File

@@ -0,0 +1,378 @@
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
/*!
\namespace QxtMetaObject
\inmodule QxtCore
\brief The QxtMetaObject namespace provides extensions to QMetaObject
including QxtMetaObject::bind
*/
#include "qxtmetaobject.h"
#include "qxtboundfunction.h"
#include "qxtboundcfunction.h"
#include "qxtmetatype.h"
#include <QByteArray>
#include <QMetaObject>
#include <QMetaMethod>
#include <QtDebug>
#ifndef QXT_DOXYGEN_RUN
class QxtBoundArgument
{
// This class intentionally left blank
};
Q_DECLARE_METATYPE(QxtBoundArgument)
class QxtBoundFunctionBase;
QxtBoundFunction::QxtBoundFunction(QObject* parent) : QObject(parent)
{
// initializer only
}
#endif
bool QxtBoundFunction::invoke(Qt::ConnectionType type, QXT_IMPL_10ARGS(QVariant))
{
return invoke(type, QXT_VAR_ARG(1), QXT_VAR_ARG(2), QXT_VAR_ARG(3), QXT_VAR_ARG(4), QXT_VAR_ARG(5), QXT_VAR_ARG(6), QXT_VAR_ARG(7), QXT_VAR_ARG(8), QXT_VAR_ARG(9), QXT_VAR_ARG(10));
}
bool QxtBoundFunction::invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QVariant))
{
return invoke(type, returnValue, QXT_VAR_ARG(1), QXT_VAR_ARG(2), QXT_VAR_ARG(3), QXT_VAR_ARG(4), QXT_VAR_ARG(5), QXT_VAR_ARG(6), QXT_VAR_ARG(7), QXT_VAR_ARG(8), QXT_VAR_ARG(9), QXT_VAR_ARG(10));
}
QxtBoundFunctionBase::QxtBoundFunctionBase(QObject* parent, QGenericArgument* params[10], QByteArray types[10]) : QxtBoundFunction(parent)
{
for (int i = 0; i < 10; i++)
{
if (!params[i]) break;
if (QByteArray(params[i]->name()) == "QxtBoundArgument")
{
arg[i] = QGenericArgument("QxtBoundArgument", params[i]->data());
}
else
{
data[i] = qxtConstructFromGenericArgument(*params[i]);
arg[i] = p[i] = QGenericArgument(params[i]->name(), data[i]);
}
bindTypes[i] = types[i];
}
}
QxtBoundFunctionBase::~QxtBoundFunctionBase()
{
for (int i = 0; i < 10; i++)
{
if (arg[i].name() == 0) return;
if (QByteArray(arg[i].name()) != "QxtBoundArgument") qxtDestroyFromGenericArgument(arg[i]);
}
}
int QxtBoundFunctionBase::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod)
{
if (_id == 0)
{
for (int i = 0; i < 10; i++)
{
if (QByteArray(arg[i].name()) == "QxtBoundArgument")
{
p[i] = QGenericArgument(bindTypes[i].constData(), _a[(quintptr)(arg[i].data())]);
}
}
invokeImpl(Qt::DirectConnection, QGenericReturnArgument(), p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]);
}
_id = -1;
}
return _id;
}
bool QxtBoundFunctionBase::invokeBase(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument))
{
QGenericArgument* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 };
for (int i = 0; i < 10; i++)
{
if (QByteArray(arg[i].name()) == "QxtBoundArgument")
{
p[i] = *args[(quintptr)(arg[i].data()) - 1];
}
}
return invokeImpl(type, returnValue, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]);
}
bool QxtBoundFunction::invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument))
{
return reinterpret_cast<QxtBoundFunctionBase*>(this)->invokeBase(type, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
}
#ifndef QXT_DOXYGEN_RUN
class QxtBoundSlot : public QxtBoundFunctionBase
{
public:
QByteArray sig;
QxtBoundSlot(QObject* receiver, const char* invokable, QGenericArgument* params[10], QByteArray types[10]) : QxtBoundFunctionBase(receiver, params, types), sig(invokable)
{
// initializers only
}
virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument))
{
if (!QMetaObject::invokeMethod(parent(), QxtMetaObject::methodName(sig.constData()), type, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))
{
qWarning() << "QxtBoundFunction: call to" << sig << "failed";
return false;
}
return true;
}
};
#endif
namespace QxtMetaObject
{
/*!
Returns the name of the given method.
Example usage:
\code
QByteArray method = QxtMetaObject::methodName(" int foo ( int bar, double baz )");
// method is now "foo"
\endcode
*/
QByteArray methodName(const char* method)
{
QByteArray name = methodSignature(method);
const int idx = name.indexOf("(");
if (idx != -1)
name.truncate(idx);
return name;
}
/*!
Returns the signature of the given method.
*/
QByteArray methodSignature(const char* method)
{
QByteArray name = QMetaObject::normalizedSignature(method);
if(name[0] >= '0' && name[0] <= '9')
return name.mid(1);
return name;
}
/*!
Checks if \a method contains parentheses and begins with 1 or 2.
*/
bool isSignalOrSlot(const char* method)
{
QByteArray m(method);
return (m.count() && (m[0] >= '0' && m[0] <= '9') && m.contains('(') && m.contains(')'));
}
/*!
* Creates a binding to the provided signal, slot, or Q_INVOKABLE method using the
* provided parameter list. The type of each argument is deduced from the type of
* the QVariant. This function cannot bind positional arguments; see the
* overload using QGenericArgument.
*
* If the provided QObject does not implement the requested method, or if the
* argument list is incompatible with the method's function signature, this
* function returns NULL.
*
* The returned QxtBoundFunction is created as a child of the receiver.
* Changing the parent will result in undefined behavior.
*
* \sa QxtMetaObject::connect, QxtBoundFunction
*/
QxtBoundFunction* bind(QObject* recv, const char* invokable, QXT_IMPL_10ARGS(QVariant))
{
if (!recv)
{
qWarning() << "QxtMetaObject::bind: cannot connect to null QObject";
return 0;
}
QVariant* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 };
QByteArray connSlot("2"), recvSlot(QMetaObject::normalizedSignature(invokable));
const QMetaObject* meta = recv->metaObject();
int methodID = meta->indexOfMethod(QxtMetaObject::methodSignature(recvSlot.constData()));
if (methodID == -1)
{
qWarning() << "QxtMetaObject::bind: no such method " << recvSlot;
return 0;
}
QMetaMethod method = meta->method(methodID);
int argCount = method.parameterTypes().count();
const QList<QByteArray> paramTypes = method.parameterTypes();
for (int i = 0; i < argCount; i++)
{
if (paramTypes[i] == "QxtBoundArgument") continue;
int type = QMetaType::type(paramTypes[i].constData());
if (!args[i]->canConvert((QVariant::Type)type))
{
qWarning() << "QxtMetaObject::bind: incompatible parameter list for " << recvSlot;
return 0;
}
}
return QxtMetaObject::bind(recv, invokable, QXT_ARG(1), QXT_ARG(2), QXT_ARG(3), QXT_ARG(4), QXT_ARG(5), QXT_ARG(6), QXT_ARG(7), QXT_ARG(8), QXT_ARG(9), QXT_ARG(10));
}
/*!
* Creates a binding to the provided signal, slot, or Q_INVOKABLE method using the
* provided parameter list. Use the Q_ARG macro to specify constant parameters, or
* use the QXT_BIND macro to relay a parameter from a connected signal or passed
* via the QxtBoundFunction::invoke() method.
*
* If the provided QObject does not implement the requested method, or if the
* argument list is incompatible with the method's function signature, this
* function returns NULL.
*
* The returned QxtBoundFunction is created as a child of the receiver.
* Changing the parent will result in undefined behavior.
*
* \sa QxtMetaObject::connect, QxtBoundFunction, QXT_BIND
*/
QxtBoundFunction* bind(QObject* recv, const char* invokable, QXT_IMPL_10ARGS(QGenericArgument))
{
if (!recv)
{
qWarning() << "QxtMetaObject::bind: cannot connect to null QObject";
return 0;
}
QGenericArgument* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 };
QByteArray connSlot("2"), recvSlot(QMetaObject::normalizedSignature(invokable)), bindTypes[10];
const QMetaObject* meta = recv->metaObject();
int methodID = meta->indexOfMethod(QxtMetaObject::methodSignature(recvSlot.constData()).constData());
if (methodID == -1)
{
qWarning() << "QxtMetaObject::bind: no such method " << recvSlot;
return 0;
}
QMetaMethod method = meta->method(methodID);
int argCount = method.parameterTypes().count();
connSlot += QxtMetaObject::methodName(invokable) + '(';
for (int i = 0; i < 10; i++)
{
if (args[i]->name() == 0) break; // done
if (i >= argCount)
{
qWarning() << "QxtMetaObject::bind: too many arguments passed to " << invokable;
return 0;
}
if (i > 0) connSlot += ','; // argument separator
if (QByteArray(args[i]->name()) == "QxtBoundArgument")
{
Q_ASSERT_X((quintptr)(args[i]->data()) > 0 && (quintptr)(args[i]->data()) <= 10, "QXT_BIND", "invalid argument number");
connSlot += method.parameterTypes()[i];
bindTypes[i] = method.parameterTypes()[i];
}
else
{
connSlot += args[i]->name(); // type name
}
}
connSlot = QMetaObject::normalizedSignature(connSlot += ')');
if (!QMetaObject::checkConnectArgs(recvSlot.constData(), connSlot.constData()))
{
qWarning() << "QxtMetaObject::bind: provided parameters " << connSlot.mid(connSlot.indexOf('(')) << " is incompatible with " << invokable;
return 0;
}
return new QxtBoundSlot(recv, invokable, args, bindTypes);
}
/*!
Connects a signal to a QxtBoundFunction.
*/
bool connect(QObject* sender, const char* signal, QxtBoundFunction* slot, Qt::ConnectionType type)
{
Q_ASSERT(sender);
const QMetaObject* meta = sender->metaObject();
int methodID = meta->indexOfMethod(meta->normalizedSignature(signal).mid(1).constData());
if (methodID < 0)
{
qWarning() << "QxtMetaObject::connect: no such signal: " << QByteArray(signal).mid(1);
return false;
}
return QMetaObject::connect(sender, methodID, slot, QObject::staticMetaObject.methodCount(), (int)(type));
}
/*!
\relates QxtMetaObject
This overload always invokes the member using the connection type Qt::AutoConnection.
\sa QMetaObject::invokeMethod()
*/
bool invokeMethod(QObject* object, const char* member, const QVariant& arg0,
const QVariant& arg1, const QVariant& arg2, const QVariant& arg3,
const QVariant& arg4, const QVariant& arg5, const QVariant& arg6,
const QVariant& arg7, const QVariant& arg8, const QVariant& arg9)
{
return invokeMethod(object, member, Qt::AutoConnection,
arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
}
/*!
\relates QxtMetaObject
Invokes the \a member (a signal or a slot name) on the \a object.
Returns \c true if the member could be invoked. Returns \c false
if there is no such member or the parameters did not match.
\sa QMetaObject::invokeMethod()
*/
bool invokeMethod(QObject* object, const char* member, Qt::ConnectionType type,
const QVariant& arg0, const QVariant& arg1, const QVariant& arg2,
const QVariant& arg3, const QVariant& arg4, const QVariant& arg5,
const QVariant& arg6, const QVariant& arg7, const QVariant& arg8, const QVariant& arg9)
{
#define QXT_MO_ARG(i) QGenericArgument(arg ## i.typeName(), arg ## i.constData())
return QMetaObject::invokeMethod(object, methodName(member), type,
QXT_MO_ARG(0), QXT_MO_ARG(1), QXT_MO_ARG(2), QXT_MO_ARG(3), QXT_MO_ARG(4),
QXT_MO_ARG(5), QXT_MO_ARG(6), QXT_MO_ARG(7), QXT_MO_ARG(8), QXT_MO_ARG(9));
}
}

View File

@@ -0,0 +1,112 @@
#ifndef QXTMETAOBJECT_H
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#define QXTMETAOBJECT_H
#include <QMetaObject>
#include <QVariant>
#include <QGenericArgument>
#include <typeinfo>
#include "qxtnullable.h"
#include "qxtglobal.h"
QT_FORWARD_DECLARE_CLASS(QByteArray)
class QxtBoundArgument;
class QxtBoundFunction;
#define QXT_PROTO_10ARGS(T) T p1 = T(), T p2 = T(), T p3 = T(), T p4 = T(), T p5 = T(), T p6 = T(), T p7 = T(), T p8 = T(), T p9 = T(), T p10 = T()
#define QXT_PROTO_9ARGS(T) T p2 = T(), T p3 = T(), T p4 = T(), T p5 = T(), T p6 = T(), T p7 = T(), T p8 = T(), T p9 = T(), T p10 = T()
#define QXT_IMPL_10ARGS(T) T p1, T p2, T p3, T p4, T p5, T p6, T p7, T p8, T p9, T p10
class QXT_CORE_EXPORT QxtGenericFunctionPointer
{
template<typename FUNCTION>
friend QxtGenericFunctionPointer qxtFuncPtr(FUNCTION funcPtr);
public:
QxtGenericFunctionPointer(const QxtGenericFunctionPointer& other)
{
funcPtr = other.funcPtr;
typeName = other.typeName;
}
typedef void(voidFunc)();
voidFunc* funcPtr;
QByteArray typeName;
protected:
QxtGenericFunctionPointer(voidFunc* ptr, const QByteArray& typeIdName)
{
funcPtr = ptr;
typeName = typeIdName;
}
};
template<typename FUNCTION>
QxtGenericFunctionPointer qxtFuncPtr(FUNCTION funcPtr)
{
return QxtGenericFunctionPointer(reinterpret_cast<QxtGenericFunctionPointer::voidFunc*>(funcPtr), typeid(funcPtr).name());
}
namespace QxtMetaObject
{
QXT_CORE_EXPORT QByteArray methodName(const char* method);
QXT_CORE_EXPORT QByteArray methodSignature(const char* method);
QXT_CORE_EXPORT bool isSignalOrSlot(const char* method);
QXT_CORE_EXPORT QxtBoundFunction* bind(QObject* recv, const char* invokable, QXT_PROTO_10ARGS(QGenericArgument));
QXT_CORE_EXPORT QxtBoundFunction* bind(QObject* recv, const char* invokable, QVariant p1, QXT_PROTO_9ARGS(QVariant));
QXT_CORE_EXPORT bool connect(QObject* sender, const char* signal, QxtBoundFunction* slot,
Qt::ConnectionType type = Qt::AutoConnection);
QXT_CORE_EXPORT bool invokeMethod(QObject* object, const char* member,
const QVariant& arg0 = QVariant(), const QVariant& arg1 = QVariant(),
const QVariant& arg2 = QVariant(), const QVariant& arg3 = QVariant(),
const QVariant& arg4 = QVariant(), const QVariant& arg5 = QVariant(),
const QVariant& arg6 = QVariant(), const QVariant& arg7 = QVariant(),
const QVariant& arg8 = QVariant(), const QVariant& arg9 = QVariant());
QXT_CORE_EXPORT bool invokeMethod(QObject* object, const char* member, Qt::ConnectionType type,
const QVariant& arg0 = QVariant(), const QVariant& arg1 = QVariant(),
const QVariant& arg2 = QVariant(), const QVariant& arg3 = QVariant(),
const QVariant& arg4 = QVariant(), const QVariant& arg5 = QVariant(),
const QVariant& arg6 = QVariant(), const QVariant& arg7 = QVariant(),
const QVariant& arg8 = QVariant(), const QVariant& arg9 = QVariant());
}
/*!
* \relates QxtMetaObject
* Refers to the n'th parameter of QxtBoundFunction::invoke() or of a signal connected to
* a QxtBoundFunction.
* \sa QxtMetaObject::bind
*/
#define QXT_BIND(n) QGenericArgument("QxtBoundArgument", reinterpret_cast<void*>(n))
#endif // QXTMETAOBJECT_H

View File

@@ -0,0 +1,144 @@
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#ifndef QXTMETATYPE_H
#define QXTMETATYPE_H
#include <QMetaType>
#include <QDataStream>
#include <QGenericArgument>
#include <QtDebug>
#include <qxtglobal.h>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
#define qxtcreate create
#else
#define qxtcreate construct
#endif
template <typename T>
class /*QXT_CORE_EXPORT*/ QxtMetaType
{
public:
static inline T* construct(const T* copy = 0)
{
return QMetaType::qxtcreate(qMetaTypeId<T>(), reinterpret_cast<const void*>(copy));
}
static inline void destroy(T* data)
{
QMetaType::destroy(qMetaTypeId<T>(), data);
}
// no need to reimplement isRegistered since this class will fail at compile time if it isn't
static inline bool load(QDataStream& stream, T* data)
{
return QMetaType::load(stream, qMetaTypeId<T>(), reinterpret_cast<void*>(data));
}
static inline bool save(QDataStream& stream, const T* data)
{
return QMetaType::save(stream, qMetaTypeId<T>(), reinterpret_cast<const void*>(data));
}
static inline int type()
{
return qMetaTypeId<T>();
}
static inline const char* name()
{
return QMetaType::typeName(qMetaTypeId<T>());
}
};
template <>
class /*QXT_CORE_EXPORT*/ QxtMetaType<void>
{
public:
static inline void* construct(const void* copy = 0)
{
Q_UNUSED(copy);
return 0;
}
static inline void destroy(void* data)
{
Q_UNUSED(data);
}
static inline bool load(QDataStream& stream, void* data)
{
Q_UNUSED(stream);
Q_UNUSED(data);
return false;
}
static inline bool save(QDataStream& stream, const void* data)
{
Q_UNUSED(stream);
Q_UNUSED(data);
return false;
}
static inline int type()
{
return 0;
}
static inline const char* name()
{
return 0;
}
};
inline void* qxtConstructByName(const char* typeName, const void* copy = 0)
{
return QMetaType::qxtcreate(QMetaType::type(typeName), copy);
}
inline void qxtDestroyByName(const char* typeName, void* data)
{
QMetaType::destroy(QMetaType::type(typeName), data);
}
inline void* qxtConstructFromGenericArgument(QGenericArgument arg)
{
return qxtConstructByName(arg.name(), arg.data());
}
inline void qxtDestroyFromGenericArgument(QGenericArgument arg)
{
qxtDestroyByName(arg.name(), arg.data());
}
#endif

View File

@@ -0,0 +1,33 @@
#include "qxtnull.h"
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
// nothing here

View File

@@ -0,0 +1,68 @@
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#ifndef QXTNULL_H
#define QXTNULL_H
#include <qxtglobal.h>
/*!
\class QxtNull QxtNull
\inmodule QxtCore
\brief An object representing the "null" value for QxtNullable.
\sa QxtNullable
*/
struct QXT_CORE_EXPORT QxtNull
{
/*! integer cast operator
* In expressions, QxtNull behaves as an integer zero for compatibility with generic functions.
*/
operator int() const
{
return 0;
}
enum { isNull = true };
};
#ifndef QXT_NO_MACROS
/*! \relates QxtNull
* A convenience alias for QxtNull().
*/
#define QXT_NULL QxtNull()
#endif // QXT_NO_MACROS
#endif // QXTNULL_H

View File

@@ -0,0 +1,152 @@
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
/*!
\class QxtNullable QxtNullable
\inmodule QxtCore
\brief distinct null value compatible with any data type.
in general it's a templated abstraction to allow any data type to be
expressed with a null value distinct from any real value. An example
of such a use is for optional arguments.
\n
prepare a function for argument skipping:
\code
void somefunction( qxtNull(int,a) , qxtNull(int,b) )
{
if (!a.isNull())
{
int i = a.value();
//do something with i
}
if (!b.isNull())
{
int x = b.value();
//do something with x
}
}
\endcode
usage:
\code
somefunction(SKIP,1,2);
somefunction(3,4);
somefunction(3,SKIP,6);
somefunction(1);
\endcode
*/
#ifndef QXTNULLABLE_H
#define QXTNULLABLE_H
#include <qxtglobal.h>
/*! \relates QxtNullable
* defines a skipable argument with type \a t and variable name \a n
*/
#define qxtNull(t,n) QxtNullable<t> n = QxtNullable<t>()
#include <qxtnull.h>
template<typename T>
class /*QXT_CORE_EXPORT*/ QxtNullable
{
public:
QxtNullable(QxtNull);
QxtNullable(const T& p);
QxtNullable();
///determinates if the Value is set to something meaningfull
bool isNull() const;
///delete Value
void nullify();
T& value() const;
operator T() const;
void operator=(const T& p);
private:
T* val;
};
template<typename T>
QxtNullable<T>::QxtNullable(QxtNull)
{
val = 0;
}
template<typename T>
QxtNullable<T>::QxtNullable(const T& p)
{
val = const_cast<T*>(&p);
}
template<typename T>
QxtNullable<T>::QxtNullable()
{
val = 0;
}
template<typename T>
QxtNullable<T>::operator T() const
{
return *val;
}
template<typename T>
T& QxtNullable<T>::value() const
{
return *val;
}
template<typename T>
bool QxtNullable<T>::isNull() const
{
return (val == 0);
}
template<typename T>
void QxtNullable<T>::nullify()
{
val = 0;
}
template<typename T>
void QxtNullable<T>::operator=(const T & p)
{
val = const_cast<T*>(&p);
}
#endif