[pypy-commit] pypy reflex-support: added overload tests

wlav noreply at buildbot.pypy.org
Fri Feb 17 23:40:06 CET 2012


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r52594:83cc067a5dfc
Date: 2012-02-16 13:57 -0800
http://bitbucket.org/pypy/pypy/changeset/83cc067a5dfc/

Log:	added overload tests

diff --git a/pypy/module/cppyy/test/Makefile b/pypy/module/cppyy/test/Makefile
--- a/pypy/module/cppyy/test/Makefile
+++ b/pypy/module/cppyy/test/Makefile
@@ -1,4 +1,4 @@
-dicts = example01Dict.so datatypesDict.so advancedcppDict.so stltypesDict.so operatorsDict.so fragileDict.so std_streamsDict.so
+dicts = example01Dict.so datatypesDict.so advancedcppDict.so overloadsDict.so stltypesDict.so operatorsDict.so fragileDict.so std_streamsDict.so
 all : $(dicts)
 
 ROOTSYS := ${ROOTSYS}
diff --git a/pypy/module/cppyy/test/overloads.cxx b/pypy/module/cppyy/test/overloads.cxx
new file mode 100644
--- /dev/null
+++ b/pypy/module/cppyy/test/overloads.cxx
@@ -0,0 +1,49 @@
+#include "overloads.h"
+
+
+a_overload::a_overload() { i1 = 42; i2 = -1; }
+
+ns_a_overload::a_overload::a_overload() { i1 = 88; i2 = -34; }
+int ns_a_overload::b_overload::f(const std::vector<int>* v) { return (*v)[0]; }
+
+ns_b_overload::a_overload::a_overload() { i1 = -33; i2 = 89; }
+
+b_overload::b_overload() { i1 = -2; i2 = 13; }
+
+c_overload::c_overload() {}
+int c_overload::get_int(a_overload* a)                { return a->i1; }
+int c_overload::get_int(ns_a_overload::a_overload* a) { return a->i1; }
+int c_overload::get_int(ns_b_overload::a_overload* a) { return a->i1; }
+int c_overload::get_int(short* p)                     { return *p; }
+int c_overload::get_int(b_overload* b)                { return b->i2; }
+int c_overload::get_int(int* p)                       { return *p; }
+
+d_overload::d_overload() {}
+int d_overload::get_int(int* p)                       { return *p; }
+int d_overload::get_int(b_overload* b)                { return b->i2; }
+int d_overload::get_int(short* p)                     { return *p; }
+int d_overload::get_int(ns_b_overload::a_overload* a) { return a->i1; }
+int d_overload::get_int(ns_a_overload::a_overload* a) { return a->i1; }
+int d_overload::get_int(a_overload* a)                { return a->i1; }
+
+
+more_overloads::more_overloads() {}
+std::string more_overloads::call(const aa_ol&) { return "aa_ol"; }
+std::string more_overloads::call(const bb_ol&, void* n) { n = 0; return "bb_ol"; }
+std::string more_overloads::call(const cc_ol&) { return "cc_ol"; }
+std::string more_overloads::call(const dd_ol&) { return "dd_ol"; }
+
+std::string more_overloads::call_unknown(const dd_ol&) { return "dd_ol"; }
+
+std::string more_overloads::call(double)  { return "double"; }
+std::string more_overloads::call(int)     { return "int"; }
+std::string more_overloads::call1(int)    { return "int"; }
+std::string more_overloads::call1(double) { return "double"; }
+
+
+more_overloads2::more_overloads2() {}
+std::string more_overloads2::call(const bb_ol&) { return "bb_olref"; }
+std::string more_overloads2::call(const bb_ol*) { return "bb_olptr"; }
+
+std::string more_overloads2::call(const dd_ol*, int) { return "dd_olptr"; }
+std::string more_overloads2::call(const dd_ol&, int) { return "dd_olref"; }
diff --git a/pypy/module/cppyy/test/overloads.h b/pypy/module/cppyy/test/overloads.h
new file mode 100644
--- /dev/null
+++ b/pypy/module/cppyy/test/overloads.h
@@ -0,0 +1,90 @@
+#include <string>
+#include <vector>
+
+class a_overload {
+public:
+   a_overload();
+   int i1, i2;
+};
+
+namespace ns_a_overload {
+   class a_overload {
+   public:
+      a_overload();
+      int i1, i2;
+   };
+
+   class b_overload {
+   public:
+      int f(const std::vector<int>* v);
+   };
+}
+
+namespace ns_b_overload {
+   class a_overload {
+   public:
+      a_overload();
+      int i1, i2;
+   };
+}
+
+class b_overload {
+public:
+   b_overload();
+   int i1, i2;
+};
+
+class c_overload {
+public:
+   c_overload();
+   int get_int(a_overload* a);
+   int get_int(ns_a_overload::a_overload* a);
+   int get_int(ns_b_overload::a_overload* a);
+   int get_int(short* p);
+   int get_int(b_overload* b);
+   int get_int(int* p);
+};
+
+class d_overload {
+public:
+   d_overload();
+//   int get_int(void* p) { return *(int*)p; }
+   int get_int(int* p);
+   int get_int(b_overload* b);
+   int get_int(short* p);
+   int get_int(ns_b_overload::a_overload* a);
+   int get_int(ns_a_overload::a_overload* a);
+   int get_int(a_overload* a);
+};
+
+
+class aa_ol {};
+class bb_ol;
+class cc_ol {};
+class dd_ol;
+
+class more_overloads {
+public:
+   more_overloads();
+   std::string call(const aa_ol&);
+   std::string call(const bb_ol&, void* n=0);
+   std::string call(const cc_ol&);
+   std::string call(const dd_ol&);
+
+   std::string call_unknown(const dd_ol&);
+
+   std::string call(double);
+   std::string call(int);
+   std::string call1(int);
+   std::string call1(double);
+};
+
+class more_overloads2 {
+public:
+   more_overloads2();
+   std::string call(const bb_ol&);
+   std::string call(const bb_ol*);
+
+   std::string call(const dd_ol*, int);
+   std::string call(const dd_ol&, int);
+};
diff --git a/pypy/module/cppyy/test/overloads.xml b/pypy/module/cppyy/test/overloads.xml
new file mode 100644
--- /dev/null
+++ b/pypy/module/cppyy/test/overloads.xml
@@ -0,0 +1,14 @@
+<lcgdict>
+
+  <class name="std::string" />
+
+  <class pattern="*_overload" />
+
+  <namespace pattern="ns_*_overload" />
+  <class pattern="ns_*_overload::*_overload" />
+
+  <class pattern="*_ol" />
+  <class name="more_overloads" />
+  <class name="more_overloads2" />
+
+</lcgdict>
diff --git a/pypy/module/cppyy/test/test_advancedcpp.py b/pypy/module/cppyy/test/test_advancedcpp.py
--- a/pypy/module/cppyy/test/test_advancedcpp.py
+++ b/pypy/module/cppyy/test/test_advancedcpp.py
@@ -18,8 +18,8 @@
     def setup_class(cls):
         cls.space = space
         env = os.environ
-        cls.w_test_dct  = space.wrap(test_dct)
-        cls.w_datatypes = cls.space.appexec([], """():
+        cls.w_test_dct = space.wrap(test_dct)
+        cls.w_advanced = cls.space.appexec([], """():
             import cppyy
             return cppyy.load_reflection_info(%r)""" % (test_dct, ))
 
diff --git a/pypy/module/cppyy/test/test_operators.py b/pypy/module/cppyy/test/test_operators.py
--- a/pypy/module/cppyy/test/test_operators.py
+++ b/pypy/module/cppyy/test/test_operators.py
@@ -20,7 +20,7 @@
         env = os.environ
         cls.w_N = space.wrap(5)    # should be imported from the dictionary
         cls.w_test_dct  = space.wrap(test_dct)
-        cls.w_datatypes = cls.space.appexec([], """():
+        cls.w_operators = cls.space.appexec([], """():
             import cppyy
             return cppyy.load_reflection_info(%r)""" % (test_dct, ))
 
diff --git a/pypy/module/cppyy/test/test_overloads.py b/pypy/module/cppyy/test/test_overloads.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cppyy/test/test_overloads.py
@@ -0,0 +1,136 @@
+import py, os, sys
+from pypy.conftest import gettestobjspace
+
+
+currpath = py.path.local(__file__).dirpath()
+test_dct = str(currpath.join("overloadsDict.so"))
+
+space = gettestobjspace(usemodules=['cppyy'])
+
+def setup_module(mod):
+    if sys.platform == 'win32':
+        py.test.skip("win32 not supported so far")
+    err = os.system("cd '%s' && make overloadsDict.so" % currpath)
+    if err:
+        raise OSError("'make' failed (see stderr)")
+
+class AppTestOVERLOADS:
+    def setup_class(cls):
+        cls.space = space
+        env = os.environ
+        cls.w_test_dct  = space.wrap(test_dct)
+        cls.w_overloads = cls.space.appexec([], """():
+            import cppyy
+            return cppyy.load_reflection_info(%r)""" % (test_dct, ))
+
+    def test01_class_based_overloads(self):
+        """Test functions overloaded on different C++ clases"""
+
+        import cppyy
+        a_overload = cppyy.gbl.a_overload
+        b_overload = cppyy.gbl.b_overload
+        c_overload = cppyy.gbl.c_overload
+        d_overload = cppyy.gbl.d_overload
+
+        ns_a_overload = cppyy.gbl.ns_a_overload
+        ns_b_overload = cppyy.gbl.ns_b_overload
+
+        assert c_overload().get_int(a_overload()) == 42
+        assert c_overload().get_int(b_overload()) == 13
+        assert d_overload().get_int(a_overload()) == 42
+        assert d_overload().get_int(b_overload()) == 13
+
+        assert c_overload().get_int(ns_a_overload.a_overload()) ==  88
+        assert c_overload().get_int(ns_b_overload.a_overload()) == -33
+
+        assert d_overload().get_int(ns_a_overload.a_overload()) ==  88
+        assert d_overload().get_int(ns_b_overload.a_overload()) == -33
+
+    def test02_class_based_overloads_explicit_resolution(self):
+        """Test explicitly resolved function overloads"""
+
+        # TODO: write disp() or equivalent on methods for ol selection
+
+        import cppyy
+        a_overload = cppyy.gbl.a_overload
+        b_overload = cppyy.gbl.b_overload
+        c_overload = cppyy.gbl.c_overload
+        d_overload = cppyy.gbl.d_overload
+
+        ns_a_overload = cppyy.gbl.ns_a_overload
+
+        c = c_overload()
+#        raises(TypeError, c.get_int.disp, 12)
+#        assert c.get_int.disp('a_overload* a')(a_overload()) == 42
+#        assert c.get_int.disp('b_overload* b')(b_overload()) == 13
+
+#        assert c_overload().get_int.disp('a_overload* a')(a_overload())  == 42
+#        assert c_overload.get_int.disp('b_overload* b')(c, b_overload()) == 13
+
+        d = d_overload()
+#        assert d.get_int.disp('a_overload* a')(a_overload()) == 42
+#        assert d.get_int.disp('b_overload* b')(b_overload()) == 13
+
+        nb = ns_a_overload.b_overload()
+        raises(TypeError, nb.f, c_overload())
+
+    def test03_fragile_class_based_overloads(self):
+        """Test functions overloaded on void* and non-existing classes"""
+
+        # TODO: make Reflex generate unknown classes ...
+
+        import cppyy
+        more_overloads = cppyy.gbl.more_overloads
+        aa_ol = cppyy.gbl.aa_ol
+#        bb_ol = cppyy.gbl.bb_ol
+        cc_ol = cppyy.gbl.cc_ol
+#        dd_ol = cppyy.gbl.dd_ol
+
+        assert more_overloads().call(aa_ol()).c_str() == "aa_ol"
+#        assert more_overloads().call(bb_ol()).c_str() == "dd_ol"    # <- bb_ol has an unknown + void*
+        assert more_overloads().call(cc_ol()).c_str() == "cc_ol"
+#        assert more_overloads().call(dd_ol()).c_str() == "dd_ol"    # <- dd_ol has an unknown
+
+    def test04_fully_fragile_overloads(self):
+        """Test that unknown* is preferred over unknown&"""
+
+        # TODO: make Reflex generate unknown classes ...
+        return
+
+        import cppyy
+        more_overloads2 = cppyy.gbl.more_overloads2
+        bb_ol = cppyy.gbl.bb_ol
+        dd_ol = cppyy.gbl.dd_ol
+
+        assert more_overloads2().call(bb_ol())    == "bb_olptr"
+        assert more_overloads2().call(dd_ol(), 1) == "dd_olptr"
+
+    def test05_array_overloads(self):
+        """Test functions overloaded on different arrays"""
+
+        # TODO: buffer to pointer interface
+        return
+
+        import cppyy
+        c_overload = cppyy.gbl.c_overload
+
+        from array import array
+
+        ai = array('i', [525252])
+        assert c_overload().get_int(ai) == 525252
+        assert d_overload().get_int(ai) == 525252
+
+        ah = array('h', [25])
+        assert c_overload().get_int(ah) == 25
+        assert d_overload().get_int(ah) == 25
+
+    def test06_double_int_overloads(self):
+        """Test overloads on int/doubles"""
+
+        import cppyy
+        more_overloads = cppyy.gbl.more_overloads
+
+#        assert more_overloads().call(1).c_str()   == "int"
+#        assert more_overloads().call(1.).c_str()  == "double"
+        assert more_overloads().call1(1).c_str()  == "int"
+        assert more_overloads().call1(1.).c_str() == "double"


More information about the pypy-commit mailing list