Author: Wim Lavrijsen <[email protected]>
Branch: reflex-support
Changeset: r45187:5a71dcc697ce
Date: 2011-06-27 17:32 -0700
http://bitbucket.org/pypy/pypy/changeset/5a71dcc697ce/
Log: further STL support and initial class-specific pythonizations
diff --git a/pypy/module/cppyy/executor.py b/pypy/module/cppyy/executor.py
--- a/pypy/module/cppyy/executor.py
+++ b/pypy/module/cppyy/executor.py
@@ -77,13 +77,23 @@
_immutable_ = True
libffitype = libffi.types.slong
+ def _wrap_result(self, space, result):
+ return space.wrap(result)
+
def execute(self, space, func, cppthis, num_args, args):
result = capi.c_call_l(func.cpptype.handle, func.method_index,
cppthis, num_args, args)
- return space.wrap(result)
+ return self._wrap_result(space, result)
def execute_libffi(self, space, libffifunc, argchain):
return space.wrap(libffifunc.call(argchain, lltype.Signed))
+class ConstLongRefExecutor(LongExecutor):
+ _immutable_ = True
+
+ def _wrap_result(self, space, result):
+ longptr = rffi.cast(rffi.LONGP, result)
+ return space.wrap(longptr[0])
+
class FloatExecutor(FunctionExecutor):
_immutable_ = True
@@ -170,6 +180,7 @@
# 2) drop '&': by-ref is pretty much the same as by-value, python-wise
if compound and compound[len(compound)-1] == "&":
+ # TODO: this does not actually work with Reflex (?)
try:
return _executors[clean_name](space, "", None)
except KeyError:
@@ -203,6 +214,8 @@
_executors["unsigned short int*"] = ShortPtrExecutor
_executors["int"] = LongExecutor
_executors["int*"] = LongPtrExecutor
+_executors["const int&"] = ConstLongRefExecutor
+_executors["int&"] = ConstLongRefExecutor
_executors["unsigned int"] = LongExecutor
_executors["unsigned int*"] = LongPtrExecutor
_executors["long int"] = LongExecutor
diff --git a/pypy/module/cppyy/helper.py b/pypy/module/cppyy/helper.py
--- a/pypy/module/cppyy/helper.py
+++ b/pypy/module/cppyy/helper.py
@@ -55,7 +55,7 @@
#- operator mappings --------------------------------------------------------
_operator_mappings = {}
-def map_operator_name(cppname, nargs):
+def map_operator_name(cppname, nargs, result_type):
from pypy.module.cppyy import capi
if cppname[0:8] == "operator":
@@ -72,6 +72,14 @@
except KeyError:
pass
+ # return-type dependent mapping
+ if op == "[]":
+ if result_type.find("const") != 0:
+ cpd = compound(result_type)
+ if cpd and cpd[len(cpd)-1] == "&":
+ return "__setitem__"
+ return "__getitem__"
+
# a couple more cases that depend on whether args were given
if op == "*": # dereference (not python) vs. multiplication
@@ -98,7 +106,7 @@
# _operator_mappings["-"] = "__sub__" # id. (eq. __neg__)
# _operator_mappings["*"] = "__mul__" # double meaning in C++
-_operator_mappings["[]"] = "__getitem__"
+# _operator_mappings["[]"] = "__getitem__" # depends on return type
_operator_mappings["()"] = "__call__"
_operator_mappings["/"] = "__div__" # __truediv__ in p3
_operator_mappings["%"] = "__mod__"
diff --git a/pypy/module/cppyy/interp_cppyy.py
b/pypy/module/cppyy/interp_cppyy.py
--- a/pypy/module/cppyy/interp_cppyy.py
+++ b/pypy/module/cppyy/interp_cppyy.py
@@ -338,7 +338,8 @@
for i in range(num_methods):
method_name = capi.charp2str_free(capi.c_method_name(self.handle,
i))
pymethod_name = helper.map_operator_name(
- method_name, capi.c_method_num_args(self.handle, i))
+ method_name, capi.c_method_num_args(self.handle, i),
+ capi.charp2str_free(capi.c_method_result_type(self.handle, i)))
cppfunction = self._make_cppfunction(i)
overload = args_temp.setdefault(pymethod_name, [])
overload.append(cppfunction)
diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py
--- a/pypy/module/cppyy/pythonify.py
+++ b/pypy/module/cppyy/pythonify.py
@@ -153,6 +153,7 @@
if cppdm.is_static():
setattr(metacpp, dm_name, cppdm)
+ _pythonize(pycpptype)
return pycpptype
def make_cpptemplatetype(template_name, scope):
@@ -195,6 +196,14 @@
get_cppclass = get_cppitem # TODO: restrict to classes only (?)
+def _pythonize(pyclass):
+
+ # map size -> __len__ (generally true for STL)
+ if hasattr(pyclass, 'size') and \
+ not hasattr(pyclass,'__len__') and callable(pyclass.size):
+ pyclass.__len__ = pyclass.size
+
+
_loaded_shared_libs = {}
def load_lib(name):
try:
diff --git a/pypy/module/cppyy/test/test_stltypes.py
b/pypy/module/cppyy/test/test_stltypes.py
--- a/pypy/module/cppyy/test/test_stltypes.py
+++ b/pypy/module/cppyy/test/test_stltypes.py
@@ -43,8 +43,9 @@
for i in range(self.N):
v.push_back(i)
assert v.size() == i+1
-# assert v[i] == i
+ assert v.at(i) == i
+ assert v[i] == i
assert v.size() == self.N
-# assert len(v) == self.N
+ assert len(v) == self.N
v.destruct()
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit