wlav avatar wlav committed 1ea72a9

tests for STL map and allow iterations over std::pair

Comments (0)

Files changed (4)

pypy/module/cppyy/pythonify.py

                 return self.c_str() == other.c_str()
             else:
                 return self.c_str() == other
-        pyclass.__eq__ = eq
+        pyclass.__eq__  = eq
         pyclass.__str__ = pyclass.c_str
 
+    # std::pair unpacking through iteration
+    if 'std::pair' in pyclass.__name__:
+        def getitem(self, idx):
+            if idx == 0: return self.first
+            if idx == 1: return self.second
+            raise IndexError("out of bounds")
+        def return2(self):
+            return 2
+        pyclass.__getitem__ = getitem
+        pyclass.__len__     = return2
+
 _loaded_dictionaries = {}
 def load_reflection_info(name):
     """Takes the name of a library containing reflection info, returns a handle

pypy/module/cppyy/test/stltypes.h

 #include <list>
 #include <map>
 #include <string>
+#include <utility>
 #include <vector>
 
 //- basic example class
    std::STLTYPE<TTYPE >::iterator STLTYPE##_##N##_i;                         \
    std::STLTYPE<TTYPE >::const_iterator STLTYPE##_##N##_ci
 
+#define STLTYPE_INSTANTIATION2(STLTYPE, TTYPE1, TTYPE2, N)                   \
+   std::STLTYPE<TTYPE1, TTYPE2 > STLTYPE##_##N;                              \
+   std::pair<TTYPE1, TTYPE2 > STLTYPE##_##N##_p;                             \
+   std::pair<const TTYPE1, TTYPE2 > STLTYPE##_##N##_cp;                      \
+   std::STLTYPE<TTYPE1, TTYPE2 >::iterator STLTYPE##_##N##_i;                \
+   std::STLTYPE<TTYPE1, TTYPE2 >::const_iterator STLTYPE##_##N##_ci
+
+
 //- instantiations of used STL types
 namespace {
 
 
     struct _CppyyListInstances {
 
-        STLTYPE_INSTANTIATION(list, int,          1);
-        STLTYPE_INSTANTIATION(list, float,        2);
-        STLTYPE_INSTANTIATION(list, double,       3);
+        STLTYPE_INSTANTIATION(list, int,    1);
+        STLTYPE_INSTANTIATION(list, float,  2);
+        STLTYPE_INSTANTIATION(list, double, 3);
+
+    };
+
+    struct _CppyyMapInstances {
+
+        STLTYPE_INSTANTIATION2(map, int,         int, 1);
+        STLTYPE_INSTANTIATION2(map, std::string, int, 2);
 
     };
 

pypy/module/cppyy/test/stltypes.xml

   <class pattern="std::list<*>::const_iterator" />
   <class name="std::__detail::_List_node_base" />
 
+  <class pattern="std::map<*>" />
+  <class pattern="std::pair<*>" />
+  <class pattern="std::map<*>::iterator" />
+  <class pattern="std::map<*>::const_iterator" />
+
   <class pattern="__gnu_cxx::__normal_iterator<*>" />
 
   <!-- the following are for testing, not for iteration -->

pypy/module/cppyy/test/test_stltypes.py

         assert s == c.get_string1()
 
 
-class AppTestSTLSTRING:
+class AppTestSTLLIST:
     spaceconfig = dict(usemodules=['cppyy'])
 
     def setup_class(cls):
         for arg in a:
            pass
 
+
+class AppTestSTLMAP:
+    spaceconfig = dict(usemodules=['cppyy', 'itertools'])
+
+    def setup_class(cls):
+        cls.w_N = cls.space.wrap(13)
+        cls.w_test_dct  = cls.space.wrap(test_dct)
+        cls.w_stlstring = cls.space.appexec([], """():
+            import cppyy, math
+            return cppyy.load_reflection_info(%r)""" % (test_dct, ))
+
+    def test01_builtin_map_type(self):
+        """Test access to a map<int,int>"""
+
+        import cppyy
+        std = cppyy.gbl.std
+
+        a = std.map(int, int)()
+        for i in range(self.N):
+            a[i] = i
+            assert a[i] == i
+
+        assert len(a) == self.N
+
+        for key, value in a:
+            assert key == value
+        assert key   == self.N-1
+        assert value == self.N-1
+
+        # add a variation, just in case
+        m = std.map(int, int)()
+        for i in range(self.N):
+            m[i] = i*i
+            assert m[i] == i*i
+
+        for key, value in m:
+            assert key*key == value
+        assert key   == self.N-1
+        assert value == (self.N-1)*(self.N-1)
+
+    def test02_keyed_maptype(self):
+        """Test access to a map<std::string,int>"""
+
+        import cppyy
+        std = cppyy.gbl.std
+
+        a = std.map(std.string, int)()
+        for i in range(self.N):
+            a[str(i)] = i
+            import pdb
+            pdb.set_trace()
+            assert a[str(i)] == i
+
+        assert len(a) == self.N
+
+    def test03_empty_maptype(self):
+        """Test behavior of empty map<int,int>"""
+
+        import cppyy
+        std = cppyy.gbl.std
+
+        m = std.map(int, int)()
+        for key, value in m:
+           pass
+
+    def test04_unsignedvalue_typemap_types(self):
+        """Test assignability of maps with unsigned value types"""
+
+        import cppyy, math
+        std = cppyy.gbl.std
+
+        mui = std.map(str, 'unsigned int')()
+        mui['one'] = 1
+        assert mui['one'] == 1
+        raises(ValueError, mui.__setitem__, 'minus one', -1)
+
+        # UInt_t is always 32b, sys.maxint follows system int
+        maxint32 = int(math.pow(2,31)-1)
+        mui['maxint'] = maxint32 + 3
+        assert mui['maxint'] == maxint32 + 3
+
+        mul = std.map(str, 'unsigned long')()
+        mul['two'] = 2
+        assert mul['two'] == 2
+        mul['maxint'] = maxvalue + 3
+        assert mul['maxint'] == maxvalue + 3
+
+        raises(ValueError, mul.__setitem__, 'minus two', -2)
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.