Author: Wim Lavrijsen <wlavrij...@lbl.gov> Branch: cppyy-packaging Changeset: r94856:8820afbc98c3 Date: 2018-07-12 20:23 -0700 http://bitbucket.org/pypy/pypy/changeset/8820afbc98c3/
Log: moves for strings (incl. from temporary python str) diff --git a/pypy/module/_cppyy/converter.py b/pypy/module/_cppyy/converter.py --- a/pypy/module/_cppyy/converter.py +++ b/pypy/module/_cppyy/converter.py @@ -622,7 +622,6 @@ self.ref_buffer = lltype.nullptr(rffi.VOIDPP.TO) class StdStringConverter(InstanceConverter): - def __init__(self, space, extra): from pypy.module._cppyy import interp_cppyy cppclass = interp_cppyy.scope_byname(space, capi.std_string_name) @@ -648,6 +647,34 @@ def free_argument(self, space, arg): capi.c_destruct(space, self.clsdecl, rffi.cast(capi.C_OBJECT, rffi.cast(rffi.VOIDPP, arg)[0])) +class StdStringMoveConverter(StdStringConverter): + def _unwrap_object(self, space, w_obj): + # moving is same as by-ref, but have to check that move is allowed + moveit_reason = 3 + from pypy.module._cppyy.interp_cppyy import W_CPPInstance, INSTANCE_FLAGS_IS_RVALUE + try: + obj = space.interp_w(W_CPPInstance, w_obj) + if obj and obj.rt_flags & INSTANCE_FLAGS_IS_RVALUE: + obj.rt_flags &= ~INSTANCE_FLAGS_IS_RVALUE + moveit_reason = 1 + else: + moveit_reason = 0 + except: + pass + + if moveit_reason: + try: + return StdStringConverter._unwrap_object(self, space, w_obj) + except Exception: + if moveit_reason == 1: + # TODO: if the method fails on some other converter, then the next + # overload can not be an rvalue anymore + obj = space.interp_w(W_CPPInstance, w_obj) + obj.rt_flags |= INSTANCE_FLAGS_IS_RVALUE + raise + + raise oefmt(space.w_ValueError, "object is not an rvalue") + class StdStringRefConverter(InstancePtrConverter): _immutable_fields_ = ['cppclass', 'typecode'] typecode = 'V' @@ -900,6 +927,7 @@ _converters["std::basic_string<char>"] = StdStringConverter _converters["const std::basic_string<char>&"] = StdStringConverter # TODO: shouldn't copy _converters["std::basic_string<char>&"] = StdStringRefConverter +_converters["std::basic_string<char>&&"] = StdStringMoveConverter _converters["PyObject*"] = PyObjectConverter @@ -1017,6 +1045,7 @@ ("std::basic_string<char>", "string"), ("const std::basic_string<char>&", "const string&"), ("std::basic_string<char>&", "string&"), + ("std::basic_string<char>&&", "string&&"), ("PyObject*", "_object*"), ) 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 @@ -22,12 +22,12 @@ def test01_builtin_type_vector_types(self): """Test access to std::vector<int>/std::vector<double>""" - import _cppyy + import _cppyy as cppyy - assert _cppyy.gbl.std is _cppyy.gbl.std - assert _cppyy.gbl.std.vector is _cppyy.gbl.std.vector + assert cppyy.gbl.std is cppyy.gbl.std + assert cppyy.gbl.std.vector is cppyy.gbl.std.vector - assert callable(_cppyy.gbl.std.vector) + assert callable(cppyy.gbl.std.vector) type_info = ( ("int", int), @@ -36,10 +36,10 @@ ) for c_type, p_type in type_info: - tv1 = getattr(_cppyy.gbl.std, 'vector<%s>' % c_type) - tv2 = _cppyy.gbl.std.vector(p_type) + tv1 = getattr(cppyy.gbl.std, 'vector<%s>' % c_type) + tv2 = cppyy.gbl.std.vector(p_type) assert tv1 is tv2 - assert tv1.iterator is _cppyy.gbl.std.vector(p_type).iterator + assert tv1.iterator is cppyy.gbl.std.vector(p_type).iterator #----- v = tv1(); v += range(self.N) # default args from Reflex are useless :/ @@ -73,16 +73,16 @@ def test02_user_type_vector_type(self): """Test access to an std::vector<just_a_class>""" - import _cppyy + import _cppyy as cppyy - assert _cppyy.gbl.std is _cppyy.gbl.std - assert _cppyy.gbl.std.vector is _cppyy.gbl.std.vector + assert cppyy.gbl.std is cppyy.gbl.std + assert cppyy.gbl.std.vector is cppyy.gbl.std.vector - assert callable(_cppyy.gbl.std.vector) + assert callable(cppyy.gbl.std.vector) - tv1 = getattr(_cppyy.gbl.std, 'vector<just_a_class>') - tv2 = _cppyy.gbl.std.vector('just_a_class') - tv3 = _cppyy.gbl.std.vector(_cppyy.gbl.just_a_class) + tv1 = getattr(cppyy.gbl.std, 'vector<just_a_class>') + tv2 = cppyy.gbl.std.vector('just_a_class') + tv3 = cppyy.gbl.std.vector(cppyy.gbl.just_a_class) assert tv1 is tv2 assert tv2 is tv3 @@ -95,7 +95,7 @@ assert hasattr(v, 'end' ) for i in range(self.N): - v.push_back(_cppyy.gbl.just_a_class()) + v.push_back(cppyy.gbl.just_a_class()) v[i].m_i = i assert v[i].m_i == i @@ -105,9 +105,9 @@ def test03_empty_vector_type(self): """Test behavior of empty std::vector<int>""" - import _cppyy + import _cppyy as cppyy - v = _cppyy.gbl.std.vector(int)() + v = cppyy.gbl.std.vector(int)() for arg in v: pass v.__destruct__() @@ -115,9 +115,9 @@ def test04_vector_iteration(self): """Test iteration over an std::vector<int>""" - import _cppyy + import _cppyy as cppyy - v = _cppyy.gbl.std.vector(int)() + v = cppyy.gbl.std.vector(int)() for i in range(self.N): v.push_back(i) @@ -140,9 +140,9 @@ def test05_push_back_iterables_with_iadd(self): """Test usage of += of iterable on push_back-able container""" - import _cppyy + import _cppyy as cppyy - v = _cppyy.gbl.std.vector(int)() + v = cppyy.gbl.std.vector(int)() v += [1, 2, 3] assert len(v) == 3 @@ -159,7 +159,7 @@ raises(TypeError, v.__iadd__, (7, '8')) # string shouldn't pass assert len(v) == 7 # TODO: decide whether this should roll-back - v2 = _cppyy.gbl.std.vector(int)() + v2 = cppyy.gbl.std.vector(int)() v2 += [8, 9] assert len(v2) == 2 assert v2[0] == 8 @@ -174,9 +174,9 @@ def test06_vector_indexing(self): """Test python-style indexing to an std::vector<int>""" - import _cppyy + import _cppyy as cppyy - v = _cppyy.gbl.std.vector(int)() + v = cppyy.gbl.std.vector(int)() for i in range(self.N): v.push_back(i) @@ -209,9 +209,9 @@ def test01_string_argument_passing(self): """Test mapping of python strings and std::string""" - import _cppyy - std = _cppyy.gbl.std - stringy_class = _cppyy.gbl.stringy_class + import _cppyy as cppyy + std = cppyy.gbl.std + stringy_class = cppyy.gbl.stringy_class c, s = stringy_class(""), std.string("test1") @@ -240,9 +240,9 @@ def test02_string_data_access(self): """Test access to std::string object data members""" - import _cppyy - std = _cppyy.gbl.std - stringy_class = _cppyy.gbl.stringy_class + import _cppyy as cppyy + std = cppyy.gbl.std + stringy_class = cppyy.gbl.stringy_class c, s = stringy_class("dummy"), std.string("test string") @@ -261,9 +261,9 @@ return # don't bother; is fixed in cling-support - import _cppyy - std = _cppyy.gbl.std - stringy_class = _cppyy.gbl.stringy_class + import _cppyy as cppyy + std = cppyy.gbl.std + stringy_class = cppyy.gbl.stringy_class t0 = "aap\0noot" assert t0 == "aap\0noot" @@ -288,8 +288,8 @@ def test01_builtin_list_type(self): """Test access to a list<int>""" - import _cppyy - std = _cppyy.gbl.std + import _cppyy as cppyy + std = cppyy.gbl.std type_info = ( ("int", int), @@ -299,9 +299,9 @@ for c_type, p_type in type_info: tl1 = getattr(std, 'list<%s>' % c_type) - tl2 = _cppyy.gbl.std.list(p_type) + tl2 = cppyy.gbl.std.list(p_type) assert tl1 is tl2 - assert tl1.iterator is _cppyy.gbl.std.list(p_type).iterator + assert tl1.iterator is cppyy.gbl.std.list(p_type).iterator #----- a = tl1() @@ -323,8 +323,8 @@ def test02_empty_list_type(self): """Test behavior of empty list<int>""" - import _cppyy - std = _cppyy.gbl.std + import _cppyy as cppyy + std = cppyy.gbl.std a = std.list(int)() for arg in a: @@ -344,8 +344,8 @@ def test01_builtin_map_type(self): """Test access to a map<int,int>""" - import _cppyy - std = _cppyy.gbl.std + import _cppyy as cppyy + std = cppyy.gbl.std a = std.map(int, int)() for i in range(self.N): @@ -373,8 +373,8 @@ def test02_keyed_maptype(self): """Test access to a map<std::string,int>""" - import _cppyy - std = _cppyy.gbl.std + import _cppyy as cppyy + std = cppyy.gbl.std a = std.map(std.string, int)() for i in range(self.N): @@ -386,8 +386,8 @@ def test03_empty_maptype(self): """Test behavior of empty map<int,int>""" - import _cppyy - std = _cppyy.gbl.std + import _cppyy as cppyy + std = cppyy.gbl.std m = std.map(int, int)() for key, value in m: @@ -396,8 +396,9 @@ def test04_unsignedvalue_typemap_types(self): """Test assignability of maps with unsigned value types""" - import _cppyy, math, sys - std = _cppyy.gbl.std + import _cppyy as cppyy + import math, sys + std = cppyy.gbl.std mui = std.map(str, 'unsigned int')() mui['one'] = 1 @@ -420,8 +421,8 @@ def test05_STL_like_class_indexing_overloads(self): """Test overloading of operator[] in STL like class""" - import _cppyy - stl_like_class = _cppyy.gbl.stl_like_class + import _cppyy as cppyy + stl_like_class = cppyy.gbl.stl_like_class a = stl_like_class(int)() assert a["some string" ] == 'string' @@ -430,8 +431,8 @@ def test06_STL_like_class_iterators(self): """Test the iterator protocol mapping for an STL like class""" - import _cppyy - stl_like_class = _cppyy.gbl.stl_like_class + import _cppyy as cppyy + stl_like_class = cppyy.gbl.stl_like_class a = stl_like_class(int)() for i in a: @@ -452,8 +453,8 @@ def test01_builtin_vector_iterators(self): """Test iterator comparison with operator== reflected""" - import _cppyy - std = _cppyy.gbl.std + import _cppyy as cppyy + std = cppyy.gbl.std v = std.vector(int)() v.resize(1) @@ -489,9 +490,9 @@ def test01_explicit_templates(self): """Explicit use of Template class""" - import _cppyy + import _cppyy as cppyy - vector = _cppyy.Template('vector', _cppyy.gbl.std) + vector = cppyy.Template('vector', cppyy.gbl.std) assert vector[int] == vector(int) v = vector[int]() _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit