Author: Wim Lavrijsen <wlavrij...@lbl.gov> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit