// Version: $Id: 5381340096e7b74d7b70354e7c06acf21f1899b5 $ // // // Commentary: // // // Change Log: // // // Code: #pragma once #include // ///////////////////////////////////////////////////////////////// // dtkMetaTypeHandler implementation // ///////////////////////////////////////////////////////////////// template inline bool dtkMetaTypeHandler::canConvert(const QList& types) { bool can_convert = true; QVariant var = QVariant(qMetaTypeId(reinterpret_cast(0)), 0); foreach (int i, types) { if (!var.canConvert(i)) { can_convert = false; break; } } return can_convert; } // ///////////////////////////////////////////////////////////////// template inline bool dtkMetaTypeHandler::canConvert(const QList& types) { return dtkMetaTypeHandlerHelper < T *, std::is_constructible::value && !std::is_abstract::value >::canConvert(types); } template inline QVariant dtkMetaTypeHandler::variantFromValue(T *t) { return QVariant::fromValue(t); } template inline T *dtkMetaTypeHandler::clone(T *t) { return dtkMetaTypeHandlerHelper < T *, std::is_copy_constructible::value && !std::is_abstract::value >::clone(t); } template inline void dtkMetaTypeHandler::copy(T *s, T *t) { dtkMetaTypeHandlerHelper::value>::copy(s, t); } // ///////////////////////////////////////////////////////////////// template inline bool dtkMetaTypeHandler::canConvert(const QList& types) { return dtkMetaTypeHandlerHelper < T *, std::is_constructible::value && !std::is_abstract::value >::canConvert(types); } template inline QVariant dtkMetaTypeHandler::variantFromValue(T *t) { QString class_name(t->metaObject()->className()); int class_type = QMetaType::type(qPrintable(class_name + "*")); if (class_type == QMetaType::UnknownType) return QVariant::fromValue(t); return QVariant(class_type, &t, 1); } template inline T *dtkMetaTypeHandler::clone(T *t) { QString class_name(t->metaObject()->className()); int class_type = QMetaType::type(qPrintable(class_name)); if (class_type == QMetaType::UnknownType) { return dtkMetaTypeHandlerHelper < T *, std::is_copy_constructible::value && !std::is_abstract::value >::clone(t); } return static_cast(QMetaType::create(class_type, t)); } template inline void dtkMetaTypeHandler::copy(T *s, T *t) { QString t_class_name(t->metaObject()->className()); int t_class_type = QMetaType::type(qPrintable(t_class_name)); QString s_class_name(s->metaObject()->className()); int s_class_type = QMetaType::type(qPrintable(s_class_name)); if (t_class_type == QMetaType::UnknownType || (t_class_type != s_class_type)) { return dtkMetaTypeHandlerHelper < T *, std::is_copy_assignable::value && !std::is_abstract::value >::copy(s, t); } QMetaType::construct(t_class_type, t, s); } // ///////////////////////////////////////////////////////////////// // dtkMetaTypeHandlerHelper implementation // ///////////////////////////////////////////////////////////////// template inline bool dtkMetaTypeHandlerHelper::canConvert(const QList& types) { int from = qMetaTypeId(); if ((types.size() == 1 && types.first() == from) || types.isEmpty()) return true; bool can_convert = true; T *ptr = new T(); QVariant var = QVariant::fromValue(ptr); foreach (int to, types) { if (!(var.canConvert(to) || QMetaType::hasRegisteredConverterFunction(from, to))) { can_convert = false; break; } } delete ptr; return can_convert; } template inline T *dtkMetaTypeHandlerHelper::clone(T *t) { return new T(*t); } template inline void dtkMetaTypeHandlerHelper::copy(T *s, T *t) { *t = *s; } // ///////////////////////////////////////////////////////////////// template inline bool dtkMetaTypeHandlerHelper::canConvert(const QList& types) { int from = qMetaTypeId(); if ((types.size() == 1 && types.first() == from) || types.isEmpty()) return true; foreach (int to, types) { if (!QMetaType::hasRegisteredConverterFunction(from, to)) return false; } return true; } template inline T *dtkMetaTypeHandlerHelper::clone(T *) { return NULL; } template inline void dtkMetaTypeHandlerHelper::copy(T *s, T *t) { Q_UNUSED(s); Q_UNUSED(t); } // ///////////////////////////////////////////////////////////////// // dtkMetaType implementation // ///////////////////////////////////////////////////////////////// template inline bool dtkMetaType::canConvert(int type) { QList list ; list.append(type); return dtkMetaType::canConvert(QList(list)); } template inline bool dtkMetaType::canConvert(const QList& types) { return dtkMetaTypeHandler::canConvert(types); } template inline QVariant dtkMetaType::variantFromValue(const T& t) { return QVariant::fromValue(t); } template inline QVariant dtkMetaType::variantFromValue(T *t) { return dtkMetaTypeHandler::variantFromValue(t); } template inline T *dtkMetaType::clone(T *t) { return dtkMetaTypeHandler::clone(t); } template inline void dtkMetaType::copy(T *s, T *t) { dtkMetaTypeHandler::copy(s, t); } // ///////////////////////////////////////////////////////////////// // Stream operators implementation // ///////////////////////////////////////////////////////////////// template inline QDataStream& operator << (QDataStream& s, T *t) { s << *t; return s; } template inline QDataStream& operator >> (QDataStream& s, T *&t) { if (!t) { t = new T(); } s >> *t; return s; } template inline QDataStream& operator << (QDataStream& s, const QList& l) { s << quint32(l.size()); for (int i = 0; i < l.size(); ++i) s << dtkMetaType::variantFromValue(l.at(i)); return s; } template inline QDataStream& operator >> (QDataStream& s, QList& l) { l.clear(); quint32 c; s >> c; for (quint32 i = 0; i < c; ++i) { QVariant var; s >> var; l << var.value(); if (s.atEnd()) break; } return s; } template inline QDataStream& operator << (QDataStream& s, const QVector& v) { s << quint32(v.size()); for (typename QVector::const_iterator it = v.begin(); it != v.end(); ++it) s << dtkMetaType::variantFromValue(*it); return s; } template inline QDataStream& operator >> (QDataStream& s, QVector& v) { v.clear(); quint32 c; s >> c; v.resize(c); for (quint32 i = 0; i < c; ++i) { QVariant var; s >> var; v[i] = var.value(); } return s; } template inline QDataStream& operator << (QDataStream& s, const std::list& l) { s << quint32(l.size()); for (typename std::list::const_iterator it = l.begin(); it != l.end(); ++it) s << dtkMetaType::variantFromValue(*it); return s; } template inline QDataStream& operator >> (QDataStream& s, std::list& l) { l.clear(); quint32 c; s >> c; for (quint32 i = 0; i < c; ++i) { QVariant var; s >> var; l.push_back(var.value()); if (s.atEnd()) break; } return s; } template inline QDataStream& operator << (QDataStream& s, const std::vector& v) { s << quint32(v.size()); for (typename std::vector::const_iterator it = v.begin(); it != v.end(); ++it) s << dtkMetaType::variantFromValue(*it); return s; } template inline QDataStream& operator >> (QDataStream& s, std::vector& v) { v.clear(); quint32 c; s >> c; v.resize(c); for (quint32 i = 0; i < c; ++i) { QVariant var; // Very important to instantiate a void QVariant at each step, otherwise, it keeps the same pointer T* to store the stream. s >> var; v[i] = var.value(); } return s; } // // dtkMeta.tpp ends here