JNI: clean up SFINAE constraints in QJniArray
Rename the predictate for checking whether a container type has the required member functions and types to IfContiguousContainer (we need size(), data(), and value_type members). And since std::initializer_list always meets that criteria, remove the constraint from the respective constructor. Add an IfConvertible predicate to test whether the element type of an existing array can be converted to the element type of the new array. Change-Id: I7e5ba31de9664088b027c277c068c948f2189238 Reviewed-by: Marc Mutz <marc.mutz@qt.io> (cherry picked from commit 468126d34a8c3a2fdd486768f935d13ebe565dd0) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
a2b442fef8
commit
4ef415825c
@ -89,13 +89,13 @@ private:
|
|||||||
class QT_TECH_PREVIEW_API QJniArrayBase
|
class QT_TECH_PREVIEW_API QJniArrayBase
|
||||||
{
|
{
|
||||||
// for SFINAE'ing out the fromContainer named constructor
|
// for SFINAE'ing out the fromContainer named constructor
|
||||||
template <typename Container, typename = void> struct CanConvertHelper : std::false_type {};
|
template <typename C, typename = void> struct IsContiguousContainerHelper : std::false_type {};
|
||||||
template <typename Container>
|
template <typename C>
|
||||||
struct CanConvertHelper<Container, std::void_t<decltype(std::data(std::declval<Container>())),
|
struct IsContiguousContainerHelper<C, std::void_t<decltype(std::data(std::declval<C>())),
|
||||||
decltype(std::size(std::declval<Container>())),
|
decltype(std::size(std::declval<C>())),
|
||||||
typename Container::value_type
|
typename C::value_type
|
||||||
>
|
>
|
||||||
> : std::true_type {};
|
> : std::true_type {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using size_type = jsize;
|
using size_type = jsize;
|
||||||
@ -114,13 +114,12 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Container>
|
template <typename C>
|
||||||
static constexpr bool canConvert = CanConvertHelper<q20::remove_cvref_t<Container>>::value;
|
static constexpr bool isContiguousContainer = IsContiguousContainerHelper<q20::remove_cvref_t<C>>::value;
|
||||||
template <typename Container>
|
template <typename C>
|
||||||
using IfCanConvert = std::enable_if_t<canConvert<Container>, bool>;
|
using if_contiguous_container = std::enable_if_t<isContiguousContainer<C>, bool>;
|
||||||
template <typename Container
|
|
||||||
, IfCanConvert<Container> = true
|
template <typename Container, if_contiguous_container<Container> = true>
|
||||||
>
|
|
||||||
static auto fromContainer(Container &&container)
|
static auto fromContainer(Container &&container)
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(size_t(std::size(container)) <= size_t((std::numeric_limits<size_type>::max)()),
|
Q_ASSERT_X(size_t(std::size(container)) <= size_t((std::numeric_limits<size_type>::max)()),
|
||||||
@ -218,23 +217,21 @@ public:
|
|||||||
QJniArray &operator=(const QJniArray &other) = default;
|
QJniArray &operator=(const QJniArray &other) = default;
|
||||||
QJniArray &operator=(QJniArray &&other) noexcept = default;
|
QJniArray &operator=(QJniArray &&other) noexcept = default;
|
||||||
|
|
||||||
template <typename Container
|
template <typename Container, if_contiguous_container<Container> = true>
|
||||||
, IfCanConvert<Container> = true
|
|
||||||
>
|
|
||||||
explicit QJniArray(Container &&container)
|
explicit QJniArray(Container &&container)
|
||||||
: QJniArrayBase(QJniArrayBase::fromContainer(std::forward<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)
|
Q_IMPLICIT inline QJniArray(std::initializer_list<T> list)
|
||||||
: QJniArrayBase(QJniArrayBase::fromContainer(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)
|
QJniArray(QJniArray<Other> &&other)
|
||||||
: QJniArrayBase(std::forward<QJniArray<Other>>(other))
|
: QJniArrayBase(std::forward<QJniArray<Other>>(other))
|
||||||
{
|
{
|
||||||
|
@ -822,7 +822,7 @@ auto QJniObject::LocalFrame<Args...>::convertToJni(T &&value)
|
|||||||
return newLocalRef<jstring>(QJniObject::fromString(value));
|
return newLocalRef<jstring>(QJniObject::fromString(value));
|
||||||
} else if constexpr (QtJniTypes::IsJniArray<Type>::value) {
|
} else if constexpr (QtJniTypes::IsJniArray<Type>::value) {
|
||||||
return value.arrayObject();
|
return value.arrayObject();
|
||||||
} else if constexpr (QJniArrayBase::canConvert<T>) {
|
} else if constexpr (QJniArrayBase::isContiguousContainer<T>) {
|
||||||
using QJniArrayType = decltype(QJniArrayBase::fromContainer(std::forward<T>(value)));
|
using QJniArrayType = decltype(QJniArrayBase::fromContainer(std::forward<T>(value)));
|
||||||
using ArrayType = decltype(std::declval<QJniArrayType>().arrayObject());
|
using ArrayType = decltype(std::declval<QJniArrayType>().arrayObject());
|
||||||
return newLocalRef<ArrayType>(QJniArrayBase::fromContainer(std::forward<T>(value)).template object<jobject>());
|
return newLocalRef<ArrayType>(QJniArrayBase::fromContainer(std::forward<T>(value)).template object<jobject>());
|
||||||
@ -843,7 +843,7 @@ auto QJniObject::LocalFrame<Args...>::convertFromJni(QJniObject &&object)
|
|||||||
return object.toString();
|
return object.toString();
|
||||||
} else if constexpr (QtJniTypes::IsJniArray<Type>::value) {
|
} else if constexpr (QtJniTypes::IsJniArray<Type>::value) {
|
||||||
return T(std::move(object));
|
return T(std::move(object));
|
||||||
} else if constexpr (QJniArrayBase::canConvert<Type>) {
|
} else if constexpr (QJniArrayBase::isContiguousContainer<Type>) {
|
||||||
// if we were to create a QJniArray from Type...
|
// if we were to create a QJniArray from Type...
|
||||||
using QJniArrayType = decltype(QJniArrayBase::fromContainer(std::declval<Type>()));
|
using QJniArrayType = decltype(QJniArrayBase::fromContainer(std::declval<Type>()));
|
||||||
// then that QJniArray would have elements of type
|
// then that QJniArray would have elements of type
|
||||||
|
Loading…
x
Reference in New Issue
Block a user