diff options
| author | steven-vd <steven@vandorp.lu> | 2026-08-16 15:00:32 +0200 |
|---|---|---|
| committer | steven-vd <steven@vandorp.lu> | 2026-08-17 09:31:42 +0200 |
| commit | ee081ca70322cd01d0642fdb1860e6bfbfb48e85 (patch) | |
| tree | 295fdba93b08b24562c6d49e971bbf3425eac50c /benchmarks/RapidXML/count_highway_crossings.cpp | |
Diffstat (limited to 'benchmarks/RapidXML/count_highway_crossings.cpp')
| -rw-r--r-- | benchmarks/RapidXML/count_highway_crossings.cpp | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/benchmarks/RapidXML/count_highway_crossings.cpp b/benchmarks/RapidXML/count_highway_crossings.cpp new file mode 100644 index 0000000..6d0ecf6 --- /dev/null +++ b/benchmarks/RapidXML/count_highway_crossings.cpp @@ -0,0 +1,84 @@ +#include "rapidxml.hpp" +#include <cstddef> +#include <cstring> + +namespace rx = rapidxml; + +inline bool is_highway_crossing(rx::xml_node<>* tag_node) { + rx::xml_attribute<>* k = tag_node->first_attribute(); + if (!k) return false; + + rx::xml_attribute<>* v = k->next_attribute(); + if (!v) return false; + + return std::strcmp(k->value(), "highway") == 0 && + std::strcmp(v->value(), "crossing") == 0; +} + +size_t count_highway_crossings(char* buffer, size_t len) { + rx::xml_document<> doc; + + try { + doc.parse<rx::parse_no_data_nodes | rx::parse_no_element_values>(buffer); + } catch (const rx::parse_error&) { + return 0; + } + + size_t count = 0; + + rx::xml_node<>* osm = doc.first_node("osm"); + if (!osm) + return count; + + for (rx::xml_node<>* node = osm->first_node("node"); + node; + node = node->next_sibling("node")) { + + for (rx::xml_node<>* tag = node->first_node("tag"); + tag; + tag = tag->next_sibling("tag")) { + + if (is_highway_crossing(tag)) + ++count; + } + } + + return count; +} + +size_t count_highway_crossings_cheat_and_early_out(char* buffer, size_t len) { + rx::xml_document<> doc; + + try { + doc.parse<rx::parse_no_data_nodes | rx::parse_no_element_values>(buffer); + } catch (const rx::parse_error&) { + return 0; + } + + size_t count = 0; + + rx::xml_node<>* osm = doc.first_node("osm"); + if (!osm) + return count; + + // Equivalent to iterating over all children and stopping at "way". + // next_sibling() avoids inspecting unrelated nodes between elements. + for (rx::xml_node<>* top = osm->first_node(); + top; + top = top->next_sibling()) { + + if (std::strcmp(top->name(), "way") == 0) + break; + + for (rx::xml_node<>* tag = top->first_node("tag"); + tag; + tag = tag->next_sibling("tag")) { + + if (is_highway_crossing(tag)) + ++count; + } + } + + return count; +} + |
