Skip to content

Commit

Permalink
remove rapidxml (#361)
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos authored Jul 12, 2023
1 parent aa0c4df commit 0581abb
Show file tree
Hide file tree
Showing 16 changed files with 1,280 additions and 3,714 deletions.
22 changes: 9 additions & 13 deletions include/ylt/struct_xml/xml_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,18 @@

namespace struct_xml {

template <int Flags = 0, typename T>
inline bool from_xml(T &&t, char *buf) {
return iguana::from_xml<Flags>(std::forward<T>(t), buf);
template <typename T, typename View>
inline void from_xml(T &&t, const View &str) {
iguana::from_xml(std::forward<T>(t), str);
}

template <int Flags = 0, typename T>
inline bool from_xml(T &&t, const std::string &str) {
return from_xml<Flags>(std::forward<T>(t), str.data());
template <typename Num>
inline Num get_number(std::string_view str) {
return iguana::get_number<Num>(str);
}

template <int Flags = 0, typename T>
inline bool from_xml(T &&t, std::string_view str) {
return from_xml<Flags>(std::forward<T>(t), str.data());
}

inline std::string get_last_read_err() { return iguana::get_last_read_err(); }
template <typename T, typename map_type = std::unordered_map<std::string_view,
std::string_view>>
using xml_attr_t = iguana::xml_attr_t<T, map_type>;

using any_t = iguana::any_t;
} // namespace struct_xml
4 changes: 0 additions & 4 deletions include/ylt/struct_xml/xml_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,4 @@ inline void to_xml(T &&t, Stream &s) {
iguana::to_xml(std::forward<T>(t), s);
}

template <int Flags = 0, typename Stream, typename T>
inline bool to_xml_pretty(T &&t, Stream &s) {
return iguana::to_xml_pretty<Flags>(std::forward<T>(t), s);
}
} // namespace struct_xml
166 changes: 112 additions & 54 deletions include/ylt/thirdparty/iguana/json_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ void from_json(T &value, It &&it, It &&end);

namespace detail {

template <sequence_container U, class It>
IGUANA_INLINE void parse_item(U &value, It &&it, It &&end);

template <str_t U, class It>
IGUANA_INLINE void parse_escape(U &value, It &&it, It &&end) {
if (it == end)
Expand Down Expand Up @@ -101,9 +104,76 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) {
parse_item(reinterpret_cast<T &>(value), it, end);
}

template <str_t U, class It>
IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, bool skip = false) {
if (!skip) {
template <bool skip = false, char_t U, class It>
IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) {
if constexpr (!skip) {
skip_ws(it, end);
match<'"'>(it, end);
}
if (it == end) [[unlikely]]
throw std::runtime_error("Unxpected end of buffer");
if (*it == '\\') [[unlikely]] {
if (++it == end) [[unlikely]] {
throw std::runtime_error("Unxpected end of buffer");
}
else if (*it == 'n') {
value = '\n';
}
else if (*it == 't') {
value = '\t';
}
else if (*it == 'r') {
value = '\r';
}
else if (*it == 'b') {
value = '\b';
}
else if (*it == 'f') {
value = '\f';
}
else [[unlikely]] {
value = *it;
}
}
else {
value = *it;
}
++it;
if constexpr (!skip) {
match<'"'>(it, end);
}
}

template <bool_t U, class It>
IGUANA_INLINE void parse_item(U &&value, It &&it, It &&end) {
skip_ws(it, end);

if (it < end) [[likely]] {
switch (*it) {
case 't': {
++it;
match<"rue">(it, end);
value = true;
break;
}
case 'f': {
++it;
match<"alse">(it, end);
value = false;
break;
}
[[unlikely]] default
: throw std::runtime_error("Expected true or false");
}
}
else [[unlikely]] {
throw std::runtime_error("Expected true or false");
}
}

template <bool skip = false, str_t U, class It>
IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) {
if constexpr (!skip) {
skip_ws(it, end);
match<'"'>(it, end);
}
Expand Down Expand Up @@ -148,11 +218,11 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, bool skip = false) {
}
}

template <str_view_t U, class It>
IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, bool skip = false) {
template <bool skip = false, str_view_t U, class It>
IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) {
static_assert(std::contiguous_iterator<std::decay_t<It>>,
"must be contiguous");
if (!skip) {
if constexpr (!skip) {
skip_ws(it, end);
match<'"'>(it, end);
}
Expand All @@ -173,8 +243,23 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, bool skip = false) {
template <fixed_array U, class It>
IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) {
using T = std::remove_reference_t<U>;
constexpr auto n = sizeof(T) / sizeof(decltype(std::declval<T>()[0]));
skip_ws(it, end);

if constexpr (std::is_same_v<char, std::remove_reference_t<
decltype(std::declval<T>()[0])>>) {
if (*it == '"') {
match<'"'>(it, end);
auto value_it = std::begin(value);
for (size_t i = 0; i < n; ++i) {
if (*it != '"') [[likely]] {
parse_item<true>(*value_it++, it, end);
}
}
match<'"'>(it, end);
return;
}
}
match<'['>(it, end);
skip_ws(it, end);
if (it == end) {
Expand All @@ -185,11 +270,7 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) {
++it;
return;
}

constexpr auto n = sizeof(T) / sizeof(decltype(std::declval<T>()[0]));

auto value_it = std::begin(value);

for (size_t i = 0; i < n; ++i) {
parse_item(*value_it++, it, end);
skip_ws(it, end);
Expand Down Expand Up @@ -299,41 +380,14 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) {
match<']'>(it, end);
}

template <bool_t U, class It>
IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) {
skip_ws(it, end);

if (it < end) [[likely]] {
switch (*it) {
case 't': {
++it;
match<"rue">(it, end);
value = true;
break;
}
case 'f': {
++it;
match<"alse">(it, end);
value = false;
break;
}
[[unlikely]] default
: throw std::runtime_error("Expected true or false");
}
}
else [[unlikely]] {
throw std::runtime_error("Expected true or false");
}
}

template <optional U, class It>
IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) {
skip_ws(it, end);
if (it < end && *it == '"') {
if (it < end && *it == '"') [[likely]] {
++it;
}
using T = std::remove_reference_t<U>;
if (it == end) {
if (it == end) [[unlikely]] {
throw std::runtime_error("Unexexpected eof");
}
if (*it == 'n') {
Expand All @@ -350,28 +404,33 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) {
using value_type = typename T::value_type;
value_type t;
if constexpr (str_t<value_type> || str_view_t<value_type>) {
parse_item(t, it, end, true);
parse_item<true>(t, it, end);
}
else {
parse_item(t, it, end);
}

value = std::move(t);
}
}

template <char_t U, class It>
template <unique_ptr_t U, class It>
IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) {
// TODO: this does not handle escaped chars
skip_ws(it, end);
match<'"'>(it, end);
if (it == end) [[unlikely]]
throw std::runtime_error("Unxpected end of buffer");
if (*it == '\\') [[unlikely]]
if (++it == end) [[unlikely]]
throw std::runtime_error("Unxpected end of buffer");
value = *it++;
match<'"'>(it, end);
if (it < end && *it == '"') [[likely]] {
++it;
}
if (it == end) [[unlikely]] {
throw std::runtime_error("Unexexpected eof");
}
if (*it == 'n') {
++it;
match<"ull">(it, end);
}
else {
using value_type = typename std::remove_reference_t<U>::element_type;
value = std::make_unique<value_type>();
parse_item(*value, it, end);
}
}

IGUANA_INLINE void skip_object_value(auto &&it, auto &&end) {
Expand Down Expand Up @@ -399,7 +458,6 @@ IGUANA_INLINE void skip_object_value(auto &&it, auto &&end) {
continue;
}
}

break;
}
}
Expand Down Expand Up @@ -437,7 +495,7 @@ IGUANA_INLINE void from_json(T &value, It &&it, It &&end) {
// compile time versions of keys
it = start;
static thread_local std::string static_key{};
detail::parse_item(static_key, it, end, true);
detail::parse_item<true>(static_key, it, end);
key = static_key;
}
else [[likely]] {
Expand All @@ -451,7 +509,7 @@ IGUANA_INLINE void from_json(T &value, It &&it, It &&end) {
}
else {
static thread_local std::string static_key{};
detail::parse_item(static_key, it, end, false);
detail::parse_item(static_key, it, end);
key = static_key;
}

Expand Down
36 changes: 22 additions & 14 deletions include/ylt/thirdparty/iguana/json_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,6 @@ constexpr inline bool is_basic_string_view = false;
template <typename T>
constexpr inline bool is_basic_string_view<std::basic_string_view<T>> = true;

template <typename T>
concept str_view_t = is_basic_string_view<std::remove_reference_t<T>>;

template <class T>
concept str_t =
std::convertible_to<std::decay_t<T>, std::string_view> && !str_view_t<T>;

template <typename Type>
constexpr inline bool is_std_vector_v = false;

Expand Down Expand Up @@ -103,6 +96,15 @@ concept array = requires(Type arr) {
template <typename Type>
concept fixed_array = c_array<Type> || array<Type>;

template <typename T>
concept str_view_t = is_basic_string_view<std::remove_reference_t<T>>;

// eliminate char a[]
template <class T>
concept str_t =
std::convertible_to<std::decay_t<T>, std::string_view> && !str_view_t<T> &&
!c_array<T>;

template <typename Type>
concept tuple = !array<Type> && requires(Type tuple) {
std::get<0>(tuple);
Expand Down Expand Up @@ -135,10 +137,6 @@ concept sequence_container = is_std_list_v<std::remove_reference_t<Type>> ||
is_std_vector_v<std::remove_reference_t<Type>> ||
is_std_deque_v<std::remove_reference_t<Type>>;

template <class T>
concept non_refletable = container<T> || c_array<T> || tuple<T> ||
optional<T> || std::is_fundamental_v<T>;

template <class T>
concept associat_container_t =
is_associat_container<std::remove_cvref_t<T>>::value;
Expand All @@ -151,8 +149,18 @@ template <class T>
concept tuple_t = is_tuple<std::remove_cvref_t<T>>::value;

template <class T>
concept string_container_t =
std::convertible_to<std::decay_t<T>, std::string_view>;
concept string_container_t = str_t<T> || str_view_t<T>;

template <typename Type>
concept unique_ptr_t = requires(Type ptr) {
ptr.operator*();
typename std::remove_cvref_t<Type>::element_type;
}
&&!requires(Type ptr, Type ptr2) { ptr = ptr2; };

template <class T>
concept non_refletable = container<T> || c_array<T> || tuple<T> ||
optional<T> || unique_ptr_t<T> || std::is_fundamental_v<T>;

template <size_t N>
struct string_literal {
Expand Down Expand Up @@ -245,7 +253,7 @@ IGUANA_INLINE void skip_ws(auto &&it, auto &&end) {
IGUANA_INLINE void skip_ws_no_comments(auto &&it, auto &&end) {
while (it != end) {
// assuming ascii
if (static_cast<uint8_t>(*it) < 33) {
if (static_cast<uint8_t>(*it) < 33) [[likely]] {
++it;
}
else {
Expand Down
Loading

0 comments on commit 0581abb

Please sign in to comment.