[pypy-commit] pypy cppyy-packaging: support for vector<bool>
wlav
pypy.commits at gmail.com
Thu Jul 19 14:04:07 EDT 2018
Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: cppyy-packaging
Changeset: r94879:e3fd3632d44e
Date: 2018-07-19 10:43 -0700
http://bitbucket.org/pypy/pypy/changeset/e3fd3632d44e/
Log: support for vector<bool>
diff --git a/pypy/module/_cppyy/capi/loadable_capi.py b/pypy/module/_cppyy/capi/loadable_capi.py
--- a/pypy/module/_cppyy/capi/loadable_capi.py
+++ b/pypy/module/_cppyy/capi/loadable_capi.py
@@ -274,7 +274,8 @@
'stdvector_valuetype' : ([c_ccharp], c_ccharp),
'stdvector_valuesize' : ([c_ccharp], c_size_t),
-
+ 'vectorbool_getitem' : ([c_object, c_int], c_int),
+ 'vectorbool_setitem' : ([c_object, c_int, c_int], c_void),
}
# size/offset are backend-specific but fixed after load
@@ -657,17 +658,43 @@
return charp2str_free(space, call_capi(space, 'stdvector_valuetype', [_ArgS(pystr)]))
def c_stdvector_valuesize(space, pystr):
return _cdata_to_size_t(space, call_capi(space, 'stdvector_valuesize', [_ArgS(pystr)]))
+def c_vectorbool_getitem(space, vbool, idx):
+ return call_capi(space, 'vectorbool_getitem', [_ArgH(vbool), _ArgL(idx)])
+def c_vectorbool_setitem(space, vbool, idx, value):
+ call_capi(space, 'vectorbool_setitem', [_ArgH(vbool), _ArgL(idx), _ArgL(value)])
# TODO: factor these out ...
# pythonizations
def stdstring_c_str(space, w_self):
"""Return a python string taking into account \0"""
-
from pypy.module._cppyy import interp_cppyy
cppstr = space.interp_w(interp_cppyy.W_CPPInstance, w_self, can_be_None=False)
return space.newtext(c_stdstring2charp(space, cppstr._rawobject))
+def vbool_getindex(space, w_vbool, w_idx):
+ idx = space.getindex_w(w_idx, space.w_IndexError, "std::vector<bool> index")
+ sz = space.len_w(w_vbool)
+ if idx < 0: idx += sz
+ if idx < 0 or idx >= sz:
+ raise IndexError
+ return idx
+
+def vectorbool_getitem(space, w_self, w_idx):
+ """Index a std::vector<bool>, return the value"""
+ from pypy.module._cppyy import interp_cppyy
+ vbool = space.interp_w(interp_cppyy.W_CPPInstance, w_self, can_be_None=False)
+ idx = vbool_getindex(space, w_self, w_idx)
+ item = c_vectorbool_getitem(space, vbool._rawobject, idx)
+ return space.newbool(space.is_true(item))
+
+def vectorbool_setitem(space, w_self, w_idx, w_value):
+ """Index a std::vector<bool>, set the value"""
+ from pypy.module._cppyy import interp_cppyy
+ vbool = space.interp_w(interp_cppyy.W_CPPInstance, w_self, can_be_None=False)
+ idx = vbool_getindex(space, w_self, w_idx)
+ c_vectorbool_setitem(space, vbool._rawobject, idx, int(space.is_true(w_value)))
+
# setup pythonizations for later use at run-time
_pythonizations = {}
def register_pythonizations(space):
@@ -678,6 +705,9 @@
### std::string
stdstring_c_str,
+ ### std::vector<bool>
+ vectorbool_getitem,
+ vectorbool_setitem,
]
for f in allfuncs:
@@ -692,3 +722,7 @@
space.setattr(w_pycppclass, space.newtext("c_str"), _pythonizations["stdstring_c_str"])
_method_alias(space, w_pycppclass, "_cppyy_as_builtin", "c_str")
_method_alias(space, w_pycppclass, "__str__", "c_str")
+
+ if name == "std::vector<bool>":
+ space.setattr(w_pycppclass, space.newtext("__getitem__"), _pythonizations["vectorbool_getitem"])
+ space.setattr(w_pycppclass, space.newtext("__setitem__"), _pythonizations["vectorbool_setitem"])
diff --git a/pypy/module/_cppyy/include/capi.h b/pypy/module/_cppyy/include/capi.h
--- a/pypy/module/_cppyy/include/capi.h
+++ b/pypy/module/_cppyy/include/capi.h
@@ -219,6 +219,10 @@
const char* cppyy_stdvector_valuetype(const char* clname);
RPY_EXTERN
size_t cppyy_stdvector_valuesize(const char* clname);
+ RPY_EXTERN
+ int cppyy_vectorbool_getitem(cppyy_object_t ptr, int idx);
+ RPY_EXTERN
+ void cppyy_vectorbool_setitem(cppyy_object_t ptr, int idx, int value);
#ifdef __cplusplus
}
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
@@ -431,18 +431,19 @@
# not on vector, which is pythonized in the capi (interp-level; there is
# also the fallback on the indexed __getitem__, but that is slower)
# TODO: if not (0 <= name.find('vector') <= 5):
- if ('begin' in pyclass.__dict__ and 'end' in pyclass.__dict__):
- if _cppyy._scope_byname(name+'::iterator') or \
- _cppyy._scope_byname(name+'::const_iterator'):
- def __iter__(self):
- i = self.begin()
- while i != self.end():
- yield i.__deref__()
- i.__preinc__()
- i.__destruct__()
- raise StopIteration
- pyclass.__iter__ = __iter__
- # else: rely on numbered iteration
+ if not (0 <= name.find('vector<bool') <= 5):
+ if ('begin' in pyclass.__dict__ and 'end' in pyclass.__dict__):
+ if _cppyy._scope_byname(name+'::iterator') or \
+ _cppyy._scope_byname(name+'::const_iterator'):
+ def __iter__(self):
+ i = self.begin()
+ while i != self.end():
+ yield i.__deref__()
+ i.__preinc__()
+ i.__destruct__()
+ raise StopIteration
+ pyclass.__iter__ = __iter__
+ # else: rely on numbered iteration
# add python collection based initializer
if 0 <= name.find('vector') <= 5:
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
@@ -197,6 +197,26 @@
assert v2[-1] == v[-2]
assert v2[self.N-4] == v[-2]
+ def test07_vector_bool(self):
+ """Usability of std::vector<bool> which can be a specialization"""
+
+ import _cppyy as cppyy
+
+ vb = cppyy.gbl.std.vector(bool)(8)
+ assert [x for x in vb] == [False]*8
+
+ vb[0] = True
+ assert vb[0]
+ vb[-1] = True
+ assert vb[7]
+
+ print [x for x in vb]
+
+ assert [x for x in vb] == [True]+[False]*6+[True]
+
+ assert len(vb[4:8]) == 4
+ assert list(vb[4:8]) == [False]*3+[True]
+
class AppTestSTLSTRING:
spaceconfig = dict(usemodules=['_cppyy', '_rawffi', 'itertools'])
More information about the pypy-commit
mailing list