unknown
1970-01-01 00:00:00 UTC
class QObject;
class QWidget;
-template <class T> class QSharedPointer;
-template <class T> class QWeakPointer;
-template <class T> class QPointer;
+
+#define QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER(Name) \
+ template <class T> class Name; \
+
+QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER)
namespace QtPrivate
{
@@ -509,6 +1348,116 @@ namespace QtPrivate
enum { Value = true };
};
+ template<typename T>
+ struct IsSequentialContainer
+ {
+ enum { Value = false };
+ };
+
+ template<typename T>
+ struct IsAssociativeContainer
+ {
+ enum { Value = false };
+ };
+
+ template<typename T, bool = QtPrivate::IsSequentialContainer<T>::Value>
+ struct SequentialContainerConverterHelper
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::value_type>::Defined>
+ struct ValueTypeIsMetaType
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct SequentialContainerConverterHelper<T, true> : ValueTypeIsMetaType<T>
+ {
+ };
+
+ template<typename T, bool = QtPrivate::IsAssociativeContainer<T>::Value>
+ struct AssociativeContainerConverterHelper
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::mapped_type>::Defined>
+ struct AssociativeValueTypeIsMetaType
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::key_type>::Defined>
+ struct KeyAndValueTypeIsMetaType
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct KeyAndValueTypeIsMetaType<T, true> : AssociativeValueTypeIsMetaType<T>
+ {
+ };
+
+ template<typename T>
+ struct AssociativeContainerConverterHelper<T, true> : KeyAndValueTypeIsMetaType<T>
+ {
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::first_type>::Defined
+ && QMetaTypeId2<typename T::second_type>::Defined>
+ struct IsMetaTypePair
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct IsMetaTypePair<T, true>
+ {
+ inline static bool registerConverter(int id);
+ };
+
+ template<typename T>
+ struct IsPair
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+ template<typename T, typename U>
+ struct IsPair<QPair<T, U> > : IsMetaTypePair<QPair<T, U> > {};
+ template<typename T, typename U>
+ struct IsPair<std::pair<T, U> > : IsMetaTypePair<std::pair<T, U> > {};
+
+ template<typename T>
+ struct MetaTypePairHelper : IsPair<T> {};
+
+ template<typename T, typename = void>
+ struct MetaTypeSmartPointerHelper
+ {
+ static bool registerConverter(int) { return false; }
+ };
+
Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type);
} // namespace QtPrivate
@@ -546,11 +1495,16 @@ namespace QtPrivate {
{ return -1; }
};
+#ifndef Q_COMPILER_VARIADIC_TEMPLATES
// Function pointers don't derive from QObject
template <class Result> struct IsPointerToTypeDerivedFromQObject<Result(*)()> { enum { Value = false }; };
template <class Result, class Arg0> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0)> { enum { Value = false }; };
template <class Result, class Arg0, class Arg1> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1)> { enum { Value = false }; };
template <class Result, class Arg0, class Arg1, class Arg2> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1, Arg2)> { enum { Value = false }; };
+#else
+ template <typename Result, typename... Args>
+ struct IsPointerToTypeDerivedFromQObject<Result(*)(Args...)> { enum { Value = false }; };
+#endif
template<typename T>
struct QMetaTypeTypeFlags
@@ -571,6 +1525,24 @@ namespace QtPrivate {
{
enum DefinedType { Defined = defined };
};
+
+ template<typename SmartPointer>
+ struct QSmartPointerConvertFunctor
+ {
+ QObject* operator()(const SmartPointer &p) const
+ {
+ return p.operator->();
+ }
+ };
+
+ template<typename T>
+ struct QSmartPointerConvertFunctor<QWeakPointer<T> >
+ {
+ QObject* operator()(const QWeakPointer<T> &p) const
+ {
+ return p.data();
+ }
+ };
}
template <typename T>
@@ -593,14 +1565,23 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz
if (defined)
flags |= QMetaType::WasDeclaredAsMetaType;
- return QMetaType::registerNormalizedType(normalizedTypeName,
+ const int id = QMetaType::registerNormalizedType(normalizedTypeName,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Delete,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Create,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Destruct,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Construct,
- sizeof(T),
+ int(sizeof(T)),
flags,
QtPrivate::MetaObjectForType<T>::value());
+
+ if (id > 0) {
+ QtPrivate::SequentialContainerConverterHelper<T>::registerConverter(id);
+ QtPrivate::AssociativeContainerConverterHelper<T>::registerConverter(id);
+ QtPrivate::MetaTypePairHelper<T>::registerConverter(id);
+ QtPrivate::MetaTypeSmartPointerHelper<T>::registerConverter(id);
+ }
+
+ return id;
}
template <typename T>
@@ -686,7 +1667,7 @@ struct QMetaTypeIdQObject<T*, /* isPointerToTypeDerivedFromQObject */ true>
template <typename T>
inline int qRegisterMetaTypeStreamOperators()
{
- register int id = qMetaTypeId<T>();
+ int id = qMetaTypeId<T>();
QMetaType::registerStreamOperators(id, QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Save,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Load);
return id;
@@ -746,6 +1727,7 @@ typedef QMap<QString, QVariant> QVariantMap;
typedef QHash<QString, QVariant> QVariantHash;
#define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \
+QT_BEGIN_NAMESPACE \
template <typename T> \
struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
{ \
@@ -761,8 +1743,8 @@ struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
Q_ASSERT(tName); \
const int tNameLen = qstrlen(tName); \
QByteArray typeName; \
- typeName.reserve(sizeof(#SINGLE_ARG_TEMPLATE) + 1 + tNameLen + 1 + 1); \
- typeName.append(#SINGLE_ARG_TEMPLATE, sizeof(#SINGLE_ARG_TEMPLATE) - 1) \
+ typeName.reserve(int(sizeof(#SINGLE_ARG_TEMPLATE)) + 1 + tNameLen + 1 + 1); \
+ typeName.append(#SINGLE_ARG_TEMPLATE, int(sizeof(#SINGLE_ARG_TEMPLATE)) - 1) \
.append('<').append(tName, tNameLen); \
if (typeName.endsWith('>')) \
typeName.append(' '); \
@@ -773,9 +1755,18 @@ struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
metatype_id.storeRelease(newId); \
return newId; \
} \
-};
+}; \
+namespace QtPrivate { \
+template<typename T> \
+struct IsSequentialContainer<SINGLE_ARG_TEMPLATE<T> > \
+{ \
+ enum { Value = true }; \
+}; \
+} \
+QT_END_NAMESPACE
#define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \
+QT_BEGIN_NAMESPACE \
template<typename T, typename U> \
struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
{ \
@@ -794,8 +1785,8 @@ struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
const int tNameLen = qstrlen(tName); \
const int uNameLen = qstrlen(uName); \
QByteArray typeName; \
- typeName.reserve(sizeof(#DOUBLE_ARG_TEMPLATE) + 1 + tNameLen + 1 + uNameLen + 1 + 1); \
- typeName.append(#DOUBLE_ARG_TEMPLATE, sizeof(#DOUBLE_ARG_TEMPLATE) - 1) \
+ typeName.reserve(int(sizeof(#DOUBLE_ARG_TEMPLATE)) + 1 + tNameLen + 1 + uNameLen + 1 + 1); \
+ typeName.append(#DOUBLE_ARG_TEMPLATE, int(sizeof(#DOUBLE_ARG_TEMPLATE)) - 1) \
.append('<').append(tName, tNameLen).append(',').append(uName, uNameLen); \
if (typeName.endsWith('>')) \
typeName.append(' '); \
@@ -806,19 +1797,30 @@ struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
metatype_id.storeRelease(newId); \
return newId; \
} \
+}; \
+QT_END_NAMESPACE
+
+namespace QtPrivate {
+
+template<typename T, bool /* isSharedPointerToQObjectDerived */ = false>
+struct SharedPointerMetaTypeIdHelper
+{
+ enum {
+ Defined = 0
+ };
+ static int qt_metatype_id()
+ {
+ return -1;
+ }
};
+}
+
#define Q_DECLARE_SMART_POINTER_METATYPE(SMART_POINTER) \
-template <typename T, bool = QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \
-struct QMetaTypeId_ ## SMART_POINTER ## _QObjectStar \
-{ \
- enum { \
- Defined = 0 \
- }; \
-};\
- \
+QT_BEGIN_NAMESPACE \
+namespace QtPrivate { \
template<typename T> \
-struct QMetaTypeId_ ## SMART_POINTER ## _QObjectStar<T, true> \
+struct SharedPointerMetaTypeIdHelper<SMART_POINTER<T>, true> \
{ \
enum { \
Defined = 1 \
@@ -830,8 +1832,8 @@ struct QMetaTypeId_ ## SMART_POINTER ## _QObjectStar<T, true> \
return id; \
const char * const cName = T::staticMetaObject.className(); \
QByteArray typeName; \
- typeName.reserve(sizeof(#SMART_POINTER) + 1 + strlen(cName) + 1); \
- typeName.append(#SMART_POINTER, sizeof(#SMART_POINTER) - 1) \
+ typeName.reserve(int(sizeof(#SMART_POINTER) + 1 + strlen(cName) + 1)); \
+ typeName.append(#SMART_POINTER, int(sizeof(#SMART_POINTER)) - 1) \
.append('<').append(cName).append('>'); \
const int newId = qRegisterNormalizedMetaType< SMART_POINTER<T> >( \
typeName, \
@@ -840,51 +1842,85 @@ struct QMetaTypeId_ ## SMART_POINTER ## _QObjectStar<T, true> \
return newId; \
} \
}; \
-\
template<typename T> \
-struct QMetaTypeId< SMART_POINTER<T> > : public QMetaTypeId_ ## SMART_POINTER ## _QObjectStar<T> \
+struct MetaTypeSmartPointerHelper<SMART_POINTER<T> , \
+ typename QEnableIf<IsPointerToTypeDerivedFromQObject<T*>::Value >::Type> \
{ \
-};
+ static bool registerConverter(int id) \
+ { \
+ const int toId = QMetaType::QObjectStar; \
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { \
+ QtPrivate::QSmartPointerConvertFunctor<SMART_POINTER<T> > o; \
+ static const QtPrivate::ConverterFunctor<SMART_POINTER<T>, \
+ QObject*, \
+ QSmartPointerConvertFunctor<SMART_POINTER<T> > > f(o); \
+ return QMetaType::registerConverterFunction(&f, id, toId); \
+ } \
+ return true; \
+ } \
+}; \
+} \
+template <typename T> \
+struct QMetaTypeId< SMART_POINTER<T> > \
+ : QtPrivate::SharedPointerMetaTypeIdHelper< SMART_POINTER<T>, \
+ QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \
+{ \
+};\
+QT_END_NAMESPACE
-#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F) \
- F(QList) \
- F(QVector) \
- F(QQueue) \
- F(QStack) \
- F(QSet) \
- F(QLinkedList)
+#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER(TEMPLATENAME) \
+ QT_BEGIN_NAMESPACE \
+ template <class T> class TEMPLATENAME; \
+ QT_END_NAMESPACE \
+ Q_DECLARE_METATYPE_TEMPLATE_1ARG(TEMPLATENAME)
-#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \
- F(QHash, class) \
- F(QMap, class) \
- F(QPair, struct)
+QT_END_NAMESPACE
-#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \
- F(QSharedPointer) \
- F(QWeakPointer) \
- F(QPointer)
+QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER)
-#define Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER(TEMPLATENAME) \
- template <class T> class TEMPLATENAME; \
- Q_DECLARE_METATYPE_TEMPLATE_1ARG(TEMPLATENAME)
+#undef Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER
-QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER)
+#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE Q_DECLARE_METATYPE_TEMPLATE_1ARG
-#undef Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER
+Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::vector)
+Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::list)
-#define Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER(TEMPLATENAME, CPPTYPE) \
+#define Q_FORWARD_DECLARE_METATYPE_TEMPLATE_2ARG_ITER(TEMPLATENAME, CPPTYPE) \
+ QT_BEGIN_NAMESPACE \
template <class T1, class T2> CPPTYPE TEMPLATENAME; \
- Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME)
+ QT_END_NAMESPACE \
-QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER)
+QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(Q_FORWARD_DECLARE_METATYPE_TEMPLATE_2ARG_ITER)
#undef Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER
+#define Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(TEMPLATENAME) \
+ QT_BEGIN_NAMESPACE \
+ namespace QtPrivate { \
+ template<typename T, typename U> \
+ struct IsAssociativeContainer<TEMPLATENAME<T, U> > \
+ { \
+ enum { Value = true }; \
+ }; \
+ } \
+ QT_END_NAMESPACE \
+ Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME)
+
+Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QHash)
+Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QMap)
+Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(std::map)
+
+Q_DECLARE_METATYPE_TEMPLATE_2ARG(QPair)
+Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::pair)
+
#define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \
Q_DECLARE_SMART_POINTER_METATYPE(TEMPLATENAME)
+
QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER)
+QT_BEGIN_NAMESPACE
+
#undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER
inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
@@ -987,5 +2023,62 @@ QT_END_NAMESPACE
QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE)
+Q_DECLARE_METATYPE(QtMetaTypePrivate::QSequentialIterableImpl)
+Q_DECLARE_METATYPE(QtMetaTypePrivate::QAssociativeIterableImpl)
+Q_DECLARE_METATYPE(QtMetaTypePrivate::QPairVariantInterfaceImpl)
+
+QT_BEGIN_NAMESPACE
+
+template <typename T>
+inline bool QtPrivate::IsMetaTypePair<T, true>::registerConverter(int id)
+{
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
+ QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QPairVariantInterfaceImpl,
+ QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+ }
+ return true;
+}
+
+namespace QtPrivate {
+ template<typename T>
+ struct ValueTypeIsMetaType<T, true>
+ {
+ static bool registerConverter(int id)
+ {
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>();
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
+ QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QSequentialIterableImpl,
+ QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+ }
+ return true;
+ }
+ };
+
+ template<typename T>
+ struct AssociativeValueTypeIsMetaType<T, true>
+ {
+ static bool registerConverter(int id)
+ {
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>();
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
+ QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QAssociativeIterableImpl,
+ QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+ }
+ return true;
+ }
+ };
+}
+
+QT_END_NAMESPACE
#endif // QMETATYPE_H
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index aaa09fa..e2000af 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -208,6 +208,7 @@ public:
#ifdef Q_QDOC
static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type);
static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor);
+ static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type);
#else
//Connect a signal to a pointer to qobject member function
template <typename Func1, typename Func2>
@@ -217,7 +218,9 @@ public:
{
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
- reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0));
+
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
@@ -243,9 +246,22 @@ public:
static inline typename QtPrivate::QEnableIf<int(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0, QMetaObject::Connection>::Type
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
{
+ return connect(sender, signal, sender, slot, Qt::DirectConnection);
+ }
+
+ //connect to a function pointer (not a member)
+ template <typename Func1, typename Func2>
+ static inline typename QtPrivate::QEnableIf<int(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0 &&
+ !QtPrivate::FunctionPointer<Func2>::IsPointerToMemberFunction, QMetaObject::Connection>::Type
+ connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
+ Qt::ConnectionType type = Qt::AutoConnection)
+ {
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
+
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
"The slot requires more arguments than the signal provides.");
@@ -254,11 +270,15 @@ public:
Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
"Return type of the slot is not compatible with the return type of the signal.");
- return connectImpl(sender, reinterpret_cast<void **>(&signal), sender, 0,
+ const int *types = 0;
+ if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
+ types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
+
+ return connectImpl(sender, reinterpret_cast<void **>(&signal), context, 0,
new QtPrivate::QStaticSlotObject<Func2,
typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
typename SignalType::ReturnType>(slot),
- Qt::DirectConnection, 0, &SignalType::Object::staticMetaObject);
+ type, types, &SignalType::Object::staticMetaObject);
}
//connect to a functor
@@ -266,6 +286,15 @@ public:
static inline typename QtPrivate::QEnableIf<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::Type
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
{
+ return connect(sender, signal, sender, slot, Qt::DirectConnection);
+ }
+
+ //connect to a functor, with a "context" object defining in which event loop is going to be executed
+ template <typename Func1, typename Func2>
+ static inline typename QtPrivate::QEnableIf<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::Type
+ connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
+ Qt::ConnectionType type = Qt::AutoConnection)
+ {
#if defined (Q_COMPILER_DECLTYPE) && defined (Q_COMPILER_VARIADIC_TEMPLATES)
typedef QtPrivate::FunctionPointer<Func1> SignalType;
const int FunctorArgumentCount = QtPrivate::ComputeFunctorArgumentCount<Func2 , typename SignalType::Arguments>::Value;
@@ -287,9 +316,10 @@ public:
C++11 variadic templates
*/
#ifndef Q_COMPILER_DECLTYPE //Workaround the lack of decltype using another function as indirection
- return connect_functor(sender, signal, slot, &Func2::operator()); }
+ return connect_functor(sender, signal, context, slot, &Func2::operator(), type); }
template <typename Func1, typename Func2, typename Func2Operator>
- static inline QMetaObject::Connection connect_functor(const QObject *sender, Func1 signal, Func2 slot, Func2Operator) {
+ static inline QMetaObject::Connection connect_functor(const QObject *sender, Func1 signal, const QObject *context,
+ Func2 slot, Func2Operator, Qt::ConnectionType type) {
typedef QtPrivate::FunctionPointer<Func2Operator> SlotType ;
#else
typedef QtPrivate::FunctionPointer<decltype(&Func2::operator())> SlotType ;
@@ -307,11 +337,18 @@ public:
Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<SlotReturnType, typename SignalType::ReturnType>::value),
"Return type of the slot is not compatible with the return type of the signal.");
- return connectImpl(sender, reinterpret_cast<void **>(&signal), sender, 0,
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
+
+ const int *types = 0;
+ if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
+ types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
+
+ return connectImpl(sender, reinterpret_cast<void **>(&signal), context, 0,
new QtPrivate::QFunctorSlotObject<Func2, SlotArgumentCount,
typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value,
typename SignalType::ReturnType>(slot),
- Qt::DirectConnection, 0, &SignalType::Object::staticMetaObject);
+ type, types, &SignalType::Object::staticMetaObject);
}
#endif //Q_QDOC
@@ -335,7 +372,9 @@ public:
{
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
- reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0));
+
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
@@ -477,18 +516,18 @@ inline QT_DEPRECATED QList<T> qFindChildren(const QObject *o, const QRegExp &re)
template <class T>
inline T qobject_cast(QObject *object)
{
-#if !defined(QT_NO_QOBJECT_CHECK)
- reinterpret_cast<T>(object)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(object));
-#endif
+ typedef typename QtPrivate::remove_cv<typename QtPrivate::remove_pointer<T>::type>::type ObjType;
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
+ "qobject_cast requires the type to have a Q_OBJECT macro");
return static_cast<T>(reinterpret_cast<T>(object)->staticMetaObject.cast(object));
}
template <class T>
inline T qobject_cast(const QObject *object)
{
-#if !defined(QT_NO_QOBJECT_CHECK)
- reinterpret_cast<T>(object)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(const_cast<QObject *>(object)));
-#endif
+ typedef typename QtPrivate::remove_cv<typename QtPrivate::remove_pointer<T>::type>::type ObjType;
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
+ "qobject_cast requires the type to have a Q_OBJECT macro");
return static_cast<T>(reinterpret_cast<T>(object)->staticMetaObject.cast(object));
}
diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h
index 0b5631f..1bbd548 100644
--- a/src/corelib/kernel/qobject_impl.h
+++ b/src/corelib/kernel/qobject_impl.h
@@ -204,7 +204,6 @@ namespace QtPrivate {
public:
explicit QFunctorSlotObject(const Func &f) : QSlotObjectBase(&impl), function(f) {}
};
-
}
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index afbe1a5..7354c3f 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -125,7 +125,7 @@ class QString;
/* qmake ignore Q_OBJECT */
#define Q_OBJECT_CHECK \
- template <typename T> inline void qt_check_for_QOBJECT_macro(const T &_q_argument) const \
+ template <typename ThisObject> inline void qt_check_for_QOBJECT_macro(const ThisObject &_q_argument) const \
{ int i = qYouForgotTheQ_OBJECT_Macro(this, &_q_argument); i = i + 1; }
template <typename T>
@@ -456,6 +456,7 @@ class Q_CORE_EXPORT QMetaObject::Connection {
void *d_ptr; //QObjectPrivate::Connection*
explicit Connection(void *data) : d_ptr(data) { }
friend class QObject;
+ friend class QObjectPrivate;
friend struct QMetaObject;
public:
~Connection();
@@ -479,6 +480,16 @@ public:
inline const QMetaObject *QMetaObject::superClass() const
{ return d.superdata; }
+namespace QtPrivate {
+ /* Trait that tells is a the Object has a Q_OBJECT macro */
+ template <typename Object> struct HasQ_OBJECT_Macro {
+ template <typename T>
+ static char test(int (T::*)(QMetaObject::Call, int, void **));
+ static int test(int (Object::*)(QMetaObject::Call, int, void **));
+ enum { Value = sizeof(test(&Object::qt_metacall)) == sizeof(int) };
+ };
+}
+
QT_END_NAMESPACE
#endif // QOBJECTDEFS_H
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index 4f44d92..fb6601f 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -129,7 +129,7 @@ namespace QtPrivate {
its call function is the same as the FunctionPointer::call function.
*/
#ifndef Q_COMPILER_VARIADIC_TEMPLATES
- template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1}; };
+ template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1, IsPointerToMemberFunction = false}; };
//Pointers to member functions
template<class Obj, typename Ret> struct FunctionPointer<Ret (Obj::*) ()>
{
@@ -137,7 +137,7 @@ namespace QtPrivate {
typedef void Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) ();
- enum {ArgumentCount = 0};
+ enum {ArgumentCount = 0, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) { (o->*f)(), ApplyReturnValue<R>(arg[0]); }
};
@@ -147,7 +147,7 @@ namespace QtPrivate {
typedef List<Arg1, void> Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1);
- enum {ArgumentCount = 1};
+ enum {ArgumentCount = 1, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)((*reinterpret_cast<typename RemoveRef<typename Args::Car>::Type *>(arg[1]))), ApplyReturnValue<R>(arg[0]);
@@ -159,7 +159,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, void> > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2);
- enum {ArgumentCount = 2};
+ enum {ArgumentCount = 2, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -172,7 +172,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, void> > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3);
- enum {ArgumentCount = 3};
+ enum {ArgumentCount = 3, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -186,7 +186,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4);
- enum {ArgumentCount = 4};
+ enum {ArgumentCount = 4, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -201,7 +201,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, void> > > > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5);
- enum {ArgumentCount = 5};
+ enum {ArgumentCount = 5, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -218,7 +218,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
- enum {ArgumentCount = 6};
+ enum {ArgumentCount = 6, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -237,7 +237,7 @@ namespace QtPrivate {
typedef void Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) () const;
- enum {ArgumentCount = 0};
+ enum {ArgumentCount = 0, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) { (o->*f)(), ApplyReturnValue<R>(arg[0]); }
};
@@ -247,7 +247,7 @@ namespace QtPrivate {
typedef List<Arg1, void> Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1) const;
- enum {ArgumentCount = 1};
+ enum {ArgumentCount = 1, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)((*reinterpret_cast<typename RemoveRef<typename Args::Car>::Type *>(arg[1]))), ApplyReturnValue<R>(arg[0]);
@@ -259,7 +259,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, void> > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2) const;
- enum {ArgumentCount = 2};
+ enum {ArgumentCount = 2, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -272,7 +272,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, void> > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3) const;
- enum {ArgumentCount = 3};
+ enum {ArgumentCount = 3, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -286,7 +286,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4) const;
- enum {ArgumentCount = 4};
+ enum {ArgumentCount = 4, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -301,7 +301,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, void> > > > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5) const;
- enum {ArgumentCount = 5};
+ enum {ArgumentCount = 5, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -318,7 +318,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const;
- enum {ArgumentCount = 6};
+ enum {ArgumentCount = 6, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -336,7 +336,7 @@ namespace QtPrivate {
typedef void Arguments;
typedef Ret (*Function) ();
typedef Ret ReturnType;
- enum {ArgumentCount = 0};
+ enum {ArgumentCount = 0, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg) { f(), ApplyReturnValue<R>(arg[0]); }
};
@@ -345,7 +345,7 @@ namespace QtPrivate {
typedef List<Arg1, void> Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Arg1);
- enum {ArgumentCount = 1};
+ enum {ArgumentCount = 1, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg)
{ f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1])), ApplyReturnValue<R>(arg[0]); }
@@ -355,7 +355,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, void> > Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Arg1, Arg2);
- enum {ArgumentCount = 2};
+ enum {ArgumentCount = 2, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg) {
f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -366,7 +366,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, void> > > Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Arg1, Arg2, Arg3);
- enum {ArgumentCount = 3};
+ enum {ArgumentCount = 3, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg) {
f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -379,7 +379,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > > Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4);
- enum {ArgumentCount = 4};
+ enum {ArgumentCount = 4, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg) {
f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -394,7 +394,7 @@ namespace QtPrivate {
List<Arg4, List<Arg5, void > > > > > Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5);
- enum {ArgumentCount = 5};
+ enum {ArgumentCount = 5, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg) {
f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -409,7 +409,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > > Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
- enum {ArgumentCount = 6};
+ enum {ArgumentCount = 6, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg) {
f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -493,25 +493,25 @@ namespace QtPrivate {
template <int N> struct Indexes
{ typedef typename IndexesAppend<typename Indexes<N - 1>::Value, N - 1>::Value Value; };
template <> struct Indexes<0> { typedef IndexesList<> Value; };
- template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1}; };
+ template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1, IsPointerToMemberFunction = false}; };
template <typename, typename, typename, typename> struct FunctorCall;
- template <int... I, typename... SignalArgs, typename R, typename Function>
- struct FunctorCall<IndexesList<I...>, List<SignalArgs...>, R, Function> {
+ template <int... II, typename... SignalArgs, typename R, typename Function>
+ struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, Function> {
static void call(Function f, void **arg) {
- f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[I+1]))...), ApplyReturnValue<R>(arg[0]);
+ f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
}
};
- template <int... I, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
- struct FunctorCall<IndexesList<I...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...)> {
+ template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
+ struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...)> {
static void call(SlotRet (Obj::*f)(SlotArgs...), Obj *o, void **arg) {
- (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[I+1]))...), ApplyReturnValue<R>(arg[0]);
+ (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
}
};
- template <int... I, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
- struct FunctorCall<IndexesList<I...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...) const> {
+ template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
+ struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...) const> {
static void call(SlotRet (Obj::*f)(SlotArgs...) const, Obj *o, void **arg) {
- (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[I+1]))...), ApplyReturnValue<R>(arg[0]);
+ (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
}
};
@@ -521,7 +521,7 @@ namespace QtPrivate {
typedef List<Args...> Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Args...);
- enum {ArgumentCount = sizeof...(Args)};
+ enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true};
template <typename SignalArgs, typename R>
static void call(Function f, Obj *o, void **arg) {
FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, o, arg);
@@ -533,7 +533,7 @@ namespace QtPrivate {
typedef List<Args...> Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Args...) const;
- enum {ArgumentCount = sizeof...(Args)};
+ enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true};
template <typename SignalArgs, typename R>
static void call(Function f, Obj *o, void **arg) {
FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, o, arg);
@@ -545,7 +545,7 @@ namespace QtPrivate {
typedef List<Args...> Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Args...);
- enum {ArgumentCount = sizeof...(Args)};
+ enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = false};
template <typename SignalArgs, typename R>
static void call(Function f, void *, void **arg) {
FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, arg);
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 6f212f5..5ff33cc 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -49,6 +49,7 @@
#include <QtCore/qmap.h>
#include <QtCore/qhash.h>
#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
#include <QtCore/qobject.h>
QT_BEGIN_NAMESPACE
@@ -432,6 +433,14 @@ class Q_CORE_EXPORT QVariant
{ return cmp(v); }
inline bool operator!=(const QVariant &v) const
{ return !cmp(v); }
+ inline bool operator<(const QVariant &v) const
+ { return compare(v) < 0; }
+ inline bool operator<=(const QVariant &v) const
+ { return compare(v) <= 0; }
+ inline bool operator>(const QVariant &v) const
+ { return compare(v) > 0; }
+ inline bool operator>=(const QVariant &v) const
+ { return compare(v) >= 0; }
protected:
friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
@@ -449,6 +458,7 @@ public:
Private d;
void create(int type, const void *copy);
bool cmp(const QVariant &other) const;
+ int compare(const QVariant &other) const;
bool convert(const int t, void *ptr) const;
private:
@@ -562,6 +572,107 @@ inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
}
#endif
+class Q_CORE_EXPORT QSequentialIterable
+{
+ QtMetaTypePrivate::QSequentialIterableImpl m_impl;
+public:
+ struct Q_CORE_EXPORT const_iterator
+ {
+ private:
+ QtMetaTypePrivate::QSequentialIterableImpl m_impl;
+ QAtomicInt *ref;
+ friend class QSequentialIterable;
+ explicit const_iterator(const QSequentialIterable &iter, QAtomicInt *ref_);
+
+ explicit const_iterator(const QtMetaTypePrivate::QSequentialIterableImpl &impl, QAtomicInt *ref_);
+
+ void begin();
+ void end();
+ public:
+ ~const_iterator();
+
+ const_iterator(const const_iterator &other);
+
+ const_iterator& operator=(const const_iterator &other);
+
+ const QVariant operator*() const;
+ bool operator==(const const_iterator &o) const;
+ bool operator!=(const const_iterator &o) const;
+ const_iterator &operator++();
+ const_iterator operator++(int);
+ const_iterator &operator--();
+ const_iterator operator--(int);
+ const_iterator &operator+=(int j);
+ const_iterator &operator-=(int j);
+ const_iterator operator+(int j) const;
+ const_iterator operator-(int j) const;
+ };
+
+ friend struct const_iterator;
+
+ explicit QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl impl);
+
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ QVariant at(int idx) const;
+ int size() const;
+
+ bool canReverseIterate() const;
+};
+
+class Q_CORE_EXPORT QAssociativeIterable
+{
+ QtMetaTypePrivate::QAssociativeIterableImpl m_impl;
+public:
+ struct Q_CORE_EXPORT const_iterator
+ {
+ private:
+ QtMetaTypePrivate::QAssociativeIterableImpl m_impl;
+ QAtomicInt *ref;
+ friend class QAssociativeIterable;
+ explicit const_iterator(const QAssociativeIterable &iter, QAtomicInt *ref_);
+
+ explicit const_iterator(const QtMetaTypePrivate::QAssociativeIterableImpl &impl, QAtomicInt *ref_);
+
+ void begin();
+ void end();
+ public:
+ ~const_iterator();
+ const_iterator(const const_iterator &other);
+
+ const_iterator& operator=(const const_iterator &other);
+
+ const QVariant key() const;
+
+ const QVariant value() const;
+
+ const QVariant operator*() const;
+ bool operator==(const const_iterator &o) const;
+ bool operator!=(const const_iterator &o) const;
+ const_iterator &operator++();
+ const_iterator operator++(int);
+ const_iterator &operator--();
+ const_iterator operator--(int);
+ const_iterator &operator+=(int j);
+ const_iterator &operator-=(int j);
+ const_iterator operator+(int j) const;
+ const_iterator operator-(int j) const;
+ };
+
+ friend struct const_iterator;
+
+ explicit QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl impl);
+
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ QVariant value(const QVariant &key) const;
+
+ int size() const;
+};
+
+#ifndef QT_MOC
namespace QtPrivate {
template<typename T>
struct QVariantValueHelper : TreatAsQObjectBeforeMetaType<QVariantValueHelper<T>, T, const QVariant &, T>
@@ -571,26 +682,132 @@ namespace QtPrivate {
const int vid = qMetaTypeId<T>();
if (vid == v.userType())
return *reinterpret_cast<const T *>(v.constData());
- if (vid < int(QMetaType::User)) {
T t;
if (v.convert(vid, &t))
return t;
- }
return T();
}
#ifndef QT_NO_QOBJECT
static T object(const QVariant &v)
{
- return qobject_cast<T>(QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject ? v.d.data.o : 0);
+ return qobject_cast<T>(QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject
+ ? v.d.data.o
+ : QVariantValueHelper::metaType(v));
}
#endif
};
+
+ template<typename T>
+ struct QVariantValueHelperInterface : QVariantValueHelper<T>
+ {
+ };
+
+ template<>
+ struct QVariantValueHelperInterface<QSequentialIterable>
+ {
+ static QSequentialIterable invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QVariantList>()) {
+ return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QVariantList*>(v.constData())));
+ }
+ if (v.userType() == qMetaTypeId<QStringList>()) {
+ return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QStringList*>(v.constData())));
+ }
+ return QSequentialIterable(v.value<QtMetaTypePrivate::QSequentialIterableImpl>());
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QAssociativeIterable>
+ {
+ static QAssociativeIterable invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QVariantMap>()) {
+ return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantMap*>(v.constData())));
+ }
+ if (v.userType() == qMetaTypeId<QVariantHash>()) {
+ return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantHash*>(v.constData())));
+ }
+ return QAssociativeIterable(v.value<QtMetaTypePrivate::QAssociativeIterableImpl>());
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QVariantList>
+ {
+ static QVariantList invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QStringList>() || QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) {
+ QSequentialIterable iter = QVariantValueHelperInterface<QSequentialIterable>::invoke(v);
+ QVariantList l;
+ l.reserve(iter.size());
+ for (QSequentialIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
+ l << *it;
+ return l;
+ }
+ return QVariantValueHelper<QVariantList>::invoke(v);
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QVariantHash>
+ {
+ static QVariantHash invoke(const QVariant &v)
+ {
+ if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
+ QVariantHash l;
+ l.reserve(iter.size());
+ for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
+ l.insert(it.key().toString(), it.value());
+ return l;
+ }
+ return QVariantValueHelper<QVariantHash>::invoke(v);
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QVariantMap>
+ {
+ static QVariantMap invoke(const QVariant &v)
+ {
+ if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
+ QVariantMap l;
+ for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
+ l.insert(it.key().toString(), it.value());
+ return l;
+ }
+ return QVariantValueHelper<QVariantMap>::invoke(v);
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QPair<QVariant, QVariant> >
+ {
+ static QPair<QVariant, QVariant> invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QPair<QVariant, QVariant> >())
+ return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
+
+ if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
+ QtMetaTypePrivate::QPairVariantInterfaceImpl pi = v.value<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
+
+ const QtMetaTypePrivate::VariantData d1 = pi.first();
+ QVariant v1(d1.metaTypeId, d1.data, d1.flags);
+ if (d1.metaTypeId == qMetaTypeId<QVariant>())
+ v1 = *reinterpret_cast<const QVariant*>(d1.data);
+
+ const QtMetaTypePrivate::VariantData d2 = pi.second();
+ QVariant v2(d2.metaTypeId, d2.data, d2.flags);
+ if (d2.metaTypeId == qMetaTypeId<QVariant>())
+ v2 = *reinterpret_cast<const QVariant*>(d2.data);
+
+ return QPair<QVariant, QVariant>(v1, v2);
+ }
+ return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
+ }
+ };
}
-#ifndef QT_MOC
template<typename T> inline T qvariant_cast(const QVariant &v)
{
- return QtPrivate::QVariantValueHelper<T>::invoke(v);
+ return QtPrivate::QVariantValueHelperInterface<T>::invoke(v);
}
template<> inline QVariant qvariant_cast<QVariant>(const QVariant &v)
diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h
index b91a0e9..1ec9325 100644
--- a/src/corelib/plugin/qplugin.h
+++ b/src/corelib/plugin/qplugin.h
@@ -44,6 +44,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qpointer.h>
+#include <QtCore/qjsonobject.h>
QT_BEGIN_NAMESPACE
@@ -59,11 +60,22 @@ QT_BEGIN_NAMESPACE
typedef QObject *(*QtPluginInstanceFunction)();
typedef const char *(*QtPluginMetaDataFunction)();
-struct QStaticPlugin
+struct Q_CORE_EXPORT QStaticPlugin
{
+ // Note: This struct is initialized using an initializer list.
+ // As such, it cannot have any new constructors or variables.
+#ifndef Q_QDOC
QtPluginInstanceFunction instance;
- QtPluginMetaDataFunction metaData;
+ QtPluginMetaDataFunction rawMetaData;
+#else
+ // Since qdoc gets confused by the use of function
+ // pointers, we add these dummes for it to parse instead:
+ QObject *instance();
+ const char *rawMetaData();
+#endif
+ QJsonObject metaData() const;
};
+Q_DECLARE_TYPEINFO(QStaticPlugin, Q_PRIMITIVE_TYPE);
void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
diff --git a/src/corelib/plugin/qpluginloader.h b/src/corelib/plugin/qpluginloader.h
index 8f8833e..88c8ba4 100644
--- a/src/corelib/plugin/qpluginloader.h
+++ b/src/corelib/plugin/qpluginloader.h
@@ -43,6 +43,7 @@
#define QPLUGINLOADER_H
#include <QtCore/qlibrary.h>
+#include <QtCore/qplugin.h>
#ifndef QT_NO_LIBRARY
@@ -65,6 +66,7 @@ public:
QJsonObject metaData() const;
static QObjectList staticInstances();
+ static QVector<QStaticPlugin> staticPlugins();
bool load();
bool unload();
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index cf0a6a5..ddcc25f 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -60,11 +60,11 @@
// Processor dependent implementation
#elif defined(Q_PROCESSOR_ALPHA)
# include "QtCore/qatomic_alpha.h"
-#elif defined(Q_PROCESSOR_ARM_V7)
+#elif defined(Q_PROCESSOR_ARM_V7) && defined(Q_PROCESSOR_ARM_32)
# include "QtCore/qatomic_armv7.h"
-#elif defined(Q_PROCESSOR_ARM_V6)
+#elif defined(Q_PROCESSOR_ARM_V6) && defined(Q_PROCESSOR_ARM_32)
# include "QtCore/qatomic_armv6.h"
-#elif defined(Q_PROCESSOR_ARM_V5)
+#elif defined(Q_PROCESSOR_ARM_V5) && defined(Q_PROCESSOR_ARM_32)
# include "QtCore/qatomic_armv5.h"
#elif defined(Q_PROCESSOR_BFIN)
# include "QtCore/qatomic_bfin.h"
diff --git a/src/corelib/thread/qgenericatomic.h b/src/corelib/thread/qgenericatomic.h
index a0a851e..3a213f6 100644
--- a/src/corelib/thread/qgenericatomic.h
+++ b/src/corelib/thread/qgenericatomic.h
@@ -172,7 +172,7 @@ template <typename BaseClass> struct QGenericAtomicOps
{
// implement fetchAndStore on top of testAndSet
Q_FOREVER {
- register T tmp = load(_q_value);
+ T tmp = load(_q_value);
if (BaseClass::testAndSetRelaxed(_q_value, tmp, newValue))
return tmp;
}
@@ -207,7 +207,7 @@ template <typename BaseClass> struct QGenericAtomicOps
{
// implement fetchAndAdd on top of testAndSet
Q_FOREVER {
- register T tmp = BaseClass::load(_q_value);
+ T tmp = BaseClass::load(_q_value);
if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp + valueToAdd)))
return tmp;
}
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index 19c0f82..f06981c 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -86,6 +86,9 @@ public:
bool isFinished() const;
bool isRunning() const;
+ void requestInterruption();
+ bool isInterruptionRequested() const;
+
void setStackSize(uint stackSize);
uint stackSize() const;
diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h
index ffc16de..22a42c2 100644
--- a/src/corelib/thread/qthreadpool.h
+++ b/src/corelib/thread/qthreadpool.h
@@ -83,6 +83,8 @@ public:
void releaseThread();
bool waitForDone(int msecs = -1);
+
+ void clear();
};
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h
index e3b7688..c6eede0 100644
--- a/src/corelib/tools/qalgorithms.h
+++ b/src/corelib/tools/qalgorithms.h
@@ -53,27 +53,30 @@ QT_BEGIN_NAMESPACE
*/
namespace QAlgorithmsPrivate {
+#if QT_DEPRECATED_SINCE(5, 2)
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
template <typename RandomAccessIterator, typename T>
-inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy);
+QT_DEPRECATED inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy);
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
template <typename RandomAccessIterator, typename T>
-inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &);
+QT_DEPRECATED inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &);
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+#endif // QT_DEPRECATED_SINCE(5, 2)
}
+#if QT_DEPRECATED_SINCE(5, 2)
template <typename InputIterator, typename OutputIterator>
-inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest)
+QT_DEPRECATED inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest)
{
while (begin != end)
*dest++ = *begin++;
@@ -81,7 +84,7 @@ inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterat
}
template <typename BiIterator1, typename BiIterator2>
-inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest)
+QT_DEPRECATED inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest)
{
while (begin != end)
*--dest = *--end;
@@ -89,7 +92,7 @@ inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2
}
template <typename InputIterator1, typename InputIterator2>
-inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
+QT_DEPRECATED inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
{
for (; first1 != last1; ++first1, ++first2)
if (!(*first1 == *first2))
@@ -98,20 +101,20 @@ inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 f
}
template <typename ForwardIterator, typename T>
-inline void qFill(ForwardIterator first, ForwardIterator last, const T &val)
+QT_DEPRECATED inline void qFill(ForwardIterator first, ForwardIterator last, const T &val)
{
for (; first != last; ++first)
*first = val;
}
template <typename Container, typename T>
-inline void qFill(Container &container, const T &val)
+QT_DEPRECATED inline void qFill(Container &container, const T &val)
{
qFill(container.begin(), container.end(), val);
}
template <typename InputIterator, typename T>
-inline InputIterator qFind(InputIterator first, InputIterator last, const T &val)
+QT_DEPRECATED inline InputIterator qFind(InputIterator first, InputIterator last, const T &val)
{
while (first != last && !(*first == val))
++first;
@@ -119,13 +122,13 @@ inline InputIterator qFind(InputIterator first, InputIterator last, const T &val
}
template <typename Container, typename T>
-inline typename Container::const_iterator qFind(const Container &container, const T &val)
+QT_DEPRECATED inline typename Container::const_iterator qFind(const Container &container, const T &val)
{
return qFind(container.constBegin(), container.constEnd(), val);
}
template <typename InputIterator, typename T, typename Size>
-inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n)
+QT_DEPRECATED inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n)
{
for (; first != last; ++first)
if (*first == value)
@@ -133,7 +136,7 @@ inline void qCount(InputIterator first, InputIterator last, const T &value, Size
}
template <typename Container, typename T, typename Size>
-inline void qCount(const Container &container, const T &value, Size &n)
+QT_DEPRECATED inline void qCount(const Container &container, const T &value, Size &n)
{
qCount(container.constBegin(), container.constEnd(), value, n);
}
@@ -150,7 +153,7 @@ LessThan qGreater()
}
#else
template <typename T>
-class qLess
+class QT_DEPRECATED qLess
{
public:
inline bool operator()(const T &t1, const T &t2) const
@@ -160,7 +163,7 @@ public:
};
template <typename T>
-class qGreater
+class QT_DEPRECATED qGreater
{
public:
inline bool operator()(const T &t1, const T &t2) const
@@ -171,21 +174,21 @@ public:
#endif
template <typename RandomAccessIterator>
-inline void qSort(RandomAccessIterator start, RandomAccessIterator end)
+QT_DEPRECATED inline void qSort(RandomAccessIterator start, RandomAccessIterator end)
{
if (start != end)
QAlgorithmsPrivate::qSortHelper(start, end, *start);
}
template <typename RandomAccessIterator, typename LessThan>
-inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
+QT_DEPRECATED inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
{
if (start != end)
QAlgorithmsPrivate::qSortHelper(start, end, *start, lessThan);
}
template<typename Container>
-inline void qSort(Container &c)
+QT_DEPRECATED inline void qSort(Container &c)
{
#ifdef Q_CC_BOR
// Work around Borland 5.5 optimizer bug
@@ -196,21 +199,21 @@ inline void qSort(Container &c)
}
template <typename RandomAccessIterator>
-inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end)
+QT_DEPRECATED inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end)
{
if (start != end)
QAlgorithmsPrivate::qStableSortHelper(start, end, *start);
}
template <typename RandomAccessIterator, typename LessThan>
-inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
+QT_DEPRECATED inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
{
if (start != end)
QAlgorithmsPrivate::qStableSortHelper(start, end, *start, lessThan);
}
template<typename Container>
-inline void qStableSort(Container &c)
+QT_DEPRECATED inline void qStableSort(Container &c)
{
#ifdef Q_CC_BOR
// Work around Borland 5.5 optimizer bug
@@ -221,7 +224,7 @@ inline void qStableSort(Container &c)
}
template <typename RandomAccessIterator, typename T>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
{
// Implementation is duplicated from QAlgorithmsPrivate to keep existing code
// compiling. We have to allow using *begin and value with different types,
@@ -244,19 +247,19 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
return QAlgorithmsPrivate::qLowerBoundHelper(begin, end, value, lessThan);
}
template <typename Container, typename T>
-Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value)
{
return QAlgorithmsPrivate::qLowerBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
}
template <typename RandomAccessIterator, typename T>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
{
// Implementation is duplicated from QAlgorithmsPrivate.
RandomAccessIterator middle;
@@ -277,19 +280,19 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
return QAlgorithmsPrivate::qUpperBoundHelper(begin, end, value, lessThan);
}
template <typename Container, typename T>
-Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value)
{
return QAlgorithmsPrivate::qUpperBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
}
template <typename RandomAccessIterator, typename T>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
{
// Implementation is duplicated from QAlgorithmsPrivate.
RandomAccessIterator it = qLowerBound(begin, end, value);
@@ -301,16 +304,17 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
return QAlgorithmsPrivate::qBinaryFindHelper(begin, end, value, lessThan);
}
template <typename Container, typename T>
-Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value)
{
return QAlgorithmsPrivate::qBinaryFindHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
}
+#endif // QT_DEPRECATED_SINCE(5, 2)
template <typename ForwardIterator>
Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
@@ -333,8 +337,10 @@ inline void qDeleteAll(const Container &c)
*/
namespace QAlgorithmsPrivate {
+#if QT_DEPRECATED_SINCE(5, 2)
+
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan)
{
top:
int span = int(end - start);
@@ -387,13 +393,13 @@ top:
}
template <typename RandomAccessIterator, typename T>
-inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
+QT_DEPRECATED inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
{
qSortHelper(begin, end, dummy, qLess<T>());
}
template <typename RandomAccessIterator>
-Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end)
{
--end;
while (begin < end)
@@ -401,7 +407,7 @@ Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessItera
}
template <typename RandomAccessIterator>
-Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end)
{
qReverse(begin, middle);
qReverse(middle, end);
@@ -409,7 +415,7 @@ Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterat
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan)
{
const int len1 = pivot - begin;
const int len2 = end - pivot;
@@ -444,7 +450,7 @@ Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterato
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan)
{
const int span = end - begin;
if (span < 2)
@@ -457,13 +463,13 @@ Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAc
}
template <typename RandomAccessIterator, typename T>
-inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
+QT_DEPRECATED inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
{
qStableSortHelper(begin, end, dummy, qLess<T>());
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
RandomAccessIterator middle;
int n = int(end - begin);
@@ -484,7 +490,7 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
RandomAccessIterator middle;
int n = end - begin;
@@ -504,7 +510,7 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
RandomAccessIterator it = qLowerBoundHelper(begin, end, value, lessThan);
@@ -514,8 +520,77 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator
return it;
}
+#endif // QT_DEPRECATED_SINCE(5, 2)
+
} //namespace QAlgorithmsPrivate
+
+// Use __builtin_popcount on gcc. Clang claims to be gcc
+// but has a bug where __builtin_popcount is not marked as
+// constexpr.
+#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
+#define QALGORITHMS_USE_BUILTIN_POPCOUNT
+#endif
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint32 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcount(v);
+#else
+ // See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 24) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint8 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcount(v);
+#else
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint16 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcount(v);
+#else
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint64 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcountll(v);
+#else
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 24) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 36) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 48) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 60) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(long unsigned int v)
+{
+ return qPopulationCount(static_cast<quint64>(v));
+}
+
+#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
+#undef QALGORITHMS_USE_BUILTIN_POPCOUNT
+#endif
+
+
QT_END_NAMESPACE
#endif // QALGORITHMS_H
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
index 3cd8c51..c8a0825 100644
--- a/src/corelib/tools/qarraydataops.h
+++ b/src/corelib/tools/qarraydataops.h
@@ -62,7 +62,7 @@ struct QPodArrayOps
Q_ASSERT(newSize <= this->alloc);
::memset(this->end(), 0, (newSize - this->size) * sizeof(T));
- this->size = newSize;
+ this->size = int(newSize);
}
void copyAppend(const T *b, const T *e)
@@ -84,7 +84,7 @@ struct QPodArrayOps
const T *const end = iter + n;
for (; iter != end; ++iter)
::memcpy(iter, &t, sizeof(T));
- this->size += n;
+ this->size += int(n);
}
void truncate(size_t newSize)
@@ -92,7 +92,7 @@ struct QPodArrayOps
Q_ASSERT(!this->ref.isShared());
Q_ASSERT(newSize < size_t(this->size));
- this->size = newSize;
+ this->size = int(newSize);
}
void destroyAll() // Call from destructors, ONLY!
diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h
index 1103712..eaf9b2f 100644
--- a/src/corelib/tools/qbitarray.h
+++ b/src/corelib/tools/qbitarray.h
@@ -61,6 +61,7 @@ public:
QBitArray(const QBitArray &other) : d(other.d) {}
inline QBitArray &operator=(const QBitArray &other) { d = other.d; return *this; }
#ifdef Q_COMPILER_RVALUE_REFS
+ inline QBitArray(QBitArray &&other) : d(std::move(other.d)) {}
inline QBitArray &operator=(QBitArray &&other)
{ qSwap(d, other.d); return *this; }
#endif
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index f3cc301..ae8166d 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -173,6 +173,15 @@ private:
typedef QTypedArrayData<char> Data;
public:
+ enum Base64Option {
+ Base64Encoding = 0,
+ Base64UrlEncoding = 1,
+
+ KeepTrailingEquals = 0,
+ OmitTrailingEquals = 2
+ };
+ Q_DECLARE_FLAGS(Base64Options, Base64Option)
+
inline QByteArray();
QByteArray(const char *, int size = -1);
QByteArray(int size, char c);
@@ -317,7 +326,8 @@ public:
qulonglong toULongLong(bool *ok = 0, int base = 10) const;
float toFloat(bool *ok = 0) const;
double toDouble(bool *ok = 0) const;
- QByteArray toBase64() const;
+ QByteArray toBase64(Base64Options options) const;
+ QByteArray toBase64() const; // ### Qt6 merge with previous
QByteArray toHex() const;
QByteArray toPercentEncoding(const QByteArray &exclude = QByteArray(),
const QByteArray &include = QByteArray(),
@@ -339,7 +349,8 @@ public:
static QByteArray number(qulonglong, int base = 10);
static QByteArray number(double, char f = 'g', int prec = 6);
static QByteArray fromRawData(const char *, int size);
- static QByteArray fromBase64(const QByteArray &base64);
+ static QByteArray fromBase64(const QByteArray &base64, Base64Options options);
+ static QByteArray fromBase64(const QByteArray &base64); // ### Qt6 merge with previous
static QByteArray fromHex(const QByteArray &hexEncoded);
static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%');
@@ -373,7 +384,7 @@ public:
bool isNull() const;
inline QByteArray(QByteArrayDataPtr dd)
- : d(reinterpret_cast<Data *>(dd.ptr))
+ : d(static_cast<Data *>(dd.ptr))
{
}
@@ -392,6 +403,8 @@ public:
inline DataPtr &data_ptr() { return d; }
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QByteArray::Base64Options)
+
inline QByteArray::QByteArray(): d(Data::sharedNull()) { }
inline QByteArray::~QByteArray() { if (!d->ref.deref()) Data::deallocate(d); }
inline int QByteArray::size() const
diff --git a/src/corelib/tools/qcryptographichash.h b/src/corelib/tools/qcryptographichash.h
index d4e75c4..c4f7c3a 100644
--- a/src/corelib/tools/qcryptographichash.h
+++ b/src/corelib/tools/qcryptographichash.h
@@ -55,9 +55,12 @@ class Q_CORE_EXPORT QCryptographicHash
{
public:
enum Algorithm {
+#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
Md4,
Md5,
- Sha1,
+#endif
+ Sha1 = 2,
+#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
Sha224,
Sha256,
Sha384,
@@ -66,6 +69,7 @@ public:
Sha3_256,
Sha3_384,
Sha3_512
+#endif
};
explicit QCryptographicHash(Algorithm method);
diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h
index 5c16680..b9f6995 100644
--- a/src/corelib/tools/qdatetime.h
+++ b/src/corelib/tools/qdatetime.h
@@ -50,6 +50,7 @@
QT_BEGIN_NAMESPACE
+class QTimeZone;
class Q_CORE_EXPORT QDate
{
@@ -168,6 +169,9 @@ public:
bool operator>(const QTime &other) const { return mds > other.mds; }
bool operator>=(const QTime &other) const { return mds >= other.mds; }
+ static inline QTime fromMSecsSinceStartOfDay(int msecs) { QTime t; t.mds = msecs; return t; }
+ inline int msecsSinceStartOfDay() const { return mds == NullTime ? 0 : mds; }
+
static QTime currentTime();
#ifndef QT_NO_DATESTRING
static QTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
@@ -203,6 +207,11 @@ public:
QDateTime();
explicit QDateTime(const QDate &);
QDateTime(const QDate &, const QTime &, Qt::TimeSpec spec = Qt::LocalTime);
+ // ### Qt 6: Merge with above with default offsetSeconds = 0
+ QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, int offsetSeconds);
+#ifndef QT_BOOTSTRAPPED
+ QDateTime(const QDate &date, const QTime &time, const QTimeZone &timeZone);
+#endif // QT_BOOTSTRAPPED
QDateTime(const QDateTime &other);
~QDateTime();
@@ -216,13 +225,28 @@ public:
QDate date() const;
QTime time() const;
Qt::TimeSpec timeSpec() const;
+ int offsetFromUtc() const;
+#ifndef QT_BOOTSTRAPPED
+ QTimeZone timeZone() const;
+#endif // QT_BOOTSTRAPPED
+ QString timeZoneAbbreviation() const;
+ bool isDaylightTime() const;
+
qint64 toMSecsSinceEpoch() const;
+ // ### Qt 6: use quint64 instead of uint
uint toTime_t() const;
+
void setDate(const QDate &date);
void setTime(const QTime &time);
void setTimeSpec(Qt::TimeSpec spec);
+ void setOffsetFromUtc(int offsetSeconds);
+#ifndef QT_BOOTSTRAPPED
+ void setTimeZone(const QTimeZone &toZone);
+#endif // QT_BOOTSTRAPPED
void setMSecsSinceEpoch(qint64 msecs);
+ // ### Qt 6: use quint64 instead of uint
void setTime_t(uint secsSince1Jan1970UTC);
+
#ifndef QT_NO_DATESTRING
QString toString(Qt::DateFormat f = Qt::TextDate) const;
QString toString(const QString &format) const;
@@ -232,9 +256,15 @@ public:
QDateTime addYears(int years) const;
QDateTime addSecs(qint64 secs) const;
QDateTime addMSecs(qint64 msecs) const;
+
QDateTime toTimeSpec(Qt::TimeSpec spec) const;
inline QDateTime toLocalTime() const { return toTimeSpec(Qt::LocalTime); }
inline QDateTime toUTC() const { return toTimeSpec(Qt::UTC); }
+ QDateTime toOffsetFromUtc(int offsetSeconds) const;
+#ifndef QT_BOOTSTRAPPED
+ QDateTime toTimeZone(const QTimeZone &toZone) const;
+#endif // QT_BOOTSTRAPPED
+
qint64 daysTo(const QDateTime &) const;
qint64 secsTo(const QDateTime &) const;
qint64 msecsTo(const QDateTime &) const;
@@ -246,8 +276,10 @@ public:
inline bool operator>(const QDateTime &other) const { return other < *this; }
inline bool operator>=(const QDateTime &other) const { return !(*this < other); }
- void setUtcOffset(int seconds);
- int utcOffset() const;
+#if QT_DEPRECATED_SINCE(5, 2)
+ QT_DEPRECATED void setUtcOffset(int seconds);
+ QT_DEPRECATED int utcOffset() const;
+#endif // QT_DEPRECATED_SINCE
static QDateTime currentDateTime();
static QDateTime currentDateTimeUtc();
@@ -255,8 +287,20 @@ public:
static QDateTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
static QDateTime fromString(const QString &s, const QString &format);
#endif
+ // ### Qt 6: use quint64 instead of uint
static QDateTime fromTime_t(uint secsSince1Jan1970UTC);
+ // ### Qt 6: Merge with above with default spec = Qt::LocalTime
+ static QDateTime fromTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec,
+ int offsetFromUtc = 0);
+#ifndef QT_BOOTSTRAPPED
+ static QDateTime fromTime_t(uint secsSince1Jan1970UTC, const QTimeZone &timeZone);
+#endif
static QDateTime fromMSecsSinceEpoch(qint64 msecs);
+ // ### Qt 6: Merge with above with default spec = Qt::LocalTime
+ static QDateTime fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetFromUtc = 0);
+#ifndef QT_BOOTSTRAPPED
+ static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone);
+#endif
static qint64 currentMSecsSinceEpoch() Q_DECL_NOTHROW;
private:
@@ -272,6 +316,10 @@ private:
friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &);
friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDateTime &);
#endif
+
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)
+ friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QDateTime &);
+#endif
};
Q_DECLARE_SHARED(QDateTime)
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index e99a67d..9dd0e61 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -509,6 +509,20 @@ private:
static void deleteNode2(QHashData::Node *node);
static void duplicateNode(QHashData::Node *originalNode, void *newNode);
+
+ bool isValidIterator(const iterator &it) const
+ {
+#if defined(QT_DEBUG) && !defined(Q_HASH_NO_ITERATOR_DEBUG)
+ QHashData::Node *node = it.i;
+ while (node->next)
+ node = node->next;
+ return (static_cast<void *>(node) == d);
+#else
+ Q_UNUSED(it);
+ return true;
+#endif
+ }
+ friend class QSet<Key>;
};
@@ -831,9 +845,27 @@ Q_OUTOFLINE_TEMPLATE T QHash<Key, T>::take(const Key &akey)
template <class Key, class T>
Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::erase(iterator it)
{
+ Q_ASSERT_X(isValidIterator(it), "QHash::erase", "The specified iterator argument 'it' is invalid");
+
if (it == iterator(e))
return it;
+ if (d->ref.isShared()) {
+ int bucketNum = (it.i->h % d->numBuckets);
+ iterator bucketIterator(*(d->buckets + bucketNum));
+ int stepsFromBucketStartToIte = 0;
+ while (bucketIterator != it) {
+ ++stepsFromBucketStartToIte;
+ ++bucketIterator;
+ }
+ detach();
+ it = iterator(*(d->buckets + bucketNum));
+ while (stepsFromBucketStartToIte > 0) {
+ --stepsFromBucketStartToIte;
+ ++it;
+ }
+ }
+
iterator ret = it;
++ret;
diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h
index b9ca1b9..79a62cb 100644
--- a/src/corelib/tools/qlinkedlist.h
+++ b/src/corelib/tools/qlinkedlist.h
@@ -48,6 +48,12 @@
#include <iterator>
#include <list>
+#include <algorithm>
+
+#if defined(Q_COMPILER_INITIALIZER_LISTS)
+# include <initializer_list>
+#endif
+
QT_BEGIN_NAMESPACE
@@ -78,6 +84,13 @@ class QLinkedList
public:
inline QLinkedList() : d(const_cast<QLinkedListData *>(&QLinkedListData::shared_null)) { }
inline QLinkedList(const QLinkedList<T> &l) : d(l.d) { d->ref.ref(); if (!d->sharable) detach(); }
+#if defined(Q_COMPILER_INITIALIZER_LISTS)
+ inline QLinkedList(std::initializer_list<T> list)
+ : d(const_cast<QLinkedListData *>(&QLinkedListData::shared_null))
+ {
+ std::copy(list.begin(), list.end(), std::back_inserter(*this));
+ }
+#endif
~QLinkedList();
QLinkedList<T> &operator=(const QLinkedList<T> &);
#ifdef Q_COMPILER_RVALUE_REFS
@@ -91,7 +104,7 @@ public:
inline int size() const { return d->size; }
inline void detach()
- { if (d->ref.isShared()) detach_helper(); }
+ { if (d->ref.isShared()) detach_helper2(this->e); }
inline bool isDetached() const { return !d->ref.isShared(); }
inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QLinkedListData::shared_null) d->sharable = sharable; }
inline bool isSharedWith(const QLinkedList<T> &other) const { return d == other.d; }
@@ -219,9 +232,9 @@ public:
typedef qptrdiff difference_type;
static inline QLinkedList<T> fromStdList(const std::list<T> &list)
- { QLinkedList<T> tmp; qCopy(list.begin(), list.end(), std::back_inserter(tmp)); return tmp; }
+ { QLinkedList<T> tmp; std::copy(list.begin(), list.end(), std::back_inserter(tmp)); return tmp; }
inline std::list<T> toStdList() const
- { std::list<T> tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
+ { std::list<T> tmp; std::copy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
// comfort
QLinkedList<T> &operator+=(const QLinkedList<T> &l);
@@ -232,6 +245,7 @@ public:
private:
void detach_helper();
+ iterator detach_helper2(iterator);
void freeData(QLinkedListData*);
};
@@ -245,6 +259,14 @@ inline QLinkedList<T>::~QLinkedList()
template <typename T>
void QLinkedList<T>::detach_helper()
{
+ detach_helper2(this->e);
+}
+
+template <typename T>
+typename QLinkedList<T>::iterator QLinkedList<T>::detach_helper2(iterator orgite)
+{
+ // detach and convert orgite to an iterator in the detached instance
+ bool isEndIterator = (orgite.i == this->e);
union { QLinkedListData *d; Node *e; } x;
x.d = new QLinkedListData;
x.d->ref.initializeOwned();
@@ -252,6 +274,22 @@ void QLinkedList<T>::detach_helper()
x.d->sharable = true;
Node *original = e->n;
Node *copy = x.e;
+ Node *org = orgite.i;
+
+ while (original != org) {
+ QT_TRY {
+ copy->n = new Node(original->t);
+ copy->n->p = copy;
+ original = original->n;
+ copy = copy->n;
+ } QT_CATCH(...) {
+ copy->n = x.e;
+ Q_ASSERT(!x.d->ref.deref()); // Don't trigger assert in free
+ freeData(x.d);
+ QT_RETHROW;
+ }
+ }
+ iterator r(copy);
while (original != e) {
QT_TRY {
copy->n = new Node(original->t);
@@ -270,6 +308,9 @@ void QLinkedList<T>::detach_helper()
if (!d->ref.deref())
freeData(d);
d = x.d;
+ if (!isEndIterator)
+ ++r; // since we stored the element right before the original node.
+ return r;
}
template <typename T>
@@ -376,7 +417,7 @@ template <typename T>
bool QLinkedList<T>::removeOne(const T &_t)
{
detach();
- iterator it = qFind(begin(), end(), _t);
+ iterator it = std::find(begin(), end(), _t);
if (it != end()) {
erase(it);
return true;
@@ -425,6 +466,9 @@ int QLinkedList<T>::count(const T &t) const
template <typename T>
typename QLinkedList<T>::iterator QLinkedList<T>::insert(iterator before, const T &t)
{
+ if (d->ref.isShared())
+ before = detach_helper2(before);
+
Node *i = before.i;
Node *m = new Node(t);
m->n = i;
@@ -448,7 +492,9 @@ typename QLinkedList<T>::iterator QLinkedList<T>::erase(typename QLinkedList<T>:
template <typename T>
typename QLinkedList<T>::iterator QLinkedList<T>::erase(iterator pos)
{
- detach();
+ if (d->ref.isShared())
+ pos = detach_helper2(pos);
+
Node *i = pos.i;
if (i != e) {
Node *n = i;
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 0592c24..333ce72 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -48,6 +48,7 @@
#include <iterator>
#include <list>
+#include <algorithm>
#ifdef Q_COMPILER_INITIALIZER_LISTS
#include <initializer_list>
#endif
@@ -123,7 +124,7 @@ public:
#ifdef Q_COMPILER_INITIALIZER_LISTS
inline QList(std::initializer_list<T> args)
: d(const_cast<QListData::Data *>(&QListData::shared_null))
- { qCopy(args.begin(), args.end(), std::back_inserter(*this)); }
+ { std::copy(args.begin(), args.end(), std::back_inserter(*this)); }
#endif
bool operator==(const QList<T> &l) const;
inline bool operator!=(const QList<T> &l) const { return !(*this == l); }
@@ -332,9 +333,9 @@ public:
static QList<T> fromSet(const QSet<T> &set);
static inline QList<T> fromStdList(const std::list<T> &list)
- { QList<T> tmp; qCopy(list.begin(), list.end(), std::back_inserter(tmp)); return tmp; }
+ { QList<T> tmp; std::copy(list.begin(), list.end(), std::back_inserter(tmp)); return tmp; }
inline std::list<T> toStdList() const
- { std::list<T> tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
+ { std::list<T> tmp; std::copy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
private:
Node *detach_helper_grow(int i, int n);
@@ -346,6 +347,11 @@ private:
void node_destruct(Node *n);
void node_copy(Node *from, Node *to, Node *src);
void node_destruct(Node *from, Node *to);
+
+ bool isValidIterator(const iterator &i) const
+ {
+ return (constBegin().i <= i.i) && (i.i <= constEnd().i);
+ }
};
#if defined(Q_CC_BOR)
@@ -433,8 +439,14 @@ Q_INLINE_TEMPLATE QList<T> &QList<T>::operator=(const QList<T> &l)
template <typename T>
inline typename QList<T>::iterator QList<T>::insert(iterator before, const T &t)
{
+ Q_ASSERT_X(isValidIterator(before), "QList::insert", "The specified iterator argument 'before' is invalid");
+
int iBefore = int(before.i - reinterpret_cast<Node *>(p.begin()));
- Node *n = reinterpret_cast<Node *>(p.insert(iBefore));
+ Node *n = 0;
+ if (d->ref.isShared())
+ n = detach_helper_grow(iBefore, 1);
+ else
+ n = reinterpret_cast<Node *>(p.insert(iBefore));
QT_TRY {
node_construct(n, t);
} QT_CATCH(...) {
@@ -445,8 +457,16 @@ inline typename QList<T>::iterator QList<T>::insert(iterator before, const T &t)
}
template <typename T>
inline typename QList<T>::iterator QList<T>::erase(iterator it)
-{ node_destruct(it.i);
- return reinterpret_cast<Node *>(p.erase(reinterpret_cast<void**>(it.i))); }
+{
+ Q_ASSERT_X(isValidIterator(it), "QList::erase", "The specified iterator argument 'it' is invalid");
+ if (d->ref.isShared()) {
+ int offset = int(it.i - reinterpret_cast<Node *>(p.begin()));
+ it = begin(); // implies detach()
+ it += offset;
+ }
+ node_destruct(it.i);
+ return reinterpret_cast<Node *>(p.erase(reinterpret_cast<void**>(it.i)));
+}
template <typename T>
inline const T &QList<T>::at(int i) const
{ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::at", "index out of range");
@@ -619,7 +639,7 @@ inline void QList<T>::move(int from, int to)
template<typename T>
Q_OUTOFLINE_TEMPLATE QList<T> QList<T>::mid(int pos, int alength) const
{
- if (alength < 0 || pos + alength > size())
+ if (alength < 0 || pos > size() - alength)
alength = size() - pos;
if (pos == 0 && alength == size())
return *this;
@@ -715,18 +735,14 @@ Q_OUTOFLINE_TEMPLATE QList<T>::QList(const QList<T> &l)
if (!d->ref.ref()) {
p.detach(d->alloc);
- struct Cleanup
- {
- Cleanup(QListData::Data *d) : d_(d) {}
- ~Cleanup() { if (d_) QListData::dispose(d_); }
-
- QListData::Data *d_;
- } tryCatch(d);
-
+ QT_TRY {
node_copy(reinterpret_cast<Node *>(p.begin()),
reinterpret_cast<Node *>(p.end()),
reinterpret_cast<Node *>(l.p.begin()));
- tryCatch.d_ = 0;
+ } QT_CATCH(...) {
+ QListData::dispose(d);
+ QT_RETHROW;
+ }
}
}
@@ -811,6 +827,19 @@ template <typename T>
Q_OUTOFLINE_TEMPLATE typename QList<T>::iterator QList<T>::erase(typename QList<T>::iterator afirst,
typename QList<T>::iterator alast)
{
+ Q_ASSERT_X(isValidIterator(afirst), "QList::erase", "The specified iterator argument 'afirst' is invalid");
+ Q_ASSERT_X(isValidIterator(alast), "QList::erase", "The specified iterator argument 'alast' is invalid");
+
+ if (d->ref.isShared()) {
+ // ### A block is erased and a detach is needed. We should shrink and only copy relevant items.
+ int offsetfirst = int(afirst.i - reinterpret_cast<Node *>(p.begin()));
+ int offsetlast = int(alast.i - reinterpret_cast<Node *>(p.begin()));
+ afirst = begin(); // implies detach()
+ alast = afirst;
+ afirst += offsetfirst;
+ alast += offsetlast;
+ }
+
for (Node *n = afirst.i; n < alast.i; ++n)
node_destruct(n);
int idx = afirst - begin();
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index 78fa336..0fc3f87 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -775,13 +775,14 @@ public:
SouthSudan = 254,
Bonaire = 255,
SintMaarten = 256,
+ Kosovo = 257,
DemocraticRepublicOfCongo = CongoKinshasa,
PeoplesRepublicOfCongo = CongoBrazzaville,
DemocraticRepublicOfKorea = NorthKorea,
RepublicOfKorea = SouthKorea,
RussianFederation = Russia,
SyrianArabRepublic = Syria,
- LastCountry = SintMaarten
+ LastCountry = Kosovo
};
// GENERATED PART ENDS HERE
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 449fcbc..db0cd6a 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -140,32 +140,32 @@ template <class Key, class T>
inline QMapNode<Key, T> *QMapNode<Key, T>::lowerBound(const Key &akey)
{
QMapNode<Key, T> *n = this;
- QMapNode<Key, T> *last = 0;
+ QMapNode<Key, T> *lastNode = 0;
while (n) {
if (!qMapLessThanKey(n->key, akey)) {
- last = n;
+ lastNode = n;
n = n->leftNode();
} else {
n = n->rightNode();
}
}
- return last;
+ return lastNode;
}
template <class Key, class T>
inline QMapNode<Key, T> *QMapNode<Key, T>::upperBound(const Key &akey)
{
QMapNode<Key, T> *n = this;
- QMapNode<Key, T> *last = 0;
+ QMapNode<Key, T> *lastNode = 0;
while (n) {
if (qMapLessThanKey(akey, n->key)) {
- last = n;
+ lastNode = n;
n = n->leftNode();
} else {
n = n->rightNode();
}
}
- return last;
+ return lastNode;
}
@@ -206,7 +206,7 @@ struct QMapData : public QMapDataBase
void deleteNode(Node *z);
Node *findNode(const Key &akey) const;
- void nodeRange(const Key &akey, Node **first, Node **last);
+ void nodeRange(const Key &akey, Node **firstNode, Node **lastNode);
Node *createNode(const Key &k, const T &v, Node *parent = 0, bool left = false)
{
@@ -288,15 +288,17 @@ void QMapData<Key, T>::deleteNode(QMapNode<Key, T> *z)
template <class Key, class T>
QMapNode<Key, T> *QMapData<Key, T>::findNode(const Key &akey) const
{
- Node *lb = root()->lowerBound(akey);
+ if (Node *r = root()) {
+ Node *lb = r->lowerBound(akey);
if (lb && !qMapLessThanKey(akey, lb->key))
return lb;
+ }
return 0;
}
template <class Key, class T>
-void QMapData<Key, T>::nodeRange(const Key &akey, QMapNode<Key, T> **first, QMapNode<Key, T> **last)
+void QMapData<Key, T>::nodeRange(const Key &akey, QMapNode<Key, T> **firstNode, QMapNode<Key, T> **lastNode)
{
Node *n = root();
Node *l = end();
@@ -307,16 +309,16 @@ void QMapData<Key, T>::nodeRange(const Key &akey, QMapNode<Key, T> **first, QMap
} else if (qMapLessThanKey(n->key, akey)) {
n = n->rightNode();
} else {
- *first = n->leftNode()->lowerBound(akey);
- if (!*first)
- *first = n;
- *last = n->rightNode()->upperBound(akey);
- if (!*last)
- *last = l;
+ *firstNode = n->leftNode() ? n->leftNode()->lowerBound(akey) : 0;
+ if (!*firstNode)
+ *firstNode = n;
+ *lastNode = n->rightNode() ? n->rightNode()->upperBound(akey) : 0;
+ if (!*lastNode)
+ *lastNode = l;
return;
}
}
- *first = *last = l;
+ *firstNode = *lastNode = l;
}
@@ -395,6 +397,14 @@ public:
QList<T> values(const Key &key) const;
int count(const Key &key) const;
+ inline const Key &firstKey() const { Q_ASSERT(!isEmpty()); return constBegin().key(); }
+ inline const Key &lastKey() const { Q_ASSERT(!isEmpty()); return (constEnd() - 1).key(); }
+
+ inline T &first() { Q_ASSERT(!isEmpty()); return *begin(); }
+ inline const T &first() const { Q_ASSERT(!isEmpty()); return *constBegin(); }
+ inline T &last() { Q_ASSERT(!isEmpty()); return *(end() - 1); }
+ inline const T &last() const { Q_ASSERT(!isEmpty()); return *(constEnd() - 1); }
+
class const_iterator;
class iterator
@@ -557,6 +567,18 @@ public:
private:
void detach_helper();
+ bool isValidIterator(const const_iterator &ci) const
+ {
+#if defined(QT_DEBUG) && !defined(Q_MAP_NO_ITERATOR_DEBUG)
+ const QMapNodeBase *n = ci.i;
+ while (n->parent())
+ n = n->parent();
+ return n->left == d->root();
+#else
+ Q_UNUSED(ci);
+ return true;
+#endif
+ }
};
template <class Key, class T>
@@ -621,12 +643,12 @@ Q_INLINE_TEMPLATE int QMap<Key, T>::count(const Key &akey) const
Node *lastNode;
d->nodeRange(akey, &firstNode, &lastNode);
- const_iterator first(firstNode);
- const const_iterator last(lastNode);
+ const_iterator ci_first(firstNode);
+ const const_iterator ci_last(lastNode);
int cnt = 0;
- while (first != last) {
+ while (ci_first != ci_last) {
++cnt;
- ++first;
+ ++ci_first;
}
return cnt;
}
@@ -643,12 +665,12 @@ Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::insert(const Key
detach();
Node *n = d->root();
Node *y = d->end();
- Node *last = 0;
+ Node *lastNode = 0;
bool left = true;
while (n) {
y = n;
if (!qMapLessThanKey(n->key, akey)) {
- last = n;
+ lastNode = n;
left = true;
n = n->leftNode();
} else {
@@ -656,9 +678,9 @@ Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::insert(const Key
n = n->rightNode();
}
}
- if (last && !qMapLessThanKey(akey, last->key)) {
- last->value = avalue;
- return iterator(last);
+ if (lastNode && !qMapLessThanKey(akey, lastNode->key)) {
+ lastNode->value = avalue;
+ return iterator(lastNode);
}
Node *z = d->createNode(akey, avalue, y, left);
return iterator(z);
@@ -670,6 +692,8 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insert(const_iterator pos, const K
if (d->ref.isShared())
return this->insert(akey, avalue);
+ Q_ASSERT_X(isValidIterator(pos), "QMap::insert", "The specified const_iterator argument 'it' is invalid");
+
if (pos == constEnd()) {
// Hint is that the Node is larger than (or equal to) the largest value.
Node *n = static_cast<Node *>(pos.i->left);
@@ -753,6 +777,8 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const_iterator pos, co
if (d->ref.isShared())
return this->insertMulti(akey, avalue);
+ Q_ASSERT_X(isValidIterator(pos), "QMap::insertMulti", "The specified const_iterator argument 'pos' is invalid");
+
if (pos == constEnd()) {
// Hint is that the Node is larger than (or equal to) the largest value.
Node *n = static_cast<Node *>(pos.i->left);
@@ -836,9 +862,9 @@ template <class Key, class T>
QPair<typename QMap<Key, T>::iterator, typename QMap<Key, T>::iterator> QMap<Key, T>::equal_range(const Key &akey)
{
detach();
- Node *first, *last;
- d->nodeRange(akey, &first, &last);
- return QPair<iterator, iterator>(iterator(first), iterator(last));
+ Node *firstNode, *lastNode;
+ d->nodeRange(akey, &firstNode, &lastNode);
+ return QPair<iterator, iterator>(iterator(firstNode), iterator(lastNode));
}
#ifdef Q_MAP_DEBUG
@@ -895,6 +921,29 @@ Q_OUTOFLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::erase(iterato
if (it == iterator(d->end()))
return it;
+ Q_ASSERT_X(isValidIterator(const_iterator(it)), "QMap::erase", "The specified iterator argument 'it' is invalid");
+
+ if (d->ref.isShared()) {
+ const_iterator oldBegin = constBegin();
+ const_iterator old = const_iterator(it);
+ int backStepsWithSameKey = 0;
+
+ while (old != oldBegin) {
+ --old;
+ if (qMapLessThanKey(old.key(), it.key()))
+ break;
+ ++backStepsWithSameKey;
+ }
+
+ it = find(old.key()); // ensures detach
+ Q_ASSERT_X(it != iterator(d->end()), "QMap::erase", "Unable to locate same key in erase after detach.");
+
+ while (backStepsWithSameKey > 0) {
+ ++it;
+ --backStepsWithSameKey;
+ }
+ }
+
Node *n = it.i;
++it;
d->deleteNode(n);
@@ -1005,7 +1054,7 @@ Q_OUTOFLINE_TEMPLATE QList<T> QMap<Key, T>::values(const Key &akey) const
template <class Key, class T>
Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator QMap<Key, T>::lowerBound(const Key &akey) const
{
- Node *lb = d->root()->lowerBound(akey);
+ Node *lb = d->root() ? d->root()->lowerBound(akey) : 0;
if (!lb)
lb = d->end();
return const_iterator(lb);
@@ -1015,7 +1064,7 @@ template <class Key, class T>
Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::lowerBound(const Key &akey)
{
detach();
- Node *lb = d->root()->lowerBound(akey);
+ Node *lb = d->root() ? d->root()->lowerBound(akey) : 0;
if (!lb)
lb = d->end();
return iterator(lb);
@@ -1025,7 +1074,7 @@ template <class Key, class T>
Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator
QMap<Key, T>::upperBound(const Key &akey) const
{
- Node *ub = d->root()->upperBound(akey);
+ Node *ub = d->root() ? d->root()->upperBound(akey) : 0;
if (!ub)
ub = d->end();
return const_iterator(ub);
@@ -1035,7 +1084,7 @@ template <class Key, class T>
Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::upperBound(const Key &akey)
{
detach();
- Node *ub = d->root()->upperBound(akey);
+ Node *ub = d->root() ? d->root()->upperBound(akey) : 0;
if (!ub)
ub = d->end();
return iterator(ub);
diff --git a/src/corelib/tools/qmargins.h b/src/corelib/tools/qmargins.h
index 0d68be9..ad5e94c 100644
--- a/src/corelib/tools/qmargins.h
+++ b/src/corelib/tools/qmargins.h
@@ -242,6 +242,24 @@ inline QMargins &QMargins::operator-=(const QMargins &margins)
return *this = *this - margins;
}
+inline QMargins &QMargins::operator+=(int margin)
+{
+ m_left += margin;
+ m_top += margin;
+ m_right += margin;
+ m_bottom += margin;
+ return *this;
+}
+
+inline QMargins &QMargins::operator-=(int margin)
+{
+ m_left -= margin;
+ m_top -= margin;
+ m_right -= margin;
+ m_bottom -= margin;
+ return *this;
+}
+
inline QMargins &QMargins::operator*=(int factor)
{
return *this = *this * factor;
diff --git a/src/corelib/tools/qpair.h b/src/corelib/tools/qpair.h
index 96b1b65..9b8691a 100644
--- a/src/corelib/tools/qpair.h
+++ b/src/corelib/tools/qpair.h
@@ -57,6 +57,19 @@ struct QPair
QPair(const T1 &t1, const T2 &t2) : first(t1), second(t2) {}
// compiler-generated copy/move ctor/assignment operators are fine!
+ template <typename TT1, typename TT2>
+ QPair(const QPair<TT1, TT2> &p) : first(p.first), second(p.second) {}
+ template <typename TT1, typename TT2>
+ QPair &operator=(const QPair<TT1, TT2> &p)
+ { first = p.first; second = p.second; return *this; }
+#ifdef Q_COMPILER_RVALUE_REFS
+ template <typename TT1, typename TT2>
+ QPair(QPair<TT1, TT2> &&p) : first(std::move(p.first)), second(std::move(p.second)) {}
+ template <typename TT1, typename TT2>
+ QPair &operator=(QPair<TT1, TT2> &&p)
+ { first = std::move(p.first); second = std::move(p.second); return *this; }
+#endif
+
T1 first;
T2 second;
};
diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h
index 2155c56..dd6e5bd 100644
--- a/src/corelib/tools/qscopedpointer.h
+++ b/src/corelib/tools/qscopedpointer.h
@@ -83,6 +83,17 @@ struct QScopedPointerPodDeleter
static inline void cleanup(void *pointer) { if (pointer) free(pointer); }
};
+#ifndef QT_NO_QOBJECT
+template <typename T>
+struct QScopedPointerObjectDeleteLater
+{
+ static inline void cleanup(T *pointer) { if (pointer) pointer->deleteLater(); }
+};
+
+class QObject;
+typedef QScopedPointerObjectDeleteLater<QObject> QScopedPointerDeleteLater;
+#endif
+
template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
class QScopedPointer
{
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index d5c3637..ad2f91b 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -70,6 +70,7 @@ public:
inline QSet<T> &operator=(const QSet<T> &other)
{ q_hash = other.q_hash; return *this; }
#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSet(QSet &&other) : q_hash(qMove(other.q_hash)) {}
inline QSet<T> &operator=(QSet<T> &&other)
{ qSwap(q_hash, other.q_hash); return *this; }
#endif
@@ -180,7 +181,10 @@ public:
inline const_iterator cend() const { return q_hash.end(); }
inline const_iterator constEnd() const { return q_hash.constEnd(); }
iterator erase(iterator i)
- { return q_hash.erase(reinterpret_cast<typename Hash::iterator &>(i)); }
+ {
+ Q_ASSERT_X(isValidIterator(i), "QSet::erase", "The specified const_iterator argument 'i' is invalid");
+ return q_hash.erase(reinterpret_cast<typename Hash::iterator &>(i));
+ }
// more Qt
typedef iterator Iterator;
@@ -233,6 +237,10 @@ public:
private:
Hash q_hash;
+ bool isValidIterator(const iterator &i) const
+ {
+ return q_hash.isValidIterator(reinterpret_cast<const typename Hash::iterator&>(i));
+ }
};
template <class T>
@@ -253,8 +261,16 @@ Q_INLINE_TEMPLATE QSet<T> &QSet<T>::unite(const QSet<T> &other)
template <class T>
Q_INLINE_TEMPLATE QSet<T> &QSet<T>::intersect(const QSet<T> &other)
{
- QSet<T> copy1(*this);
- QSet<T> copy2(other);
+ QSet<T> copy1;
+ QSet<T> copy2;
+ if (size() <= other.size()) {
+ copy1 = *this;
+ copy2 = other;
+ } else {
+ copy1 = other;
+ copy2 = *this;
+ *this = copy1;
+ }
typename QSet<T>::const_iterator i = copy1.constEnd();
while (i != copy1.constBegin()) {
--i;
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index 5e30cf3..1423449 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -506,7 +506,7 @@ public:
if (o) {
// increase the strongref, but never up from zero
// or less (-1 is used by QWeakPointer on untracked QObject)
- register int tmp = o->strongref.load();
+ int tmp = o->strongref.load();
while (tmp > 0) {
// try to increment from "tmp" to "tmp + 1"
if (o->strongref.testAndSetRelaxed(tmp, tmp + 1))
@@ -801,7 +801,7 @@ namespace QtSharedPointer {
template <class X, class T>
Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &src)
{
- register X *ptr = static_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
+ X *ptr = static_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
return QtSharedPointer::copyAndSetPointer(ptr, src);
}
template <class X, class T>
@@ -813,7 +813,7 @@ Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &sr
template <class X, class T>
Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src)
{
- register X *ptr = dynamic_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
+ X *ptr = dynamic_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
if (!ptr)
return QSharedPointer<X>();
return QtSharedPointer::copyAndSetPointer(ptr, src);
@@ -827,7 +827,7 @@ Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer
template <class X, class T>
Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src)
{
- register X *ptr = const_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
+ X *ptr = const_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
return QtSharedPointer::copyAndSetPointer(ptr, src);
}
template <class X, class T>
@@ -847,7 +847,7 @@ QWeakPointer<X> qWeakPointerCast(const QSharedPointer<T> &src)
template <class X, class T>
Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &src)
{
- register X *ptr = qobject_cast<X *>(src.data());
+ X *ptr = qobject_cast<X *>(src.data());
return QtSharedPointer::copyAndSetPointer(ptr, src);
}
template <class X, class T>
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index d8aaa92..2eaed65 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -64,8 +64,12 @@ namespace std
#error qstring.h must be included before any header file that defines truncate
#endif
-QT_BEGIN_NAMESPACE
+#ifdef Q_OS_MAC
+Q_FORWARD_DECLARE_OBJC_CLASS(NSString);
+Q_FORWARD_DECLARE_CF_TYPE(CFString);
+#endif
+QT_BEGIN_NAMESPACE
class QCharRef;
class QRegExp;
@@ -657,8 +661,12 @@ public:
const_iterator constEnd() const;
// STL compatibility
+ typedef int size_type;
+ typedef qptrdiff difference_type;
typedef const QChar & const_reference;
typedef QChar & reference;
+ typedef QChar *pointer;
+ typedef const QChar *const_pointer;
typedef QChar value_type;
inline void push_back(QChar c) { append(c); }
inline void push_back(const QString &s) { append(s); }
@@ -670,6 +678,12 @@ public:
static inline QString fromStdWString(const std::wstring &s);
inline std::wstring toStdWString() const;
+#if defined(Q_OS_MAC) || defined(Q_QDOC)
+ static QString fromCFString(CFStringRef string);
+ CFStringRef toCFString() const Q_DECL_CF_RETURNS_RETAINED;
+ static QString fromNSString(const NSString *string);
+ NSString *toNSString() const Q_DECL_NS_RETURNS_AUTORELEASED;
+#endif
// compatibility
struct Null { };
static const Null null;
@@ -920,8 +934,8 @@ inline QString::~QString() { if (!d->ref.deref()) Data::deallocate(d); }
inline void QString::reserve(int asize)
{
- if (d->ref.isShared() || uint(asize) + 1u > d->alloc)
- reallocData(uint(asize) + 1u);
+ if (d->ref.isShared() || uint(asize) >= d->alloc)
+ reallocData(qMax(asize, d->size) + 1u);
if (!d->capacityReserved) {
// cannot set unconditionally, since d could be the shared_null/shared_empty (which is const)
@@ -1222,6 +1236,10 @@ public:
int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int count(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ QStringRef left(int n) const Q_REQUIRED_RESULT;
+ QStringRef right(int n) const Q_REQUIRED_RESULT;
+ QStringRef mid(int pos, int n = -1) const Q_REQUIRED_RESULT;
+
bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool startsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool startsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 3a20280..309d2a2 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -49,6 +49,7 @@
#include <new>
#include <string.h>
#include <stdlib.h>
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -192,11 +193,18 @@ private:
qint64 q_for_alignment_1;
double q_for_alignment_2;
};
+
+ bool isValidIterator(const const_iterator &i) const
+ {
+ return (i <= constEnd()) && (constBegin() <= i);
+ }
};
template <class T, int Prealloc>
Q_INLINE_TEMPLATE QVarLengthArray<T, Prealloc>::QVarLengthArray(int asize)
: s(asize) {
+ Q_STATIC_ASSERT_X(Prealloc > 0, "QVarLengthArray Prealloc must be greater than 0.");
+ Q_ASSERT_X(s >= 0, "QVarLengthArray::QVarLengthArray()", "Size must be greater than or equal to 0.");
if (s > Prealloc) {
ptr = reinterpret_cast<T *>(malloc(s * sizeof(T)));
Q_CHECK_PTR(ptr);
@@ -310,7 +318,7 @@ Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::realloc(int asize, int a
template <class T, int Prealloc>
Q_OUTOFLINE_TEMPLATE T QVarLengthArray<T, Prealloc>::value(int i) const
{
- if (i < 0 || i >= size()) {
+ if (uint(i) >= uint(size())) {
return T();
}
return at(i);
@@ -318,7 +326,7 @@ Q_OUTOFLINE_TEMPLATE T QVarLengthArray<T, Prealloc>::value(int i) const
template <class T, int Prealloc>
Q_OUTOFLINE_TEMPLATE T QVarLengthArray<T, Prealloc>::value(int i, const T &defaultValue) const
{
- return (i < 0 || i >= size()) ? defaultValue : at(i);
+ return (uint(i) >= uint(size())) ? defaultValue : at(i);
}
template <class T, int Prealloc>
@@ -353,6 +361,8 @@ inline void QVarLengthArray<T, Prealloc>::replace(int i, const T &t)
template <class T, int Prealloc>
Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, size_type n, const T &t)
{
+ Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid");
+
int offset = int(before - ptr);
if (n != 0) {
resize(s + n);
@@ -380,11 +390,14 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
template <class T, int Prealloc>
Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::erase(const_iterator abegin, const_iterator aend)
{
+ Q_ASSERT_X(isValidIterator(abegin), "QVarLengthArray::insert", "The specified const_iterator argument 'abegin' is invalid");
+ Q_ASSERT_X(isValidIterator(aend), "QVarLengthArray::insert", "The specified const_iterator argument 'aend' is invalid");
+
int f = int(abegin - ptr);
int l = int(aend - ptr);
int n = l - f;
if (QTypeInfo<T>::isComplex) {
- qCopy(ptr + l, ptr + s, ptr + f);
+ std::copy(ptr + l, ptr + s, ptr + f);
T *i = ptr + s;
T *b = ptr + s - n;
while (i != b) {
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 816e1f1..f56511e 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -56,6 +56,8 @@
#include <initializer_list>
#endif
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
class QRegion;
@@ -150,6 +152,11 @@ public:
bool contains(const T &t) const;
int count(const T &t) const;
+ // QList compatibility
+ void removeAt(int i) { remove(i); }
+ int length() const { return size(); }
+ T takeAt(int i) { T t = at(i); remove(i); return t; }
+
// STL-style
typedef typename Data::iterator iterator;
typedef typename Data::const_iterator const_iterator;
@@ -185,7 +192,7 @@ public:
inline const T &last() const { Q_ASSERT(!isEmpty()); return *(end()-1); }
inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; }
inline bool endsWith(const T &t) const { return !isEmpty() && last() == t; }
- QVector<T> mid(int pos, int length = -1) const;
+ QVector<T> mid(int pos, int len = -1) const;
T value(int i) const;
T value(int i, const T &defaultValue) const;
@@ -227,18 +234,22 @@ public:
static QVector<T> fromList(const QList<T> &list);
static inline QVector<T> fromStdVector(const std::vector<T> &vector)
- { QVector<T> tmp; tmp.reserve(int(vector.size())); qCopy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; }
+ { QVector<T> tmp; tmp.reserve(int(vector.size())); std::copy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; }
inline std::vector<T> toStdVector() const
- { std::vector<T> tmp; tmp.reserve(size()); qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
+ { std::vector<T> tmp; tmp.reserve(size()); std::copy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
private:
friend class QRegion; // Optimization for QRegion::rects()
void reallocData(const int size, const int alloc, QArrayData::AllocationOptions options = QArrayData::Default);
+ void reallocData(const int sz) { reallocData(sz, d->alloc); }
void freeData(Data *d);
void defaultConstruct(T *from, T *to);
void copyConstruct(const T *srcFrom, const T *srcTo, T *dstFrom);
void destruct(T *from, T *to);
-
+ bool isValidIterator(const iterator &i) const
+ {
+ return (i <= d->end()) && (d->begin() <= i);
+ }
class AlignmentDummy { Data header; T array[1]; };
};
@@ -398,7 +409,8 @@ QVector<T> &QVector<T>::operator=(const QVector<T> &v)
template <typename T>
QVector<T>::QVector(int asize)
{
- if (Q_LIKELY(asize)) {
+ Q_ASSERT_X(asize >= 0, "QVector::QVector", "Size must be greater than or equal to 0.");
+ if (Q_LIKELY(asize > 0)) {
d = Data::allocate(asize);
d->size = asize;
defaultConstruct(d->begin(), d->end());
@@ -410,7 +422,8 @@ QVector<T>::QVector(int asize)
template <typename T>
QVector<T>::QVector(int asize, const T &t)
{
- if (asize) {
+ Q_ASSERT_X(asize >= 0, "QVector::QVector", "Size must be greater than or equal to 0.");
+ if (asize > 0) {
d = Data::allocate(asize);
d->size = asize;
T* i = d->end();
@@ -530,7 +543,7 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo
template<typename T>
Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i) const
{
- if (i < 0 || i >= d->size) {
+ if (uint(i) >= uint(d->size)) {
return T();
}
return d->begin()[i];
@@ -538,7 +551,7 @@ Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i) const
template<typename T>
Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i, const T &defaultValue) const
{
- return ((i < 0 || i >= d->size) ? defaultValue : d->begin()[i]);
+ return uint(i) >= uint(d->size) ? defaultValue : d->begin()[i];
}
template <typename T>
@@ -558,24 +571,25 @@ void QVector<T>::append(const T &t)
}
template <typename T>
-inline void QVector<T>::removeLast()
+void QVector<T>::removeLast()
{
Q_ASSERT(!isEmpty());
+ Q_ASSERT(d->alloc);
- if (d->alloc) {
- if (d->ref.isShared()) {
- reallocData(d->size - 1, int(d->alloc));
- return;
- }
- if (QTypeInfo<T>::isComplex)
- (d->data() + d->size - 1)->~T();
+ if (!d->ref.isShared()) {
--d->size;
+ if (QTypeInfo<T>::isComplex)
+ (d->data() + d->size)->~T();
+ } else {
+ reallocData(d->size - 1);
}
}
template <typename T>
typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, const T &t)
{
+ Q_ASSERT_X(isValidIterator(before), "QVector::insert", "The specified iterator argument 'before' is invalid");
+
int offset = std::distance(d->begin(), before);
if (n != 0) {
const T copy(t);
@@ -609,6 +623,9 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c
template <typename T>
typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
{
+ Q_ASSERT_X(isValidIterator(abegin), "QVector::erase", "The specified iterator argument 'abegin' is invalid");
+ Q_ASSERT_X(isValidIterator(aend), "QVector::erase", "The specified iterator argument 'aend' is invalid");
+
const int itemsToErase = aend - abegin;
if (!itemsToErase)
@@ -632,7 +649,7 @@ typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
iterator moveEnd = d->end();
while (moveBegin != moveEnd) {
if (QTypeInfo<T>::isComplex)
- abegin->~T();
+ static_cast<T *>(abegin)->~T();
new (abegin++) T(*moveBegin++);
}
if (abegin < d->end()) {
@@ -760,17 +777,17 @@ int QVector<T>::count(const T &t) const
}
template <typename T>
-Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int length) const
+Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int len) const
{
- if (length < 0)
- length = size() - pos;
- if (pos == 0 && length == size())
+ if (len < 0)
+ len = size() - pos;
+ if (pos == 0 && len == size())
return *this;
- if (pos + length > size())
- length = size() - pos;
+ if (pos + len > size())
+ len = size() - pos;
QVector<T> copy;
- copy.reserve(length);
- for (int i = pos; i < pos + length; ++i)
+ copy.reserve(len);
+ for (int i = pos; i < pos + len; ++i)
copy += at(i);
return copy;
}
class QWidget;
-template <class T> class QSharedPointer;
-template <class T> class QWeakPointer;
-template <class T> class QPointer;
+
+#define QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER(Name) \
+ template <class T> class Name; \
+
+QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER)
namespace QtPrivate
{
@@ -509,6 +1348,116 @@ namespace QtPrivate
enum { Value = true };
};
+ template<typename T>
+ struct IsSequentialContainer
+ {
+ enum { Value = false };
+ };
+
+ template<typename T>
+ struct IsAssociativeContainer
+ {
+ enum { Value = false };
+ };
+
+ template<typename T, bool = QtPrivate::IsSequentialContainer<T>::Value>
+ struct SequentialContainerConverterHelper
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::value_type>::Defined>
+ struct ValueTypeIsMetaType
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct SequentialContainerConverterHelper<T, true> : ValueTypeIsMetaType<T>
+ {
+ };
+
+ template<typename T, bool = QtPrivate::IsAssociativeContainer<T>::Value>
+ struct AssociativeContainerConverterHelper
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::mapped_type>::Defined>
+ struct AssociativeValueTypeIsMetaType
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::key_type>::Defined>
+ struct KeyAndValueTypeIsMetaType
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct KeyAndValueTypeIsMetaType<T, true> : AssociativeValueTypeIsMetaType<T>
+ {
+ };
+
+ template<typename T>
+ struct AssociativeContainerConverterHelper<T, true> : KeyAndValueTypeIsMetaType<T>
+ {
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::first_type>::Defined
+ && QMetaTypeId2<typename T::second_type>::Defined>
+ struct IsMetaTypePair
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct IsMetaTypePair<T, true>
+ {
+ inline static bool registerConverter(int id);
+ };
+
+ template<typename T>
+ struct IsPair
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+ template<typename T, typename U>
+ struct IsPair<QPair<T, U> > : IsMetaTypePair<QPair<T, U> > {};
+ template<typename T, typename U>
+ struct IsPair<std::pair<T, U> > : IsMetaTypePair<std::pair<T, U> > {};
+
+ template<typename T>
+ struct MetaTypePairHelper : IsPair<T> {};
+
+ template<typename T, typename = void>
+ struct MetaTypeSmartPointerHelper
+ {
+ static bool registerConverter(int) { return false; }
+ };
+
Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type);
} // namespace QtPrivate
@@ -546,11 +1495,16 @@ namespace QtPrivate {
{ return -1; }
};
+#ifndef Q_COMPILER_VARIADIC_TEMPLATES
// Function pointers don't derive from QObject
template <class Result> struct IsPointerToTypeDerivedFromQObject<Result(*)()> { enum { Value = false }; };
template <class Result, class Arg0> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0)> { enum { Value = false }; };
template <class Result, class Arg0, class Arg1> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1)> { enum { Value = false }; };
template <class Result, class Arg0, class Arg1, class Arg2> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1, Arg2)> { enum { Value = false }; };
+#else
+ template <typename Result, typename... Args>
+ struct IsPointerToTypeDerivedFromQObject<Result(*)(Args...)> { enum { Value = false }; };
+#endif
template<typename T>
struct QMetaTypeTypeFlags
@@ -571,6 +1525,24 @@ namespace QtPrivate {
{
enum DefinedType { Defined = defined };
};
+
+ template<typename SmartPointer>
+ struct QSmartPointerConvertFunctor
+ {
+ QObject* operator()(const SmartPointer &p) const
+ {
+ return p.operator->();
+ }
+ };
+
+ template<typename T>
+ struct QSmartPointerConvertFunctor<QWeakPointer<T> >
+ {
+ QObject* operator()(const QWeakPointer<T> &p) const
+ {
+ return p.data();
+ }
+ };
}
template <typename T>
@@ -593,14 +1565,23 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz
if (defined)
flags |= QMetaType::WasDeclaredAsMetaType;
- return QMetaType::registerNormalizedType(normalizedTypeName,
+ const int id = QMetaType::registerNormalizedType(normalizedTypeName,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Delete,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Create,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Destruct,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Construct,
- sizeof(T),
+ int(sizeof(T)),
flags,
QtPrivate::MetaObjectForType<T>::value());
+
+ if (id > 0) {
+ QtPrivate::SequentialContainerConverterHelper<T>::registerConverter(id);
+ QtPrivate::AssociativeContainerConverterHelper<T>::registerConverter(id);
+ QtPrivate::MetaTypePairHelper<T>::registerConverter(id);
+ QtPrivate::MetaTypeSmartPointerHelper<T>::registerConverter(id);
+ }
+
+ return id;
}
template <typename T>
@@ -686,7 +1667,7 @@ struct QMetaTypeIdQObject<T*, /* isPointerToTypeDerivedFromQObject */ true>
template <typename T>
inline int qRegisterMetaTypeStreamOperators()
{
- register int id = qMetaTypeId<T>();
+ int id = qMetaTypeId<T>();
QMetaType::registerStreamOperators(id, QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Save,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Load);
return id;
@@ -746,6 +1727,7 @@ typedef QMap<QString, QVariant> QVariantMap;
typedef QHash<QString, QVariant> QVariantHash;
#define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \
+QT_BEGIN_NAMESPACE \
template <typename T> \
struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
{ \
@@ -761,8 +1743,8 @@ struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
Q_ASSERT(tName); \
const int tNameLen = qstrlen(tName); \
QByteArray typeName; \
- typeName.reserve(sizeof(#SINGLE_ARG_TEMPLATE) + 1 + tNameLen + 1 + 1); \
- typeName.append(#SINGLE_ARG_TEMPLATE, sizeof(#SINGLE_ARG_TEMPLATE) - 1) \
+ typeName.reserve(int(sizeof(#SINGLE_ARG_TEMPLATE)) + 1 + tNameLen + 1 + 1); \
+ typeName.append(#SINGLE_ARG_TEMPLATE, int(sizeof(#SINGLE_ARG_TEMPLATE)) - 1) \
.append('<').append(tName, tNameLen); \
if (typeName.endsWith('>')) \
typeName.append(' '); \
@@ -773,9 +1755,18 @@ struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
metatype_id.storeRelease(newId); \
return newId; \
} \
-};
+}; \
+namespace QtPrivate { \
+template<typename T> \
+struct IsSequentialContainer<SINGLE_ARG_TEMPLATE<T> > \
+{ \
+ enum { Value = true }; \
+}; \
+} \
+QT_END_NAMESPACE
#define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \
+QT_BEGIN_NAMESPACE \
template<typename T, typename U> \
struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
{ \
@@ -794,8 +1785,8 @@ struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
const int tNameLen = qstrlen(tName); \
const int uNameLen = qstrlen(uName); \
QByteArray typeName; \
- typeName.reserve(sizeof(#DOUBLE_ARG_TEMPLATE) + 1 + tNameLen + 1 + uNameLen + 1 + 1); \
- typeName.append(#DOUBLE_ARG_TEMPLATE, sizeof(#DOUBLE_ARG_TEMPLATE) - 1) \
+ typeName.reserve(int(sizeof(#DOUBLE_ARG_TEMPLATE)) + 1 + tNameLen + 1 + uNameLen + 1 + 1); \
+ typeName.append(#DOUBLE_ARG_TEMPLATE, int(sizeof(#DOUBLE_ARG_TEMPLATE)) - 1) \
.append('<').append(tName, tNameLen).append(',').append(uName, uNameLen); \
if (typeName.endsWith('>')) \
typeName.append(' '); \
@@ -806,19 +1797,30 @@ struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
metatype_id.storeRelease(newId); \
return newId; \
} \
+}; \
+QT_END_NAMESPACE
+
+namespace QtPrivate {
+
+template<typename T, bool /* isSharedPointerToQObjectDerived */ = false>
+struct SharedPointerMetaTypeIdHelper
+{
+ enum {
+ Defined = 0
+ };
+ static int qt_metatype_id()
+ {
+ return -1;
+ }
};
+}
+
#define Q_DECLARE_SMART_POINTER_METATYPE(SMART_POINTER) \
-template <typename T, bool = QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \
-struct QMetaTypeId_ ## SMART_POINTER ## _QObjectStar \
-{ \
- enum { \
- Defined = 0 \
- }; \
-};\
- \
+QT_BEGIN_NAMESPACE \
+namespace QtPrivate { \
template<typename T> \
-struct QMetaTypeId_ ## SMART_POINTER ## _QObjectStar<T, true> \
+struct SharedPointerMetaTypeIdHelper<SMART_POINTER<T>, true> \
{ \
enum { \
Defined = 1 \
@@ -830,8 +1832,8 @@ struct QMetaTypeId_ ## SMART_POINTER ## _QObjectStar<T, true> \
return id; \
const char * const cName = T::staticMetaObject.className(); \
QByteArray typeName; \
- typeName.reserve(sizeof(#SMART_POINTER) + 1 + strlen(cName) + 1); \
- typeName.append(#SMART_POINTER, sizeof(#SMART_POINTER) - 1) \
+ typeName.reserve(int(sizeof(#SMART_POINTER) + 1 + strlen(cName) + 1)); \
+ typeName.append(#SMART_POINTER, int(sizeof(#SMART_POINTER)) - 1) \
.append('<').append(cName).append('>'); \
const int newId = qRegisterNormalizedMetaType< SMART_POINTER<T> >( \
typeName, \
@@ -840,51 +1842,85 @@ struct QMetaTypeId_ ## SMART_POINTER ## _QObjectStar<T, true> \
return newId; \
} \
}; \
-\
template<typename T> \
-struct QMetaTypeId< SMART_POINTER<T> > : public QMetaTypeId_ ## SMART_POINTER ## _QObjectStar<T> \
+struct MetaTypeSmartPointerHelper<SMART_POINTER<T> , \
+ typename QEnableIf<IsPointerToTypeDerivedFromQObject<T*>::Value >::Type> \
{ \
-};
+ static bool registerConverter(int id) \
+ { \
+ const int toId = QMetaType::QObjectStar; \
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { \
+ QtPrivate::QSmartPointerConvertFunctor<SMART_POINTER<T> > o; \
+ static const QtPrivate::ConverterFunctor<SMART_POINTER<T>, \
+ QObject*, \
+ QSmartPointerConvertFunctor<SMART_POINTER<T> > > f(o); \
+ return QMetaType::registerConverterFunction(&f, id, toId); \
+ } \
+ return true; \
+ } \
+}; \
+} \
+template <typename T> \
+struct QMetaTypeId< SMART_POINTER<T> > \
+ : QtPrivate::SharedPointerMetaTypeIdHelper< SMART_POINTER<T>, \
+ QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \
+{ \
+};\
+QT_END_NAMESPACE
-#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F) \
- F(QList) \
- F(QVector) \
- F(QQueue) \
- F(QStack) \
- F(QSet) \
- F(QLinkedList)
+#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER(TEMPLATENAME) \
+ QT_BEGIN_NAMESPACE \
+ template <class T> class TEMPLATENAME; \
+ QT_END_NAMESPACE \
+ Q_DECLARE_METATYPE_TEMPLATE_1ARG(TEMPLATENAME)
-#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \
- F(QHash, class) \
- F(QMap, class) \
- F(QPair, struct)
+QT_END_NAMESPACE
-#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \
- F(QSharedPointer) \
- F(QWeakPointer) \
- F(QPointer)
+QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER)
-#define Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER(TEMPLATENAME) \
- template <class T> class TEMPLATENAME; \
- Q_DECLARE_METATYPE_TEMPLATE_1ARG(TEMPLATENAME)
+#undef Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER
-QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER)
+#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE Q_DECLARE_METATYPE_TEMPLATE_1ARG
-#undef Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER
+Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::vector)
+Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::list)
-#define Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER(TEMPLATENAME, CPPTYPE) \
+#define Q_FORWARD_DECLARE_METATYPE_TEMPLATE_2ARG_ITER(TEMPLATENAME, CPPTYPE) \
+ QT_BEGIN_NAMESPACE \
template <class T1, class T2> CPPTYPE TEMPLATENAME; \
- Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME)
+ QT_END_NAMESPACE \
-QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER)
+QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(Q_FORWARD_DECLARE_METATYPE_TEMPLATE_2ARG_ITER)
#undef Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER
+#define Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(TEMPLATENAME) \
+ QT_BEGIN_NAMESPACE \
+ namespace QtPrivate { \
+ template<typename T, typename U> \
+ struct IsAssociativeContainer<TEMPLATENAME<T, U> > \
+ { \
+ enum { Value = true }; \
+ }; \
+ } \
+ QT_END_NAMESPACE \
+ Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME)
+
+Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QHash)
+Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QMap)
+Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(std::map)
+
+Q_DECLARE_METATYPE_TEMPLATE_2ARG(QPair)
+Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::pair)
+
#define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \
Q_DECLARE_SMART_POINTER_METATYPE(TEMPLATENAME)
+
QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER)
+QT_BEGIN_NAMESPACE
+
#undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER
inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
@@ -987,5 +2023,62 @@ QT_END_NAMESPACE
QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE)
+Q_DECLARE_METATYPE(QtMetaTypePrivate::QSequentialIterableImpl)
+Q_DECLARE_METATYPE(QtMetaTypePrivate::QAssociativeIterableImpl)
+Q_DECLARE_METATYPE(QtMetaTypePrivate::QPairVariantInterfaceImpl)
+
+QT_BEGIN_NAMESPACE
+
+template <typename T>
+inline bool QtPrivate::IsMetaTypePair<T, true>::registerConverter(int id)
+{
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
+ QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QPairVariantInterfaceImpl,
+ QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+ }
+ return true;
+}
+
+namespace QtPrivate {
+ template<typename T>
+ struct ValueTypeIsMetaType<T, true>
+ {
+ static bool registerConverter(int id)
+ {
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>();
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
+ QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QSequentialIterableImpl,
+ QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+ }
+ return true;
+ }
+ };
+
+ template<typename T>
+ struct AssociativeValueTypeIsMetaType<T, true>
+ {
+ static bool registerConverter(int id)
+ {
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>();
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
+ QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QAssociativeIterableImpl,
+ QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+ }
+ return true;
+ }
+ };
+}
+
+QT_END_NAMESPACE
#endif // QMETATYPE_H
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index aaa09fa..e2000af 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -208,6 +208,7 @@ public:
#ifdef Q_QDOC
static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type);
static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor);
+ static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type);
#else
//Connect a signal to a pointer to qobject member function
template <typename Func1, typename Func2>
@@ -217,7 +218,9 @@ public:
{
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
- reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0));
+
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
@@ -243,9 +246,22 @@ public:
static inline typename QtPrivate::QEnableIf<int(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0, QMetaObject::Connection>::Type
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
{
+ return connect(sender, signal, sender, slot, Qt::DirectConnection);
+ }
+
+ //connect to a function pointer (not a member)
+ template <typename Func1, typename Func2>
+ static inline typename QtPrivate::QEnableIf<int(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0 &&
+ !QtPrivate::FunctionPointer<Func2>::IsPointerToMemberFunction, QMetaObject::Connection>::Type
+ connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
+ Qt::ConnectionType type = Qt::AutoConnection)
+ {
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
+
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
"The slot requires more arguments than the signal provides.");
@@ -254,11 +270,15 @@ public:
Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
"Return type of the slot is not compatible with the return type of the signal.");
- return connectImpl(sender, reinterpret_cast<void **>(&signal), sender, 0,
+ const int *types = 0;
+ if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
+ types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
+
+ return connectImpl(sender, reinterpret_cast<void **>(&signal), context, 0,
new QtPrivate::QStaticSlotObject<Func2,
typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
typename SignalType::ReturnType>(slot),
- Qt::DirectConnection, 0, &SignalType::Object::staticMetaObject);
+ type, types, &SignalType::Object::staticMetaObject);
}
//connect to a functor
@@ -266,6 +286,15 @@ public:
static inline typename QtPrivate::QEnableIf<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::Type
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
{
+ return connect(sender, signal, sender, slot, Qt::DirectConnection);
+ }
+
+ //connect to a functor, with a "context" object defining in which event loop is going to be executed
+ template <typename Func1, typename Func2>
+ static inline typename QtPrivate::QEnableIf<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::Type
+ connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
+ Qt::ConnectionType type = Qt::AutoConnection)
+ {
#if defined (Q_COMPILER_DECLTYPE) && defined (Q_COMPILER_VARIADIC_TEMPLATES)
typedef QtPrivate::FunctionPointer<Func1> SignalType;
const int FunctorArgumentCount = QtPrivate::ComputeFunctorArgumentCount<Func2 , typename SignalType::Arguments>::Value;
@@ -287,9 +316,10 @@ public:
C++11 variadic templates
*/
#ifndef Q_COMPILER_DECLTYPE //Workaround the lack of decltype using another function as indirection
- return connect_functor(sender, signal, slot, &Func2::operator()); }
+ return connect_functor(sender, signal, context, slot, &Func2::operator(), type); }
template <typename Func1, typename Func2, typename Func2Operator>
- static inline QMetaObject::Connection connect_functor(const QObject *sender, Func1 signal, Func2 slot, Func2Operator) {
+ static inline QMetaObject::Connection connect_functor(const QObject *sender, Func1 signal, const QObject *context,
+ Func2 slot, Func2Operator, Qt::ConnectionType type) {
typedef QtPrivate::FunctionPointer<Func2Operator> SlotType ;
#else
typedef QtPrivate::FunctionPointer<decltype(&Func2::operator())> SlotType ;
@@ -307,11 +337,18 @@ public:
Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<SlotReturnType, typename SignalType::ReturnType>::value),
"Return type of the slot is not compatible with the return type of the signal.");
- return connectImpl(sender, reinterpret_cast<void **>(&signal), sender, 0,
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
+
+ const int *types = 0;
+ if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
+ types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
+
+ return connectImpl(sender, reinterpret_cast<void **>(&signal), context, 0,
new QtPrivate::QFunctorSlotObject<Func2, SlotArgumentCount,
typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value,
typename SignalType::ReturnType>(slot),
- Qt::DirectConnection, 0, &SignalType::Object::staticMetaObject);
+ type, types, &SignalType::Object::staticMetaObject);
}
#endif //Q_QDOC
@@ -335,7 +372,9 @@ public:
{
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
- reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0));
+
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
+ "No Q_OBJECT in the class with the signal");
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
@@ -477,18 +516,18 @@ inline QT_DEPRECATED QList<T> qFindChildren(const QObject *o, const QRegExp &re)
template <class T>
inline T qobject_cast(QObject *object)
{
-#if !defined(QT_NO_QOBJECT_CHECK)
- reinterpret_cast<T>(object)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(object));
-#endif
+ typedef typename QtPrivate::remove_cv<typename QtPrivate::remove_pointer<T>::type>::type ObjType;
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
+ "qobject_cast requires the type to have a Q_OBJECT macro");
return static_cast<T>(reinterpret_cast<T>(object)->staticMetaObject.cast(object));
}
template <class T>
inline T qobject_cast(const QObject *object)
{
-#if !defined(QT_NO_QOBJECT_CHECK)
- reinterpret_cast<T>(object)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(const_cast<QObject *>(object)));
-#endif
+ typedef typename QtPrivate::remove_cv<typename QtPrivate::remove_pointer<T>::type>::type ObjType;
+ Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
+ "qobject_cast requires the type to have a Q_OBJECT macro");
return static_cast<T>(reinterpret_cast<T>(object)->staticMetaObject.cast(object));
}
diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h
index 0b5631f..1bbd548 100644
--- a/src/corelib/kernel/qobject_impl.h
+++ b/src/corelib/kernel/qobject_impl.h
@@ -204,7 +204,6 @@ namespace QtPrivate {
public:
explicit QFunctorSlotObject(const Func &f) : QSlotObjectBase(&impl), function(f) {}
};
-
}
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index afbe1a5..7354c3f 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -125,7 +125,7 @@ class QString;
/* qmake ignore Q_OBJECT */
#define Q_OBJECT_CHECK \
- template <typename T> inline void qt_check_for_QOBJECT_macro(const T &_q_argument) const \
+ template <typename ThisObject> inline void qt_check_for_QOBJECT_macro(const ThisObject &_q_argument) const \
{ int i = qYouForgotTheQ_OBJECT_Macro(this, &_q_argument); i = i + 1; }
template <typename T>
@@ -456,6 +456,7 @@ class Q_CORE_EXPORT QMetaObject::Connection {
void *d_ptr; //QObjectPrivate::Connection*
explicit Connection(void *data) : d_ptr(data) { }
friend class QObject;
+ friend class QObjectPrivate;
friend struct QMetaObject;
public:
~Connection();
@@ -479,6 +480,16 @@ public:
inline const QMetaObject *QMetaObject::superClass() const
{ return d.superdata; }
+namespace QtPrivate {
+ /* Trait that tells is a the Object has a Q_OBJECT macro */
+ template <typename Object> struct HasQ_OBJECT_Macro {
+ template <typename T>
+ static char test(int (T::*)(QMetaObject::Call, int, void **));
+ static int test(int (Object::*)(QMetaObject::Call, int, void **));
+ enum { Value = sizeof(test(&Object::qt_metacall)) == sizeof(int) };
+ };
+}
+
QT_END_NAMESPACE
#endif // QOBJECTDEFS_H
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index 4f44d92..fb6601f 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -129,7 +129,7 @@ namespace QtPrivate {
its call function is the same as the FunctionPointer::call function.
*/
#ifndef Q_COMPILER_VARIADIC_TEMPLATES
- template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1}; };
+ template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1, IsPointerToMemberFunction = false}; };
//Pointers to member functions
template<class Obj, typename Ret> struct FunctionPointer<Ret (Obj::*) ()>
{
@@ -137,7 +137,7 @@ namespace QtPrivate {
typedef void Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) ();
- enum {ArgumentCount = 0};
+ enum {ArgumentCount = 0, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) { (o->*f)(), ApplyReturnValue<R>(arg[0]); }
};
@@ -147,7 +147,7 @@ namespace QtPrivate {
typedef List<Arg1, void> Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1);
- enum {ArgumentCount = 1};
+ enum {ArgumentCount = 1, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)((*reinterpret_cast<typename RemoveRef<typename Args::Car>::Type *>(arg[1]))), ApplyReturnValue<R>(arg[0]);
@@ -159,7 +159,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, void> > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2);
- enum {ArgumentCount = 2};
+ enum {ArgumentCount = 2, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -172,7 +172,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, void> > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3);
- enum {ArgumentCount = 3};
+ enum {ArgumentCount = 3, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -186,7 +186,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4);
- enum {ArgumentCount = 4};
+ enum {ArgumentCount = 4, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -201,7 +201,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, void> > > > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5);
- enum {ArgumentCount = 5};
+ enum {ArgumentCount = 5, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -218,7 +218,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
- enum {ArgumentCount = 6};
+ enum {ArgumentCount = 6, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -237,7 +237,7 @@ namespace QtPrivate {
typedef void Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) () const;
- enum {ArgumentCount = 0};
+ enum {ArgumentCount = 0, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) { (o->*f)(), ApplyReturnValue<R>(arg[0]); }
};
@@ -247,7 +247,7 @@ namespace QtPrivate {
typedef List<Arg1, void> Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1) const;
- enum {ArgumentCount = 1};
+ enum {ArgumentCount = 1, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)((*reinterpret_cast<typename RemoveRef<typename Args::Car>::Type *>(arg[1]))), ApplyReturnValue<R>(arg[0]);
@@ -259,7 +259,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, void> > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2) const;
- enum {ArgumentCount = 2};
+ enum {ArgumentCount = 2, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -272,7 +272,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, void> > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3) const;
- enum {ArgumentCount = 3};
+ enum {ArgumentCount = 3, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -286,7 +286,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4) const;
- enum {ArgumentCount = 4};
+ enum {ArgumentCount = 4, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -301,7 +301,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, void> > > > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5) const;
- enum {ArgumentCount = 5};
+ enum {ArgumentCount = 5, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -318,7 +318,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > > Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const;
- enum {ArgumentCount = 6};
+ enum {ArgumentCount = 6, IsPointerToMemberFunction = true};
template <typename Args, typename R>
static void call(Function f, Obj *o, void **arg) {
(o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -336,7 +336,7 @@ namespace QtPrivate {
typedef void Arguments;
typedef Ret (*Function) ();
typedef Ret ReturnType;
- enum {ArgumentCount = 0};
+ enum {ArgumentCount = 0, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg) { f(), ApplyReturnValue<R>(arg[0]); }
};
@@ -345,7 +345,7 @@ namespace QtPrivate {
typedef List<Arg1, void> Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Arg1);
- enum {ArgumentCount = 1};
+ enum {ArgumentCount = 1, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg)
{ f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1])), ApplyReturnValue<R>(arg[0]); }
@@ -355,7 +355,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, void> > Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Arg1, Arg2);
- enum {ArgumentCount = 2};
+ enum {ArgumentCount = 2, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg) {
f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -366,7 +366,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, void> > > Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Arg1, Arg2, Arg3);
- enum {ArgumentCount = 3};
+ enum {ArgumentCount = 3, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg) {
f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -379,7 +379,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > > Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4);
- enum {ArgumentCount = 4};
+ enum {ArgumentCount = 4, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg) {
f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -394,7 +394,7 @@ namespace QtPrivate {
List<Arg4, List<Arg5, void > > > > > Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5);
- enum {ArgumentCount = 5};
+ enum {ArgumentCount = 5, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg) {
f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -409,7 +409,7 @@ namespace QtPrivate {
typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > > Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
- enum {ArgumentCount = 6};
+ enum {ArgumentCount = 6, IsPointerToMemberFunction = false};
template <typename Args, typename R>
static void call(Function f, void *, void **arg) {
f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
@@ -493,25 +493,25 @@ namespace QtPrivate {
template <int N> struct Indexes
{ typedef typename IndexesAppend<typename Indexes<N - 1>::Value, N - 1>::Value Value; };
template <> struct Indexes<0> { typedef IndexesList<> Value; };
- template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1}; };
+ template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1, IsPointerToMemberFunction = false}; };
template <typename, typename, typename, typename> struct FunctorCall;
- template <int... I, typename... SignalArgs, typename R, typename Function>
- struct FunctorCall<IndexesList<I...>, List<SignalArgs...>, R, Function> {
+ template <int... II, typename... SignalArgs, typename R, typename Function>
+ struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, Function> {
static void call(Function f, void **arg) {
- f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[I+1]))...), ApplyReturnValue<R>(arg[0]);
+ f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
}
};
- template <int... I, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
- struct FunctorCall<IndexesList<I...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...)> {
+ template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
+ struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...)> {
static void call(SlotRet (Obj::*f)(SlotArgs...), Obj *o, void **arg) {
- (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[I+1]))...), ApplyReturnValue<R>(arg[0]);
+ (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
}
};
- template <int... I, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
- struct FunctorCall<IndexesList<I...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...) const> {
+ template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
+ struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...) const> {
static void call(SlotRet (Obj::*f)(SlotArgs...) const, Obj *o, void **arg) {
- (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[I+1]))...), ApplyReturnValue<R>(arg[0]);
+ (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
}
};
@@ -521,7 +521,7 @@ namespace QtPrivate {
typedef List<Args...> Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Args...);
- enum {ArgumentCount = sizeof...(Args)};
+ enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true};
template <typename SignalArgs, typename R>
static void call(Function f, Obj *o, void **arg) {
FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, o, arg);
@@ -533,7 +533,7 @@ namespace QtPrivate {
typedef List<Args...> Arguments;
typedef Ret ReturnType;
typedef Ret (Obj::*Function) (Args...) const;
- enum {ArgumentCount = sizeof...(Args)};
+ enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true};
template <typename SignalArgs, typename R>
static void call(Function f, Obj *o, void **arg) {
FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, o, arg);
@@ -545,7 +545,7 @@ namespace QtPrivate {
typedef List<Args...> Arguments;
typedef Ret ReturnType;
typedef Ret (*Function) (Args...);
- enum {ArgumentCount = sizeof...(Args)};
+ enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = false};
template <typename SignalArgs, typename R>
static void call(Function f, void *, void **arg) {
FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, arg);
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 6f212f5..5ff33cc 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -49,6 +49,7 @@
#include <QtCore/qmap.h>
#include <QtCore/qhash.h>
#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
#include <QtCore/qobject.h>
QT_BEGIN_NAMESPACE
@@ -432,6 +433,14 @@ class Q_CORE_EXPORT QVariant
{ return cmp(v); }
inline bool operator!=(const QVariant &v) const
{ return !cmp(v); }
+ inline bool operator<(const QVariant &v) const
+ { return compare(v) < 0; }
+ inline bool operator<=(const QVariant &v) const
+ { return compare(v) <= 0; }
+ inline bool operator>(const QVariant &v) const
+ { return compare(v) > 0; }
+ inline bool operator>=(const QVariant &v) const
+ { return compare(v) >= 0; }
protected:
friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
@@ -449,6 +458,7 @@ public:
Private d;
void create(int type, const void *copy);
bool cmp(const QVariant &other) const;
+ int compare(const QVariant &other) const;
bool convert(const int t, void *ptr) const;
private:
@@ -562,6 +572,107 @@ inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
}
#endif
+class Q_CORE_EXPORT QSequentialIterable
+{
+ QtMetaTypePrivate::QSequentialIterableImpl m_impl;
+public:
+ struct Q_CORE_EXPORT const_iterator
+ {
+ private:
+ QtMetaTypePrivate::QSequentialIterableImpl m_impl;
+ QAtomicInt *ref;
+ friend class QSequentialIterable;
+ explicit const_iterator(const QSequentialIterable &iter, QAtomicInt *ref_);
+
+ explicit const_iterator(const QtMetaTypePrivate::QSequentialIterableImpl &impl, QAtomicInt *ref_);
+
+ void begin();
+ void end();
+ public:
+ ~const_iterator();
+
+ const_iterator(const const_iterator &other);
+
+ const_iterator& operator=(const const_iterator &other);
+
+ const QVariant operator*() const;
+ bool operator==(const const_iterator &o) const;
+ bool operator!=(const const_iterator &o) const;
+ const_iterator &operator++();
+ const_iterator operator++(int);
+ const_iterator &operator--();
+ const_iterator operator--(int);
+ const_iterator &operator+=(int j);
+ const_iterator &operator-=(int j);
+ const_iterator operator+(int j) const;
+ const_iterator operator-(int j) const;
+ };
+
+ friend struct const_iterator;
+
+ explicit QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl impl);
+
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ QVariant at(int idx) const;
+ int size() const;
+
+ bool canReverseIterate() const;
+};
+
+class Q_CORE_EXPORT QAssociativeIterable
+{
+ QtMetaTypePrivate::QAssociativeIterableImpl m_impl;
+public:
+ struct Q_CORE_EXPORT const_iterator
+ {
+ private:
+ QtMetaTypePrivate::QAssociativeIterableImpl m_impl;
+ QAtomicInt *ref;
+ friend class QAssociativeIterable;
+ explicit const_iterator(const QAssociativeIterable &iter, QAtomicInt *ref_);
+
+ explicit const_iterator(const QtMetaTypePrivate::QAssociativeIterableImpl &impl, QAtomicInt *ref_);
+
+ void begin();
+ void end();
+ public:
+ ~const_iterator();
+ const_iterator(const const_iterator &other);
+
+ const_iterator& operator=(const const_iterator &other);
+
+ const QVariant key() const;
+
+ const QVariant value() const;
+
+ const QVariant operator*() const;
+ bool operator==(const const_iterator &o) const;
+ bool operator!=(const const_iterator &o) const;
+ const_iterator &operator++();
+ const_iterator operator++(int);
+ const_iterator &operator--();
+ const_iterator operator--(int);
+ const_iterator &operator+=(int j);
+ const_iterator &operator-=(int j);
+ const_iterator operator+(int j) const;
+ const_iterator operator-(int j) const;
+ };
+
+ friend struct const_iterator;
+
+ explicit QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl impl);
+
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ QVariant value(const QVariant &key) const;
+
+ int size() const;
+};
+
+#ifndef QT_MOC
namespace QtPrivate {
template<typename T>
struct QVariantValueHelper : TreatAsQObjectBeforeMetaType<QVariantValueHelper<T>, T, const QVariant &, T>
@@ -571,26 +682,132 @@ namespace QtPrivate {
const int vid = qMetaTypeId<T>();
if (vid == v.userType())
return *reinterpret_cast<const T *>(v.constData());
- if (vid < int(QMetaType::User)) {
T t;
if (v.convert(vid, &t))
return t;
- }
return T();
}
#ifndef QT_NO_QOBJECT
static T object(const QVariant &v)
{
- return qobject_cast<T>(QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject ? v.d.data.o : 0);
+ return qobject_cast<T>(QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject
+ ? v.d.data.o
+ : QVariantValueHelper::metaType(v));
}
#endif
};
+
+ template<typename T>
+ struct QVariantValueHelperInterface : QVariantValueHelper<T>
+ {
+ };
+
+ template<>
+ struct QVariantValueHelperInterface<QSequentialIterable>
+ {
+ static QSequentialIterable invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QVariantList>()) {
+ return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QVariantList*>(v.constData())));
+ }
+ if (v.userType() == qMetaTypeId<QStringList>()) {
+ return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QStringList*>(v.constData())));
+ }
+ return QSequentialIterable(v.value<QtMetaTypePrivate::QSequentialIterableImpl>());
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QAssociativeIterable>
+ {
+ static QAssociativeIterable invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QVariantMap>()) {
+ return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantMap*>(v.constData())));
+ }
+ if (v.userType() == qMetaTypeId<QVariantHash>()) {
+ return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantHash*>(v.constData())));
+ }
+ return QAssociativeIterable(v.value<QtMetaTypePrivate::QAssociativeIterableImpl>());
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QVariantList>
+ {
+ static QVariantList invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QStringList>() || QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) {
+ QSequentialIterable iter = QVariantValueHelperInterface<QSequentialIterable>::invoke(v);
+ QVariantList l;
+ l.reserve(iter.size());
+ for (QSequentialIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
+ l << *it;
+ return l;
+ }
+ return QVariantValueHelper<QVariantList>::invoke(v);
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QVariantHash>
+ {
+ static QVariantHash invoke(const QVariant &v)
+ {
+ if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
+ QVariantHash l;
+ l.reserve(iter.size());
+ for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
+ l.insert(it.key().toString(), it.value());
+ return l;
+ }
+ return QVariantValueHelper<QVariantHash>::invoke(v);
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QVariantMap>
+ {
+ static QVariantMap invoke(const QVariant &v)
+ {
+ if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
+ QVariantMap l;
+ for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
+ l.insert(it.key().toString(), it.value());
+ return l;
+ }
+ return QVariantValueHelper<QVariantMap>::invoke(v);
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QPair<QVariant, QVariant> >
+ {
+ static QPair<QVariant, QVariant> invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QPair<QVariant, QVariant> >())
+ return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
+
+ if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
+ QtMetaTypePrivate::QPairVariantInterfaceImpl pi = v.value<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
+
+ const QtMetaTypePrivate::VariantData d1 = pi.first();
+ QVariant v1(d1.metaTypeId, d1.data, d1.flags);
+ if (d1.metaTypeId == qMetaTypeId<QVariant>())
+ v1 = *reinterpret_cast<const QVariant*>(d1.data);
+
+ const QtMetaTypePrivate::VariantData d2 = pi.second();
+ QVariant v2(d2.metaTypeId, d2.data, d2.flags);
+ if (d2.metaTypeId == qMetaTypeId<QVariant>())
+ v2 = *reinterpret_cast<const QVariant*>(d2.data);
+
+ return QPair<QVariant, QVariant>(v1, v2);
+ }
+ return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
+ }
+ };
}
-#ifndef QT_MOC
template<typename T> inline T qvariant_cast(const QVariant &v)
{
- return QtPrivate::QVariantValueHelper<T>::invoke(v);
+ return QtPrivate::QVariantValueHelperInterface<T>::invoke(v);
}
template<> inline QVariant qvariant_cast<QVariant>(const QVariant &v)
diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h
index b91a0e9..1ec9325 100644
--- a/src/corelib/plugin/qplugin.h
+++ b/src/corelib/plugin/qplugin.h
@@ -44,6 +44,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qpointer.h>
+#include <QtCore/qjsonobject.h>
QT_BEGIN_NAMESPACE
@@ -59,11 +60,22 @@ QT_BEGIN_NAMESPACE
typedef QObject *(*QtPluginInstanceFunction)();
typedef const char *(*QtPluginMetaDataFunction)();
-struct QStaticPlugin
+struct Q_CORE_EXPORT QStaticPlugin
{
+ // Note: This struct is initialized using an initializer list.
+ // As such, it cannot have any new constructors or variables.
+#ifndef Q_QDOC
QtPluginInstanceFunction instance;
- QtPluginMetaDataFunction metaData;
+ QtPluginMetaDataFunction rawMetaData;
+#else
+ // Since qdoc gets confused by the use of function
+ // pointers, we add these dummes for it to parse instead:
+ QObject *instance();
+ const char *rawMetaData();
+#endif
+ QJsonObject metaData() const;
};
+Q_DECLARE_TYPEINFO(QStaticPlugin, Q_PRIMITIVE_TYPE);
void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
diff --git a/src/corelib/plugin/qpluginloader.h b/src/corelib/plugin/qpluginloader.h
index 8f8833e..88c8ba4 100644
--- a/src/corelib/plugin/qpluginloader.h
+++ b/src/corelib/plugin/qpluginloader.h
@@ -43,6 +43,7 @@
#define QPLUGINLOADER_H
#include <QtCore/qlibrary.h>
+#include <QtCore/qplugin.h>
#ifndef QT_NO_LIBRARY
@@ -65,6 +66,7 @@ public:
QJsonObject metaData() const;
static QObjectList staticInstances();
+ static QVector<QStaticPlugin> staticPlugins();
bool load();
bool unload();
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index cf0a6a5..ddcc25f 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -60,11 +60,11 @@
// Processor dependent implementation
#elif defined(Q_PROCESSOR_ALPHA)
# include "QtCore/qatomic_alpha.h"
-#elif defined(Q_PROCESSOR_ARM_V7)
+#elif defined(Q_PROCESSOR_ARM_V7) && defined(Q_PROCESSOR_ARM_32)
# include "QtCore/qatomic_armv7.h"
-#elif defined(Q_PROCESSOR_ARM_V6)
+#elif defined(Q_PROCESSOR_ARM_V6) && defined(Q_PROCESSOR_ARM_32)
# include "QtCore/qatomic_armv6.h"
-#elif defined(Q_PROCESSOR_ARM_V5)
+#elif defined(Q_PROCESSOR_ARM_V5) && defined(Q_PROCESSOR_ARM_32)
# include "QtCore/qatomic_armv5.h"
#elif defined(Q_PROCESSOR_BFIN)
# include "QtCore/qatomic_bfin.h"
diff --git a/src/corelib/thread/qgenericatomic.h b/src/corelib/thread/qgenericatomic.h
index a0a851e..3a213f6 100644
--- a/src/corelib/thread/qgenericatomic.h
+++ b/src/corelib/thread/qgenericatomic.h
@@ -172,7 +172,7 @@ template <typename BaseClass> struct QGenericAtomicOps
{
// implement fetchAndStore on top of testAndSet
Q_FOREVER {
- register T tmp = load(_q_value);
+ T tmp = load(_q_value);
if (BaseClass::testAndSetRelaxed(_q_value, tmp, newValue))
return tmp;
}
@@ -207,7 +207,7 @@ template <typename BaseClass> struct QGenericAtomicOps
{
// implement fetchAndAdd on top of testAndSet
Q_FOREVER {
- register T tmp = BaseClass::load(_q_value);
+ T tmp = BaseClass::load(_q_value);
if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp + valueToAdd)))
return tmp;
}
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index 19c0f82..f06981c 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -86,6 +86,9 @@ public:
bool isFinished() const;
bool isRunning() const;
+ void requestInterruption();
+ bool isInterruptionRequested() const;
+
void setStackSize(uint stackSize);
uint stackSize() const;
diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h
index ffc16de..22a42c2 100644
--- a/src/corelib/thread/qthreadpool.h
+++ b/src/corelib/thread/qthreadpool.h
@@ -83,6 +83,8 @@ public:
void releaseThread();
bool waitForDone(int msecs = -1);
+
+ void clear();
};
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h
index e3b7688..c6eede0 100644
--- a/src/corelib/tools/qalgorithms.h
+++ b/src/corelib/tools/qalgorithms.h
@@ -53,27 +53,30 @@ QT_BEGIN_NAMESPACE
*/
namespace QAlgorithmsPrivate {
+#if QT_DEPRECATED_SINCE(5, 2)
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
template <typename RandomAccessIterator, typename T>
-inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy);
+QT_DEPRECATED inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy);
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
template <typename RandomAccessIterator, typename T>
-inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &);
+QT_DEPRECATED inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &);
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+#endif // QT_DEPRECATED_SINCE(5, 2)
}
+#if QT_DEPRECATED_SINCE(5, 2)
template <typename InputIterator, typename OutputIterator>
-inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest)
+QT_DEPRECATED inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest)
{
while (begin != end)
*dest++ = *begin++;
@@ -81,7 +84,7 @@ inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterat
}
template <typename BiIterator1, typename BiIterator2>
-inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest)
+QT_DEPRECATED inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest)
{
while (begin != end)
*--dest = *--end;
@@ -89,7 +92,7 @@ inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2
}
template <typename InputIterator1, typename InputIterator2>
-inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
+QT_DEPRECATED inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
{
for (; first1 != last1; ++first1, ++first2)
if (!(*first1 == *first2))
@@ -98,20 +101,20 @@ inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 f
}
template <typename ForwardIterator, typename T>
-inline void qFill(ForwardIterator first, ForwardIterator last, const T &val)
+QT_DEPRECATED inline void qFill(ForwardIterator first, ForwardIterator last, const T &val)
{
for (; first != last; ++first)
*first = val;
}
template <typename Container, typename T>
-inline void qFill(Container &container, const T &val)
+QT_DEPRECATED inline void qFill(Container &container, const T &val)
{
qFill(container.begin(), container.end(), val);
}
template <typename InputIterator, typename T>
-inline InputIterator qFind(InputIterator first, InputIterator last, const T &val)
+QT_DEPRECATED inline InputIterator qFind(InputIterator first, InputIterator last, const T &val)
{
while (first != last && !(*first == val))
++first;
@@ -119,13 +122,13 @@ inline InputIterator qFind(InputIterator first, InputIterator last, const T &val
}
template <typename Container, typename T>
-inline typename Container::const_iterator qFind(const Container &container, const T &val)
+QT_DEPRECATED inline typename Container::const_iterator qFind(const Container &container, const T &val)
{
return qFind(container.constBegin(), container.constEnd(), val);
}
template <typename InputIterator, typename T, typename Size>
-inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n)
+QT_DEPRECATED inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n)
{
for (; first != last; ++first)
if (*first == value)
@@ -133,7 +136,7 @@ inline void qCount(InputIterator first, InputIterator last, const T &value, Size
}
template <typename Container, typename T, typename Size>
-inline void qCount(const Container &container, const T &value, Size &n)
+QT_DEPRECATED inline void qCount(const Container &container, const T &value, Size &n)
{
qCount(container.constBegin(), container.constEnd(), value, n);
}
@@ -150,7 +153,7 @@ LessThan qGreater()
}
#else
template <typename T>
-class qLess
+class QT_DEPRECATED qLess
{
public:
inline bool operator()(const T &t1, const T &t2) const
@@ -160,7 +163,7 @@ public:
};
template <typename T>
-class qGreater
+class QT_DEPRECATED qGreater
{
public:
inline bool operator()(const T &t1, const T &t2) const
@@ -171,21 +174,21 @@ public:
#endif
template <typename RandomAccessIterator>
-inline void qSort(RandomAccessIterator start, RandomAccessIterator end)
+QT_DEPRECATED inline void qSort(RandomAccessIterator start, RandomAccessIterator end)
{
if (start != end)
QAlgorithmsPrivate::qSortHelper(start, end, *start);
}
template <typename RandomAccessIterator, typename LessThan>
-inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
+QT_DEPRECATED inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
{
if (start != end)
QAlgorithmsPrivate::qSortHelper(start, end, *start, lessThan);
}
template<typename Container>
-inline void qSort(Container &c)
+QT_DEPRECATED inline void qSort(Container &c)
{
#ifdef Q_CC_BOR
// Work around Borland 5.5 optimizer bug
@@ -196,21 +199,21 @@ inline void qSort(Container &c)
}
template <typename RandomAccessIterator>
-inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end)
+QT_DEPRECATED inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end)
{
if (start != end)
QAlgorithmsPrivate::qStableSortHelper(start, end, *start);
}
template <typename RandomAccessIterator, typename LessThan>
-inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
+QT_DEPRECATED inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
{
if (start != end)
QAlgorithmsPrivate::qStableSortHelper(start, end, *start, lessThan);
}
template<typename Container>
-inline void qStableSort(Container &c)
+QT_DEPRECATED inline void qStableSort(Container &c)
{
#ifdef Q_CC_BOR
// Work around Borland 5.5 optimizer bug
@@ -221,7 +224,7 @@ inline void qStableSort(Container &c)
}
template <typename RandomAccessIterator, typename T>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
{
// Implementation is duplicated from QAlgorithmsPrivate to keep existing code
// compiling. We have to allow using *begin and value with different types,
@@ -244,19 +247,19 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
return QAlgorithmsPrivate::qLowerBoundHelper(begin, end, value, lessThan);
}
template <typename Container, typename T>
-Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value)
{
return QAlgorithmsPrivate::qLowerBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
}
template <typename RandomAccessIterator, typename T>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
{
// Implementation is duplicated from QAlgorithmsPrivate.
RandomAccessIterator middle;
@@ -277,19 +280,19 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
return QAlgorithmsPrivate::qUpperBoundHelper(begin, end, value, lessThan);
}
template <typename Container, typename T>
-Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value)
{
return QAlgorithmsPrivate::qUpperBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
}
template <typename RandomAccessIterator, typename T>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
{
// Implementation is duplicated from QAlgorithmsPrivate.
RandomAccessIterator it = qLowerBound(begin, end, value);
@@ -301,16 +304,17 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
return QAlgorithmsPrivate::qBinaryFindHelper(begin, end, value, lessThan);
}
template <typename Container, typename T>
-Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value)
{
return QAlgorithmsPrivate::qBinaryFindHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
}
+#endif // QT_DEPRECATED_SINCE(5, 2)
template <typename ForwardIterator>
Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
@@ -333,8 +337,10 @@ inline void qDeleteAll(const Container &c)
*/
namespace QAlgorithmsPrivate {
+#if QT_DEPRECATED_SINCE(5, 2)
+
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan)
{
top:
int span = int(end - start);
@@ -387,13 +393,13 @@ top:
}
template <typename RandomAccessIterator, typename T>
-inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
+QT_DEPRECATED inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
{
qSortHelper(begin, end, dummy, qLess<T>());
}
template <typename RandomAccessIterator>
-Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end)
{
--end;
while (begin < end)
@@ -401,7 +407,7 @@ Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessItera
}
template <typename RandomAccessIterator>
-Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end)
{
qReverse(begin, middle);
qReverse(middle, end);
@@ -409,7 +415,7 @@ Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterat
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan)
{
const int len1 = pivot - begin;
const int len2 = end - pivot;
@@ -444,7 +450,7 @@ Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterato
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan)
{
const int span = end - begin;
if (span < 2)
@@ -457,13 +463,13 @@ Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAc
}
template <typename RandomAccessIterator, typename T>
-inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
+QT_DEPRECATED inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
{
qStableSortHelper(begin, end, dummy, qLess<T>());
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
RandomAccessIterator middle;
int n = int(end - begin);
@@ -484,7 +490,7 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
RandomAccessIterator middle;
int n = end - begin;
@@ -504,7 +510,7 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
RandomAccessIterator it = qLowerBoundHelper(begin, end, value, lessThan);
@@ -514,8 +520,77 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator
return it;
}
+#endif // QT_DEPRECATED_SINCE(5, 2)
+
} //namespace QAlgorithmsPrivate
+
+// Use __builtin_popcount on gcc. Clang claims to be gcc
+// but has a bug where __builtin_popcount is not marked as
+// constexpr.
+#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
+#define QALGORITHMS_USE_BUILTIN_POPCOUNT
+#endif
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint32 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcount(v);
+#else
+ // See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 24) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint8 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcount(v);
+#else
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint16 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcount(v);
+#else
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint64 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcountll(v);
+#else
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 24) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 36) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 48) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 60) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(long unsigned int v)
+{
+ return qPopulationCount(static_cast<quint64>(v));
+}
+
+#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
+#undef QALGORITHMS_USE_BUILTIN_POPCOUNT
+#endif
+
+
QT_END_NAMESPACE
#endif // QALGORITHMS_H
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
index 3cd8c51..c8a0825 100644
--- a/src/corelib/tools/qarraydataops.h
+++ b/src/corelib/tools/qarraydataops.h
@@ -62,7 +62,7 @@ struct QPodArrayOps
Q_ASSERT(newSize <= this->alloc);
::memset(this->end(), 0, (newSize - this->size) * sizeof(T));
- this->size = newSize;
+ this->size = int(newSize);
}
void copyAppend(const T *b, const T *e)
@@ -84,7 +84,7 @@ struct QPodArrayOps
const T *const end = iter + n;
for (; iter != end; ++iter)
::memcpy(iter, &t, sizeof(T));
- this->size += n;
+ this->size += int(n);
}
void truncate(size_t newSize)
@@ -92,7 +92,7 @@ struct QPodArrayOps
Q_ASSERT(!this->ref.isShared());
Q_ASSERT(newSize < size_t(this->size));
- this->size = newSize;
+ this->size = int(newSize);
}
void destroyAll() // Call from destructors, ONLY!
diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h
index 1103712..eaf9b2f 100644
--- a/src/corelib/tools/qbitarray.h
+++ b/src/corelib/tools/qbitarray.h
@@ -61,6 +61,7 @@ public:
QBitArray(const QBitArray &other) : d(other.d) {}
inline QBitArray &operator=(const QBitArray &other) { d = other.d; return *this; }
#ifdef Q_COMPILER_RVALUE_REFS
+ inline QBitArray(QBitArray &&other) : d(std::move(other.d)) {}
inline QBitArray &operator=(QBitArray &&other)
{ qSwap(d, other.d); return *this; }
#endif
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index f3cc301..ae8166d 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -173,6 +173,15 @@ private:
typedef QTypedArrayData<char> Data;
public:
+ enum Base64Option {
+ Base64Encoding = 0,
+ Base64UrlEncoding = 1,
+
+ KeepTrailingEquals = 0,
+ OmitTrailingEquals = 2
+ };
+ Q_DECLARE_FLAGS(Base64Options, Base64Option)
+
inline QByteArray();
QByteArray(const char *, int size = -1);
QByteArray(int size, char c);
@@ -317,7 +326,8 @@ public:
qulonglong toULongLong(bool *ok = 0, int base = 10) const;
float toFloat(bool *ok = 0) const;
double toDouble(bool *ok = 0) const;
- QByteArray toBase64() const;
+ QByteArray toBase64(Base64Options options) const;
+ QByteArray toBase64() const; // ### Qt6 merge with previous
QByteArray toHex() const;
QByteArray toPercentEncoding(const QByteArray &exclude = QByteArray(),
const QByteArray &include = QByteArray(),
@@ -339,7 +349,8 @@ public:
static QByteArray number(qulonglong, int base = 10);
static QByteArray number(double, char f = 'g', int prec = 6);
static QByteArray fromRawData(const char *, int size);
- static QByteArray fromBase64(const QByteArray &base64);
+ static QByteArray fromBase64(const QByteArray &base64, Base64Options options);
+ static QByteArray fromBase64(const QByteArray &base64); // ### Qt6 merge with previous
static QByteArray fromHex(const QByteArray &hexEncoded);
static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%');
@@ -373,7 +384,7 @@ public:
bool isNull() const;
inline QByteArray(QByteArrayDataPtr dd)
- : d(reinterpret_cast<Data *>(dd.ptr))
+ : d(static_cast<Data *>(dd.ptr))
{
}
@@ -392,6 +403,8 @@ public:
inline DataPtr &data_ptr() { return d; }
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QByteArray::Base64Options)
+
inline QByteArray::QByteArray(): d(Data::sharedNull()) { }
inline QByteArray::~QByteArray() { if (!d->ref.deref()) Data::deallocate(d); }
inline int QByteArray::size() const
diff --git a/src/corelib/tools/qcryptographichash.h b/src/corelib/tools/qcryptographichash.h
index d4e75c4..c4f7c3a 100644
--- a/src/corelib/tools/qcryptographichash.h
+++ b/src/corelib/tools/qcryptographichash.h
@@ -55,9 +55,12 @@ class Q_CORE_EXPORT QCryptographicHash
{
public:
enum Algorithm {
+#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
Md4,
Md5,
- Sha1,
+#endif
+ Sha1 = 2,
+#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
Sha224,
Sha256,
Sha384,
@@ -66,6 +69,7 @@ public:
Sha3_256,
Sha3_384,
Sha3_512
+#endif
};
explicit QCryptographicHash(Algorithm method);
diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h
index 5c16680..b9f6995 100644
--- a/src/corelib/tools/qdatetime.h
+++ b/src/corelib/tools/qdatetime.h
@@ -50,6 +50,7 @@
QT_BEGIN_NAMESPACE
+class QTimeZone;
class Q_CORE_EXPORT QDate
{
@@ -168,6 +169,9 @@ public:
bool operator>(const QTime &other) const { return mds > other.mds; }
bool operator>=(const QTime &other) const { return mds >= other.mds; }
+ static inline QTime fromMSecsSinceStartOfDay(int msecs) { QTime t; t.mds = msecs; return t; }
+ inline int msecsSinceStartOfDay() const { return mds == NullTime ? 0 : mds; }
+
static QTime currentTime();
#ifndef QT_NO_DATESTRING
static QTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
@@ -203,6 +207,11 @@ public:
QDateTime();
explicit QDateTime(const QDate &);
QDateTime(const QDate &, const QTime &, Qt::TimeSpec spec = Qt::LocalTime);
+ // ### Qt 6: Merge with above with default offsetSeconds = 0
+ QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, int offsetSeconds);
+#ifndef QT_BOOTSTRAPPED
+ QDateTime(const QDate &date, const QTime &time, const QTimeZone &timeZone);
+#endif // QT_BOOTSTRAPPED
QDateTime(const QDateTime &other);
~QDateTime();
@@ -216,13 +225,28 @@ public:
QDate date() const;
QTime time() const;
Qt::TimeSpec timeSpec() const;
+ int offsetFromUtc() const;
+#ifndef QT_BOOTSTRAPPED
+ QTimeZone timeZone() const;
+#endif // QT_BOOTSTRAPPED
+ QString timeZoneAbbreviation() const;
+ bool isDaylightTime() const;
+
qint64 toMSecsSinceEpoch() const;
+ // ### Qt 6: use quint64 instead of uint
uint toTime_t() const;
+
void setDate(const QDate &date);
void setTime(const QTime &time);
void setTimeSpec(Qt::TimeSpec spec);
+ void setOffsetFromUtc(int offsetSeconds);
+#ifndef QT_BOOTSTRAPPED
+ void setTimeZone(const QTimeZone &toZone);
+#endif // QT_BOOTSTRAPPED
void setMSecsSinceEpoch(qint64 msecs);
+ // ### Qt 6: use quint64 instead of uint
void setTime_t(uint secsSince1Jan1970UTC);
+
#ifndef QT_NO_DATESTRING
QString toString(Qt::DateFormat f = Qt::TextDate) const;
QString toString(const QString &format) const;
@@ -232,9 +256,15 @@ public:
QDateTime addYears(int years) const;
QDateTime addSecs(qint64 secs) const;
QDateTime addMSecs(qint64 msecs) const;
+
QDateTime toTimeSpec(Qt::TimeSpec spec) const;
inline QDateTime toLocalTime() const { return toTimeSpec(Qt::LocalTime); }
inline QDateTime toUTC() const { return toTimeSpec(Qt::UTC); }
+ QDateTime toOffsetFromUtc(int offsetSeconds) const;
+#ifndef QT_BOOTSTRAPPED
+ QDateTime toTimeZone(const QTimeZone &toZone) const;
+#endif // QT_BOOTSTRAPPED
+
qint64 daysTo(const QDateTime &) const;
qint64 secsTo(const QDateTime &) const;
qint64 msecsTo(const QDateTime &) const;
@@ -246,8 +276,10 @@ public:
inline bool operator>(const QDateTime &other) const { return other < *this; }
inline bool operator>=(const QDateTime &other) const { return !(*this < other); }
- void setUtcOffset(int seconds);
- int utcOffset() const;
+#if QT_DEPRECATED_SINCE(5, 2)
+ QT_DEPRECATED void setUtcOffset(int seconds);
+ QT_DEPRECATED int utcOffset() const;
+#endif // QT_DEPRECATED_SINCE
static QDateTime currentDateTime();
static QDateTime currentDateTimeUtc();
@@ -255,8 +287,20 @@ public:
static QDateTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
static QDateTime fromString(const QString &s, const QString &format);
#endif
+ // ### Qt 6: use quint64 instead of uint
static QDateTime fromTime_t(uint secsSince1Jan1970UTC);
+ // ### Qt 6: Merge with above with default spec = Qt::LocalTime
+ static QDateTime fromTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec,
+ int offsetFromUtc = 0);
+#ifndef QT_BOOTSTRAPPED
+ static QDateTime fromTime_t(uint secsSince1Jan1970UTC, const QTimeZone &timeZone);
+#endif
static QDateTime fromMSecsSinceEpoch(qint64 msecs);
+ // ### Qt 6: Merge with above with default spec = Qt::LocalTime
+ static QDateTime fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetFromUtc = 0);
+#ifndef QT_BOOTSTRAPPED
+ static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone);
+#endif
static qint64 currentMSecsSinceEpoch() Q_DECL_NOTHROW;
private:
@@ -272,6 +316,10 @@ private:
friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &);
friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDateTime &);
#endif
+
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)
+ friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QDateTime &);
+#endif
};
Q_DECLARE_SHARED(QDateTime)
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index e99a67d..9dd0e61 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -509,6 +509,20 @@ private:
static void deleteNode2(QHashData::Node *node);
static void duplicateNode(QHashData::Node *originalNode, void *newNode);
+
+ bool isValidIterator(const iterator &it) const
+ {
+#if defined(QT_DEBUG) && !defined(Q_HASH_NO_ITERATOR_DEBUG)
+ QHashData::Node *node = it.i;
+ while (node->next)
+ node = node->next;
+ return (static_cast<void *>(node) == d);
+#else
+ Q_UNUSED(it);
+ return true;
+#endif
+ }
+ friend class QSet<Key>;
};
@@ -831,9 +845,27 @@ Q_OUTOFLINE_TEMPLATE T QHash<Key, T>::take(const Key &akey)
template <class Key, class T>
Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::erase(iterator it)
{
+ Q_ASSERT_X(isValidIterator(it), "QHash::erase", "The specified iterator argument 'it' is invalid");
+
if (it == iterator(e))
return it;
+ if (d->ref.isShared()) {
+ int bucketNum = (it.i->h % d->numBuckets);
+ iterator bucketIterator(*(d->buckets + bucketNum));
+ int stepsFromBucketStartToIte = 0;
+ while (bucketIterator != it) {
+ ++stepsFromBucketStartToIte;
+ ++bucketIterator;
+ }
+ detach();
+ it = iterator(*(d->buckets + bucketNum));
+ while (stepsFromBucketStartToIte > 0) {
+ --stepsFromBucketStartToIte;
+ ++it;
+ }
+ }
+
iterator ret = it;
++ret;
diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h
index b9ca1b9..79a62cb 100644
--- a/src/corelib/tools/qlinkedlist.h
+++ b/src/corelib/tools/qlinkedlist.h
@@ -48,6 +48,12 @@
#include <iterator>
#include <list>
+#include <algorithm>
+
+#if defined(Q_COMPILER_INITIALIZER_LISTS)
+# include <initializer_list>
+#endif
+
QT_BEGIN_NAMESPACE
@@ -78,6 +84,13 @@ class QLinkedList
public:
inline QLinkedList() : d(const_cast<QLinkedListData *>(&QLinkedListData::shared_null)) { }
inline QLinkedList(const QLinkedList<T> &l) : d(l.d) { d->ref.ref(); if (!d->sharable) detach(); }
+#if defined(Q_COMPILER_INITIALIZER_LISTS)
+ inline QLinkedList(std::initializer_list<T> list)
+ : d(const_cast<QLinkedListData *>(&QLinkedListData::shared_null))
+ {
+ std::copy(list.begin(), list.end(), std::back_inserter(*this));
+ }
+#endif
~QLinkedList();
QLinkedList<T> &operator=(const QLinkedList<T> &);
#ifdef Q_COMPILER_RVALUE_REFS
@@ -91,7 +104,7 @@ public:
inline int size() const { return d->size; }
inline void detach()
- { if (d->ref.isShared()) detach_helper(); }
+ { if (d->ref.isShared()) detach_helper2(this->e); }
inline bool isDetached() const { return !d->ref.isShared(); }
inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QLinkedListData::shared_null) d->sharable = sharable; }
inline bool isSharedWith(const QLinkedList<T> &other) const { return d == other.d; }
@@ -219,9 +232,9 @@ public:
typedef qptrdiff difference_type;
static inline QLinkedList<T> fromStdList(const std::list<T> &list)
- { QLinkedList<T> tmp; qCopy(list.begin(), list.end(), std::back_inserter(tmp)); return tmp; }
+ { QLinkedList<T> tmp; std::copy(list.begin(), list.end(), std::back_inserter(tmp)); return tmp; }
inline std::list<T> toStdList() const
- { std::list<T> tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
+ { std::list<T> tmp; std::copy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
// comfort
QLinkedList<T> &operator+=(const QLinkedList<T> &l);
@@ -232,6 +245,7 @@ public:
private:
void detach_helper();
+ iterator detach_helper2(iterator);
void freeData(QLinkedListData*);
};
@@ -245,6 +259,14 @@ inline QLinkedList<T>::~QLinkedList()
template <typename T>
void QLinkedList<T>::detach_helper()
{
+ detach_helper2(this->e);
+}
+
+template <typename T>
+typename QLinkedList<T>::iterator QLinkedList<T>::detach_helper2(iterator orgite)
+{
+ // detach and convert orgite to an iterator in the detached instance
+ bool isEndIterator = (orgite.i == this->e);
union { QLinkedListData *d; Node *e; } x;
x.d = new QLinkedListData;
x.d->ref.initializeOwned();
@@ -252,6 +274,22 @@ void QLinkedList<T>::detach_helper()
x.d->sharable = true;
Node *original = e->n;
Node *copy = x.e;
+ Node *org = orgite.i;
+
+ while (original != org) {
+ QT_TRY {
+ copy->n = new Node(original->t);
+ copy->n->p = copy;
+ original = original->n;
+ copy = copy->n;
+ } QT_CATCH(...) {
+ copy->n = x.e;
+ Q_ASSERT(!x.d->ref.deref()); // Don't trigger assert in free
+ freeData(x.d);
+ QT_RETHROW;
+ }
+ }
+ iterator r(copy);
while (original != e) {
QT_TRY {
copy->n = new Node(original->t);
@@ -270,6 +308,9 @@ void QLinkedList<T>::detach_helper()
if (!d->ref.deref())
freeData(d);
d = x.d;
+ if (!isEndIterator)
+ ++r; // since we stored the element right before the original node.
+ return r;
}
template <typename T>
@@ -376,7 +417,7 @@ template <typename T>
bool QLinkedList<T>::removeOne(const T &_t)
{
detach();
- iterator it = qFind(begin(), end(), _t);
+ iterator it = std::find(begin(), end(), _t);
if (it != end()) {
erase(it);
return true;
@@ -425,6 +466,9 @@ int QLinkedList<T>::count(const T &t) const
template <typename T>
typename QLinkedList<T>::iterator QLinkedList<T>::insert(iterator before, const T &t)
{
+ if (d->ref.isShared())
+ before = detach_helper2(before);
+
Node *i = before.i;
Node *m = new Node(t);
m->n = i;
@@ -448,7 +492,9 @@ typename QLinkedList<T>::iterator QLinkedList<T>::erase(typename QLinkedList<T>:
template <typename T>
typename QLinkedList<T>::iterator QLinkedList<T>::erase(iterator pos)
{
- detach();
+ if (d->ref.isShared())
+ pos = detach_helper2(pos);
+
Node *i = pos.i;
if (i != e) {
Node *n = i;
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 0592c24..333ce72 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -48,6 +48,7 @@
#include <iterator>
#include <list>
+#include <algorithm>
#ifdef Q_COMPILER_INITIALIZER_LISTS
#include <initializer_list>
#endif
@@ -123,7 +124,7 @@ public:
#ifdef Q_COMPILER_INITIALIZER_LISTS
inline QList(std::initializer_list<T> args)
: d(const_cast<QListData::Data *>(&QListData::shared_null))
- { qCopy(args.begin(), args.end(), std::back_inserter(*this)); }
+ { std::copy(args.begin(), args.end(), std::back_inserter(*this)); }
#endif
bool operator==(const QList<T> &l) const;
inline bool operator!=(const QList<T> &l) const { return !(*this == l); }
@@ -332,9 +333,9 @@ public:
static QList<T> fromSet(const QSet<T> &set);
static inline QList<T> fromStdList(const std::list<T> &list)
- { QList<T> tmp; qCopy(list.begin(), list.end(), std::back_inserter(tmp)); return tmp; }
+ { QList<T> tmp; std::copy(list.begin(), list.end(), std::back_inserter(tmp)); return tmp; }
inline std::list<T> toStdList() const
- { std::list<T> tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
+ { std::list<T> tmp; std::copy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
private:
Node *detach_helper_grow(int i, int n);
@@ -346,6 +347,11 @@ private:
void node_destruct(Node *n);
void node_copy(Node *from, Node *to, Node *src);
void node_destruct(Node *from, Node *to);
+
+ bool isValidIterator(const iterator &i) const
+ {
+ return (constBegin().i <= i.i) && (i.i <= constEnd().i);
+ }
};
#if defined(Q_CC_BOR)
@@ -433,8 +439,14 @@ Q_INLINE_TEMPLATE QList<T> &QList<T>::operator=(const QList<T> &l)
template <typename T>
inline typename QList<T>::iterator QList<T>::insert(iterator before, const T &t)
{
+ Q_ASSERT_X(isValidIterator(before), "QList::insert", "The specified iterator argument 'before' is invalid");
+
int iBefore = int(before.i - reinterpret_cast<Node *>(p.begin()));
- Node *n = reinterpret_cast<Node *>(p.insert(iBefore));
+ Node *n = 0;
+ if (d->ref.isShared())
+ n = detach_helper_grow(iBefore, 1);
+ else
+ n = reinterpret_cast<Node *>(p.insert(iBefore));
QT_TRY {
node_construct(n, t);
} QT_CATCH(...) {
@@ -445,8 +457,16 @@ inline typename QList<T>::iterator QList<T>::insert(iterator before, const T &t)
}
template <typename T>
inline typename QList<T>::iterator QList<T>::erase(iterator it)
-{ node_destruct(it.i);
- return reinterpret_cast<Node *>(p.erase(reinterpret_cast<void**>(it.i))); }
+{
+ Q_ASSERT_X(isValidIterator(it), "QList::erase", "The specified iterator argument 'it' is invalid");
+ if (d->ref.isShared()) {
+ int offset = int(it.i - reinterpret_cast<Node *>(p.begin()));
+ it = begin(); // implies detach()
+ it += offset;
+ }
+ node_destruct(it.i);
+ return reinterpret_cast<Node *>(p.erase(reinterpret_cast<void**>(it.i)));
+}
template <typename T>
inline const T &QList<T>::at(int i) const
{ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::at", "index out of range");
@@ -619,7 +639,7 @@ inline void QList<T>::move(int from, int to)
template<typename T>
Q_OUTOFLINE_TEMPLATE QList<T> QList<T>::mid(int pos, int alength) const
{
- if (alength < 0 || pos + alength > size())
+ if (alength < 0 || pos > size() - alength)
alength = size() - pos;
if (pos == 0 && alength == size())
return *this;
@@ -715,18 +735,14 @@ Q_OUTOFLINE_TEMPLATE QList<T>::QList(const QList<T> &l)
if (!d->ref.ref()) {
p.detach(d->alloc);
- struct Cleanup
- {
- Cleanup(QListData::Data *d) : d_(d) {}
- ~Cleanup() { if (d_) QListData::dispose(d_); }
-
- QListData::Data *d_;
- } tryCatch(d);
-
+ QT_TRY {
node_copy(reinterpret_cast<Node *>(p.begin()),
reinterpret_cast<Node *>(p.end()),
reinterpret_cast<Node *>(l.p.begin()));
- tryCatch.d_ = 0;
+ } QT_CATCH(...) {
+ QListData::dispose(d);
+ QT_RETHROW;
+ }
}
}
@@ -811,6 +827,19 @@ template <typename T>
Q_OUTOFLINE_TEMPLATE typename QList<T>::iterator QList<T>::erase(typename QList<T>::iterator afirst,
typename QList<T>::iterator alast)
{
+ Q_ASSERT_X(isValidIterator(afirst), "QList::erase", "The specified iterator argument 'afirst' is invalid");
+ Q_ASSERT_X(isValidIterator(alast), "QList::erase", "The specified iterator argument 'alast' is invalid");
+
+ if (d->ref.isShared()) {
+ // ### A block is erased and a detach is needed. We should shrink and only copy relevant items.
+ int offsetfirst = int(afirst.i - reinterpret_cast<Node *>(p.begin()));
+ int offsetlast = int(alast.i - reinterpret_cast<Node *>(p.begin()));
+ afirst = begin(); // implies detach()
+ alast = afirst;
+ afirst += offsetfirst;
+ alast += offsetlast;
+ }
+
for (Node *n = afirst.i; n < alast.i; ++n)
node_destruct(n);
int idx = afirst - begin();
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index 78fa336..0fc3f87 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -775,13 +775,14 @@ public:
SouthSudan = 254,
Bonaire = 255,
SintMaarten = 256,
+ Kosovo = 257,
DemocraticRepublicOfCongo = CongoKinshasa,
PeoplesRepublicOfCongo = CongoBrazzaville,
DemocraticRepublicOfKorea = NorthKorea,
RepublicOfKorea = SouthKorea,
RussianFederation = Russia,
SyrianArabRepublic = Syria,
- LastCountry = SintMaarten
+ LastCountry = Kosovo
};
// GENERATED PART ENDS HERE
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 449fcbc..db0cd6a 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -140,32 +140,32 @@ template <class Key, class T>
inline QMapNode<Key, T> *QMapNode<Key, T>::lowerBound(const Key &akey)
{
QMapNode<Key, T> *n = this;
- QMapNode<Key, T> *last = 0;
+ QMapNode<Key, T> *lastNode = 0;
while (n) {
if (!qMapLessThanKey(n->key, akey)) {
- last = n;
+ lastNode = n;
n = n->leftNode();
} else {
n = n->rightNode();
}
}
- return last;
+ return lastNode;
}
template <class Key, class T>
inline QMapNode<Key, T> *QMapNode<Key, T>::upperBound(const Key &akey)
{
QMapNode<Key, T> *n = this;
- QMapNode<Key, T> *last = 0;
+ QMapNode<Key, T> *lastNode = 0;
while (n) {
if (qMapLessThanKey(akey, n->key)) {
- last = n;
+ lastNode = n;
n = n->leftNode();
} else {
n = n->rightNode();
}
}
- return last;
+ return lastNode;
}
@@ -206,7 +206,7 @@ struct QMapData : public QMapDataBase
void deleteNode(Node *z);
Node *findNode(const Key &akey) const;
- void nodeRange(const Key &akey, Node **first, Node **last);
+ void nodeRange(const Key &akey, Node **firstNode, Node **lastNode);
Node *createNode(const Key &k, const T &v, Node *parent = 0, bool left = false)
{
@@ -288,15 +288,17 @@ void QMapData<Key, T>::deleteNode(QMapNode<Key, T> *z)
template <class Key, class T>
QMapNode<Key, T> *QMapData<Key, T>::findNode(const Key &akey) const
{
- Node *lb = root()->lowerBound(akey);
+ if (Node *r = root()) {
+ Node *lb = r->lowerBound(akey);
if (lb && !qMapLessThanKey(akey, lb->key))
return lb;
+ }
return 0;
}
template <class Key, class T>
-void QMapData<Key, T>::nodeRange(const Key &akey, QMapNode<Key, T> **first, QMapNode<Key, T> **last)
+void QMapData<Key, T>::nodeRange(const Key &akey, QMapNode<Key, T> **firstNode, QMapNode<Key, T> **lastNode)
{
Node *n = root();
Node *l = end();
@@ -307,16 +309,16 @@ void QMapData<Key, T>::nodeRange(const Key &akey, QMapNode<Key, T> **first, QMap
} else if (qMapLessThanKey(n->key, akey)) {
n = n->rightNode();
} else {
- *first = n->leftNode()->lowerBound(akey);
- if (!*first)
- *first = n;
- *last = n->rightNode()->upperBound(akey);
- if (!*last)
- *last = l;
+ *firstNode = n->leftNode() ? n->leftNode()->lowerBound(akey) : 0;
+ if (!*firstNode)
+ *firstNode = n;
+ *lastNode = n->rightNode() ? n->rightNode()->upperBound(akey) : 0;
+ if (!*lastNode)
+ *lastNode = l;
return;
}
}
- *first = *last = l;
+ *firstNode = *lastNode = l;
}
@@ -395,6 +397,14 @@ public:
QList<T> values(const Key &key) const;
int count(const Key &key) const;
+ inline const Key &firstKey() const { Q_ASSERT(!isEmpty()); return constBegin().key(); }
+ inline const Key &lastKey() const { Q_ASSERT(!isEmpty()); return (constEnd() - 1).key(); }
+
+ inline T &first() { Q_ASSERT(!isEmpty()); return *begin(); }
+ inline const T &first() const { Q_ASSERT(!isEmpty()); return *constBegin(); }
+ inline T &last() { Q_ASSERT(!isEmpty()); return *(end() - 1); }
+ inline const T &last() const { Q_ASSERT(!isEmpty()); return *(constEnd() - 1); }
+
class const_iterator;
class iterator
@@ -557,6 +567,18 @@ public:
private:
void detach_helper();
+ bool isValidIterator(const const_iterator &ci) const
+ {
+#if defined(QT_DEBUG) && !defined(Q_MAP_NO_ITERATOR_DEBUG)
+ const QMapNodeBase *n = ci.i;
+ while (n->parent())
+ n = n->parent();
+ return n->left == d->root();
+#else
+ Q_UNUSED(ci);
+ return true;
+#endif
+ }
};
template <class Key, class T>
@@ -621,12 +643,12 @@ Q_INLINE_TEMPLATE int QMap<Key, T>::count(const Key &akey) const
Node *lastNode;
d->nodeRange(akey, &firstNode, &lastNode);
- const_iterator first(firstNode);
- const const_iterator last(lastNode);
+ const_iterator ci_first(firstNode);
+ const const_iterator ci_last(lastNode);
int cnt = 0;
- while (first != last) {
+ while (ci_first != ci_last) {
++cnt;
- ++first;
+ ++ci_first;
}
return cnt;
}
@@ -643,12 +665,12 @@ Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::insert(const Key
detach();
Node *n = d->root();
Node *y = d->end();
- Node *last = 0;
+ Node *lastNode = 0;
bool left = true;
while (n) {
y = n;
if (!qMapLessThanKey(n->key, akey)) {
- last = n;
+ lastNode = n;
left = true;
n = n->leftNode();
} else {
@@ -656,9 +678,9 @@ Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::insert(const Key
n = n->rightNode();
}
}
- if (last && !qMapLessThanKey(akey, last->key)) {
- last->value = avalue;
- return iterator(last);
+ if (lastNode && !qMapLessThanKey(akey, lastNode->key)) {
+ lastNode->value = avalue;
+ return iterator(lastNode);
}
Node *z = d->createNode(akey, avalue, y, left);
return iterator(z);
@@ -670,6 +692,8 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insert(const_iterator pos, const K
if (d->ref.isShared())
return this->insert(akey, avalue);
+ Q_ASSERT_X(isValidIterator(pos), "QMap::insert", "The specified const_iterator argument 'it' is invalid");
+
if (pos == constEnd()) {
// Hint is that the Node is larger than (or equal to) the largest value.
Node *n = static_cast<Node *>(pos.i->left);
@@ -753,6 +777,8 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const_iterator pos, co
if (d->ref.isShared())
return this->insertMulti(akey, avalue);
+ Q_ASSERT_X(isValidIterator(pos), "QMap::insertMulti", "The specified const_iterator argument 'pos' is invalid");
+
if (pos == constEnd()) {
// Hint is that the Node is larger than (or equal to) the largest value.
Node *n = static_cast<Node *>(pos.i->left);
@@ -836,9 +862,9 @@ template <class Key, class T>
QPair<typename QMap<Key, T>::iterator, typename QMap<Key, T>::iterator> QMap<Key, T>::equal_range(const Key &akey)
{
detach();
- Node *first, *last;
- d->nodeRange(akey, &first, &last);
- return QPair<iterator, iterator>(iterator(first), iterator(last));
+ Node *firstNode, *lastNode;
+ d->nodeRange(akey, &firstNode, &lastNode);
+ return QPair<iterator, iterator>(iterator(firstNode), iterator(lastNode));
}
#ifdef Q_MAP_DEBUG
@@ -895,6 +921,29 @@ Q_OUTOFLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::erase(iterato
if (it == iterator(d->end()))
return it;
+ Q_ASSERT_X(isValidIterator(const_iterator(it)), "QMap::erase", "The specified iterator argument 'it' is invalid");
+
+ if (d->ref.isShared()) {
+ const_iterator oldBegin = constBegin();
+ const_iterator old = const_iterator(it);
+ int backStepsWithSameKey = 0;
+
+ while (old != oldBegin) {
+ --old;
+ if (qMapLessThanKey(old.key(), it.key()))
+ break;
+ ++backStepsWithSameKey;
+ }
+
+ it = find(old.key()); // ensures detach
+ Q_ASSERT_X(it != iterator(d->end()), "QMap::erase", "Unable to locate same key in erase after detach.");
+
+ while (backStepsWithSameKey > 0) {
+ ++it;
+ --backStepsWithSameKey;
+ }
+ }
+
Node *n = it.i;
++it;
d->deleteNode(n);
@@ -1005,7 +1054,7 @@ Q_OUTOFLINE_TEMPLATE QList<T> QMap<Key, T>::values(const Key &akey) const
template <class Key, class T>
Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator QMap<Key, T>::lowerBound(const Key &akey) const
{
- Node *lb = d->root()->lowerBound(akey);
+ Node *lb = d->root() ? d->root()->lowerBound(akey) : 0;
if (!lb)
lb = d->end();
return const_iterator(lb);
@@ -1015,7 +1064,7 @@ template <class Key, class T>
Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::lowerBound(const Key &akey)
{
detach();
- Node *lb = d->root()->lowerBound(akey);
+ Node *lb = d->root() ? d->root()->lowerBound(akey) : 0;
if (!lb)
lb = d->end();
return iterator(lb);
@@ -1025,7 +1074,7 @@ template <class Key, class T>
Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator
QMap<Key, T>::upperBound(const Key &akey) const
{
- Node *ub = d->root()->upperBound(akey);
+ Node *ub = d->root() ? d->root()->upperBound(akey) : 0;
if (!ub)
ub = d->end();
return const_iterator(ub);
@@ -1035,7 +1084,7 @@ template <class Key, class T>
Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::upperBound(const Key &akey)
{
detach();
- Node *ub = d->root()->upperBound(akey);
+ Node *ub = d->root() ? d->root()->upperBound(akey) : 0;
if (!ub)
ub = d->end();
return iterator(ub);
diff --git a/src/corelib/tools/qmargins.h b/src/corelib/tools/qmargins.h
index 0d68be9..ad5e94c 100644
--- a/src/corelib/tools/qmargins.h
+++ b/src/corelib/tools/qmargins.h
@@ -242,6 +242,24 @@ inline QMargins &QMargins::operator-=(const QMargins &margins)
return *this = *this - margins;
}
+inline QMargins &QMargins::operator+=(int margin)
+{
+ m_left += margin;
+ m_top += margin;
+ m_right += margin;
+ m_bottom += margin;
+ return *this;
+}
+
+inline QMargins &QMargins::operator-=(int margin)
+{
+ m_left -= margin;
+ m_top -= margin;
+ m_right -= margin;
+ m_bottom -= margin;
+ return *this;
+}
+
inline QMargins &QMargins::operator*=(int factor)
{
return *this = *this * factor;
diff --git a/src/corelib/tools/qpair.h b/src/corelib/tools/qpair.h
index 96b1b65..9b8691a 100644
--- a/src/corelib/tools/qpair.h
+++ b/src/corelib/tools/qpair.h
@@ -57,6 +57,19 @@ struct QPair
QPair(const T1 &t1, const T2 &t2) : first(t1), second(t2) {}
// compiler-generated copy/move ctor/assignment operators are fine!
+ template <typename TT1, typename TT2>
+ QPair(const QPair<TT1, TT2> &p) : first(p.first), second(p.second) {}
+ template <typename TT1, typename TT2>
+ QPair &operator=(const QPair<TT1, TT2> &p)
+ { first = p.first; second = p.second; return *this; }
+#ifdef Q_COMPILER_RVALUE_REFS
+ template <typename TT1, typename TT2>
+ QPair(QPair<TT1, TT2> &&p) : first(std::move(p.first)), second(std::move(p.second)) {}
+ template <typename TT1, typename TT2>
+ QPair &operator=(QPair<TT1, TT2> &&p)
+ { first = std::move(p.first); second = std::move(p.second); return *this; }
+#endif
+
T1 first;
T2 second;
};
diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h
index 2155c56..dd6e5bd 100644
--- a/src/corelib/tools/qscopedpointer.h
+++ b/src/corelib/tools/qscopedpointer.h
@@ -83,6 +83,17 @@ struct QScopedPointerPodDeleter
static inline void cleanup(void *pointer) { if (pointer) free(pointer); }
};
+#ifndef QT_NO_QOBJECT
+template <typename T>
+struct QScopedPointerObjectDeleteLater
+{
+ static inline void cleanup(T *pointer) { if (pointer) pointer->deleteLater(); }
+};
+
+class QObject;
+typedef QScopedPointerObjectDeleteLater<QObject> QScopedPointerDeleteLater;
+#endif
+
template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
class QScopedPointer
{
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index d5c3637..ad2f91b 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -70,6 +70,7 @@ public:
inline QSet<T> &operator=(const QSet<T> &other)
{ q_hash = other.q_hash; return *this; }
#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSet(QSet &&other) : q_hash(qMove(other.q_hash)) {}
inline QSet<T> &operator=(QSet<T> &&other)
{ qSwap(q_hash, other.q_hash); return *this; }
#endif
@@ -180,7 +181,10 @@ public:
inline const_iterator cend() const { return q_hash.end(); }
inline const_iterator constEnd() const { return q_hash.constEnd(); }
iterator erase(iterator i)
- { return q_hash.erase(reinterpret_cast<typename Hash::iterator &>(i)); }
+ {
+ Q_ASSERT_X(isValidIterator(i), "QSet::erase", "The specified const_iterator argument 'i' is invalid");
+ return q_hash.erase(reinterpret_cast<typename Hash::iterator &>(i));
+ }
// more Qt
typedef iterator Iterator;
@@ -233,6 +237,10 @@ public:
private:
Hash q_hash;
+ bool isValidIterator(const iterator &i) const
+ {
+ return q_hash.isValidIterator(reinterpret_cast<const typename Hash::iterator&>(i));
+ }
};
template <class T>
@@ -253,8 +261,16 @@ Q_INLINE_TEMPLATE QSet<T> &QSet<T>::unite(const QSet<T> &other)
template <class T>
Q_INLINE_TEMPLATE QSet<T> &QSet<T>::intersect(const QSet<T> &other)
{
- QSet<T> copy1(*this);
- QSet<T> copy2(other);
+ QSet<T> copy1;
+ QSet<T> copy2;
+ if (size() <= other.size()) {
+ copy1 = *this;
+ copy2 = other;
+ } else {
+ copy1 = other;
+ copy2 = *this;
+ *this = copy1;
+ }
typename QSet<T>::const_iterator i = copy1.constEnd();
while (i != copy1.constBegin()) {
--i;
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index 5e30cf3..1423449 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -506,7 +506,7 @@ public:
if (o) {
// increase the strongref, but never up from zero
// or less (-1 is used by QWeakPointer on untracked QObject)
- register int tmp = o->strongref.load();
+ int tmp = o->strongref.load();
while (tmp > 0) {
// try to increment from "tmp" to "tmp + 1"
if (o->strongref.testAndSetRelaxed(tmp, tmp + 1))
@@ -801,7 +801,7 @@ namespace QtSharedPointer {
template <class X, class T>
Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &src)
{
- register X *ptr = static_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
+ X *ptr = static_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
return QtSharedPointer::copyAndSetPointer(ptr, src);
}
template <class X, class T>
@@ -813,7 +813,7 @@ Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &sr
template <class X, class T>
Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src)
{
- register X *ptr = dynamic_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
+ X *ptr = dynamic_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
if (!ptr)
return QSharedPointer<X>();
return QtSharedPointer::copyAndSetPointer(ptr, src);
@@ -827,7 +827,7 @@ Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer
template <class X, class T>
Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src)
{
- register X *ptr = const_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
+ X *ptr = const_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
return QtSharedPointer::copyAndSetPointer(ptr, src);
}
template <class X, class T>
@@ -847,7 +847,7 @@ QWeakPointer<X> qWeakPointerCast(const QSharedPointer<T> &src)
template <class X, class T>
Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &src)
{
- register X *ptr = qobject_cast<X *>(src.data());
+ X *ptr = qobject_cast<X *>(src.data());
return QtSharedPointer::copyAndSetPointer(ptr, src);
}
template <class X, class T>
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index d8aaa92..2eaed65 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -64,8 +64,12 @@ namespace std
#error qstring.h must be included before any header file that defines truncate
#endif
-QT_BEGIN_NAMESPACE
+#ifdef Q_OS_MAC
+Q_FORWARD_DECLARE_OBJC_CLASS(NSString);
+Q_FORWARD_DECLARE_CF_TYPE(CFString);
+#endif
+QT_BEGIN_NAMESPACE
class QCharRef;
class QRegExp;
@@ -657,8 +661,12 @@ public:
const_iterator constEnd() const;
// STL compatibility
+ typedef int size_type;
+ typedef qptrdiff difference_type;
typedef const QChar & const_reference;
typedef QChar & reference;
+ typedef QChar *pointer;
+ typedef const QChar *const_pointer;
typedef QChar value_type;
inline void push_back(QChar c) { append(c); }
inline void push_back(const QString &s) { append(s); }
@@ -670,6 +678,12 @@ public:
static inline QString fromStdWString(const std::wstring &s);
inline std::wstring toStdWString() const;
+#if defined(Q_OS_MAC) || defined(Q_QDOC)
+ static QString fromCFString(CFStringRef string);
+ CFStringRef toCFString() const Q_DECL_CF_RETURNS_RETAINED;
+ static QString fromNSString(const NSString *string);
+ NSString *toNSString() const Q_DECL_NS_RETURNS_AUTORELEASED;
+#endif
// compatibility
struct Null { };
static const Null null;
@@ -920,8 +934,8 @@ inline QString::~QString() { if (!d->ref.deref()) Data::deallocate(d); }
inline void QString::reserve(int asize)
{
- if (d->ref.isShared() || uint(asize) + 1u > d->alloc)
- reallocData(uint(asize) + 1u);
+ if (d->ref.isShared() || uint(asize) >= d->alloc)
+ reallocData(qMax(asize, d->size) + 1u);
if (!d->capacityReserved) {
// cannot set unconditionally, since d could be the shared_null/shared_empty (which is const)
@@ -1222,6 +1236,10 @@ public:
int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int count(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ QStringRef left(int n) const Q_REQUIRED_RESULT;
+ QStringRef right(int n) const Q_REQUIRED_RESULT;
+ QStringRef mid(int pos, int n = -1) const Q_REQUIRED_RESULT;
+
bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool startsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool startsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 3a20280..309d2a2 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -49,6 +49,7 @@
#include <new>
#include <string.h>
#include <stdlib.h>
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -192,11 +193,18 @@ private:
qint64 q_for_alignment_1;
double q_for_alignment_2;
};
+
+ bool isValidIterator(const const_iterator &i) const
+ {
+ return (i <= constEnd()) && (constBegin() <= i);
+ }
};
template <class T, int Prealloc>
Q_INLINE_TEMPLATE QVarLengthArray<T, Prealloc>::QVarLengthArray(int asize)
: s(asize) {
+ Q_STATIC_ASSERT_X(Prealloc > 0, "QVarLengthArray Prealloc must be greater than 0.");
+ Q_ASSERT_X(s >= 0, "QVarLengthArray::QVarLengthArray()", "Size must be greater than or equal to 0.");
if (s > Prealloc) {
ptr = reinterpret_cast<T *>(malloc(s * sizeof(T)));
Q_CHECK_PTR(ptr);
@@ -310,7 +318,7 @@ Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::realloc(int asize, int a
template <class T, int Prealloc>
Q_OUTOFLINE_TEMPLATE T QVarLengthArray<T, Prealloc>::value(int i) const
{
- if (i < 0 || i >= size()) {
+ if (uint(i) >= uint(size())) {
return T();
}
return at(i);
@@ -318,7 +326,7 @@ Q_OUTOFLINE_TEMPLATE T QVarLengthArray<T, Prealloc>::value(int i) const
template <class T, int Prealloc>
Q_OUTOFLINE_TEMPLATE T QVarLengthArray<T, Prealloc>::value(int i, const T &defaultValue) const
{
- return (i < 0 || i >= size()) ? defaultValue : at(i);
+ return (uint(i) >= uint(size())) ? defaultValue : at(i);
}
template <class T, int Prealloc>
@@ -353,6 +361,8 @@ inline void QVarLengthArray<T, Prealloc>::replace(int i, const T &t)
template <class T, int Prealloc>
Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, size_type n, const T &t)
{
+ Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid");
+
int offset = int(before - ptr);
if (n != 0) {
resize(s + n);
@@ -380,11 +390,14 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
template <class T, int Prealloc>
Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::erase(const_iterator abegin, const_iterator aend)
{
+ Q_ASSERT_X(isValidIterator(abegin), "QVarLengthArray::insert", "The specified const_iterator argument 'abegin' is invalid");
+ Q_ASSERT_X(isValidIterator(aend), "QVarLengthArray::insert", "The specified const_iterator argument 'aend' is invalid");
+
int f = int(abegin - ptr);
int l = int(aend - ptr);
int n = l - f;
if (QTypeInfo<T>::isComplex) {
- qCopy(ptr + l, ptr + s, ptr + f);
+ std::copy(ptr + l, ptr + s, ptr + f);
T *i = ptr + s;
T *b = ptr + s - n;
while (i != b) {
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 816e1f1..f56511e 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -56,6 +56,8 @@
#include <initializer_list>
#endif
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
class QRegion;
@@ -150,6 +152,11 @@ public:
bool contains(const T &t) const;
int count(const T &t) const;
+ // QList compatibility
+ void removeAt(int i) { remove(i); }
+ int length() const { return size(); }
+ T takeAt(int i) { T t = at(i); remove(i); return t; }
+
// STL-style
typedef typename Data::iterator iterator;
typedef typename Data::const_iterator const_iterator;
@@ -185,7 +192,7 @@ public:
inline const T &last() const { Q_ASSERT(!isEmpty()); return *(end()-1); }
inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; }
inline bool endsWith(const T &t) const { return !isEmpty() && last() == t; }
- QVector<T> mid(int pos, int length = -1) const;
+ QVector<T> mid(int pos, int len = -1) const;
T value(int i) const;
T value(int i, const T &defaultValue) const;
@@ -227,18 +234,22 @@ public:
static QVector<T> fromList(const QList<T> &list);
static inline QVector<T> fromStdVector(const std::vector<T> &vector)
- { QVector<T> tmp; tmp.reserve(int(vector.size())); qCopy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; }
+ { QVector<T> tmp; tmp.reserve(int(vector.size())); std::copy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; }
inline std::vector<T> toStdVector() const
- { std::vector<T> tmp; tmp.reserve(size()); qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
+ { std::vector<T> tmp; tmp.reserve(size()); std::copy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
private:
friend class QRegion; // Optimization for QRegion::rects()
void reallocData(const int size, const int alloc, QArrayData::AllocationOptions options = QArrayData::Default);
+ void reallocData(const int sz) { reallocData(sz, d->alloc); }
void freeData(Data *d);
void defaultConstruct(T *from, T *to);
void copyConstruct(const T *srcFrom, const T *srcTo, T *dstFrom);
void destruct(T *from, T *to);
-
+ bool isValidIterator(const iterator &i) const
+ {
+ return (i <= d->end()) && (d->begin() <= i);
+ }
class AlignmentDummy { Data header; T array[1]; };
};
@@ -398,7 +409,8 @@ QVector<T> &QVector<T>::operator=(const QVector<T> &v)
template <typename T>
QVector<T>::QVector(int asize)
{
- if (Q_LIKELY(asize)) {
+ Q_ASSERT_X(asize >= 0, "QVector::QVector", "Size must be greater than or equal to 0.");
+ if (Q_LIKELY(asize > 0)) {
d = Data::allocate(asize);
d->size = asize;
defaultConstruct(d->begin(), d->end());
@@ -410,7 +422,8 @@ QVector<T>::QVector(int asize)
template <typename T>
QVector<T>::QVector(int asize, const T &t)
{
- if (asize) {
+ Q_ASSERT_X(asize >= 0, "QVector::QVector", "Size must be greater than or equal to 0.");
+ if (asize > 0) {
d = Data::allocate(asize);
d->size = asize;
T* i = d->end();
@@ -530,7 +543,7 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo
template<typename T>
Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i) const
{
- if (i < 0 || i >= d->size) {
+ if (uint(i) >= uint(d->size)) {
return T();
}
return d->begin()[i];
@@ -538,7 +551,7 @@ Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i) const
template<typename T>
Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i, const T &defaultValue) const
{
- return ((i < 0 || i >= d->size) ? defaultValue : d->begin()[i]);
+ return uint(i) >= uint(d->size) ? defaultValue : d->begin()[i];
}
template <typename T>
@@ -558,24 +571,25 @@ void QVector<T>::append(const T &t)
}
template <typename T>
-inline void QVector<T>::removeLast()
+void QVector<T>::removeLast()
{
Q_ASSERT(!isEmpty());
+ Q_ASSERT(d->alloc);
- if (d->alloc) {
- if (d->ref.isShared()) {
- reallocData(d->size - 1, int(d->alloc));
- return;
- }
- if (QTypeInfo<T>::isComplex)
- (d->data() + d->size - 1)->~T();
+ if (!d->ref.isShared()) {
--d->size;
+ if (QTypeInfo<T>::isComplex)
+ (d->data() + d->size)->~T();
+ } else {
+ reallocData(d->size - 1);
}
}
template <typename T>
typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, const T &t)
{
+ Q_ASSERT_X(isValidIterator(before), "QVector::insert", "The specified iterator argument 'before' is invalid");
+
int offset = std::distance(d->begin(), before);
if (n != 0) {
const T copy(t);
@@ -609,6 +623,9 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c
template <typename T>
typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
{
+ Q_ASSERT_X(isValidIterator(abegin), "QVector::erase", "The specified iterator argument 'abegin' is invalid");
+ Q_ASSERT_X(isValidIterator(aend), "QVector::erase", "The specified iterator argument 'aend' is invalid");
+
const int itemsToErase = aend - abegin;
if (!itemsToErase)
@@ -632,7 +649,7 @@ typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
iterator moveEnd = d->end();
while (moveBegin != moveEnd) {
if (QTypeInfo<T>::isComplex)
- abegin->~T();
+ static_cast<T *>(abegin)->~T();
new (abegin++) T(*moveBegin++);
}
if (abegin < d->end()) {
@@ -760,17 +777,17 @@ int QVector<T>::count(const T &t) const
}
template <typename T>
-Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int length) const
+Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int len) const
{
- if (length < 0)
- length = size() - pos;
- if (pos == 0 && length == size())
+ if (len < 0)
+ len = size() - pos;
+ if (pos == 0 && len == size())
return *this;
- if (pos + length > size())
- length = size() - pos;
+ if (pos + len > size())
+ len = size() - pos;
QVector<T> copy;
- copy.reserve(length);
- for (int i = pos; i < pos + length; ++i)
+ copy.reserve(len);
+ for (int i = pos; i < pos + len; ++i)
copy += at(i);
return copy;
}