Skip to content

Commit 7147c78

Browse files
committed
registry api
1 parent 706255f commit 7147c78

File tree

3 files changed

+63
-63
lines changed

3 files changed

+63
-63
lines changed

src/odr/internal/odf/odf_element_registry.cpp

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,39 @@ void ElementRegistry::clear() noexcept {
1717
return m_elements.size();
1818
}
1919

20-
ExtendedElementIdentifier ElementRegistry::create_element() {
21-
m_elements.emplace_back();
22-
return ExtendedElementIdentifier(m_elements.size());
20+
std::tuple<ExtendedElementIdentifier, ElementRegistry::Element &>
21+
ElementRegistry::create_element(const ElementType type,
22+
const pugi::xml_node node) {
23+
Element &element = m_elements.emplace_back();
24+
ExtendedElementIdentifier element_id(m_elements.size());
25+
element.type = type;
26+
element.node = node;
27+
return {element_id, element};
2328
}
2429

25-
ElementRegistry::Table &
26-
ElementRegistry::create_table_element(const ExtendedElementIdentifier id) {
27-
check_element_id(id);
28-
auto [it, success] = m_tables.emplace(id.element_id(), Table{});
29-
return it->second;
30+
std::tuple<ExtendedElementIdentifier, ElementRegistry::Element &,
31+
ElementRegistry::Text &>
32+
ElementRegistry::create_text_element(const pugi::xml_node first_node) {
33+
const auto &[element_id, element] =
34+
create_element(ElementType::text, first_node);
35+
auto [it, success] = m_texts.emplace(element_id.element_id(), Text{});
36+
return {element_id, element, it->second};
3037
}
3138

32-
ElementRegistry::Text &
33-
ElementRegistry::create_text_element(const ExtendedElementIdentifier id) {
34-
check_element_id(id);
35-
auto [it, success] = m_texts.emplace(id.element_id(), Text{});
36-
return it->second;
39+
std::tuple<ExtendedElementIdentifier, ElementRegistry::Element &,
40+
ElementRegistry::Table &>
41+
ElementRegistry::create_table_element(const pugi::xml_node node) {
42+
const auto &[element_id, element] = create_element(ElementType::table, node);
43+
auto [it, success] = m_tables.emplace(element_id.element_id(), Table{});
44+
return {element_id, element, it->second};
3745
}
3846

39-
ElementRegistry::Sheet &
40-
ElementRegistry::create_sheet_element(const ExtendedElementIdentifier id) {
41-
check_element_id(id);
42-
auto [it, success] = m_sheets.emplace(id.element_id(), Sheet{});
43-
return it->second;
47+
std::tuple<ExtendedElementIdentifier, ElementRegistry::Element &,
48+
ElementRegistry::Sheet &>
49+
ElementRegistry::create_sheet_element(const pugi::xml_node node) {
50+
const auto &[element_id, element] = create_element(ElementType::table, node);
51+
auto [it, success] = m_sheets.emplace(element_id.element_id(), Sheet{});
52+
return {element_id, element, it->second};
4453
}
4554

4655
[[nodiscard]] ElementRegistry::Element &
@@ -103,6 +112,10 @@ void ElementRegistry::append_child(const ExtendedElementIdentifier parent_id,
103112
const ExtendedElementIdentifier child_id) {
104113
check_element_id(parent_id);
105114
check_element_id(child_id);
115+
if (!element(child_id).parent_id.is_null()) {
116+
throw std::invalid_argument(
117+
"DocumentElementRegistry::append_child: child already has a parent");
118+
}
106119

107120
const ExtendedElementIdentifier previous_sibling_id(
108121
element(parent_id).last_child_id);
@@ -121,15 +134,15 @@ void ElementRegistry::append_column(const ExtendedElementIdentifier table_id,
121134
const ExtendedElementIdentifier column_id) {
122135
check_table_id(table_id);
123136
check_element_id(column_id);
137+
if (!element(column_id).parent_id.is_null()) {
138+
throw std::invalid_argument(
139+
"DocumentElementRegistry::append_column: child already has a parent");
140+
}
124141

125142
const ExtendedElementIdentifier previous_sibling_id(
126143
table_element(table_id).last_column_id);
127144

128145
element(column_id).parent_id = table_id;
129-
element(column_id).first_child_id = null_element_id;
130-
element(column_id).last_child_id = null_element_id;
131-
element(column_id).previous_sibling_id = previous_sibling_id.element_id();
132-
element(column_id).next_sibling_id = null_element_id;
133146

134147
if (table_element(table_id).first_column_id == null_element_id) {
135148
table_element(table_id).first_column_id = column_id.element_id();
@@ -143,15 +156,15 @@ void ElementRegistry::append_shape(const ExtendedElementIdentifier sheet_id,
143156
const ExtendedElementIdentifier shape_id) {
144157
check_sheet_id(sheet_id);
145158
check_element_id(shape_id);
159+
if (!element(shape_id).parent_id.is_null()) {
160+
throw std::invalid_argument(
161+
"DocumentElementRegistry::append_shape: child already has a parent");
162+
}
146163

147164
const ExtendedElementIdentifier previous_sibling_id(
148165
sheet_element(sheet_id).last_shape_id);
149166

150167
element(shape_id).parent_id = sheet_id;
151-
element(shape_id).first_child_id = null_element_id;
152-
element(shape_id).last_child_id = null_element_id;
153-
element(shape_id).previous_sibling_id = previous_sibling_id.element_id();
154-
element(shape_id).next_sibling_id = null_element_id;
155168

156169
if (sheet_element(sheet_id).first_shape_id == null_element_id) {
157170
sheet_element(sheet_id).first_shape_id = shape_id.element_id();
@@ -166,12 +179,12 @@ void ElementRegistry::append_sheet_cell(
166179
const ExtendedElementIdentifier cell_id) {
167180
check_sheet_id(sheet_id);
168181
check_element_id(cell_id);
182+
if (!element(cell_id).parent_id.is_null()) {
183+
throw std::invalid_argument("DocumentElementRegistry::append_sheet_cell: "
184+
"child already has a parent");
185+
}
169186

170187
element(cell_id).parent_id = sheet_id;
171-
element(cell_id).first_child_id = null_element_id;
172-
element(cell_id).last_child_id = null_element_id;
173-
element(cell_id).previous_sibling_id = null_element_id;
174-
element(cell_id).next_sibling_id = null_element_id;
175188
}
176189

177190
void ElementRegistry::check_element_id(

src/odr/internal/odf/odf_element_registry.hpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,24 @@ class ElementRegistry final {
7575

7676
[[nodiscard]] std::size_t size() const noexcept;
7777

78-
ExtendedElementIdentifier create_element();
79-
Table &create_table_element(ExtendedElementIdentifier id);
80-
Text &create_text_element(ExtendedElementIdentifier id);
81-
Sheet &create_sheet_element(ExtendedElementIdentifier id);
78+
std::tuple<ExtendedElementIdentifier, Element &>
79+
create_element(ElementType type, pugi::xml_node node);
80+
std::tuple<ExtendedElementIdentifier, Element &, Text &>
81+
create_text_element(pugi::xml_node first_node);
82+
std::tuple<ExtendedElementIdentifier, Element &, Table &>
83+
create_table_element(pugi::xml_node node);
84+
std::tuple<ExtendedElementIdentifier, Element &, Sheet &>
85+
create_sheet_element(pugi::xml_node node);
8286

8387
[[nodiscard]] Element &element(ExtendedElementIdentifier id);
8488
[[nodiscard]] const Element &element(ExtendedElementIdentifier id) const;
8589

86-
[[nodiscard]] Table &table_element(ExtendedElementIdentifier id);
87-
[[nodiscard]] const Table &table_element(ExtendedElementIdentifier id) const;
88-
8990
[[nodiscard]] Text &text_element(ExtendedElementIdentifier id);
9091
[[nodiscard]] const Text &text_element(ExtendedElementIdentifier id) const;
9192

93+
[[nodiscard]] Table &table_element(ExtendedElementIdentifier id);
94+
[[nodiscard]] const Table &table_element(ExtendedElementIdentifier id) const;
95+
9296
[[nodiscard]] Sheet &sheet_element(ExtendedElementIdentifier id);
9397
[[nodiscard]] const Sheet &sheet_element(ExtendedElementIdentifier id) const;
9498

@@ -103,8 +107,8 @@ class ElementRegistry final {
103107

104108
private:
105109
std::vector<Element> m_elements;
106-
std::unordered_map<ElementIdentifier, Table> m_tables;
107110
std::unordered_map<ElementIdentifier, Text> m_texts;
111+
std::unordered_map<ElementIdentifier, Table> m_tables;
108112
std::unordered_map<ElementIdentifier, Sheet> m_sheets;
109113

110114
void check_element_id(ExtendedElementIdentifier id) const;

src/odr/internal/odf/odf_parser.cpp

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,7 @@ parse_element_tree(ElementRegistry &registry, const ElementType type,
4444
return {ExtendedElementIdentifier::null(), pugi::xml_node()};
4545
}
4646

47-
const ExtendedElementIdentifier element_id = registry.create_element();
48-
ElementRegistry::Element &element = registry.element(element_id);
49-
element.type = type;
50-
element.node = node;
47+
const auto &[element_id, _] = registry.create_element(type, node);
5148

5249
children_parser(registry, element_id, node);
5350

@@ -80,14 +77,10 @@ parse_text_element(ElementRegistry &registry, const pugi::xml_node first) {
8077
return {ExtendedElementIdentifier::null(), pugi::xml_node()};
8178
}
8279

83-
const ExtendedElementIdentifier element_id = registry.create_element();
84-
ElementRegistry::Element &element = registry.element(element_id);
85-
element.type = ElementType::text;
86-
element.node = first;
87-
auto &[last] = registry.create_text_element(element_id);
80+
const auto &[element_id, _, text] = registry.create_text_element(first);
8881

89-
for (last = first; is_text_node(last.next_sibling());
90-
last = last.next_sibling()) {
82+
pugi::xml_node last = first;
83+
for (; is_text_node(last.next_sibling()); last = last.next_sibling()) {
9184
}
9285

9386
return {element_id, last.next_sibling()};
@@ -99,10 +92,8 @@ parse_table_row(ElementRegistry &registry, const pugi::xml_node node) {
9992
return {ExtendedElementIdentifier::null(), pugi::xml_node()};
10093
}
10194

102-
const ExtendedElementIdentifier element_id = registry.create_element();
103-
ElementRegistry::Element &element = registry.element(element_id);
104-
element.type = ElementType::table_row;
105-
element.node = node;
95+
const auto &[element_id, _] =
96+
registry.create_element(ElementType::table_row, node);
10697

10798
for (const pugi::xml_node cell_node : node.children()) {
10899
// TODO log warning if repeated
@@ -119,11 +110,7 @@ parse_table(ElementRegistry &registry, const pugi::xml_node node) {
119110
return {ExtendedElementIdentifier::null(), pugi::xml_node()};
120111
}
121112

122-
const ExtendedElementIdentifier element_id = registry.create_element();
123-
ElementRegistry::Element &element = registry.element(element_id);
124-
element.type = ElementType::table;
125-
element.node = node;
126-
registry.create_table_element(element_id);
113+
const auto &[element_id, _, table] = registry.create_table_element(node);
127114

128115
// TODO inflate table first?
129116

@@ -152,11 +139,7 @@ parse_sheet(ElementRegistry &registry, const pugi::xml_node node) {
152139
return {ExtendedElementIdentifier::null(), pugi::xml_node()};
153140
}
154141

155-
const ExtendedElementIdentifier element_id = registry.create_element();
156-
ElementRegistry::Element &element = registry.element(element_id);
157-
element.type = ElementType::sheet;
158-
element.node = node;
159-
ElementRegistry::Sheet &sheet = registry.create_sheet_element(element_id);
142+
const auto &[element_id, _, sheet] = registry.create_sheet_element(node);
160143

161144
TableCursor cursor;
162145

0 commit comments

Comments
 (0)