summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/global/qtypeinfo.h19
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp9
2 files changed, 22 insertions, 6 deletions
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index 9b85a41266..be21526339 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -41,6 +41,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qcontainerfwd.h>
#include <variant>
+#include <optional>
#ifndef QTYPEINFO_H
#define QTYPEINFO_H
@@ -342,12 +343,16 @@ namespace QTypeTraits
*/
namespace detail {
-// find out whether T has a value_type typedef
+// find out whether T is a conteiner
// this is required to check the value type of containers for the existence of the comparison operator
template <typename, typename = void>
-struct has_value_type : std::false_type {};
+struct is_container : std::false_type {};
template <typename T>
-struct has_value_type<T, std::void_t<typename T::value_type>> : std::true_type {};
+struct is_container<T, std::void_t<
+ std::is_convertible<decltype(std::declval<T>().begin() != std::declval<T>().end()), bool>,
+ typename T::value_type
+>> : std::true_type {};
+
// Checks the existence of the comparison operator for the class itself
template <typename, typename = void>
@@ -357,7 +362,7 @@ struct has_operator_equal<T, std::void_t<decltype(bool(std::declval<const T&>()
: std::true_type {};
// Two forward declarations
-template<typename T, bool = has_value_type<T>::value>
+template<typename T, bool = is_container<T>::value>
struct expand_operator_equal_container;
template<typename T>
struct expand_operator_equal_tuple;
@@ -366,7 +371,7 @@ struct expand_operator_equal_tuple;
template<typename T>
using expand_operator_equal = expand_operator_equal_container<T>;
-// if T doesn't have a value_type member check if it's a tuple like object
+// if T isn't a container check if it's a tuple like object
template<typename T, bool>
struct expand_operator_equal_container : expand_operator_equal_tuple<T> {};
// if T::value_type exists, check first T::value_type, then T itself
@@ -380,6 +385,8 @@ using expand_operator_equal_recursive = std::conjunction<expand_operator_equal<T
template<typename T>
struct expand_operator_equal_tuple : has_operator_equal<T> {};
+template<typename T>
+struct expand_operator_equal_tuple<std::optional<T>> : has_operator_equal<T> {};
template<typename T1, typename T2>
struct expand_operator_equal_tuple<std::pair<T1, T2>> : expand_operator_equal_recursive<T1, T2> {};
template<typename ...T>
@@ -394,7 +401,7 @@ template <typename T>
struct has_operator_less_than<T, std::void_t<decltype(bool(std::declval<const T&>() < std::declval<const T&>()))>>
: std::true_type{};
-template<typename T, bool = has_value_type<T>::value>
+template<typename T, bool = is_container<T>::value>
struct expand_operator_less_than_container;
template<typename T>
struct expand_operator_less_than_tuple;
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
index 35d3f433ec..3d729eae67 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -101,6 +101,11 @@ static_assert(!QTypeTraits::has_operator_less_than_v<QHash<int, QString>>);
static_assert(!QTypeTraits::has_operator_equal_v<QHash<int, NoOperators>>);
static_assert(!QTypeTraits::has_operator_less_than_v<QHash<int, NoOperators>>);
+// QSharedPointer
+static_assert(QTypeTraits::has_operator_equal_v<QSharedPointer<QString>>);
+// smart pointer equality doesn't depend on T
+static_assert(QTypeTraits::has_operator_equal_v<QSharedPointer<NoOperators>>);
+
// std::vector
static_assert(QTypeTraits::has_operator_equal_v<std::vector<QString>>);
static_assert(QTypeTraits::has_operator_less_than_v<std::vector<QString>>);
@@ -127,6 +132,10 @@ static_assert(QTypeTraits::has_operator_less_than_v<std::map<int, QString>>);
static_assert(!QTypeTraits::has_operator_equal_v<std::map<int, NoOperators>>);
static_assert(!QTypeTraits::has_operator_less_than_v<std::map<int, NoOperators>>);
+// std::optional
+static_assert(QTypeTraits::has_operator_equal_v<std::optional<QString>>);
+static_assert(!QTypeTraits::has_operator_equal_v<std::optional<NoOperators>>);
+
// nested types
static_assert(QTypeTraits::has_operator_equal_v<Nested>);
static_assert(!QTypeTraits::has_operator_less_than_v<Nested>);