// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \class QJniArrayBase \brief The QJniArrayBase class provides common, type-independent APIs for QJniArray. \inmodule QtCore \ingroup frameworks-technologies \since 6.8 */ /*! \typedef QJniArrayBase::size_type A 32 bit integer. */ /*! \fn template > auto QJniArrayBase::fromContainer(Container &&container) Creates a Java array holding the data in \a container, and returns a QJniArray instance that wraps it. //! [forward-iterable-containers] \constraints \c{Container} is a container that stores elements of a \l{JNI types}{JNI type} or equivalent C++ type, and provides a forward iterator. The specialization of the constructed QJniArray depends on the value type of the \a container. For a \c{Container} (such as e.g. \c{QList}) it will typically be \c{QJniArray}, with the following exceptions: \table \header \li Container \li Specialization \row \li QByteArray \li QJniArray \row \li QStringList \li QJniArray \header \li Container::value_type \li Specialization \row \li QJniObject \li QJniArray \endtable //! [forward-iterable-containers] \sa QJniArray::toContainer() */ /*! \fn QJniArrayBase::operator QJniObject() const \return a QJniObject wrapping the same \c{jobject} as this QJniArray instance. */ /*! \fn void QJniArrayBase::swap(QJniArrayBase &other) \memberswap{array object} */ /*! \fn template T QJniArrayBase::object() const \return the object held by the QJniArray as type T, which can be one of the \l {QJniObject#Object Types}{JNI Object Types}. */ /*! \fn bool QJniArrayBase::isValid() const \return whether the QJniArray object wraps a valid `jobject`. For invalid QJniArray instances, object() returns \nullptr. Iterating over an invalid object is safe (begin() will return the same as end()), and calling \l{QJniArray::}{toContainer()} on an invalid array will return an empty container. \sa QJniObject::isValid(), object(), QJniArray::toContainer() */ /*! \fn bool QJniArrayBase::isEmpty() const \return \c true if the array has size 0; otherwise returns \c false. An \l{isValid}{invalid} array is always empty. \c isValid(), size() */ /*! \fn QJniArrayBase::size_type QJniArrayBase::size() const \return the size of the array. */ /*! \class QJniArray \brief The QJniArray class is a template class that represents an array in Java. \inmodule QtCore \ingroup frameworks-technologies \since 6.8 The QJniArray template makes it easy to work with Java methods that return or take a Java array. \note \l{Java arrays} can hold primitive types and objects. The array itself can be treated like a Java Object, and the JNI framework provides explicit APIs to work with such arrays. In addition, the Java class library provides container types such as \c{List} or \c{ArrayList}. Objects of those types can not be represented by a QJniArray. Instead, use QJniObject to call the class-specific member functions. To create a QJniArray instance, either construct it from a corresponding C++ container: \code QList intList; const QJniArray intArray = QJniArray(intList); \endcode or from an initializer list: \code const QJniArray intArray{1, 2, 3}; \endcode QJniArray will create a new Java array and copy the C++-side data into it. When calling functions that return an array via QJniObject::callMethod, such as \c{char[] toCharArray()} in the Java \c{String} class, specify the return type as a C array (\c{jchar[]} in the following): \code const auto charArray = stringObject.callMethod("toCharArray"); \endcode The \c{charArray} variable will be of type \c{QJniArray}, and hold a new global reference to the \c{jcharArray} JNI object. Note that the arrays in the code snippets above are all const. Accessing elements in a const array is considerably more efficient than operating on a mutable array. A QJniArray can also be constructed from an existing \c{jarray} or QJniObject. However, note that no type checking is performed to verify that the \c{jarray} or QJniObject indeed represents an array holding elements of the specified type, and accessing a mismatching QJniArray results in undefined behavior. The data in a QJniArray can either be accessed element by element using at() or \l{QJniArray::}{operator[]()}, or iterated over. \code for (const auto &value : array) process(value); \endcode To copy the entire array into a C++ side Qt container, use the toContainer() function. \code const auto bytes = object.callMethod("getBytes"); QByteArray data = bytes.toContainer(); \endcode which happens implicitly in \code const auto data = object.callMethod("getBytes"); \endcode The return type of toContainer() depends on the type that QJniArray has been instantiated with. //! [type-mapping] For \c{QJniArray} this will typically be \c{QList}, with the following exceptions: \table \header \li Specialization \li C++ type \row \li QJniArray \li QByteArray \row \li QJniArray \li QByteArray \row \li QJniArray \li QStringList \row \li QJniArray \li QStringList \endtable //! [type-mapping] An array of a fixed size can also be created without any data, and can then be populated element by element using \l{QJniArray::operator[]()}{operator[]}: \code QJniArray intArray(size); for (int i = 0; i < size; ++i) intArray[i] = i; \endcode or a mutable iterator: \code QJniArray strings(size); int i = 0; for (auto string : strings) // note: not 'auto &string' string = u"Row %1"_s.arg(i++); \endcode As in Java, the size of an array can not be changed, but the array variable can be assigned to a different array. \note Java arrays are limited to 32 bits, and the \c{size_type} member type of QJniArray is \c{jsize}, which is a 32bit integer type. Trying to construct a QJniArray from a C++ container that holds more than 2^32 elements will cause a runtime assertion. */ /*! \fn template QJniArray::QJniArray() Default constructor of QJniArray. This does not create a Java-side array, and the instance will be invalid. \sa isValid */ /*! \fn template QJniArray::QJniArray(jarray array) Constructs a QJniArray that wraps the Java-side array \a array, creating a new global reference to \a array. //! [no-array-validation] \note This constructor does not perform any validation of whether the Java-side object is an array of the correct type. Accessing a mismatching QJniArray results in undefined behavior. //! [no-array-validation] */ /*! \fn template QJniArray::QJniArray(const QJniObject &object) Constructs a QJniArray that wraps the same Java array as \a object, creating a new global reference. To construct a QJniArray from an existing local reference, use a QJniObject constructed via \l{QJniObject::}{fromLocalRef()}. \include qjniarray.qdoc no-array-validation */ /*! \fn template QJniArray::QJniArray(QJniObject &&object) Constructs a QJniArray by moving from \a object. The QJniObject becomes \l{QJniObject::isValid}{invalid}. \include qjniarray.qdoc no-array-validation */ /*! \fn template template > QJniArray::QJniArray(const QJniArray &other) Constructs a QJniArray by copying \a other. Both QJniArray objects will reference the same Java array object. \constraints the element type \c{Other} of \a other is convertible to the element type \c{T} of the QJniArray being constructed. However, no actual conversion takes place. */ /*! \fn template template > QJniArray::QJniArray(QJniArray &&other) Constructs a QJniArray by moving from \a other. The \a other array becomes \l{QJniArrayBase::isValid}{invalid}. \constraints the element type \c{Other} of \a other is convertible to the element type \c{T} of the QJniArray being constructed. However, no actual conversion takes place. */ /*! \fn template template > QJniArray &QJniArray::operator=(const QJniArray &other) Assigns \a other to this QJniArray, and returns a reference to this. Both QJniArray objects will reference the same Java array object. \constraints the element type \c{Other} of \a other is convertible to the element type \c{T} of this QJniArray. However, no actual conversion takes place. */ /*! \fn template template > QJniArray &QJniArray::operator=(QJniArray &&other) Moves \a other into this QJniArray, and returns a reference to this. The \a other array becomes \l{QJniArrayBase::isValid}{invalid}. \constraints the element type \c{Other} of \a other is convertible to the element type \c{T} of this QJniArray. However, no actual conversion takes place. */ /*! \fn template template > QJniArray::QJniArray(Container &&container) Constructs a QJniArray that wraps a newly-created Java array for elements of type \c{Container::value_type}, and populates the Java array with the data from \a container. \include qjniarray.qdoc forward-iterable-containers \sa QJniArrayBase::fromContainer(), toContainer() */ /*! \fn template QJniArray::QJniArray(std::initializer_list &list) Constructs a QJniArray that wraps a newly-created Java array for elements of type \c{T}, and populates the Java array with the data from \a list. \sa QJniArrayBase::fromContainer(), toContainer() */ /*! \fn template QJniArray::QJniArray(size_type size) \since 6.9 Constructs an empty QJniArray of size \a size. The elements in the array do not get initialized. */ /*! \fn template QJniArray::~QJniArray() Destroys the QJniArray object and releases any references held to the wrapped Java array. */ /*! \fn template auto QJniArray::arrayObject() const \return the wrapped Java object as the suitable \c{jarray} type that matches the element type \c{T} of this QJniArray object. \table \header \li T \li jarray type \row \li jbyte \li jbyteArray \row \li jchar \li jcharArray \row \li ... \li ... \row \li jobject \li jobjectArray \row \li QJniObject \li jobjectArray \row \li Q_DECLARE_JNI_CLASS \li jobjectArray \endtable */ /*! \typedef QJniArray::const_iterator A random-access, const iterator for QJniArray. */ /*! \typedef QJniArray::const_reverse_iterator A reverse iterator for the QJniArray, synonym for \c{std::reverse_iterator}. */ /*! \fn template const_iterator QJniArray::begin() const \fn template iterator QJniArray::begin() \fn template const_iterator QJniArray::constBegin() const \fn template const_iterator QJniArray::cbegin() const Returns an \l{STL-style iterators}{STL-style const iterator} pointing to the first item in the array. If the array is \l{QJniArrayBase::isValid()}{invalid}, then this will return the same iterator as the corresponding end() function. \sa end(), rbegin() */ /*! \fn template const_iterator QJniArray::end() const \fn template iterator QJniArray::end() \fn template const_iterator QJniArray::constEnd() const \fn template const_iterator QJniArray::cend() const Returns an \l{STL-style iterators}{STL-style iterator} pointing just after the last item in the list. \sa begin(), rend() */ /*! \fn template const_reverse_iterator QJniArray::rbegin() const \fn template reverse_iterator QJniArray::rbegin() \fn template const_reverse_iterator QJniArray::crbegin() const Returns an \l{STL-style iterators}{STL-style reverse iterator} pointing to the first item in the array, in reverse order. If the array is \l{QJniArrayBase::isValid()}{invalid}, then this will return the same iterator as the corresponding rend() function. \sa rend(), begin() */ /*! \fn template const_reverse_iterator QJniArray::rend() const \fn template reverse_iterator QJniArray::rend() \fn template const_reverse_iterator QJniArray::crend() const Returns an \l{STL-style iterators}{STL-style reverse iterator} pointing just after the last item in the list, in reverse order. \sa rbegin(), end() */ /*! \fn template T QJniArray::operator[](size_type i) const \fn template T QJniArray::at(size_type i) const Returns the value at position \a i in the wrapped Java array. \a i must be a valid index position in the list (i.e., 0 <= \a i < size()). \sa size() */ /*! \fn template QJniArray::reference QJniArray::operator[](size_type i) \since 6.9 Returns a reference object for value at position \a i in the wrapped Java array. \a i must be a valid index position in the list (i.e., 0 <= \a i < size()). The returned reference object holds the value at position \a i, and in most cases will convert implicitly to the value. Assigning to the returned reference will overwrite the entry in the Java array. However, calling mutating member functions on the object will not modify the entry in the array. To call member function on the result of this operator, dereference the reference object: \code QJniArray strings = object.callMethod("getStrings"); if (!strings.isEmpty()) { if (!(*array[0]).isEmpty()) { // ... } } \endcode However, if modifying the value in the array itself is not intended, make the array const, or use \l{at()} instead. \sa at(), size() */ /*! \fn template template > Container QJniArray::toContainer(Container &&container) const \return a container populated with the data in the wrapped Java array. If no \a container is provided, then the type of the container returned depends on the element type of this QJniArray. \include qjniarray.qdoc type-mapping If you pass in a named container (an lvalue) for \a container, then that container is filled, and a reference to it is returned. If you pass in a temporary container (an rvalue, incl. the default argument), then that container is filled, and returned by value. This function returns immediately if the array is \l{QJniArrayBase::isValid()}{invalid}. \sa QJniArrayBase::fromContainer() */