summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qjniarray.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qjniarray.h')
-rw-r--r--src/corelib/kernel/qjniarray.h52
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)
{