mirror of
https://github.com/mappu/miqt.git
synced 2024-12-22 08:58:37 +00:00
genbindings: add QPair<> support
This commit is contained in:
parent
dc39b7ca65
commit
58ec6e1821
@ -226,9 +226,6 @@ func AllowMethod(className string, mm CppMethod) error {
|
||||
// Any type not permitted by AllowClass is also not permitted by this method.
|
||||
func AllowType(p CppParameter, isReturnType bool) error {
|
||||
|
||||
if p.QPairOf() {
|
||||
return ErrTooComplex // e.g. QGradientStop
|
||||
}
|
||||
if t, ok := p.QSetOf(); ok {
|
||||
if err := AllowType(t, isReturnType); err != nil {
|
||||
return err
|
||||
@ -258,6 +255,14 @@ func AllowType(p CppParameter, isReturnType bool) error {
|
||||
return ErrTooComplex
|
||||
}
|
||||
}
|
||||
if kType, vType, ok := p.QPairOf(); ok {
|
||||
if err := AllowType(kType, isReturnType); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AllowType(vType, isReturnType); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if p.QMultiMapOf() {
|
||||
return ErrTooComplex // e.g. Qt5 QNetwork qsslcertificate.h has a QMultiMap<QSsl::AlternativeNameEntryType, QString>
|
||||
}
|
||||
|
@ -23,6 +23,9 @@ func (p CppParameter) RenderTypeCabi() string {
|
||||
} else if _, _, ok := p.QMapOf(); ok {
|
||||
return "struct miqt_map"
|
||||
|
||||
} else if _, _, ok := p.QPairOf(); ok {
|
||||
return "struct miqt_map"
|
||||
|
||||
} else if (p.Pointer || p.ByRef) && p.QtClassType() {
|
||||
return cabiClassName(p.ParameterType) + "*"
|
||||
|
||||
@ -267,6 +270,25 @@ func emitCABI2CppForwarding(p CppParameter, indent string) (preamble string, for
|
||||
preamble += indent + "}\n"
|
||||
return preamble, nameprefix + "_QMap"
|
||||
|
||||
} else if kType, vType, ok := p.QPairOf(); ok {
|
||||
preamble += indent + p.GetQtCppType().ParameterType + " " + nameprefix + "_QPair;\n"
|
||||
|
||||
preamble += indent + kType.RenderTypeCabi() + "* " + nameprefix + "_first_arr = static_cast<" + kType.RenderTypeCabi() + "*>(" + p.ParameterName + ".keys);\n"
|
||||
preamble += indent + vType.RenderTypeCabi() + "* " + nameprefix + "_second_arr = static_cast<" + vType.RenderTypeCabi() + "*>(" + p.ParameterName + ".values);\n"
|
||||
|
||||
kType.ParameterName = nameprefix + "_first_arr[0]"
|
||||
addPreK, addFwdK := emitCABI2CppForwarding(kType, indent+"\t")
|
||||
preamble += addPreK
|
||||
|
||||
vType.ParameterName = nameprefix + "_second_arr[0]"
|
||||
addPreV, addFwdV := emitCABI2CppForwarding(vType, indent+"\t")
|
||||
preamble += addPreV
|
||||
|
||||
preamble += indent + nameprefix + "_QPair.first = " + addFwdK + ";\n"
|
||||
preamble += indent + nameprefix + "_QPair.second = " + addFwdV + ";\n"
|
||||
|
||||
return preamble, nameprefix + "_QPair"
|
||||
|
||||
} else if p.IsFlagType() || p.IntType() || p.IsKnownEnum() {
|
||||
castSrc := p.ParameterName
|
||||
castType := p.RenderTypeQtCpp()
|
||||
@ -452,6 +474,26 @@ func emitAssignCppToCabi(assignExpression string, p CppParameter, rvalue string)
|
||||
afterCall += indent + assignExpression + "" + namePrefix + "_out;\n"
|
||||
return indent + shouldReturn + rvalue + ";\n" + afterCall
|
||||
|
||||
} else if kType, vType, ok := p.QPairOf(); ok {
|
||||
// QPair<T1,T2>
|
||||
|
||||
shouldReturn = p.RenderTypeQtCpp() + " " + namePrefix + "_ret = "
|
||||
|
||||
afterCall += indent + "// Convert QPair<> from C++ memory to manually-managed C memory\n"
|
||||
afterCall += indent + "" + kType.RenderTypeCabi() + "* " + namePrefix + "_first_arr = static_cast<" + kType.RenderTypeCabi() + "*>(malloc(sizeof(" + kType.RenderTypeCabi() + ")));\n"
|
||||
afterCall += indent + "" + vType.RenderTypeCabi() + "* " + namePrefix + "_second_arr = static_cast<" + vType.RenderTypeCabi() + "*>(malloc(sizeof(" + vType.RenderTypeCabi() + ")));\n"
|
||||
|
||||
afterCall += emitAssignCppToCabi(indent+namePrefix+"_first_arr[0] = ", kType, namePrefix+"_ret.first")
|
||||
afterCall += emitAssignCppToCabi(indent+namePrefix+"_second_arr[0] = ", vType, namePrefix+"_ret.second")
|
||||
|
||||
afterCall += indent + "struct miqt_map " + namePrefix + "_out;\n"
|
||||
afterCall += indent + "" + namePrefix + "_out.len = 1;\n"
|
||||
afterCall += indent + "" + namePrefix + "_out.keys = static_cast<void*>(" + namePrefix + "_first_arr);\n"
|
||||
afterCall += indent + "" + namePrefix + "_out.values = static_cast<void*>(" + namePrefix + "_second_arr);\n"
|
||||
|
||||
afterCall += indent + assignExpression + "" + namePrefix + "_out;\n"
|
||||
return indent + shouldReturn + rvalue + ";\n" + afterCall
|
||||
|
||||
} else if p.QtClassType() && p.ByRef {
|
||||
// It's a pointer in disguise, just needs one cast
|
||||
shouldReturn = p.RenderTypeQtCpp() + " " + namePrefix + "_ret = "
|
||||
|
@ -43,6 +43,12 @@ func (p CppParameter) RenderTypeGo(gfs *goFileState) string {
|
||||
return "map[" + t1.RenderTypeGo(gfs) + "]" + t2.RenderTypeGo(gfs)
|
||||
}
|
||||
|
||||
if t1, t2, ok := p.QPairOf(); ok {
|
||||
// Design QPair using capital-named members, in case it gets passed
|
||||
// across packages
|
||||
return "struct { First " + t1.RenderTypeGo(gfs) + " ; Second " + t2.RenderTypeGo(gfs) + " }"
|
||||
}
|
||||
|
||||
if p.ParameterType == "void" && p.Pointer {
|
||||
return "unsafe.Pointer"
|
||||
}
|
||||
@ -169,6 +175,10 @@ func (p CppParameter) parameterTypeCgo() string {
|
||||
return "C.struct_miqt_map"
|
||||
}
|
||||
|
||||
if _, _, ok := p.QPairOf(); ok {
|
||||
return "C.struct_miqt_map"
|
||||
}
|
||||
|
||||
// Cgo internally binds void* as unsafe.Pointer{}
|
||||
if p.ParameterType == "void" && p.Pointer {
|
||||
return "unsafe.Pointer"
|
||||
@ -366,6 +376,30 @@ func (gfs *goFileState) emitParameterGo2CABIForwarding(p CppParameter) (preamble
|
||||
|
||||
rvalue = nameprefix + "_mm"
|
||||
|
||||
} else if kType, vType, ok := p.QPairOf(); ok {
|
||||
// QPair<T>
|
||||
|
||||
gfs.imports["unsafe"] = struct{}{}
|
||||
|
||||
preamble += nameprefix + "_First_CArray := (*[0xffff]" + kType.parameterTypeCgo() + ")(C.malloc(C.size_t(" + kType.mallocSizeCgoExpression() + ")))\n"
|
||||
preamble += "defer C.free(unsafe.Pointer(" + nameprefix + "_First_CArray))\n"
|
||||
|
||||
preamble += nameprefix + "_Second_CArray := (*[0xffff]" + vType.parameterTypeCgo() + ")(C.malloc(C.size_t(" + vType.mallocSizeCgoExpression() + ")))\n"
|
||||
preamble += "defer C.free(unsafe.Pointer(" + nameprefix + "_Second_CArray))\n"
|
||||
|
||||
kType.ParameterName = p.ParameterName + ".First"
|
||||
addPreamble, innerRvalue := gfs.emitParameterGo2CABIForwarding(kType)
|
||||
preamble += addPreamble
|
||||
preamble += nameprefix + "_First_CArray[0] = " + innerRvalue + "\n"
|
||||
|
||||
vType.ParameterName = p.ParameterName + ".Second"
|
||||
addPreamble, innerRvalue = gfs.emitParameterGo2CABIForwarding(vType)
|
||||
preamble += addPreamble
|
||||
preamble += nameprefix + "_Second_CArray[0] = " + innerRvalue + "\n"
|
||||
|
||||
preamble += nameprefix + "_pair := C.struct_miqt_map{\nlen: 1,\nkeys: unsafe.Pointer(" + nameprefix + "_First_CArray),\nvalues: unsafe.Pointer(" + nameprefix + "_Second_CArray),\n}\n"
|
||||
|
||||
rvalue = nameprefix + "_pair"
|
||||
|
||||
} else if p.Pointer && p.ParameterType == "char" {
|
||||
// Single char* argument
|
||||
@ -506,6 +540,20 @@ func (gfs *goFileState) emitCabiToGo(assignExpr string, rt CppParameter, rvalue
|
||||
afterword += assignExpr + " " + namePrefix + "_ret\n"
|
||||
return shouldReturn + " " + rvalue + "\n" + afterword
|
||||
|
||||
} else if kType, vType, ok := rt.QPairOf(); ok {
|
||||
gfs.imports["unsafe"] = struct{}{}
|
||||
|
||||
shouldReturn = "var " + namePrefix + "_mm C.struct_miqt_map = "
|
||||
|
||||
afterword += namePrefix + "_First_CArray := (*[0xffff]" + kType.parameterTypeCgo() + ")(unsafe.Pointer(" + namePrefix + "_mm.keys))\n"
|
||||
afterword += namePrefix + "_Second_CArray := (*[0xffff]" + vType.parameterTypeCgo() + ")(unsafe.Pointer(" + namePrefix + "_mm.values))\n"
|
||||
|
||||
afterword += gfs.emitCabiToGo(namePrefix+"_entry_First := ", kType, namePrefix+"_First_CArray[0]") + "\n"
|
||||
afterword += gfs.emitCabiToGo(namePrefix+"_entry_Second := ", vType, namePrefix+"_Second_CArray[0]") + "\n"
|
||||
|
||||
afterword += assignExpr + " " + rt.RenderTypeGo(gfs) + " { First: " + namePrefix + "_entry_First , Second: " + namePrefix + "_entry_Second }\n"
|
||||
return shouldReturn + " " + rvalue + "\n" + afterword
|
||||
|
||||
} else if rt.QtClassType() {
|
||||
// Construct our Go type based on this inner CABI type
|
||||
shouldReturn = "" + namePrefix + "_ret := "
|
||||
|
@ -151,8 +151,21 @@ func (p CppParameter) QMapOf() (CppParameter, CppParameter, bool) {
|
||||
return CppParameter{}, CppParameter{}, false
|
||||
}
|
||||
|
||||
func (p CppParameter) QPairOf() bool {
|
||||
return strings.HasPrefix(p.ParameterType, `QPair<`) // TODO support this
|
||||
func (p CppParameter) QPairOf() (CppParameter, CppParameter, bool) {
|
||||
if strings.HasPrefix(p.ParameterType, `QPair<`) && strings.HasSuffix(p.ParameterType, `>`) {
|
||||
interior := tokenizeMultipleParameters(p.ParameterType[6 : len(p.ParameterType)-1])
|
||||
if len(interior) != 2 {
|
||||
panic("QPair<> has unexpected number of template arguments")
|
||||
}
|
||||
|
||||
first := parseSingleTypeString(interior[0])
|
||||
first.ParameterName = p.ParameterName + "_first"
|
||||
second := parseSingleTypeString(interior[1])
|
||||
second.ParameterName = p.ParameterName + "_second"
|
||||
return first, second, true
|
||||
}
|
||||
|
||||
return CppParameter{}, CppParameter{}, false
|
||||
}
|
||||
|
||||
func (p CppParameter) QSetOf() (CppParameter, bool) {
|
||||
|
@ -44,6 +44,20 @@ func applyTypedefs(p CppParameter) CppParameter {
|
||||
p.QtCppOriginalType = &tmp
|
||||
}
|
||||
p.ParameterType = p.ParameterType[0:bpos] + `<` + kType2.RenderTypeQtCpp() + `, ` + vType2.RenderTypeQtCpp() + `>`
|
||||
|
||||
} else if kType, vType, ok := p.QPairOf(); ok {
|
||||
kType2 := applyTypedefs(kType)
|
||||
kType2.QtCppOriginalType = nil
|
||||
|
||||
vType2 := applyTypedefs(vType)
|
||||
vType2.QtCppOriginalType = nil
|
||||
|
||||
if p.QtCppOriginalType == nil {
|
||||
tmp := p // copy
|
||||
p.QtCppOriginalType = &tmp
|
||||
}
|
||||
p.ParameterType = `QPair<` + kType2.RenderTypeQtCpp() + `, ` + vType2.RenderTypeQtCpp() + `>`
|
||||
|
||||
}
|
||||
|
||||
return p
|
||||
|
Loading…
Reference in New Issue
Block a user