summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetatype.h
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2020-03-12 16:25:31 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2020-03-18 09:54:19 +0100
commit6db55e3451e8ba244e9f2555713d44d988977871 (patch)
tree866b5475769d49a9a93cee483fc5ea6e6dfe6b87 /src/corelib/kernel/qmetatype.h
parent943cb0999dbbf1da99c1358b81ea3298ee116447 (diff)
QSequentialIterable: Treat sets as appendable
QSet and std::(unordered_)set were so far not treated as appendable, as they lack a push_back method. We do however need support for this in declarative to enable converting back from QJSValue arrays to sets. We achieve this by testing for and using the insert method. While vector has also such a method, it doesn't take a single value, but rather a position or iterator + value, so the template specialization is not ambiguous. Task-number: QTBUG-82743 Change-Id: I74fc7b1b856d9bcd38100b274ba2b69578ea8bbb Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/corelib/kernel/qmetatype.h')
-rw-r--r--src/corelib/kernel/qmetatype.h18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 59ec8de0e9..7c22ff1693 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -1014,6 +1014,24 @@ struct ContainerCapabilitiesImpl<Container, decltype(std::declval<Container>().p
{ static_cast<Container *>(const_cast<void *>(container))->push_back(*static_cast<const typename Container::value_type *>(value)); }
};
+namespace QtPrivate {
+namespace ContainerCapabilitiesMetaProgrammingHelper {
+ template<typename... Ts>
+ using void_t = void;
+}
+}
+
+template<typename Container>
+struct ContainerCapabilitiesImpl<Container, QtPrivate::ContainerCapabilitiesMetaProgrammingHelper::void_t<decltype(std::declval<Container>().insert(std::declval<typename Container::value_type>())), decltype(std::declval<typename Container::value_type>() == std::declval<typename Container::value_type>())>>
+{
+ enum {ContainerCapabilities = ContainerIsAppendable};
+
+ // The code below invokes undefined behavior if and only if the pointer passed into QSequentialIterableImpl
+ // pointed to a const object to begin with
+ static void appendImpl(const void *container, const void *value)
+ { static_cast<Container *>(const_cast<void *>(container))->insert(*static_cast<const typename Container::value_type *>(value)); }
+};
+
template<typename T, typename Category = typename std::iterator_traits<typename T::const_iterator>::iterator_category>
struct CapabilitiesImpl;