From 504cf3341c0622c16d4283eef58aed9fe9c35036 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 21 Dec 2022 16:01:59 +0100 Subject: shiboken6: Add support for std::span Convert std::span to a Python list. For the conversion from Python to C++, make it a view on a vector. A special type is introduced since a different implementation is needed for opaque containers. Task-number: PYSIDE-2174 Change-Id: I17a7385282a7d373dc73d5ac63a5d3363d61d130 Reviewed-by: Cristian Maureira-Fredes Reviewed-by: Qt CI Bot --- .../shiboken6/ApiExtractor/containertypeentry.h | 1 + sources/shiboken6/ApiExtractor/typedatabase.cpp | 10 ++++++ sources/shiboken6/ApiExtractor/typesystem.cpp | 1 + .../shiboken6/ApiExtractor/typesystemparser.cpp | 3 +- sources/shiboken6/doc/typesystem_builtin_types.rst | 13 +++---- sources/shiboken6/doc/typesystem_converters.rst | 10 +++--- .../shiboken6/generator/shiboken/cppgenerator.cpp | 1 + .../generator/shiboken/shibokengenerator.cpp | 1 + sources/shiboken6/tests/libminimal/CMakeLists.txt | 1 + sources/shiboken6/tests/libminimal/spanuser.cpp | 41 ++++++++++++++++++++++ sources/shiboken6/tests/libminimal/spanuser.h | 31 ++++++++++++++++ .../shiboken6/tests/minimalbinding/CMakeLists.txt | 1 + sources/shiboken6/tests/minimalbinding/global.h | 1 + .../tests/minimalbinding/spanuser_test.py | 31 ++++++++++++++++ .../tests/minimalbinding/typesystem_minimal.xml | 2 ++ 15 files changed, 136 insertions(+), 12 deletions(-) create mode 100644 sources/shiboken6/tests/libminimal/spanuser.cpp create mode 100644 sources/shiboken6/tests/libminimal/spanuser.h create mode 100644 sources/shiboken6/tests/minimalbinding/spanuser_test.py diff --git a/sources/shiboken6/ApiExtractor/containertypeentry.h b/sources/shiboken6/ApiExtractor/containertypeentry.h index 0f1e03054..b2003816b 100644 --- a/sources/shiboken6/ApiExtractor/containertypeentry.h +++ b/sources/shiboken6/ApiExtractor/containertypeentry.h @@ -29,6 +29,7 @@ public: MapContainer, MultiMapContainer, PairContainer, + SpanContainer, // Fixed size }; explicit ContainerTypeEntry(const QString &entryName, ContainerKind containerKind, diff --git a/sources/shiboken6/ApiExtractor/typedatabase.cpp b/sources/shiboken6/ApiExtractor/typedatabase.cpp index 240ad0df8..8f232aee1 100644 --- a/sources/shiboken6/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken6/ApiExtractor/typedatabase.cpp @@ -862,6 +862,7 @@ void TypeDatabasePrivate::addBuiltInContainerTypes(const TypeDatabaseParserConte const bool hasStdVector = findType(u"std::vector"_s) != nullptr; const bool hasStdMap = findType(u"std::map"_s) != nullptr; const bool hasStdUnorderedMap = findType(u"std::unordered_map"_s) != nullptr; + const bool hasStdSpan = findType(u"std::span"_s) != nullptr; if (hasStdPair && hasStdList && hasStdVector && hasStdMap && hasStdUnorderedMap) return; @@ -906,6 +907,15 @@ void TypeDatabasePrivate::addBuiltInContainerTypes(const TypeDatabaseParserConte "shiboken_conversion_stdmap_to_pydict", "PyDict", "shiboken_conversion_pydict_to_stdmap"); } + if (!hasStdSpan) { + auto spanSnip = containerTypeSystemSnippet( + "std::span", "span", "span", + "shiboken_conversion_cppsequence_to_pylist"); + auto pos = spanSnip.indexOf('>'); + spanSnip.insert(pos, R"( view-on="std::vector")"); + ts += spanSnip; + } + ts += ""; QBuffer buffer(&ts); buffer.open(QIODevice::ReadOnly); diff --git a/sources/shiboken6/ApiExtractor/typesystem.cpp b/sources/shiboken6/ApiExtractor/typesystem.cpp index 541c84484..6a0870914 100644 --- a/sources/shiboken6/ApiExtractor/typesystem.cpp +++ b/sources/shiboken6/ApiExtractor/typesystem.cpp @@ -1884,6 +1884,7 @@ qsizetype ContainerTypeEntry::templateParameterCount() const case MapContainer: case MultiMapContainer: case PairContainer: + case SpanContainer: result = 2; break; case ListContainer: diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp index 26b9fc94a..632bb4451 100644 --- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp +++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp @@ -375,7 +375,8 @@ ENUM_LOOKUP_BEGIN(ContainerTypeEntry::ContainerKind, Qt::CaseSensitive, {u"multi-map", ContainerTypeEntry::MultiMapContainer}, {u"hash", ContainerTypeEntry::MapContainer}, {u"multi-hash", ContainerTypeEntry::MultiMapContainer}, - {u"pair", ContainerTypeEntry::PairContainer} + {u"pair", ContainerTypeEntry::PairContainer}, + {u"span", ContainerTypeEntry::SpanContainer} }; ENUM_LOOKUP_LINEAR_SEARCH() diff --git a/sources/shiboken6/doc/typesystem_builtin_types.rst b/sources/shiboken6/doc/typesystem_builtin_types.rst index 133396d8e..dea253930 100644 --- a/sources/shiboken6/doc/typesystem_builtin_types.rst +++ b/sources/shiboken6/doc/typesystem_builtin_types.rst @@ -32,12 +32,13 @@ on platform. C++ Container Types ^^^^^^^^^^^^^^^^^^^ -Since version 6.3, some common standard containers (``std::list``, -``std::vector``, ``std::pair``, ``std::map`` and ``std::unordered_map``) -are built-in. They only need to be specified if :ref:`opaque-containers` -should be generated. In this case, the appropriate -:ref:`predefined conversion templates ` -should be specified. +The C++ containers ``std::list``\, ``std::vector``\, +``std::pair``\, ``std::map``\, ``std::span`` and ``std::unordered_map`` are +built-in. +To specify :ref:`opaque-containers`, use the :ref:`opaque-container` element. +:ref:`container-type` can still be specified to modify the built-in behavior. +For this case, a number of pre-defined conversion templates +are provided (see :ref:`predefined_templates`). .. _cpython-types: diff --git a/sources/shiboken6/doc/typesystem_converters.rst b/sources/shiboken6/doc/typesystem_converters.rst index 02600e7b1..1de39f020 100644 --- a/sources/shiboken6/doc/typesystem_converters.rst +++ b/sources/shiboken6/doc/typesystem_converters.rst @@ -175,11 +175,11 @@ defined (or automatically generated) for the containers. -.. note:: From version 6.3, we do not have to explicitly specify the - `` for C++ containers ``std::list``\, ``std::vector``\, - ``std::pair``\, ``std::map`` and ``std::unordered_map``\. They are - now built-in. However, they still have to be added for opaque - containers or when modifying the built-in behavior. +.. note:: The C++ containers ``std::list``\, ``std::vector``\, + ``std::pair``\, ``std::map``\, ``std::span`` and ``std::unordered_map`` are + built-in. + To specify :ref:`opaque-containers`, use the :ref:`opaque-container` element. + :ref:`container-type` can still be specified to modify the built-in behavior. For this case, a number of pre-defined conversion templates are provided (see :ref:`predefined_templates`). diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index c26d06999..9f2d74093 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -1143,6 +1143,7 @@ QString CppGenerator::getVirtualFunctionReturnTypeName(const AbstractMetaFunctio const auto cte = std::static_pointer_cast(typeEntry); switch (cte->containerKind()) { case ContainerTypeEntry::ListContainer: + case ContainerTypeEntry::SpanContainer: break; case ContainerTypeEntry::SetContainer: return uR"("set")"_s; diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp index 55851e650..071fa1f66 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp @@ -576,6 +576,7 @@ QString ShibokenGenerator::containerCpythonBaseName(const ContainerTypeEntryCPtr return u"PyDict"_s; case ContainerTypeEntry::ListContainer: case ContainerTypeEntry::PairContainer: + case ContainerTypeEntry::SpanContainer: break; default: Q_ASSERT(false); diff --git a/sources/shiboken6/tests/libminimal/CMakeLists.txt b/sources/shiboken6/tests/libminimal/CMakeLists.txt index 8a5ad4fe2..4a10f96bf 100644 --- a/sources/shiboken6/tests/libminimal/CMakeLists.txt +++ b/sources/shiboken6/tests/libminimal/CMakeLists.txt @@ -9,6 +9,7 @@ libminimalmacros.h listuser.cpp listuser.h minbool.h obj.cpp obj.h +spanuser.cpp spanuser.h typedef.cpp typedef.h val.h ) diff --git a/sources/shiboken6/tests/libminimal/spanuser.cpp b/sources/shiboken6/tests/libminimal/spanuser.cpp new file mode 100644 index 000000000..1fcfe1e97 --- /dev/null +++ b/sources/shiboken6/tests/libminimal/spanuser.cpp @@ -0,0 +1,41 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "spanuser.h" + +#include + +SpanUser::SpanUser() = default; + +bool SpanUser::enabled() +{ +#if __cplusplus >= 202002L + return true; +#else + return false; +#endif +} + +#if __cplusplus >= 202002L +IntSpan3 SpanUser::getIntSpan3() +{ + static int iv[] = {1, 2, 3}; + return IntSpan3(iv); +} + +ConstIntSpan3 SpanUser::getConstIntSpan3() +{ + static const int civ[] = {1, 2, 3}; + return ConstIntSpan3(civ); +} + +int SpanUser::sumIntSpan3(IntSpan3 isp3) +{ + return std::accumulate(isp3.begin(), isp3.end(), 0); +} + +int SpanUser::sumConstIntSpan3(ConstIntSpan3 ispc3) +{ + return std::accumulate(ispc3.begin(), ispc3.end(), 0); +} +#endif // C++ 20 diff --git a/sources/shiboken6/tests/libminimal/spanuser.h b/sources/shiboken6/tests/libminimal/spanuser.h new file mode 100644 index 000000000..ad6a0f2df --- /dev/null +++ b/sources/shiboken6/tests/libminimal/spanuser.h @@ -0,0 +1,31 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef SPANUSER_H +#define SPANUSER_H + +#include "libminimalmacros.h" + +#if __cplusplus >= 202002L +# include + +using IntSpan3 = std::span; +using ConstIntSpan3 = std::span; +#endif + +struct LIBMINIMAL_API SpanUser +{ + SpanUser(); + + static bool enabled(); + +#if __cplusplus >= 202002L + static IntSpan3 getIntSpan3(); + static ConstIntSpan3 getConstIntSpan3(); + + static int sumIntSpan3(IntSpan3 isp3); + static int sumConstIntSpan3(ConstIntSpan3 ispc3); +#endif // C++ 20 +}; + +#endif // SPANUSER_H diff --git a/sources/shiboken6/tests/minimalbinding/CMakeLists.txt b/sources/shiboken6/tests/minimalbinding/CMakeLists.txt index ffbf9f111..7f132bd34 100644 --- a/sources/shiboken6/tests/minimalbinding/CMakeLists.txt +++ b/sources/shiboken6/tests/minimalbinding/CMakeLists.txt @@ -13,6 +13,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/minimal/containeruser_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/minimal/obj_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/minimal/val_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/minimal/listuser_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/minimal/spanuser_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/minimal/minbooluser_wrapper.cpp ) diff --git a/sources/shiboken6/tests/minimalbinding/global.h b/sources/shiboken6/tests/minimalbinding/global.h index 4e792705a..fc5c59a26 100644 --- a/sources/shiboken6/tests/minimalbinding/global.h +++ b/sources/shiboken6/tests/minimalbinding/global.h @@ -6,4 +6,5 @@ #include "val.h" #include "minbool.h" #include "listuser.h" +#include "spanuser.h" #include "typedef.h" diff --git a/sources/shiboken6/tests/minimalbinding/spanuser_test.py b/sources/shiboken6/tests/minimalbinding/spanuser_test.py new file mode 100644 index 000000000..ee384eb81 --- /dev/null +++ b/sources/shiboken6/tests/minimalbinding/spanuser_test.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() + +from minimal import SpanUser + + +class IntSpanTest(unittest.TestCase): + + def testCreateIntSpan(self): + if not SpanUser.enabled(): + return + expected = [1, 2, 3] + self.assertEqual(SpanUser.getIntSpan3(), expected) + self.assertEqual(SpanUser.getConstIntSpan3(), expected) + + self.assertEqual(SpanUser.sumIntSpan3(expected), 6) + self.assertEqual(SpanUser.sumConstIntSpan3(expected), 6) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml b/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml index e73ddc228..ef317f415 100644 --- a/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml +++ b/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml @@ -38,6 +38,8 @@ + + -- cgit v1.2.3