From a7153388da75f64e546701d363c87067eab07095 Mon Sep 17 00:00:00 2001
From: Renato Araujo Oliveira Filho <renato.araujo@kdab.com>
Date: Mon, 18 Feb 2019 14:43:41 -0300
Subject: [PATCH] Create an example for function returning a list of smart
 pointers

---
 sources/shiboken2/tests/libsmart/smart.cpp    |  9 ++++++
 sources/shiboken2/tests/libsmart/smart.h      |  1 +
 .../tests/smartbinding/smart_pointer_test.py  | 20 ++++++++++++
 .../tests/smartbinding/typesystem_smart.xml   | 32 +++++++++++++++++++
 4 files changed, 62 insertions(+)

diff --git a/sources/shiboken2/tests/libsmart/smart.cpp b/sources/shiboken2/tests/libsmart/smart.cpp
index dbe8efa6..d553b249 100644
--- a/sources/shiboken2/tests/libsmart/smart.cpp
+++ b/sources/shiboken2/tests/libsmart/smart.cpp
@@ -62,6 +62,15 @@ SharedPtr<Obj> Obj::giveSharedPtrToObj()
     return o;
 }
 
+std::vector<SharedPtr<Obj> > Obj::giveSharedPtrToObjList(int size)
+{
+    std::vector<SharedPtr<Obj> > r;
+    for(int i=0; i < size; i++)
+        r.push_back(giveSharedPtrToObj());
+    return r;
+}
+
+
 SharedPtr<Integer> Obj::giveSharedPtrToInteger()
 {
     SharedPtr<Integer> o(new Integer);
diff --git a/sources/shiboken2/tests/libsmart/smart.h b/sources/shiboken2/tests/libsmart/smart.h
index ea64b443..4e24d126 100644
--- a/sources/shiboken2/tests/libsmart/smart.h
+++ b/sources/shiboken2/tests/libsmart/smart.h
@@ -198,6 +198,7 @@ public:
     void printObj();
     Integer takeInteger(Integer val);
     SharedPtr<Obj> giveSharedPtrToObj();
+    std::vector<SharedPtr<Obj> > giveSharedPtrToObjList(int size);
     SharedPtr<Integer> giveSharedPtrToInteger();
     int takeSharedPtrToObj(SharedPtr<Obj> pObj);
     int takeSharedPtrToInteger(SharedPtr<Integer> pInt);
diff --git a/sources/shiboken2/tests/smartbinding/smart_pointer_test.py b/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
index 730b4a0d..3e439335 100644
--- a/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
+++ b/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
@@ -143,5 +143,25 @@ class SmartPointerTests(unittest.TestCase):
         self.assertEqual(objCount(), 0)
         self.assertEqual(integerCount(), 0)
 
+    def testListOfSmartPointers(self):
+        # Create the main object
+        o = Obj()
+        self.assertEqual(objCount(), 1)
+
+        # Create a list of shared objects
+        ptrToObjList = o.giveSharedPtrToObjList(10)
+        self.assertEqual(len(ptrToObjList), 10)
+        self.assertEqual(objCount(), 11)
+
+        # Remove one from the list
+        ptrToObjList.pop()
+        self.assertEqual(len(ptrToObjList), 9)
+        self.assertEqual(objCount(), 10)
+
+        # clear and delete all objects in the list
+        ptrToObjList.clear()
+        self.assertEqual(len(ptrToObjList), 0)
+        self.assertEqual(objCount(), 1)
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/sources/shiboken2/tests/smartbinding/typesystem_smart.xml b/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
index a2654730..7969387f 100644
--- a/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
+++ b/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
@@ -5,6 +5,38 @@
     <primitive-type name="float" />
     <primitive-type name="bool" />
 
+    <template name="cpplist_to_pylist_convertion">
+    PyObject* %out = PyList_New((int) %in.size());
+    %INTYPE::const_iterator it = %in.begin();
+    for (int idx = 0; it != %in.end(); ++it, ++idx) {
+        %INTYPE_0 cppItem(*it);
+        PyList_SET_ITEM(%out, idx, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
+    }
+    return %out;
+    </template>
+    <template name="pyseq_to_cpplist_convertion">
+    Shiboken::AutoDecRef seq(PySequence_Fast(%in, 0));
+    for (int i = 0; i &lt; PySequence_Fast_GET_SIZE(seq.object()); i++) {
+        PyObject* pyItem = PySequence_Fast_GET_ITEM(seq.object(), i);
+        %OUTTYPE_0 cppItem = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
+        %out.push_back(cppItem);
+    }
+    </template>
+    <container-type name="std::vector" type="list">
+        <include file-name="list" location="global"/>
+        <conversion-rule>
+            <native-to-target>
+                <insert-template name="cpplist_to_pylist_convertion"/>
+            </native-to-target>
+            <target-to-native>
+                <add-conversion type="PySequence">
+                    <insert-template name="pyseq_to_cpplist_convertion"/>
+                </add-conversion>
+            </target-to-native>
+        </conversion-rule>
+    </container-type>
+
+
     <!-- Used in tests to check what C++ objects are allocated. -->
     <object-type name="Registry" />
 
-- 
2.17.1

