Commit 60c424d9 authored by Robert Bradshaw's avatar Robert Bradshaw

Use actual types in C++ conversion utility code.

parent 343064e8
...@@ -3330,58 +3330,26 @@ class CppClassType(CType): ...@@ -3330,58 +3330,26 @@ class CppClassType(CType):
if self.cname in builtin_cpp_conversions or self.cname in cpp_string_conversions: if self.cname in builtin_cpp_conversions or self.cname in cpp_string_conversions:
X = "XYZABC" X = "XYZABC"
tags = [] tags = []
declarations = ["cdef extern from *:"] context = {}
for ix, T in enumerate(self.templates or []): for ix, T in enumerate(self.templates or []):
if ix >= builtin_cpp_conversions[self.cname]: if ix >= builtin_cpp_conversions[self.cname]:
break break
if T.is_pyobject or not T.create_from_py_utility_code(env): if T.is_pyobject or not T.create_from_py_utility_code(env):
return False return False
tags.append(T.specialization_name()) tags.append(T.specialization_name())
if T.exception_value is not None: context[X[ix]] = T
# This is a hack due to the except value clause
# requiring a const (literal) value of the right
# (visible) type.
def guess_type(value):
if not T.is_typedef and (T.is_numeric or T.is_ptr):
return T
try:
int(value)
return c_longlong_type
except ValueError:
pass
try:
float(value)
return c_double_type
except ValueError:
pass
return T
except_type = guess_type(T.exception_value)
except_clause = "%s " % T.exception_value
if T.exception_check:
except_clause = "? %s" % except_clause
declarations.append(
" ctypedef %s %s '%s'" % (
except_type.declaration_code("", for_display=True), X[ix], T.empty_declaration_code()))
else:
except_clause = "*"
declarations.append(
" ctypedef struct %s '%s':\n pass" % (
X[ix], T.empty_declaration_code()))
declarations.append(
" cdef %s %s_from_py '%s' (object) except %s" % (
X[ix], X[ix], T.from_py_function, except_clause))
if self.cname in cpp_string_conversions: if self.cname in cpp_string_conversions:
cls = 'string' cls = 'string'
tags = type_identifier(self), tags = type_identifier(self),
else: else:
cls = self.cname[5:] cls = self.cname[5:]
cname = '__pyx_convert_%s_from_py_%s' % (cls, '__and_'.join(tags)) cname = '__pyx_convert_%s_from_py_%s' % (cls, '__and_'.join(tags))
context = { context.update({
'template_type_declarations': '\n'.join(declarations),
'cname': cname, 'cname': cname,
'maybe_unordered': self.maybe_unordered(), 'maybe_unordered': self.maybe_unordered(),
'type': self.cname, 'type': self.cname,
} })
from .UtilityCode import CythonUtilityCode from .UtilityCode import CythonUtilityCode
env.use_utility_code(CythonUtilityCode.load( env.use_utility_code(CythonUtilityCode.load(
cls.replace('unordered_', '') + ".from_py", "CppConvert.pyx", context=context)) cls.replace('unordered_', '') + ".from_py", "CppConvert.pyx", context=context))
...@@ -3394,19 +3362,15 @@ class CppClassType(CType): ...@@ -3394,19 +3362,15 @@ class CppClassType(CType):
if self.cname in builtin_cpp_conversions or self.cname in cpp_string_conversions: if self.cname in builtin_cpp_conversions or self.cname in cpp_string_conversions:
X = "XYZABC" X = "XYZABC"
tags = [] tags = []
declarations = ["cdef extern from *:"] context = {}
for ix, T in enumerate(self.templates or []): for ix, T in enumerate(self.templates or []):
if ix >= builtin_cpp_conversions[self.cname]: if ix >= builtin_cpp_conversions[self.cname]:
break break
if not T.create_to_py_utility_code(env): if not T.create_to_py_utility_code(env):
return False return False
tags.append(T.specialization_name()) tags.append(T.specialization_name())
declarations.append( context[X[ix]] = T
" ctypedef struct %s '%s':\n pass" % (
X[ix], T.empty_declaration_code()))
declarations.append(
" cdef object %s_to_py '%s' (%s)" % (
X[ix], T.to_py_function, X[ix]))
if self.cname in cpp_string_conversions: if self.cname in cpp_string_conversions:
cls = 'string' cls = 'string'
prefix = 'PyObject_' # gets specialised by explicit type casts in CoerceToPyTypeNode prefix = 'PyObject_' # gets specialised by explicit type casts in CoerceToPyTypeNode
...@@ -3415,12 +3379,11 @@ class CppClassType(CType): ...@@ -3415,12 +3379,11 @@ class CppClassType(CType):
cls = self.cname[5:] cls = self.cname[5:]
prefix = '' prefix = ''
cname = "__pyx_convert_%s%s_to_py_%s" % (prefix, cls, "____".join(tags)) cname = "__pyx_convert_%s%s_to_py_%s" % (prefix, cls, "____".join(tags))
context = { context.update({
'template_type_declarations': '\n'.join(declarations),
'cname': cname, 'cname': cname,
'maybe_unordered': self.maybe_unordered(), 'maybe_unordered': self.maybe_unordered(),
'type': self.cname, 'type': self.cname,
} })
from .UtilityCode import CythonUtilityCode from .UtilityCode import CythonUtilityCode
env.use_utility_code(CythonUtilityCode.load( env.use_utility_code(CythonUtilityCode.load(
cls.replace('unordered_', '') + ".to_py", "CppConvert.pyx", context=context)) cls.replace('unordered_', '') + ".to_py", "CppConvert.pyx", context=context))
......
...@@ -37,8 +37,6 @@ cdef inline object {{cname.replace("PyObject", py_type, 1)}}(const string& s): ...@@ -37,8 +37,6 @@ cdef inline object {{cname.replace("PyObject", py_type, 1)}}(const string& s):
#################### vector.from_py #################### #################### vector.from_py ####################
{{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass vector "std::vector" [T]: cdef cppclass vector "std::vector" [T]:
void push_back(T&) void push_back(T&)
...@@ -47,14 +45,12 @@ cdef extern from *: ...@@ -47,14 +45,12 @@ cdef extern from *:
cdef vector[X] {{cname}}(object o) except *: cdef vector[X] {{cname}}(object o) except *:
cdef vector[X] v cdef vector[X] v
for item in o: for item in o:
v.push_back(X_from_py(item)) v.push_back(<X>item)
return v return v
#################### vector.to_py #################### #################### vector.to_py ####################
{{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass vector "const std::vector" [T]: cdef cppclass vector "const std::vector" [T]:
size_t size() size_t size()
...@@ -62,13 +58,11 @@ cdef extern from *: ...@@ -62,13 +58,11 @@ cdef extern from *:
@cname("{{cname}}") @cname("{{cname}}")
cdef object {{cname}}(vector[X]& v): cdef object {{cname}}(vector[X]& v):
return [X_to_py(v[i]) for i in range(v.size())] return [v[i] for i in range(v.size())]
#################### list.from_py #################### #################### list.from_py ####################
{{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass cpp_list "std::list" [T]: cdef cppclass cpp_list "std::list" [T]:
void push_back(T&) void push_back(T&)
...@@ -77,7 +71,7 @@ cdef extern from *: ...@@ -77,7 +71,7 @@ cdef extern from *:
cdef cpp_list[X] {{cname}}(object o) except *: cdef cpp_list[X] {{cname}}(object o) except *:
cdef cpp_list[X] l cdef cpp_list[X] l
for item in o: for item in o:
l.push_back(X_from_py(item)) l.push_back(<X>item)
return l return l
...@@ -85,8 +79,6 @@ cdef cpp_list[X] {{cname}}(object o) except *: ...@@ -85,8 +79,6 @@ cdef cpp_list[X] {{cname}}(object o) except *:
cimport cython cimport cython
{{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass cpp_list "std::list" [T]: cdef cppclass cpp_list "std::list" [T]:
cppclass const_iterator: cppclass const_iterator:
...@@ -101,15 +93,13 @@ cdef object {{cname}}(const cpp_list[X]& v): ...@@ -101,15 +93,13 @@ cdef object {{cname}}(const cpp_list[X]& v):
o = [] o = []
cdef cpp_list[X].const_iterator iter = v.begin() cdef cpp_list[X].const_iterator iter = v.begin()
while iter != v.end(): while iter != v.end():
o.append(X_to_py(cython.operator.dereference(iter))) o.append(cython.operator.dereference(iter))
cython.operator.preincrement(iter) cython.operator.preincrement(iter)
return o return o
#################### set.from_py #################### #################### set.from_py ####################
{{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass set "std::{{maybe_unordered}}set" [T]: cdef cppclass set "std::{{maybe_unordered}}set" [T]:
void insert(T&) void insert(T&)
...@@ -118,7 +108,7 @@ cdef extern from *: ...@@ -118,7 +108,7 @@ cdef extern from *:
cdef set[X] {{cname}}(object o) except *: cdef set[X] {{cname}}(object o) except *:
cdef set[X] s cdef set[X] s
for item in o: for item in o:
s.insert(X_from_py(item)) s.insert(<X>item)
return s return s
...@@ -126,8 +116,6 @@ cdef set[X] {{cname}}(object o) except *: ...@@ -126,8 +116,6 @@ cdef set[X] {{cname}}(object o) except *:
cimport cython cimport cython
{{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass cpp_set "std::{{maybe_unordered}}set" [T]: cdef cppclass cpp_set "std::{{maybe_unordered}}set" [T]:
cppclass const_iterator: cppclass const_iterator:
...@@ -142,14 +130,12 @@ cdef object {{cname}}(const cpp_set[X]& s): ...@@ -142,14 +130,12 @@ cdef object {{cname}}(const cpp_set[X]& s):
o = set() o = set()
cdef cpp_set[X].const_iterator iter = s.begin() cdef cpp_set[X].const_iterator iter = s.begin()
while iter != s.end(): while iter != s.end():
o.add(X_to_py(cython.operator.dereference(iter))) o.add(cython.operator.dereference(iter))
cython.operator.preincrement(iter) cython.operator.preincrement(iter)
return o return o
#################### pair.from_py #################### #################### pair.from_py ####################
{{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass pair "std::pair" [T, U]: cdef cppclass pair "std::pair" [T, U]:
pair() pair()
...@@ -158,13 +144,11 @@ cdef extern from *: ...@@ -158,13 +144,11 @@ cdef extern from *:
@cname("{{cname}}") @cname("{{cname}}")
cdef pair[X,Y] {{cname}}(object o) except *: cdef pair[X,Y] {{cname}}(object o) except *:
x, y = o x, y = o
return pair[X,Y](X_from_py(x), Y_from_py(y)) return pair[X,Y](<X>x, <Y>y)
#################### pair.to_py #################### #################### pair.to_py ####################
{{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass pair "std::pair" [T, U]: cdef cppclass pair "std::pair" [T, U]:
T first T first
...@@ -172,13 +156,11 @@ cdef extern from *: ...@@ -172,13 +156,11 @@ cdef extern from *:
@cname("{{cname}}") @cname("{{cname}}")
cdef object {{cname}}(const pair[X,Y]& p): cdef object {{cname}}(const pair[X,Y]& p):
return X_to_py(p.first), Y_to_py(p.second) return p.first, p.second
#################### map.from_py #################### #################### map.from_py ####################
{{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass pair "std::pair" [T, U]: cdef cppclass pair "std::pair" [T, U]:
pair(T&, U&) pair(T&, U&)
...@@ -193,7 +175,7 @@ cdef map[X,Y] {{cname}}(object o) except *: ...@@ -193,7 +175,7 @@ cdef map[X,Y] {{cname}}(object o) except *:
cdef dict d = o cdef dict d = o
cdef map[X,Y] m cdef map[X,Y] m
for key, value in d.iteritems(): for key, value in d.iteritems():
m.insert(pair[X,Y](X_from_py(key), Y_from_py(value))) m.insert(pair[X,Y](<X>key, <Y>value))
return m return m
...@@ -203,8 +185,6 @@ cdef map[X,Y] {{cname}}(object o) except *: ...@@ -203,8 +185,6 @@ cdef map[X,Y] {{cname}}(object o) except *:
cimport cython cimport cython
{{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass map "std::{{maybe_unordered}}map" [T, U]: cdef cppclass map "std::{{maybe_unordered}}map" [T, U]:
cppclass value_type: cppclass value_type:
...@@ -224,15 +204,13 @@ cdef object {{cname}}(const map[X,Y]& s): ...@@ -224,15 +204,13 @@ cdef object {{cname}}(const map[X,Y]& s):
cdef map[X,Y].const_iterator iter = s.begin() cdef map[X,Y].const_iterator iter = s.begin()
while iter != s.end(): while iter != s.end():
key_value = &cython.operator.dereference(iter) key_value = &cython.operator.dereference(iter)
o[X_to_py(key_value.first)] = Y_to_py(key_value.second) o[key_value.first] = key_value.second
cython.operator.preincrement(iter) cython.operator.preincrement(iter)
return o return o
#################### complex.from_py #################### #################### complex.from_py ####################
{{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass std_complex "std::complex" [T]: cdef cppclass std_complex "std::complex" [T]:
std_complex() std_complex()
...@@ -246,8 +224,6 @@ cdef std_complex[X] {{cname}}(object o) except *: ...@@ -246,8 +224,6 @@ cdef std_complex[X] {{cname}}(object o) except *:
#################### complex.to_py #################### #################### complex.to_py ####################
{{template_type_declarations}}
cdef extern from *: cdef extern from *:
cdef cppclass std_complex "std::complex" [T]: cdef cppclass std_complex "std::complex" [T]:
X real() X real()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment