1// This is the SIP interface definition for the majority of the QPair 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 22%If (Qt_5_10_0 -) 23 24template<_TYPE1_, _TYPE2_> 25%MappedType QPair<_TYPE1_, _TYPE2_> /TypeHint="Tuple[_TYPE1_, _TYPE2_]"/ 26{ 27%TypeHeaderCode 28#include <qpair.h> 29%End 30 31%ConvertFromTypeCode 32 _TYPE1_ *first = new _TYPE1_(sipCpp->first); 33 _TYPE2_ *second = new _TYPE2_(sipCpp->second); 34 PyObject *t = sipBuildResult(NULL, "(NN)", first, sipType__TYPE1_, 35 sipTransferObj, second, sipType__TYPE2_, sipTransferObj); 36 37 if (!t) 38 { 39 delete first; 40 delete second; 41 42 return 0; 43 } 44 45 return t; 46%End 47 48%ConvertToTypeCode 49 if (!sipIsErr) 50 return (PySequence_Check(sipPy) 51#if PY_MAJOR_VERSION < 3 52 && !PyString_Check(sipPy) 53#endif 54 && !PyUnicode_Check(sipPy)); 55 56 Py_ssize_t len = PySequence_Size(sipPy); 57 58 if (len != 2) 59 { 60 // A negative length should only be an internal error so let the 61 // original exception stand. 62 if (len >= 0) 63 PyErr_Format(PyExc_TypeError, 64 "sequence has %zd elements but 2 elements are expected", 65 len); 66 67 *sipIsErr = 1; 68 69 return 0; 70 } 71 72 PyObject *firstobj = PySequence_GetItem(sipPy, 0); 73 74 if (!firstobj) 75 { 76 *sipIsErr = 1; 77 78 return 0; 79 } 80 81 int firststate; 82 _TYPE1_ *first = reinterpret_cast<_TYPE1_ *>( 83 sipForceConvertToType(firstobj, sipType__TYPE1_, sipTransferObj, 84 SIP_NOT_NONE, &firststate, sipIsErr)); 85 86 if (*sipIsErr) 87 { 88 PyErr_Format(PyExc_TypeError, 89 "the first element has type '%s' but '_TYPE1_' is expected", 90 sipPyTypeName(Py_TYPE(firstobj))); 91 92 return 0; 93 } 94 95 PyObject *secondobj = PySequence_GetItem(sipPy, 1); 96 97 if (!secondobj) 98 { 99 sipReleaseType(first, sipType__TYPE1_, firststate); 100 Py_DECREF(firstobj); 101 *sipIsErr = 1; 102 103 return 0; 104 } 105 106 int secondstate; 107 _TYPE2_ *second = reinterpret_cast<_TYPE2_ *>( 108 sipForceConvertToType(secondobj, sipType__TYPE2_, sipTransferObj, 109 SIP_NOT_NONE, &secondstate, sipIsErr)); 110 111 if (*sipIsErr) 112 { 113 PyErr_Format(PyExc_TypeError, 114 "the second element has type '%s' but '_TYPE2_' is expected", 115 sipPyTypeName(Py_TYPE(secondobj))); 116 117 Py_DECREF(secondobj); 118 sipReleaseType(first, sipType__TYPE1_, firststate); 119 Py_DECREF(firstobj); 120 *sipIsErr = 1; 121 122 return 0; 123 } 124 125 *sipCppPtr = new QPair<_TYPE1_, _TYPE2_>(*first, *second); 126 127 sipReleaseType(second, sipType__TYPE2_, secondstate); 128 Py_DECREF(secondobj); 129 sipReleaseType(first, sipType__TYPE1_, firststate); 130 Py_DECREF(firstobj); 131 132 return sipGetState(sipTransferObj); 133%End 134}; 135 136%End 137 138 139template<_TYPE_> 140%MappedType QPair<_TYPE_, int> /TypeHint="Tuple[_TYPE_, int]"/ 141{ 142%TypeHeaderCode 143#include <qpair.h> 144%End 145 146%ConvertFromTypeCode 147 _TYPE_ *first = new _TYPE_(sipCpp->first); 148 PyObject *t = sipBuildResult(NULL, "(Ni)", first, sipType__TYPE_, 149 sipTransferObj, sipCpp->second); 150 151 if (!t) 152 { 153 delete first; 154 155 return 0; 156 } 157 158 return t; 159%End 160 161%ConvertToTypeCode 162 if (!sipIsErr) 163 return (PySequence_Check(sipPy) 164#if PY_MAJOR_VERSION < 3 165 && !PyString_Check(sipPy) 166#endif 167 && !PyUnicode_Check(sipPy)); 168 169 Py_ssize_t len = PySequence_Size(sipPy); 170 171 if (len != 2) 172 { 173 // A negative length should only be an internal error so let the 174 // original exception stand. 175 if (len >= 0) 176 PyErr_Format(PyExc_TypeError, 177 "sequence has %zd elements but 2 elements are expected", 178 len); 179 180 *sipIsErr = 1; 181 182 return 0; 183 } 184 185 PyObject *firstobj = PySequence_GetItem(sipPy, 0); 186 187 if (!firstobj) 188 { 189 *sipIsErr = 1; 190 191 return 0; 192 } 193 194 int firststate; 195 _TYPE_ *first = reinterpret_cast<_TYPE_ *>( 196 sipForceConvertToType(firstobj, sipType__TYPE_, sipTransferObj, 197 SIP_NOT_NONE, &firststate, sipIsErr)); 198 199 if (*sipIsErr) 200 { 201 PyErr_Format(PyExc_TypeError, 202 "the first element has type '%s' but '_TYPE_' is expected", 203 sipPyTypeName(Py_TYPE(firstobj))); 204 205 return 0; 206 } 207 208 PyObject *secondobj = PySequence_GetItem(sipPy, 1); 209 210 if (!secondobj) 211 { 212 sipReleaseType(first, sipType__TYPE_, firststate); 213 Py_DECREF(firstobj); 214 *sipIsErr = 1; 215 216 return 0; 217 } 218 219 int second = sipLong_AsInt(secondobj); 220 221 if (PyErr_Occurred()) 222 { 223 if (PyErr_ExceptionMatches(PyExc_TypeError)) 224 PyErr_Format(PyExc_TypeError, 225 "the second element has type '%s' but 'int' is expected", 226 sipPyTypeName(Py_TYPE(secondobj))); 227 228 Py_DECREF(secondobj); 229 sipReleaseType(first, sipType__TYPE_, firststate); 230 Py_DECREF(firstobj); 231 *sipIsErr = 1; 232 233 return 0; 234 } 235 236 *sipCppPtr = new QPair<_TYPE_, int>(*first, second); 237 238 Py_DECREF(secondobj); 239 sipReleaseType(first, sipType__TYPE_, firststate); 240 Py_DECREF(firstobj); 241 242 return sipGetState(sipTransferObj); 243%End 244}; 245 246 247%MappedType QPair<int, int> /TypeHint="Tuple[int, int]"/ 248{ 249%TypeHeaderCode 250#include <qpair.h> 251%End 252 253%ConvertFromTypeCode 254 return Py_BuildValue("(ii)", sipCpp->first, sipCpp->second); 255%End 256 257%ConvertToTypeCode 258 if (!sipIsErr) 259 return (PySequence_Check(sipPy) 260#if PY_MAJOR_VERSION < 3 261 && !PyString_Check(sipPy) 262#endif 263 && !PyUnicode_Check(sipPy)); 264 265 Py_ssize_t len = PySequence_Size(sipPy); 266 267 if (len != 2) 268 { 269 // A negative length should only be an internal error so let the 270 // original exception stand. 271 if (len >= 0) 272 PyErr_Format(PyExc_TypeError, 273 "sequence has %zd elements but 2 elements are expected", 274 len); 275 276 *sipIsErr = 1; 277 278 return 0; 279 } 280 281 PyObject *firstobj = PySequence_GetItem(sipPy, 0); 282 283 if (!firstobj) 284 { 285 *sipIsErr = 1; 286 287 return 0; 288 } 289 290 int first = sipLong_AsInt(firstobj); 291 292 if (PyErr_Occurred()) 293 { 294 if (PyErr_ExceptionMatches(PyExc_TypeError)) 295 PyErr_Format(PyExc_TypeError, 296 "the first element has type '%s' but 'int' is expected", 297 sipPyTypeName(Py_TYPE(firstobj))); 298 299 *sipIsErr = 1; 300 301 return 0; 302 } 303 304 PyObject *secondobj = PySequence_GetItem(sipPy, 1); 305 306 if (!secondobj) 307 { 308 Py_DECREF(firstobj); 309 *sipIsErr = 1; 310 311 return 0; 312 } 313 314 int second = sipLong_AsInt(secondobj); 315 316 if (PyErr_Occurred()) 317 { 318 if (PyErr_ExceptionMatches(PyExc_TypeError)) 319 PyErr_Format(PyExc_TypeError, 320 "the second element has type '%s' but 'int' is expected", 321 sipPyTypeName(Py_TYPE(secondobj))); 322 323 Py_DECREF(secondobj); 324 Py_DECREF(firstobj); 325 *sipIsErr = 1; 326 327 return 0; 328 } 329 330 *sipCppPtr = new QPair<int, int>(first, second); 331 332 Py_DECREF(secondobj); 333 Py_DECREF(firstobj); 334 335 return sipGetState(sipTransferObj); 336%End 337}; 338