@@ -35,34 +35,7 @@ namespace winmd::reader
3535 {
3636 for (auto &&[name, type] : members.types )
3737 {
38- switch (get_category (type))
39- {
40- case category::interface_type:
41- members.interfaces .push_back (type);
42- continue ;
43- case category::class_type:
44- if (extends_type (type, " System" sv, " Attribute" sv))
45- {
46- members.attributes .push_back (type);
47- continue ;
48- }
49- members.classes .push_back (type);
50- continue ;
51- case category::enum_type:
52- members.enums .push_back (type);
53- continue ;
54- case category::struct_type:
55- if (get_attribute (type, " Windows.Foundation.Metadata" sv, " ApiContractAttribute" sv))
56- {
57- members.contracts .push_back (type);
58- continue ;
59- }
60- members.structs .push_back (type);
61- continue ;
62- case category::delegate_type:
63- members.delegates .push_back (type);
64- continue ;
65- }
38+ add_type_to_members (type, members);
6639 }
6740 }
6841 }
@@ -165,6 +138,32 @@ namespace winmd::reader
165138 remove (members.delegates , name);
166139 }
167140
141+ // This won't invalidate any existing database or row_base (e.g. TypeDef) instances
142+ // However, it may invalidate iterators and references to namespace_members, because those are stored in std::vector
143+ void add_database (std::string_view const & file)
144+ {
145+ auto & db = m_databases.emplace_back (file, this );
146+ for (auto && type : db.TypeDef )
147+ {
148+ if (type.Flags ().value == 0 || is_nested (type))
149+ {
150+ continue ;
151+ }
152+
153+ auto & ns = m_namespaces[type.TypeNamespace ()];
154+ auto [iter, inserted] = ns.types .try_emplace (type.TypeName (), type);
155+ if (inserted)
156+ {
157+ add_type_to_members (type, ns);
158+ }
159+ }
160+
161+ for (auto && row : db.NestedClass )
162+ {
163+ m_nested_types[row.EnclosingType ()].push_back (row.NestedType ());
164+ }
165+ }
166+
168167 std::vector<TypeDef> const & nested_types (TypeDef const & enclosing_type) const
169168 {
170169 auto it = m_nested_types.find (enclosing_type);
@@ -195,6 +194,38 @@ namespace winmd::reader
195194
196195 private:
197196
197+ void add_type_to_members (TypeDef const & type, namespace_members& members)
198+ {
199+ switch (get_category (type))
200+ {
201+ case category::interface_type:
202+ members.interfaces .push_back (type);
203+ return ;
204+ case category::class_type:
205+ if (extends_type (type, " System" sv, " Attribute" sv))
206+ {
207+ members.attributes .push_back (type);
208+ return ;
209+ }
210+ members.classes .push_back (type);
211+ return ;
212+ case category::enum_type:
213+ members.enums .push_back (type);
214+ return ;
215+ case category::struct_type:
216+ if (get_attribute (type, " Windows.Foundation.Metadata" sv, " ApiContractAttribute" sv))
217+ {
218+ members.contracts .push_back (type);
219+ return ;
220+ }
221+ members.structs .push_back (type);
222+ return ;
223+ case category::delegate_type:
224+ members.delegates .push_back (type);
225+ return ;
226+ }
227+ }
228+
198229 std::list<database> m_databases;
199230 std::map<std::string_view, namespace_members> m_namespaces;
200231 std::map<TypeDef, std::vector<TypeDef>> m_nested_types;
0 commit comments