Virtual inheritance configurable at codegen time

This commit is contained in:
Thomas Krijnen
2025-01-30 13:04:14 +01:00
parent 553872ced2
commit 919df92888
6 changed files with 910 additions and 897 deletions
@@ -26,6 +26,7 @@ import documentation
from collections import defaultdict from collections import defaultdict
USE_VIRTUAL_INHERITANCE = True
class Header(codegen.Base): class Header(codegen.Base):
def __init__(self, mapping): def __init__(self, mapping):
@@ -50,7 +51,7 @@ class Header(codegen.Base):
for name, type in mapping.schema.selects.items(): for name, type in mapping.schema.selects.items():
for nm in type.values: for nm in type.values:
select_super_types[str(nm).lower()].append(name) select_super_types[str(nm).lower()].append(name)
write(templates.select, name=name) write(templates.select_virtual if USE_VIRTUAL_INHERITANCE else templates.select_plain, name=name)
def get_select_super_types(nm, bases=[]): def get_select_super_types(nm, bases=[]):
x = list(select_super_types[nm.lower()]) x = list(select_super_types[nm.lower()])
@@ -82,7 +83,9 @@ class Header(codegen.Base):
superclass = mapping.simple_type_parent(superclass) superclass = mapping.simple_type_parent(superclass)
else: else:
superclasses.append("IfcUtil::IfcBaseType") superclasses.append("IfcUtil::IfcBaseType")
superclasses.extend(get_select_super_types(name, bases=all_superclasses))
if USE_VIRTUAL_INHERITANCE:
superclasses.extend(get_select_super_types(name, bases=all_superclasses))
is_emitted = ( is_emitted = (
lambda nm: nm == "IfcUtil::IfcBaseType" lambda nm: nm == "IfcUtil::IfcBaseType"
@@ -155,8 +158,8 @@ class Header(codegen.Base):
tt = mapping.schema.entities[tt.supertypes[0]] tt = mapping.schema.entities[tt.supertypes[0]]
supertypes = list(type.supertypes) if len(type.supertypes) else ["IfcUtil::IfcBaseEntity"] supertypes = list(type.supertypes) if len(type.supertypes) else ["IfcUtil::IfcBaseEntity"]
direct_superclass = supertypes[0] if USE_VIRTUAL_INHERITANCE:
supertypes.extend(get_select_super_types(name, bases=all_supertypes)) supertypes.extend(get_select_super_types(name, bases=all_supertypes))
supertypes = list(map(case_normalize, supertypes)) supertypes = list(map(case_normalize, supertypes))
superclass = create_supertype_statement(supertypes) superclass = create_supertype_statement(supertypes)
@@ -22,6 +22,8 @@ import templates
from schema import OrderedCaseInsensitiveDict from schema import OrderedCaseInsensitiveDict
from header import USE_VIRTUAL_INHERITANCE
class Implementation(codegen.Base): class Implementation(codegen.Base):
def __init__(self, mapping): def __init__(self, mapping):
@@ -68,14 +70,15 @@ class Implementation(codegen.Base):
), ),
) )
for name, enum in mapping.schema.selects.items(): if USE_VIRTUAL_INHERITANCE:
write( for name, enum in mapping.schema.selects.items():
templates.select_function, write(
name=name, templates.select_function,
schema_name=schema_name, name=name,
schema_name_upper=schema_name_upper, schema_name=schema_name,
index_in_schema=self.names.index(str(name)), schema_name_upper=schema_name_upper,
) index_in_schema=self.names.index(str(name)),
)
write = lambda str, **kwargs: entity_implementations.append(str % kwargs) write = lambda str, **kwargs: entity_implementations.append(str % kwargs)
@@ -98,6 +101,7 @@ class Implementation(codegen.Base):
def find_template(arg): def find_template(arg):
simple = mapping.schema.is_simpletype(arg["list_instance_type"]) simple = mapping.schema.is_simpletype(arg["list_instance_type"])
select = arg["list_instance_type"] == "IfcUtil::IfcBaseClass"
express = ( express = (
mapping.flatten_type_string(arg["list_instance_type"]) in mapping.express_to_cpp_typemapping mapping.flatten_type_string(arg["list_instance_type"]) in mapping.express_to_cpp_typemapping
) )
@@ -105,7 +109,7 @@ class Implementation(codegen.Base):
return templates.get_attr_stmt_enum return templates.get_attr_stmt_enum
elif arg["is_nested"] and arg["is_templated_list"]: elif arg["is_nested"] and arg["is_templated_list"]:
return templates.get_attr_stmt_nested_array return templates.get_attr_stmt_nested_array
elif arg["is_templated_list"] and not (simple or express): elif arg["is_templated_list"] and not (select or simple or express):
return templates.get_attr_stmt_array return templates.get_attr_stmt_array
elif arg["non_optional_type"].endswith("*"): elif arg["non_optional_type"].endswith("*"):
return templates.get_attr_stmt_entity return templates.get_attr_stmt_entity
@@ -23,6 +23,7 @@ import nodes
import templates import templates
import schema import schema
from header import USE_VIRTUAL_INHERITANCE
class Mapping: class Mapping:
@@ -180,12 +181,11 @@ class Mapping:
ty = ty.replace("*", "") ty = ty.replace("*", "")
# https://github.com/IfcOpenShell/IfcOpenShell/issues/2805 # https://github.com/IfcOpenShell/IfcOpenShell/issues/2805
# This is no longer applicable, we do support statically typed select types as aggregates # We do support statically typed select types as aggregates when USE_VIRTUAL_INHERITANCE=True
#
# if self.schema.is_select(attr_type.type):
# type_str = templates.untyped_list
if self.schema.is_simpletype(ty) or str(ty) in self.express_to_cpp_typemapping.values(): if not USE_VIRTUAL_INHERITANCE and self.schema.is_select(attr_type.type):
type_str = templates.untyped_list
elif self.schema.is_simpletype(ty) or str(ty) in self.express_to_cpp_typemapping.values():
tmpl = templates.nested_array_type if is_nested_list else templates.array_type tmpl = templates.nested_array_type if is_nested_list else templates.array_type
bounds = (attr_type.bounds.lower, attr_type.bounds.upper) if attr_type.bounds else (-1, -1) bounds = (attr_type.bounds.lower, attr_type.bounds.upper) if attr_type.bounds else (-1, -1)
type_str = tmpl % {"instance_type": ty, "lower": bounds[0], "upper": bounds[1]} type_str = tmpl % {"instance_type": ty, "lower": bounds[0], "upper": bounds[1]}
@@ -224,8 +224,8 @@ class Mapping:
isinstance(v, nodes.SimpleType) and isinstance(v.type, nodes.StringType) isinstance(v, nodes.SimpleType) and isinstance(v.type, nodes.StringType)
): ):
return "string" return "string"
# if self.schema.is_select(v): if not USE_VIRTUAL_INHERITANCE and self.schema.is_select(v):
# return "IfcUtil::IfcBaseClass" return "IfcUtil::IfcBaseClass"
if str(v) in self.schema.types or str(v) in self.schema.entities: if str(v) in self.schema.types or str(v) in self.schema.entities:
return "::%s::%s" % (self.schema.name.capitalize(), v) return "::%s::%s" % (self.schema.name.capitalize(), v)
else: else:
@@ -136,7 +136,7 @@ simpletype_impl_cast_templated = (
) )
simpletype_impl_declaration = "return *((IfcParse::type_declaration*)%(schema_name_upper)s_types[%(index_in_schema)d]);" simpletype_impl_declaration = "return *((IfcParse::type_declaration*)%(schema_name_upper)s_types[%(index_in_schema)d]);"
select = """%(documentation)s select_virtual = """%(documentation)s
class IFC_PARSE_API %(name)s : public virtual IfcUtil::IfcBaseInterface { class IFC_PARSE_API %(name)s : public virtual IfcUtil::IfcBaseInterface {
public: public:
static const IfcParse::select_type& Class(); static const IfcParse::select_type& Class();
@@ -144,6 +144,10 @@ public:
}; };
""" """
select_plain = """%(documentation)s
typedef IfcUtil::IfcBaseClass %(name)s;
"""
enumeration = """class IFC_PARSE_API %(name)s : public IfcUtil::IfcBaseType { enumeration = """class IFC_PARSE_API %(name)s : public IfcUtil::IfcBaseType {
%(documentation)s %(documentation)s
public: public:
File diff suppressed because it is too large Load Diff
+2
View File
@@ -122,6 +122,8 @@ public:
uint32_t id() const { return id_; } uint32_t id() const { return id_; }
void toString(std::ostream&, bool upper = false) const; void toString(std::ostream&, bool upper = false) const;
typedef aggregate_of_instance list;
}; };
class IFC_PARSE_API IfcBaseEntity : public IfcBaseClass { class IFC_PARSE_API IfcBaseEntity : public IfcBaseClass {