QGIS/python/core/auto_generated/qgsattributes.sip.in
Nyall Dawson 149c106ea0 Optimise conversion of QgsAttributes to Python objects
Applies the same optimisations as are present in the QgsFeature
methods to avoid the overhead of sip's QVariant conversion logic
when attributes are of a basic type
2025-02-22 05:22:41 +10:00

192 lines
5.3 KiB
Plaintext

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsattributes.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/
typedef QMap<int, QVariant> QgsAttributeMap;
typedef QMap<int, QString> QgsFieldNameMap;
typedef QMap<int, QgsField> QgsFieldMap;
typedef QVector<QVariant> QgsAttributes;
%MappedType QgsAttributes
{
%TypeHeaderCode
#include "qgsfeature.h"
%End
%ConvertFromTypeCode
// Create the list.
PyObject *l;
if ( ( l = PyList_New( sipCpp->size() ) ) == NULL )
return NULL;
// Set the list elements.
for ( int i = 0; i < sipCpp->size(); ++i )
{
const QVariant v = sipCpp->at( i );
PyObject *tobj = NULL;
if ( !v.isValid() )
{
Py_INCREF( Py_None );
tobj = Py_None;
}
// QByteArray null handling is "special"! See null_from_qvariant_converter in conversions.sip
else if ( QgsVariantUtils::isNull( v, true ) && v.userType() != QMetaType::Type::QByteArray )
{
PyObject *vartype = sipConvertFromEnum( v.type(), sipType_QVariant_Type );
PyObject *args = PyTuple_Pack( 1, vartype );
PyTypeObject *typeObj = sipTypeAsPyTypeObject( sipType_QVariant );
tobj = PyObject_Call( ( PyObject * )typeObj, args, nullptr );
Py_DECREF( args );
Py_DECREF( vartype );
}
else
{
switch ( v.userType() )
{
case QMetaType::Type::Int:
tobj = PyLong_FromLong( v.toInt() );
break;
case QMetaType::Type::UInt:
tobj = PyLong_FromUnsignedLong( v.toUInt() );
break;
case QMetaType::Type::Long:
case QMetaType::Type::LongLong:
tobj = PyLong_FromLongLong( v.toLongLong() );
break;
case QMetaType::Type::ULong:
case QMetaType::Type::ULongLong:
tobj = PyLong_FromUnsignedLongLong( v.toULongLong() );
break;
case QMetaType::Type::Bool:
tobj = PyBool_FromLong( v.toBool() ? 1 : 0 );
break;
case QMetaType::Type::Float:
case QMetaType::Type::Double:
tobj = PyFloat_FromDouble( v.toDouble() );
break;
case QMetaType::Type::QString:
tobj = PyUnicode_FromString( v.toString().toUtf8().constData() );
break;
default:
{
QVariant *newV = new QVariant( v );
tobj = sipConvertFromNewType( newV, sipType_QVariant, sipTransferObj );
break;
}
}
}
if ( tobj == NULL )
{
Py_DECREF( l );
return NULL;
}
PyList_SET_ITEM( l, i, tobj );
}
return l;
%End
%ConvertToTypeCode
// Check the type if that is all that is required.
if ( sipIsErr == NULL )
{
if ( !PyList_Check( sipPy ) )
return 0;
for ( SIP_SSIZE_T i = 0; i < PyList_GET_SIZE( sipPy ); ++i )
if ( !sipCanConvertToType( PyList_GET_ITEM( sipPy, i ), sipType_QVariant, SIP_NOT_NONE ) )
return 0;
return 1;
}
SIP_SSIZE_T listSize = PyList_GET_SIZE( sipPy );
// Initialize attributes to null. This has two motivations:
// 1. It speeds up the QVector construction, as otherwise we are creating n default QVariant objects (default QVariant constructor is not free!)
// 2. It lets us shortcut in the loop below when a Py_None is encountered in the list
const QVariant nullVariant( QVariant::Int );
QgsAttributes *qv = new QgsAttributes( listSize, nullVariant );
QVariant *outData = qv->data();
for ( SIP_SSIZE_T i = 0; i < listSize; ++i )
{
PyObject *obj = PyList_GET_ITEM( sipPy, i );
if ( obj == Py_None )
{
// outData was already initialized to null values
*outData++;
}
else if ( PyBool_Check( obj ) )
{
*outData++ = QVariant( PyObject_IsTrue( obj ) == 1 );
}
else if ( PyLong_Check( obj ) )
{
*outData++ = QVariant( PyLong_AsLongLong( obj ) );
}
else if ( PyFloat_Check( obj ) )
{
*outData++ = QVariant( PyFloat_AsDouble( obj ) );
}
else if ( PyUnicode_Check( obj ) )
{
*outData++ = QVariant( QString::fromUtf8( PyUnicode_AsUTF8( obj ) ) );
}
else
{
int state;
QVariant *t = reinterpret_cast<QVariant *>( sipConvertToType( obj, sipType_QVariant, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr ) );
if ( *sipIsErr )
{
sipReleaseType( t, sipType_QVariant, state );
delete qv;
return 0;
}
*outData++ = *t;
sipReleaseType( t, sipType_QVariant, state );
}
}
*sipCppPtr = qv;
return sipGetState( sipTransferObj );
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsattributes.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/