Browse Source

Add support for struct containing arrays

master
heck 4 years ago
parent
commit
e459df5781
  1. 16
      examples/ext/lib_test/lib_test/gen/config.json
  2. 2
      examples/ext/lib_test/lib_test/lib_test.cc
  3. 28
      examples/ext/lib_test/tests/test_lib_test.py
  4. 74
      pEpACIDgen/gen_backend/gen_pybind11.ysl2

16
examples/ext/lib_test/lib_test/gen/config.json

@ -5,6 +5,10 @@
"variables": [
],
"functions": [
"// func_TTAPSa_args_V",
"func_TACS_args_V"
],
"//functions": [
"func_V_args_V",
"func_Pi_args_V",
"func_V_args_Pi",
@ -36,7 +40,17 @@
"func_pppTAPS_args_V",
"func_V_args_pTAPS",
"func_ppTAPS_args_ppTAPS",
"func_pppTAPS_args_pppTAPS"
"func_pppTAPS_args_pppTAPS",
"func_TTAPSa_args_V",
"//func_TTAPSa_args_TTAPSa",
"//func_V_args_pTTAPSa",
"//func_ppTTAPSa_args_ppTTAPSa",
"//func_pppTTAPSa_args_pppTTAPSa",
"func_TACS_args_V",
"//func_TACS_args_TACS",
"//func_V_args_pTACS",
"//func_ppTACS_args_ppTACS",
"//func_pppTACS_args_pppTACS"
],
"debug_ast" : "True",
"debug_acid" : "True",

2
examples/ext/lib_test/lib_test/lib_test.cc

@ -1,10 +1,12 @@
#include <string>
#include <iostream>
#include <algorithm>
#include <pybind11/pybind11.h>
#include <pybind11/detail/common.h>
#include "lib_test.h"
using namespace std;
namespace py = pybind11;
PYBIND11_MODULE(lib_test, m) {
#include "gen/py_module.pybind11"

28
examples/ext/lib_test/tests/test_lib_test.py

@ -251,6 +251,34 @@ def test_func_pppTAPS_args_pppTAPS():
assert(inout.field__P_1 == 23);
assert(inout.field__P_2 == 23);
def test_struct_field_array_of_structs_immutable_len():
a = CS()
b = PS()
assert(len(a.field_APS_1) == 3)
a.field_APS_1 = [b]
assert(len(a.field_APS_1) == 3)
a.field_APS_1 = [b,b]
assert(len(a.field_APS_1) == 3)
a.field_APS_1 = [b,b,b]
assert(len(a.field_APS_1) == 3)
a.field_APS_1 = []
assert(len(a.field_APS_1) == 3)
@pytest.mark.skip("throw exception instead of warnning")
def test_struct_field_array_of_structs_accept_unityped_arr_only():
a = CS()
b = PS()
with pytest.raises(Exception):
a.field_APS_1 = [b,"invalid_type"]
def test_struct_field_array_of_structs_of_structs_set_get():
a = CS()
b = PS()
b.field__P_1 = 23
b.field__P_2 = 23
a.field_APS_1 = [b]
assert(a.field_APS_1[0].field__P_1 == 23)
assert(a.field_APS_1[0].field__P_2 == 23)
def PS_to_string(ps):

74
pEpACIDgen/gen_backend/gen_pybind11.ysl2

@ -4,6 +4,8 @@ tstylesheet {
template "module" {
document("py_module.pybind11", "text") {
||
namespace py = pybind11;
// INSERT COOL ASCII ART HERE
// METHOD
`` apply "method"
@ -37,19 +39,19 @@ tstylesheet {
[]
(
``apply "use", mode="arg_list_from_py"
) -> pybind11::tuple
) -> py::tuple
{
``apply "return", mode="create"
``apply "use", mode="create_args_c"
`apply "return", mode="assign"`::«@name»(
``apply "use", mode="arg_list_c"
);
return pybind11::make_tuple(
return py::make_tuple(
`apply "return", mode="return"``if "count(use)>0" > ,`
``apply "use", mode="return_args_as_tuple"
);
},
pybind11::return_value_policy::copy);
py::return_value_policy::copy);
||
}
@ -67,7 +69,7 @@ tstylesheet {
const "type", "@type";
choose {
when "contains($type,'void')" {
> pybind11::none()
> py::none()
} otherwise {
choose {
when "contains($type,'*')" {
@ -174,8 +176,8 @@ tstylesheet {
template "struct" {
||
pybind11::class_<«@name»>(m, "«@name»")
.def(pybind11::init([]() { return «@name»(); }))
py::class_<«@name»>(m, "«@name»")
.def(py::init([]() { return «@name»(); }))
||
apply "field" {
with "structname", "@name"
@ -185,40 +187,86 @@ tstylesheet {
|
}
template "field" {
param "structname";
param "name", "@name";
param "type", "@type";
const "array_type", "substring-before($type, '[')";
const "array_len", "substring-before(substring-after($type, '['),']')";
choose {
when "string-length($array_len) > 0" {
||
.def_property("«$name»",
[](::«$structname» &obj) -> py::list {
//cout << "«$structname»::«$name»: getter called" << endl;
py::list l;
for(int i=0; i < «$array_len»; ++i) {
l.append(obj.«$name»[i]);
}
return l;
},
[](::«$structname» &obj, py::list val) -> void {
// cout << "«$structname»::«$name»: getter called" << endl;
if(val.size() <= 0) {
// empty array given, doing nothing (static c array cant be cleared)
} else {
int cpy_amt = std::min(static_cast<int>(val.size()), «$array_len»);
bool isUnitypedArrayOf = true;
for(int i=0; i < cpy_amt; ++i) {
if (!py::isinstance<«$array_type»>(val[i])) {
isUnitypedArrayOf = false;
break;
}
}
if(!isUnitypedArrayOf) {
cout << "«$structname»::«$name» - setter error: is not a unityped array of type «$array_type»" << std::endl;
} else {
for(int i=0; i < cpy_amt; ++i) {
obj.«$name»[i] = val[i].cast<«$array_type»>();
}
}
}
},
py::return_value_policy::copy)
||
} otherwise {
||
.def_property("«@name»",
[](::«$structname» &obj) -> «@type» {
[](::«$structname» &obj) -> «$type» {
//cout << "«$structname» ::«@name»: getter called" << endl;
return obj.«@name»;
},
||
choose {
when "@type = 'const char *'" {
when "$type = 'const char *'" {
||
[](::«$structname» &obj, «@type» cstr) -> void {
[](::«$structname» &obj, «$type» cstr) -> void {
//cout << "«$structname»::«@name»: setter called" << cstr << endl;
obj.«@name» = strdup(cstr);
},
pybind11::return_value_policy::copy)
py::return_value_policy::copy)
||
} otherwise {
||
[](::«$structname» &obj, «@type» val) -> void {
[](::«$structname» &obj, «$type» val) -> void {
//cout << "«$structname»::«@name»: setter called" << endl;
obj.«@name» = val;
},
pybind11::return_value_policy::copy)
py::return_value_policy::copy)
||
}
}
}
}
}
template "enum" {
||
pybind11::enum_<::«@name»>(m, "«@name»")
py::enum_<::«@name»>(m, "«@name»")
``apply item
;

Loading…
Cancel
Save