Skip to content

Commit

Permalink
improve judging using static array
Browse files Browse the repository at this point in the history
  • Loading branch information
bbbgan committed Apr 10, 2024
1 parent b65e375 commit 7d20997
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 10 deletions.
10 changes: 4 additions & 6 deletions iguana/detail/charconv.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,23 @@ namespace detail {
template <bool check_number = true, typename U>
std::pair<const char *, std::errc> from_chars(const char *first,
const char *last, U &value) {
#define CHECK_NUM \
if (p != last || ec != std::errc{}) \
IGUANA_UNLIKELY { throw std::runtime_error("Failed to parse number"); }
using T = std::decay_t<U>;
if constexpr (std::is_floating_point_v<T>) {
auto [p, ec] = fast_float::from_chars(first, last, value);
if constexpr (check_number) {
CHECK_NUM
if (p != last || ec != std::errc{})
IGUANA_UNLIKELY { throw std::runtime_error("Failed to parse number"); }
}
return {p, ec};
}
else {
auto [p, ec] = std::from_chars(first, last, value);
if constexpr (check_number) {
CHECK_NUM
if (p != last || ec != std::errc{})
IGUANA_UNLIKELY { throw std::runtime_error("Failed to parse number"); }
}
return {p, ec};
}
#undef CHECK_NUM
}

// not support uint8 for now
Expand Down
5 changes: 1 addition & 4 deletions iguana/json_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,7 @@ IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) {
IGUANA_UNLIKELY { throw std::runtime_error("Failed to parse number"); }
const auto start = &*it;
auto [p, ec] = detail::from_chars<false>(start, start + size, value);
// TODO: improve by static array
if (ec != std::errc{} ||
!(*p == '}' || *p == ']' || *p == ',' || *p == ' ' || *p == '\0' ||
*p == '"' || *p == '\n'))
if (ec != std::errc{} || !can_follow_number(*p))
IGUANA_UNLIKELY { throw std::runtime_error("Failed to parse number"); }
it += (p - &*it);
}
Expand Down
24 changes: 24 additions & 0 deletions iguana/json_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,4 +211,28 @@ IGUANA_INLINE bool is_numeric(char c) noexcept {
return static_cast<bool>(is_num[static_cast<unsigned int>(c)]);
}

// '\t' '\r' '\n' '"' '}' ']' ',' ' ' '\0'
IGUANA_INLINE bool can_follow_number(char c) noexcept {
static constexpr int can_follow_num[256] = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, // 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, // 2
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, // 5
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, // 7
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // F
};
return static_cast<bool>(can_follow_num[static_cast<unsigned int>(c)]);
}

} // namespace iguana

0 comments on commit 7d20997

Please sign in to comment.