[pypy-commit] pypy cppyy-packaging: moves for strings (incl. from temporary python str)
wlav
pypy.commits at gmail.com
Fri Jul 13 02:16:51 EDT 2018
Author: Wim Lavrijsen <WLavrijsen at 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]()
More information about the pypy-commit
mailing list