1// This is the SIP interface definition for the majority of the QVector based 2// mapped types. 3// 4// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com> 5// 6// This file is part of PyQt5. 7// 8// This file may be used under the terms of the GNU General Public License 9// version 3.0 as published by the Free Software Foundation and appearing in 10// the file LICENSE included in the packaging of this file. Please review the 11// following information to ensure the GNU General Public License version 3.0 12// requirements will be met: http://www.gnu.org/copyleft/gpl.html. 13// 14// If you do not wish to use this file under the terms of the GPL version 3.0 15// then you may purchase a commercial license. For more information contact 16// info@riverbankcomputing.com. 17// 18// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 19// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 21 22template<_TYPE_> 23%MappedType QVector<_TYPE_> 24 /TypeHintIn="Iterable[_TYPE_]", TypeHintOut="List[_TYPE_]", 25 TypeHintValue="[]"/ 26{ 27%TypeHeaderCode 28#include <qvector.h> 29%End 30 31%ConvertFromTypeCode 32 PyObject *l = PyList_New(sipCpp->size()); 33 34 if (!l) 35 return 0; 36 37 for (int i = 0; i < sipCpp->size(); ++i) 38 { 39 _TYPE_ *t = new _TYPE_(sipCpp->at(i)); 40 PyObject *tobj = sipConvertFromNewType(t, sipType__TYPE_, 41 sipTransferObj); 42 43 if (!tobj) 44 { 45 delete t; 46 Py_DECREF(l); 47 48 return 0; 49 } 50 51 PyList_SetItem(l, i, tobj); 52 } 53 54 return l; 55%End 56 57%ConvertToTypeCode 58 PyObject *iter = PyObject_GetIter(sipPy); 59 60 if (!sipIsErr) 61 { 62 PyErr_Clear(); 63 Py_XDECREF(iter); 64 65 return (iter 66#if PY_MAJOR_VERSION < 3 67 && !PyString_Check(sipPy) 68#endif 69 && !PyUnicode_Check(sipPy)); 70 } 71 72 if (!iter) 73 { 74 *sipIsErr = 1; 75 76 return 0; 77 } 78 79 QVector<_TYPE_> *qv = new QVector<_TYPE_>; 80 81 for (Py_ssize_t i = 0; ; ++i) 82 { 83 PyErr_Clear(); 84 PyObject *itm = PyIter_Next(iter); 85 86 if (!itm) 87 { 88 if (PyErr_Occurred()) 89 { 90 delete qv; 91 Py_DECREF(iter); 92 *sipIsErr = 1; 93 94 return 0; 95 } 96 97 break; 98 } 99 100 int state; 101 _TYPE_ *t = reinterpret_cast<_TYPE_ *>( 102 sipForceConvertToType(itm, sipType__TYPE_, sipTransferObj, 103 SIP_NOT_NONE, &state, sipIsErr)); 104 105 if (*sipIsErr) 106 { 107 PyErr_Format(PyExc_TypeError, 108 "index %zd has type '%s' but '_TYPE_' is expected", i, 109 sipPyTypeName(Py_TYPE(itm))); 110 111 Py_DECREF(itm); 112 delete qv; 113 Py_DECREF(iter); 114 115 return 0; 116 } 117 118 qv->append(*t); 119 120 sipReleaseType(t, sipType__TYPE_, state); 121 Py_DECREF(itm); 122 } 123 124 Py_DECREF(iter); 125 126 *sipCppPtr = qv; 127 128 return sipGetState(sipTransferObj); 129%End 130}; 131 132 133template<_TYPE_> 134%MappedType QVector<_TYPE_ *> 135 /TypeHintIn="Iterable[_TYPE_]", TypeHintOut="List[_TYPE_]", 136 TypeHintValue="[]"/ 137{ 138%TypeHeaderCode 139#include <qvector.h> 140%End 141 142%ConvertFromTypeCode 143 int gc_enabled = sipEnableGC(0); 144 PyObject *l = PyList_New(sipCpp->size()); 145 146 if (l) 147 { 148 for (int i = 0; i < sipCpp->size(); ++i) 149 { 150 _TYPE_ *t = sipCpp->at(i); 151 152 // The explicit (void *) cast allows _TYPE_ to be const. 153 PyObject *tobj = sipConvertFromNewType((void *)t, sipType__TYPE_, 154 sipTransferObj); 155 156 if (!tobj) 157 { 158 Py_DECREF(l); 159 l = 0; 160 161 break; 162 } 163 164 PyList_SetItem(l, i, tobj); 165 } 166 } 167 168 sipEnableGC(gc_enabled); 169 170 return l; 171%End 172 173%ConvertToTypeCode 174 PyObject *iter = PyObject_GetIter(sipPy); 175 176 if (!sipIsErr) 177 { 178 PyErr_Clear(); 179 Py_XDECREF(iter); 180 181 return (iter 182#if PY_MAJOR_VERSION < 3 183 && !PyString_Check(sipPy) 184#endif 185 && !PyUnicode_Check(sipPy)); 186 } 187 188 if (!iter) 189 { 190 *sipIsErr = 1; 191 192 return 0; 193 } 194 195 QVector<_TYPE_ *> *qv = new QVector<_TYPE_ *>; 196 197 for (Py_ssize_t i = 0; ; ++i) 198 { 199 PyErr_Clear(); 200 PyObject *itm = PyIter_Next(iter); 201 202 if (!itm) 203 { 204 if (PyErr_Occurred()) 205 { 206 delete qv; 207 Py_DECREF(iter); 208 *sipIsErr = 1; 209 210 return 0; 211 } 212 213 break; 214 } 215 216 _TYPE_ *t = reinterpret_cast<_TYPE_ *>( 217 sipForceConvertToType(itm, sipType__TYPE_, sipTransferObj, 0, 218 0, sipIsErr)); 219 220 if (*sipIsErr) 221 { 222 PyErr_Format(PyExc_TypeError, 223 "index %zd has type '%s' but '_TYPE_' is expected", i, 224 sipPyTypeName(Py_TYPE(itm))); 225 226 Py_DECREF(itm); 227 delete qv; 228 Py_DECREF(iter); 229 230 return 0; 231 } 232 233 qv->append(t); 234 235 Py_DECREF(itm); 236 } 237 238 Py_DECREF(iter); 239 240 *sipCppPtr = qv; 241 242 return sipGetState(sipTransferObj); 243%End 244}; 245 246 247template<qreal, _TYPE_> 248%MappedType QVector<QPair<qreal, _TYPE_> > 249 /TypeHintIn="Iterable[Tuple[float, _TYPE_]]", 250 TypeHintOut="List[Tuple[float, _TYPE_]]", TypeHintValue="[]"/ 251{ 252%TypeHeaderCode 253#include <qvector.h> 254#include <qpair.h> 255%End 256 257%ConvertFromTypeCode 258 PyObject *l = PyList_New(sipCpp->size()); 259 260 if (!l) 261 return 0; 262 263 for (int i = 0; i < sipCpp->size(); ++i) 264 { 265 const QPair<qreal, _TYPE_> &p = sipCpp->at(i); 266 _TYPE_ *s2 = new _TYPE_(p.second); 267 PyObject *pobj = sipBuildResult(NULL, "(dN)", (double)p.first, s2, 268 sipType__TYPE_, sipTransferObj); 269 270 if (!pobj) 271 { 272 delete s2; 273 Py_DECREF(l); 274 275 return 0; 276 } 277 278 PyList_SetItem(l, i, pobj); 279 } 280 281 return l; 282%End 283 284%ConvertToTypeCode 285 PyObject *iter = PyObject_GetIter(sipPy); 286 287 if (!sipIsErr) 288 { 289 PyErr_Clear(); 290 Py_XDECREF(iter); 291 292 return (iter 293#if PY_MAJOR_VERSION < 3 294 && !PyString_Check(sipPy) 295#endif 296 && !PyUnicode_Check(sipPy)); 297 } 298 299 if (!iter) 300 { 301 *sipIsErr = 1; 302 303 return 0; 304 } 305 306 QVector<QPair<qreal, _TYPE_> > *qv = new QVector<QPair<qreal, _TYPE_> >; 307 308 for (Py_ssize_t i = 0; ; ++i) 309 { 310 PyErr_Clear(); 311 PyObject *seq = PyIter_Next(iter); 312 313 if (!seq) 314 { 315 if (PyErr_Occurred()) 316 { 317 delete qv; 318 Py_DECREF(iter); 319 *sipIsErr = 1; 320 321 return 0; 322 } 323 324 break; 325 } 326 327 Py_ssize_t sub_len; 328 329 if (PySequence_Check(seq) 330#if PY_MAJOR_VERSION < 3 331 && !PyString_Check(seq) 332#endif 333 && !PyUnicode_Check(seq)) 334 sub_len = PySequence_Size(seq); 335 else 336 sub_len = -1; 337 338 if (sub_len != 2) 339 { 340 if (sub_len < 0) 341 PyErr_Format(PyExc_TypeError, 342 "index %zd has type '%s' but a 2 element non-string sequence is expected", 343 i, sipPyTypeName(Py_TYPE(seq))); 344 else 345 PyErr_Format(PyExc_TypeError, 346 "index %zd is a sequence of %zd sub-elements but 2 sub-elements are expected", 347 i, sub_len); 348 349 Py_DECREF(seq); 350 delete qv; 351 Py_DECREF(iter); 352 *sipIsErr = 1; 353 354 return 0; 355 } 356 357 PyObject *itm1 = PySequence_GetItem(seq, 0); 358 359 if (!itm1) 360 { 361 Py_DECREF(seq); 362 delete qv; 363 Py_DECREF(iter); 364 *sipIsErr = 1; 365 366 return 0; 367 } 368 369 PyErr_Clear(); 370 qreal s1 = PyFloat_AsDouble(itm1); 371 372 if (PyErr_Occurred()) 373 { 374 PyErr_Format(PyExc_TypeError, 375 "the first sub-element of index %zd has type '%s' but 'float' is expected", 376 i, sipPyTypeName(Py_TYPE(itm1))); 377 378 Py_DECREF(itm1); 379 Py_DECREF(seq); 380 delete qv; 381 Py_DECREF(iter); 382 *sipIsErr = 1; 383 384 return 0; 385 } 386 387 PyObject *itm2 = PySequence_GetItem(seq, 1); 388 389 if (!itm2) 390 { 391 Py_DECREF(itm1); 392 Py_DECREF(seq); 393 delete qv; 394 Py_DECREF(iter); 395 *sipIsErr = 1; 396 397 return 0; 398 } 399 400 int state2; 401 _TYPE_ *s2 = reinterpret_cast<_TYPE_ *>( 402 sipForceConvertToType(itm2, sipType__TYPE_, sipTransferObj, 403 SIP_NOT_NONE, &state2, sipIsErr)); 404 405 if (*sipIsErr) 406 { 407 PyErr_Format(PyExc_TypeError, 408 "the second sub-element of index %zd has type '%s' but '_TYPE_' is expected", 409 i, sipPyTypeName(Py_TYPE(itm2))); 410 411 Py_DECREF(itm2); 412 Py_DECREF(itm1); 413 Py_DECREF(seq); 414 delete qv; 415 Py_DECREF(iter); 416 417 return 0; 418 } 419 420 qv->append(QPair<qreal, _TYPE_>(s1, *s2)); 421 422 sipReleaseType(s2, sipType__TYPE_, state2); 423 Py_DECREF(itm2); 424 Py_DECREF(itm1); 425 Py_DECREF(seq); 426 } 427 428 Py_DECREF(iter); 429 430 *sipCppPtr = qv; 431 432 return sipGetState(sipTransferObj); 433%End 434}; 435 436 437%MappedType QVector<int> 438 /TypeHintIn="Iterable[int]", TypeHintOut="List[int]", 439 TypeHintValue="[]"/ 440{ 441%TypeHeaderCode 442#include <qvector.h> 443%End 444 445%ConvertFromTypeCode 446 PyObject *l = PyList_New(sipCpp->size()); 447 448 if (!l) 449 return 0; 450 451 for (int i = 0; i < sipCpp->size(); ++i) 452 { 453 PyObject *pobj = SIPLong_FromLong(sipCpp->value(i)); 454 455 if (!pobj) 456 { 457 Py_DECREF(l); 458 459 return 0; 460 } 461 462 PyList_SetItem(l, i, pobj); 463 } 464 465 return l; 466%End 467 468%ConvertToTypeCode 469 PyObject *iter = PyObject_GetIter(sipPy); 470 471 if (!sipIsErr) 472 { 473 PyErr_Clear(); 474 Py_XDECREF(iter); 475 476 return (iter 477#if PY_MAJOR_VERSION < 3 478 && !PyString_Check(sipPy) 479#endif 480 && !PyUnicode_Check(sipPy)); 481 } 482 483 if (!iter) 484 { 485 *sipIsErr = 1; 486 487 return 0; 488 } 489 490 QVector<int> *qv = new QVector<int>; 491 492 for (Py_ssize_t i = 0; ; ++i) 493 { 494 PyErr_Clear(); 495 PyObject *itm = PyIter_Next(iter); 496 497 if (!itm) 498 { 499 if (PyErr_Occurred()) 500 { 501 delete qv; 502 Py_DECREF(iter); 503 *sipIsErr = 1; 504 505 return 0; 506 } 507 508 break; 509 } 510 511 int val = sipLong_AsInt(itm); 512 513 if (PyErr_Occurred()) 514 { 515 if (PyErr_ExceptionMatches(PyExc_TypeError)) 516 PyErr_Format(PyExc_TypeError, 517 "index %zd has type '%s' but 'int' is expected", i, 518 sipPyTypeName(Py_TYPE(itm))); 519 520 Py_DECREF(itm); 521 delete qv; 522 Py_DECREF(iter); 523 *sipIsErr = 1; 524 525 return 0; 526 } 527 528 qv->append(val); 529 530 Py_DECREF(itm); 531 } 532 533 Py_DECREF(iter); 534 535 *sipCppPtr = qv; 536 537 return sipGetState(sipTransferObj); 538%End 539}; 540 541 542%If (Qt_5_12_0 -) 543 544%MappedType QVector<quint16> 545 /TypeHintIn="Iterable[int]", TypeHintOut="List[int]", 546 TypeHintValue="[]"/ 547{ 548%TypeHeaderCode 549#include <qvector.h> 550%End 551 552%ConvertFromTypeCode 553 PyObject *l = PyList_New(sipCpp->size()); 554 555 if (!l) 556 return 0; 557 558 for (int i = 0; i < sipCpp->size(); ++i) 559 { 560 PyObject *pobj = SIPLong_FromLong(sipCpp->value(i)); 561 562 if (!pobj) 563 { 564 Py_DECREF(l); 565 566 return 0; 567 } 568 569 PyList_SetItem(l, i, pobj); 570 } 571 572 return l; 573%End 574 575%ConvertToTypeCode 576 PyObject *iter = PyObject_GetIter(sipPy); 577 578 if (!sipIsErr) 579 { 580 PyErr_Clear(); 581 Py_XDECREF(iter); 582 583 return (iter 584#if PY_MAJOR_VERSION < 3 585 && !PyString_Check(sipPy) 586#endif 587 && !PyUnicode_Check(sipPy)); 588 } 589 590 if (!iter) 591 { 592 *sipIsErr = 1; 593 594 return 0; 595 } 596 597 QVector<quint16> *qv = new QVector<quint16>; 598 599 for (Py_ssize_t i = 0; ; ++i) 600 { 601 PyErr_Clear(); 602 PyObject *itm = PyIter_Next(iter); 603 604 if (!itm) 605 { 606 if (PyErr_Occurred()) 607 { 608 delete qv; 609 Py_DECREF(iter); 610 *sipIsErr = 1; 611 612 return 0; 613 } 614 615 break; 616 } 617 618 quint16 val = sipLong_AsUnsignedShort(itm); 619 620 if (PyErr_Occurred()) 621 { 622 if (PyErr_ExceptionMatches(PyExc_TypeError)) 623 PyErr_Format(PyExc_TypeError, 624 "index %zd has type '%s' but 'int' is expected", i, 625 sipPyTypeName(Py_TYPE(itm))); 626 627 Py_DECREF(itm); 628 delete qv; 629 Py_DECREF(iter); 630 *sipIsErr = 1; 631 632 return 0; 633 } 634 635 qv->append(val); 636 637 Py_DECREF(itm); 638 } 639 640 Py_DECREF(iter); 641 642 *sipCppPtr = qv; 643 644 return sipGetState(sipTransferObj); 645%End 646}; 647 648%End 649