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
|
||||
{
|
||||
// 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)()),
|
||||
@ -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))
|
||||
{
|
||||
|
@ -822,7 +822,7 @@ auto QJniObject::LocalFrame<Args...>::convertToJni(T &&value)
|
||||
return newLocalRef<jstring>(QJniObject::fromString(value));
|
||||
} else if constexpr (QtJniTypes::IsJniArray<Type>::value) {
|
||||
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 ArrayType = decltype(std::declval<QJniArrayType>().arrayObject());
|
||||
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();
|
||||
} else if constexpr (QtJniTypes::IsJniArray<Type>::value) {
|
||||
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...
|
||||
using QJniArrayType = decltype(QJniArrayBase::fromContainer(std::declval<Type>()));
|
||||
// then that QJniArray would have elements of type
|
||||
|
Loading…
x
Reference in New Issue
Block a user