diff options
Diffstat (limited to 'src/corelib/kernel/qjniarray.h')
-rw-r--r-- | src/corelib/kernel/qjniarray.h | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/src/corelib/kernel/qjniarray.h b/src/corelib/kernel/qjniarray.h index 976b4e92e3..e3e9d0c4dc 100644 --- a/src/corelib/kernel/qjniarray.h +++ b/src/corelib/kernel/qjniarray.h @@ -18,7 +18,7 @@ QT_BEGIN_NAMESPACE template <typename T> class QJniArray; template <typename T> -struct QJniArrayIterator +struct QT_TECH_PREVIEW_API QJniArrayIterator { QJniArrayIterator() = default; @@ -86,16 +86,16 @@ private: {} }; -class QJniArrayBase +class QT_TECH_PREVIEW_API QJniArrayBase { // for SFINAE'ing out the fromContainer named constructor - template <typename Container, typename = void> struct CanConvertHelper : std::false_type {}; - template <typename Container> - struct CanConvertHelper<Container, std::void_t<decltype(std::data(std::declval<Container>())), - decltype(std::size(std::declval<Container>())), - typename Container::value_type - > - > : std::true_type {}; + template <typename C, typename = void> struct IsContiguousContainerHelper : std::false_type {}; + template <typename C> + struct IsContiguousContainerHelper<C, std::void_t<decltype(std::data(std::declval<C>())), + decltype(std::size(std::declval<C>())), + typename C::value_type + > + > : std::true_type {}; public: using size_type = jsize; @@ -114,13 +114,12 @@ public: return 0; } - template <typename Container> - static constexpr bool canConvert = CanConvertHelper<q20::remove_cvref_t<Container>>::value; - template <typename Container> - using IfCanConvert = std::enable_if_t<canConvert<Container>, bool>; - template <typename Container - , IfCanConvert<Container> = true - > + template <typename C> + static constexpr bool isContiguousContainer = IsContiguousContainerHelper<q20::remove_cvref_t<C>>::value; + template <typename C> + using if_contiguous_container = std::enable_if_t<isContiguousContainer<C>, bool>; + + template <typename Container, if_contiguous_container<Container> = true> static auto fromContainer(Container &&container) { Q_ASSERT_X(size_t(std::size(container)) <= size_t((std::numeric_limits<size_type>::max)()), @@ -193,7 +192,7 @@ private: }; template <typename T> -class QJniArray : public QJniArrayBase +class QT_TECH_PREVIEW_API QJniArray : public QJniArrayBase { friend struct QJniArrayIterator<T>; public: @@ -218,23 +217,21 @@ public: QJniArray &operator=(const QJniArray &other) = default; QJniArray &operator=(QJniArray &&other) noexcept = default; - template <typename Container - , IfCanConvert<Container> = true - > + template <typename Container, if_contiguous_container<Container> = true> explicit QJniArray(Container &&container) : QJniArrayBase(QJniArrayBase::fromContainer(std::forward<Container>(container))) { } - template <typename E = T - , IfCanConvert<std::initializer_list<E>> = true - > Q_IMPLICIT inline QJniArray(std::initializer_list<T> list) : QJniArrayBase(QJniArrayBase::fromContainer(list)) { } - template <typename Other, std::enable_if_t<std::is_convertible_v<Other, Type>, bool> = true> + template <typename Other> + using if_convertible = std::enable_if_t<std::is_convertible_v<Other, T>, bool>; + + template <typename Other, if_convertible<Other> = true> QJniArray(QJniArray<Other> &&other) : QJniArrayBase(std::forward<QJniArray<Other>>(other)) { @@ -366,6 +363,13 @@ public: } }; +// Deduction guide so that we can construct as 'QJniArray list(Container<T>)'. Since +// fromContainer() maps several C++ types to the same JNI type (e.g. both jboolean and +// bool become QJniArray<jboolean>), we have to deduce to what fromContainer() would +// give us. +template <typename Container, QJniArrayBase::if_contiguous_container<Container> = true> +QJniArray(Container) -> QJniArray<typename decltype(QJniArrayBase::fromContainer(std::declval<Container>()))::value_type>; + template <typename ElementType, typename List, typename NewFn, typename SetFn> auto QJniArrayBase::makeArray(List &&list, NewFn &&newArray, SetFn &&setRegion) { |