aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-01-06 09:30:45 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-01-06 14:43:30 +0000
commit9bb79adbcc76b58c9b76cb4f671cdde9bb8f1ae3 (patch)
tree7f528be9ddb10b22abb051aa7895cc118b33cc62
parent4bb3abd257fceca2a638d4d5099d02b7162d747f (diff)
Add reserve()/capacity() to contiguous opaque containers
Generate bindings for reserve()/capacity() if the container supports it. [ChangeLog][shiboken6] Bindings for reserve()/capacity() were added to contiguous opaque containers. Task-number: PYSIDE-1605 Change-Id: I82dd2efc4a1831600aa2fae9427e5d13a67cdd11 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> (cherry picked from commit 683314b3491dea17f0205baa2976e71595ccb05d) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--examples/widgets/painting/plot/plot.py1
-rw-r--r--sources/shiboken6/doc/typesystem_containers.rst12
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator_container.cpp2
-rw-r--r--sources/shiboken6/libshiboken/sbkcontainer.h49
4 files changed, 64 insertions, 0 deletions
diff --git a/examples/widgets/painting/plot/plot.py b/examples/widgets/painting/plot/plot.py
index 156a6408d..a125c3253 100644
--- a/examples/widgets/painting/plot/plot.py
+++ b/examples/widgets/painting/plot/plot.py
@@ -63,6 +63,7 @@ class PlotWidget(QWidget):
self._timer.timeout.connect(self.shift)
self._points = QPointList()
+ self._points.reserve(WIDTH)
self._x = 0
self._delta_x = 0.05
self._half_height = HEIGHT / 2
diff --git a/sources/shiboken6/doc/typesystem_containers.rst b/sources/shiboken6/doc/typesystem_containers.rst
index ac22df558..c3a60a707 100644
--- a/sources/shiboken6/doc/typesystem_containers.rst
+++ b/sources/shiboken6/doc/typesystem_containers.rst
@@ -47,3 +47,15 @@ the STL and the Qt naming convention (which resembles Python's) are supported:
+-------------------------------------------+-----------------------------------+
| ``pop_front()``, ``removeFirst()`` | Removes the first element. |
+-------------------------------------------+-----------------------------------+
+ | ``reserve(size)`` | For containers that support it |
+ | | (``std::vector``, ``QList``), |
+ | | allocate memory for at least |
+ | | ``size`` elements, preventing |
+ | | reallocations. |
+ +-------------------------------------------+-----------------------------------+
+ | ``capacity()`` | For containers that support it |
+ | | (``std::vector``, ``QList``), |
+ | | return the number of elements |
+ | | that can be stored without |
+ | | reallocation. |
+ +-------------------------------------------+-----------------------------------+
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator_container.cpp b/sources/shiboken6/generator/shiboken/cppgenerator_container.cpp
index 1fa7fc463..7d20d2f16 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator_container.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator_container.cpp
@@ -175,6 +175,8 @@ CppGenerator::OpaqueContainerData
writeNoArgsMethod(s, privateObjType, "pop_front");
writeMethod(s, privateObjType, "pop_front", "removeFirst"); // Qt convention
}
+ writeMethod(s, privateObjType, "reserve");
+ writeNoArgsMethod(s, privateObjType, "capacity");
s << "{nullptr, nullptr, 0, nullptr} // Sentinel\n"
<< outdent << "};\n\n";
diff --git a/sources/shiboken6/libshiboken/sbkcontainer.h b/sources/shiboken6/libshiboken/sbkcontainer.h
index 97062a198..65bb8646e 100644
--- a/sources/shiboken6/libshiboken/sbkcontainer.h
+++ b/sources/shiboken6/libshiboken/sbkcontainer.h
@@ -67,6 +67,21 @@ struct ShibokenContainerValueConverter
static std::optional<Value> convertValueToCpp(PyObject pyArg);
};
+// SFINAE test for the presence of reserve() in a sequence container (std::vector/QList)
+template <typename T>
+class ShibokenContainerHasReserve
+{
+private:
+ using YesType = char[1];
+ using NoType = char[2];
+
+ template <typename C> static YesType& test( decltype(&C::reserve) ) ;
+ template <typename C> static NoType& test(...);
+
+public:
+ enum { value = sizeof(test<T>(nullptr)) == sizeof(YesType) };
+};
+
template <class SequenceContainer>
class ShibokenSequenceContainerPrivate // Helper for sequence type containers
{
@@ -212,6 +227,40 @@ public:
Py_RETURN_NONE;
}
+ // Support for containers with reserve/capacity
+ static PyObject *reserve(PyObject *self, PyObject *pyArg)
+ {
+ auto *d = get(self);
+ if (PyLong_Check(pyArg) == 0) {
+ PyErr_SetString(PyExc_TypeError, "wrong type passed to reserve().");
+ return nullptr;
+ }
+ if (d->m_const) {
+ PyErr_SetString(PyExc_TypeError, msgModifyConstContainer);
+ return nullptr;
+ }
+
+ if constexpr (ShibokenContainerHasReserve<SequenceContainer>::value) {
+ const Py_ssize_t size = PyLong_AsSsize_t(pyArg);
+ d->m_list->reserve(size);
+ } else {
+ PyErr_SetString(PyExc_TypeError, "Container does not support reserve().");
+ return nullptr;
+ }
+
+ Py_RETURN_NONE;
+ }
+
+ static PyObject *capacity(PyObject *self)
+ {
+ Py_ssize_t result = -1;
+ if constexpr (ShibokenContainerHasReserve<SequenceContainer>::value) {
+ const auto *d = get(self);
+ result = d->m_list->capacity();
+ }
+ return PyLong_FromSsize_t(result);
+ }
+
static ShibokenSequenceContainerPrivate *get(PyObject *self)
{
auto *data = reinterpret_cast<ShibokenContainer *>(self);