Skip to content

Commit

Permalink
Merge pull request #145 from Jacyking/master
Browse files Browse the repository at this point in the history
update iguana
  • Loading branch information
Jacyking authored Feb 1, 2024
2 parents 666c8db + 509eedd commit 083123b
Show file tree
Hide file tree
Showing 8 changed files with 317 additions and 103 deletions.
2 changes: 1 addition & 1 deletion example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ elseif(ENABLE_SQLITE3)
target_link_libraries(${PROJECT_NAME} sqlite3)
endif()

install(TARGETS ${PROJECT_NAME} DESTINATION ormpp)
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
99 changes: 99 additions & 0 deletions iguana/detail/utf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <cassert>
#include <stdexcept>

#include "iguana/define.h"

namespace iguana {
// https://github.com/Tencent/rapidjson/blob/master/include/rapidjson/reader.h
template <typename Ch = char, typename It>
Expand Down Expand Up @@ -48,4 +50,101 @@ inline void encode_utf8(OutputStream &os, unsigned codepoint) {
os.push_back(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
}
}

// https://github.com/Tencent/rapidjson/blob/master/include/rapidjson/encodings.h
static inline unsigned char GetRange(unsigned char c) {
static const unsigned char type[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 10, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3,
11, 6, 6, 6, 5, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8,
};
return type[c];
}

// https://github.com/Tencent/rapidjson/blob/master/include/rapidjson/encodings.h
template <typename Ch = char, typename It>
inline bool decode_utf8(It &&it, unsigned &codepoint) {
auto c = *(it++);
bool result = true;
auto copy = [&]() IGUANA__INLINE_LAMBDA {
c = *(it++);
codepoint = (codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu);
};
auto trans = [&](unsigned mask) IGUANA__INLINE_LAMBDA {
result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0);
};
auto tail = [&]() IGUANA__INLINE_LAMBDA {
copy();
trans(0x70);
};
if (!(c & 0x80)) {
codepoint = static_cast<unsigned char>(c);
return true;
}
unsigned char type = GetRange(static_cast<unsigned char>(c));
if (type >= 32) {
codepoint = 0;
}
else {
codepoint = (0xFFu >> type) & static_cast<unsigned char>(c);
}
switch (type) {
case 2:
tail();
return result;
case 3:
tail();
tail();
return result;
case 4:
copy();
trans(0x50);
tail();
return result;
case 5:
copy();
trans(0x10);
tail();
tail();
return result;
case 6:
tail();
tail();
tail();
return result;
case 10:
copy();
trans(0x20);
tail();
return result;
case 11:
copy();
trans(0x60);
tail();
tail();
return result;
default:
return false;
}
}

} // namespace iguana
9 changes: 6 additions & 3 deletions iguana/enum_reflection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ inline constexpr std::string_view type_string() {
constexpr std::string_view str = get_raw_name<T>();
constexpr auto next1 = str.rfind(sample[pos + 3]);
#if defined(_MSC_VER)
constexpr auto s1 = str.substr(pos + 6, next1 - pos - 6);
constexpr std::size_t npos = str.find_first_of(" ", pos);
if (npos != std::string_view::npos)
return str.substr(npos + 1, next1 - npos - 1);
else
return str.substr(pos, next1 - pos);
#else
constexpr auto s1 = str.substr(pos, next1 - pos);
return str.substr(pos, next1 - pos);
#endif
return s1;
}

template <auto T>
Expand Down
37 changes: 21 additions & 16 deletions iguana/json_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,10 +635,11 @@ IGUANA_INLINE void from_json(T &value, const Byte *data, size_t size,
}

template <bool Is_view = false, typename It>
void parse(jvalue &result, It &&it, It &&end);
void parse(jvalue &result, It &&it, It &&end, bool parse_as_double = false);

template <bool Is_view = false, typename It>
inline void parse(jarray &result, It &&it, It &&end) {
inline void parse(jarray &result, It &&it, It &&end,
bool parse_as_double = false) {
skip_ws(it, end);
match<'['>(it, end);
if (*it == ']')
Expand All @@ -652,7 +653,7 @@ inline void parse(jarray &result, It &&it, It &&end) {
}
result.emplace_back();

parse<Is_view>(result.back(), it, end);
parse<Is_view>(result.back(), it, end, parse_as_double);

if (*it == ']')
IGUANA_UNLIKELY {
Expand All @@ -666,7 +667,8 @@ inline void parse(jarray &result, It &&it, It &&end) {
}

template <bool Is_view = false, typename It>
inline void parse(jobject &result, It &&it, It &&end) {
inline void parse(jobject &result, It &&it, It &&end,
bool parse_as_double = false) {
skip_ws(it, end);
match<'{'>(it, end);
if (*it == '}')
Expand All @@ -689,7 +691,7 @@ inline void parse(jobject &result, It &&it, It &&end) {

match<':'>(it, end);

parse<Is_view>(emplaced.first->second, it, end);
parse<Is_view>(emplaced.first->second, it, end, parse_as_double);

if (*it == '}')
IGUANA_UNLIKELY {
Expand All @@ -702,7 +704,7 @@ inline void parse(jobject &result, It &&it, It &&end) {
}

template <bool Is_view, typename It>
inline void parse(jvalue &result, It &&it, It &&end) {
inline void parse(jvalue &result, It &&it, It &&end, bool parse_as_double) {
skip_ws(it, end);
switch (*it) {
case 'n':
Expand All @@ -728,7 +730,7 @@ inline void parse(jvalue &result, It &&it, It &&end) {
case '-': {
double d{};
detail::parse_item(d, it, end);
if (static_cast<int>(d) == d)
if (!parse_as_double && (static_cast<int>(d) == d))
result.emplace<int>(d);
else
result.emplace<double>(d);
Expand All @@ -746,11 +748,11 @@ inline void parse(jvalue &result, It &&it, It &&end) {
break;
case '[':
result.template emplace<jarray>();
parse<Is_view>(std::get<jarray>(result), it, end);
parse<Is_view>(std::get<jarray>(result), it, end, parse_as_double);
break;
case '{': {
result.template emplace<jobject>();
parse<Is_view>(std::get<jobject>(result), it, end);
parse<Is_view>(std::get<jobject>(result), it, end, parse_as_double);
break;
}
default:
Expand All @@ -760,11 +762,13 @@ inline void parse(jvalue &result, It &&it, It &&end) {
skip_ws(it, end);
}

// when Is_view is true, parse str as string_view
// set Is_view == true, parse str as std::string_view
// set parse_as_double == true, parse the number as double in any case
template <bool Is_view = false, typename It>
inline void parse(jvalue &result, It &&it, It &&end, std::error_code &ec) {
inline void parse(jvalue &result, It &&it, It &&end, std::error_code &ec,
bool parse_as_double = false) {
try {
parse<Is_view>(result, it, end);
parse<Is_view>(result, it, end, parse_as_double);
ec = {};
} catch (const std::runtime_error &e) {
result.template emplace<std::nullptr_t>();
Expand All @@ -774,15 +778,16 @@ inline void parse(jvalue &result, It &&it, It &&end, std::error_code &ec) {

template <bool Is_view = false, typename T, typename View,
std::enable_if_t<json_view_v<View>, int> = 0>
inline void parse(T &result, const View &view) {
parse<Is_view>(result, std::begin(view), std::end(view));
inline void parse(T &result, const View &view, bool parse_as_double = false) {
parse<Is_view>(result, std::begin(view), std::end(view), parse_as_double);
}

template <bool Is_view = false, typename T, typename View,
std::enable_if_t<json_view_v<View>, int> = 0>
inline void parse(T &result, const View &view, std::error_code &ec) noexcept {
inline void parse(T &result, const View &view, std::error_code &ec,
bool parse_as_double = false) noexcept {
try {
parse<Is_view>(result, view);
parse<Is_view>(result, view, parse_as_double);
ec = {};
} catch (std::runtime_error &e) {
ec = iguana::make_error_code(e.what());
Expand Down
Loading

0 comments on commit 083123b

Please sign in to comment.