diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2022-01-06 09:30:45 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-01-06 14:43:30 +0000 |
commit | 9bb79adbcc76b58c9b76cb4f671cdde9bb8f1ae3 (patch) | |
tree | 7f528be9ddb10b22abb051aa7895cc118b33cc62 | |
parent | 4bb3abd257fceca2a638d4d5099d02b7162d747f (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.py | 1 | ||||
-rw-r--r-- | sources/shiboken6/doc/typesystem_containers.rst | 12 | ||||
-rw-r--r-- | sources/shiboken6/generator/shiboken/cppgenerator_container.cpp | 2 | ||||
-rw-r--r-- | sources/shiboken6/libshiboken/sbkcontainer.h | 49 |
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); |