From 42981d681a04a23c2250eaf9b188e022ca42962c Mon Sep 17 00:00:00 2001 From: bbbgan <2893129936@qq.com> Date: Sun, 9 Jul 2023 23:16:09 +0800 Subject: [PATCH] add test; remove template skip_till --- iguana/xml_reader.hpp | 2 +- iguana/xml_util.hpp | 46 ++++++++++++++++++++++++++++++++----------- test/test_xml.cpp | 8 ++++---- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/iguana/xml_reader.hpp b/iguana/xml_reader.hpp index f9acc0d5..cd62b2ae 100644 --- a/iguana/xml_reader.hpp +++ b/iguana/xml_reader.hpp @@ -186,7 +186,7 @@ IGUANA_INLINE void parse_item(T &value, It &&it, It &&end, // >()) { ++it; - skip_till<']'>(it, end); + skip_till_square_bracket(it, end); ++it; match<"]>">(it, end); skip_sapces_and_newline(it, end); diff --git a/iguana/xml_util.hpp b/iguana/xml_util.hpp index 5da49dd6..6cfdc889 100644 --- a/iguana/xml_util.hpp +++ b/iguana/xml_util.hpp @@ -168,17 +168,6 @@ template struct string_literal { // TODO: get more information, now just skip it IGUANA_INLINE void parse_declaration(auto &&it, auto &&end) {} -template IGUANA_INLINE void skip_till(auto &&it, auto &&end) { - while ((it != end) && (!((... || (*it == C))))) { - ++it; - } - if (it == end) [[unlikely]] { - static constexpr char b[] = {C..., '\0'}; - std::string error = std::string("Expected one of these: ").append(b); - throw std::runtime_error(error); - } -} - IGUANA_INLINE void skip_sapces_and_newline(auto &&it, auto &&end) { while (it != end && (*it < 33)) { ++it; @@ -289,6 +278,7 @@ IGUANA_INLINE void skip_till_greater(auto &&it, auto &&end) { throw std::runtime_error("Expected >"); } +// skip_till<'>', '<'>(it, end); IGUANA_INLINE void skip_till_greater_or_space(auto &&it, auto &&end) { static_assert(std::contiguous_iterator>); @@ -329,6 +319,7 @@ IGUANA_INLINE void skip_till_greater_or_space(auto &&it, auto &&end) { throw std::runtime_error("Expected > or space"); } +// skip_till<'<'>(it, end); IGUANA_INLINE void skip_till_smaller(auto &&it, auto &&end) { static_assert(std::contiguous_iterator>); @@ -364,6 +355,39 @@ IGUANA_INLINE void skip_till_smaller(auto &&it, auto &&end) { throw std::runtime_error("Expected >"); } +// skip_till<']'>(it, end); +IGUANA_INLINE void skip_till_square_bracket(auto &&it, auto &&end) { + static_assert(std::contiguous_iterator>); + + auto has_zero = [](uint64_t chunk) { + return (((chunk - 0x0101010101010101) & ~chunk) & 0x8080808080808080); + }; + auto has_square_bracket = [&](uint64_t chunk) { + return has_zero(chunk ^ 0b010111010101110101011101010111010101110101011101); + }; + if (std::distance(it, end) >= 7) [[likely]] { + const auto end_m7 = end - 7; + for (; it < end_m7; it += 8) { + const auto chunk = *reinterpret_cast(&*it); + uint64_t test = has_square_bracket(chunk); + if (test != 0) { + it += (std::countr_zero(test) >> 3); + return; + } + } + } + + // Tail end of buffer. Should be rare we even get here + while (it < end) { + switch (*it) { + case ']': + return; + } + ++it; + } + throw std::runtime_error("Expected ]"); +} + IGUANA_INLINE auto skip_pass_smaller(auto &&it, auto &&end) { skip_till_smaller(it, end); auto res = it++ - 1; diff --git a/test/test_xml.cpp b/test/test_xml.cpp index 89cb9266..00883a18 100644 --- a/test/test_xml.cpp +++ b/test/test_xml.cpp @@ -319,22 +319,22 @@ struct test_exception_t { REFLECTION(test_exception_t, a, b, c); TEST_CASE("test exception") { { - std::string str = "3.14"; + std::string str = " d3 "; test_exception_t t; CHECK_THROWS(iguana::from_xml(t, str)); } { - std::string str = "TURE"; + std::string str = " TURE "; test_exception_t t; CHECK_THROWS(iguana::from_xml(t, str)); } { - std::string str = "ab"; + std::string str = " ab "; test_exception_t t; CHECK_THROWS(iguana::from_xml(t, str)); } { - std::string str = "ab"; + std::string str = " ab "; test_exception_t t; CHECK_THROWS(iguana::from_xml(t, str)); }