@@ -113,6 +113,7 @@ def finalize(self, can_be_instantiated_set, override_schema_name=None):
113113
114114class EarlyBoundCodeWriter :
115115 def __init__ (self , schema_name ):
116+ self .strings = []
116117 self .schema_name = schema_name
117118 self .schema_name_title = schema_name .capitalize ()
118119
@@ -126,6 +127,14 @@ def __init__(self, schema_name):
126127 ]
127128
128129 self .names = []
130+
131+ def make_string (self , s ):
132+ try :
133+ i = self .strings .index (s )
134+ except ValueError :
135+ self .strings .append (s )
136+ i = len (self .strings ) - 1
137+ return "strings[%d]" % i
129138
130139 def aggregation_type (self , aggr_type , bound1 , bound2 , decl_type ):
131140 return (
@@ -148,6 +157,9 @@ def begin_schema(self):
148157 self .names .sort (key = str .lower )
149158
150159 self .statements .append ("{factory_placeholder}" )
160+
161+ self .statements .append ("using namespace std::string_literals;" )
162+ self .statements .append ("{strings_placeholder}" )
151163
152164 self .statements .append (
153165 """
@@ -164,107 +176,109 @@ def begin_schema(self):
164176 self .statements .append ("IfcParse::schema_definition* %s_populate_schema() {" % self .schema_name )
165177
166178 def typedef (self , name , declared_type ):
179+ name_string = self .make_string (name )
167180 schema_name = self .schema_name
168181 index_in_schema = self .names .index (name )
169182 self .statements .append (
170- ' %(schema_name)s_%(name)s_type = new type_declaration("%(name)s" , %(index_in_schema)d, %(declared_type)s);'
183+ ' %(schema_name)s_%(name)s_type = new type_declaration(%(name_string)s , %(index_in_schema)d, %(declared_type)s);'
171184 % locals ()
172185 )
173186
174187 def enumeration (self , name , enum ):
175188 schema_name = self .schema_name
176189 index_in_schema = self .names .index (name )
177- self .statements .append (" {" )
178- self .statements .append (" std::vector<std::string> items; items.reserve(%d);" % len (enum .values ))
179- self .statements .extend (map (lambda v : ' items.push_back("%s");' % v , sorted (enum .values )))
190+ name_string = self .make_string (name )
191+ # @tfk we don't sort for correspondence with header file
192+ # values = sorted(enum.values)
193+ values = enum .values
180194 self .statements .append (
181- ' %(schema_name)s_%(name)s_type = new enumeration_type("%(name)s" , %(index_in_schema)d, items); '
195+ ' %(schema_name)s_%(name)s_type = new enumeration_type(%(name_string)s , %(index_in_schema)d, { '
182196 % locals ()
183197 )
184- self .statements .append (" }" )
198+ self .statements .extend (map (lambda v : ' %s%s' % (self .make_string (v ), '' if v == values [- 1 ] else ',' ), values ))
199+ self .statements .append (' });' )
185200
186201 def entity (self , name , type ):
187202 schema_name = self .schema_name
188203 index_in_schema = self .names .index (name )
204+ name_string = self .make_string (name )
189205 supertype = "0" if len (type .supertypes ) == 0 else "%s_%s_type" % (self .schema_name , type .supertypes [0 ])
190206 is_abstract = "true" if type .abstract else "false"
191207 self .statements .append (
192- ' %(schema_name)s_%(name)s_type = new entity("%(name)s" , %(is_abstract)s, %(index_in_schema)d, %(supertype)s);'
208+ ' %(schema_name)s_%(name)s_type = new entity(%(name_string)s , %(is_abstract)s, %(index_in_schema)d, %(supertype)s);'
193209 % locals ()
194210 )
195211
196212 def select (self , name , type ):
197213 schema_name = self .schema_name
198214 index_in_schema = self .names .index (name )
199- self .statements .append (" {" )
200- self .statements .append (" std::vector<const declaration*> items; items.reserve(%d);" % len (type .values ))
201- self .statements .extend (
202- map (lambda v : " items.push_back(%s_%s_type);" % (self .schema_name , v ), sorted (map (str , type .values )))
203- )
215+ name_string = self .make_string (name )
216+ values = sorted (map (str , type .values ))
204217 self .statements .append (
205- ' %(schema_name)s_%(name)s_type = new select_type("%(name)s" , %(index_in_schema)d, items); '
218+ ' %(schema_name)s_%(name)s_type = new select_type(%(name_string)s , %(index_in_schema)d, { '
206219 % locals ()
207220 )
208- self .statements .append (" }" )
221+ self .statements .extend (
222+ map (lambda v : " %s_%s_type%s" % (self .schema_name , v , '' if v == values [- 1 ] else ',' ), values )
223+ )
224+ self .statements .append (" });" )
209225
210226 def entity_attributes (self , name , attribute_definitions , is_derived ):
211227 schema_name = self .schema_name
212- self .statements .append (" {" )
213- self .statements .append (
214- " std::vector<const attribute*> attributes; attributes.reserve(%d);" % len (attribute_definitions )
215- )
228+
229+ self .statements .append (" %(schema_name)s_%(name)s_type->set_attributes({" % locals ())
216230 for attr_name , decl_type , optional in attribute_definitions :
231+ name_string = self .make_string (attr_name )
217232 optional_cpp = str (optional ).lower ()
233+ tail = '' if attr_name == attribute_definitions [- 1 ][0 ] else ','
218234 self .statements .append (
219- ' attributes.push_back( new attribute("%(attr_name)s" , %(decl_type)s, %(optional_cpp)s)); '
235+ ' new attribute(%(name_string)s , %(decl_type)s, %(optional_cpp)s)%(tail)s '
220236 % locals ()
221237 )
222- self .statements .append (" std::vector<bool> derived; derived.reserve(%d);" % len ( is_derived ) )
238+ self .statements .append (" },{" )
223239 self .statements .append (
224- " " + " " .join (map (lambda b : "derived.push_back(%s); " % str (b ).lower (), is_derived ))
240+ " " + " " .join (map (lambda i , b : "%s%s " % ( str (b ).lower (), '' if i == len ( is_derived ) - 1 else ',' ), range ( len ( is_derived ) ), is_derived ))
225241 )
226- self .statements .append (" %(schema_name)s_%(name)s_type->set_attributes(attributes, derived);" % locals ())
227- self .statements .append (" }" )
228-
242+ self .statements .append (" });" )
243+
229244 def inverse_attributes (self , name , inv_attrs ):
230245 schema_name = self .schema_name
231- self .statements .append (" {" )
232- self .statements .append (
233- " std::vector<const inverse_attribute*> attributes; attributes.reserve(%d);" % len (inv_attrs )
234- )
246+ self .statements .append (" %(schema_name)s_%(name)s_type->set_inverse_attributes({" % locals ())
235247 for attr_name , aggr_type , bound1 , bound2 , entity_ref , attribute_entity , attribute_entity_index in inv_attrs :
248+ name_string = self .make_string (attr_name )
249+ tail = '' if attr_name == inv_attrs [- 1 ][0 ] else ','
236250 self .statements .append (
237- ' attributes.push_back( new inverse_attribute("%(attr_name)s" , inverse_attribute::%(aggr_type)s_type, %(bound1)d, %(bound2)d, %(schema_name)s_%(entity_ref)s_type, %(schema_name)s_%(attribute_entity)s_type->attributes()[%(attribute_entity_index)d])); '
251+ ' new inverse_attribute(%(name_string)s , inverse_attribute::%(aggr_type)s_type, %(bound1)d, %(bound2)d, %(schema_name)s_%(entity_ref)s_type, %(schema_name)s_%(attribute_entity)s_type->attributes()[%(attribute_entity_index)d])%(tail)s '
238252 % locals ()
239253 )
240- self .statements .append (" %(schema_name)s_%(name)s_type->set_inverse_attributes(attributes);" % locals ())
241- self .statements .append (" }" )
254+ self .statements .append (" });" )
242255
243256 def entity_subtypes (self , name , tys ):
244257 schema_name = self .schema_name
245- self .statements .append (" {" )
246- self .statements .append (" std::vector<const entity*> defs; defs.reserve(%d);" % len (tys ))
258+ self .statements .append (" %(schema_name)s_%(name)s_type->set_subtypes({" % locals ())
247259 self .statements .append (
248- (" " + "" .join (map (lambda t : ("defs.push_back(%%(schema_name)s_%s_type);" % t ), tys ))) % locals ()
249- )
250- self .statements .append (" %(schema_name)s_%(name)s_type->set_subtypes(defs);" % locals ())
251- self .statements .append (" }" )
260+ (" " + "" .join (map (lambda t : ("%%(schema_name)s_%s_type%s" % (t , '' if t == tys [- 1 ] else ',' )), tys ))) % locals ()
261+ )
262+ self .statements .append (" });" )
252263
253264 def finalize (self , can_be_instantiated_set ):
254265 schema_name = self .schema_name
266+ schema_name_string = self .make_string (self .schema_name )
255267 schema_name_title = self .schema_name .capitalize ()
256268
257269 num_declarations = len (self .names )
258270
259271 self .statements .append ("" )
260272 self .statements .append (
261- " std::vector<const declaration*> declarations; declarations.reserve(%(num_declarations)d);" % locals ()
273+ " std::vector<const declaration*> declarations= {"
262274 )
263275 for type_name in self .names :
264- self .statements .append (" declarations.push_back(%(schema_name)s_%(type_name)s_type);" % locals ())
276+ tail = '' if type_name == self .names [- 1 ] else ','
277+ self .statements .append (" %(schema_name)s_%(type_name)s_type%(tail)s" % locals ())
278+ self .statements .append (" };" )
265279
266280 self .statements .append (
267- ' return new schema_definition("%(schema_name)s" , declarations, new %(schema_name)s_instance_factory());'
281+ ' return new schema_definition(%(schema_name_string)s , declarations, new %(schema_name)s_instance_factory());'
268282 % locals ()
269283 )
270284
@@ -331,6 +345,12 @@ class %(schema_name)s_instance_factory : public IfcParse::instance_factory {
331345 % locals ()
332346 )
333347
348+ strings_list = ",\n " .join ('"%s"s' % s for s in self .strings )
349+
350+ self .statements [self .statements .index ("{strings_placeholder}" )] = (
351+ "static std::string strings[] = {%s};" % strings_list
352+ )
353+
334354 def __str__ (self ):
335355 return "\n " .join (self .statements )
336356
0 commit comments