From 2463cdb6bb6eda7eb9e9051a51687ea2cc5717a6 Mon Sep 17 00:00:00 2001 From: MistEO Date: Fri, 15 Mar 2024 16:49:51 +0800 Subject: [PATCH] styles: format --- .clang-format | 2 +- benchmark/benchmark.cpp | 34 ++++++++++++++++---------- include/common/array.hpp | 13 ++++++++++ include/common/exception.hpp | 1 + include/common/object.hpp | 13 ++++++++++ include/common/value.hpp | 32 +++++++++++++++++++++++++ include/parser/bitops.hpp | 16 +++++++++++++ include/parser/packed_bytes.hpp | 38 +++++++++++++++++++++--------- include/parser/parser.hpp | 4 ++++ include/parser5/parser5.hpp | 6 +++++ include/reflection/jsonization.hpp | 7 ++++++ sample/sample.cpp | 5 ++++ test/serializing_test.cpp | 5 ++++ 13 files changed, 151 insertions(+), 25 deletions(-) diff --git a/.clang-format b/.clang-format index 16d6ac4..8cfeb34 100644 --- a/.clang-format +++ b/.clang-format @@ -151,7 +151,7 @@ RemoveParentheses: Leave RemoveSemicolon: false RequiresClausePosition: OwnLine RequiresExpressionIndentation: OuterScope -SeparateDefinitionBlocks: Leave +SeparateDefinitionBlocks: Always ShortNamespaceLines: 1000 SortIncludes: CaseSensitive # SortJavaStaticImport: diff --git a/benchmark/benchmark.cpp b/benchmark/benchmark.cpp index bf6e2b1..7101d64 100644 --- a/benchmark/benchmark.cpp +++ b/benchmark/benchmark.cpp @@ -18,8 +18,7 @@ void do_benchmark(const std::string& content, const std::string& tag) iteration_time_ms.reserve(10000); auto start = std::chrono::steady_clock::now(); bool parsed = false; - while (true) - { + while (true) { auto t0 = std::chrono::steady_clock::now(); auto opt = parser::parse(content); parsed = opt.has_value(); @@ -34,10 +33,14 @@ void do_benchmark(const std::string& content, const std::string& tag) auto loop_times = iteration_time_ms.size(); auto sum = std::accumulate(iteration_time_ms.begin(), iteration_time_ms.end(), 0.0); double mean = sum / loop_times; - double stdev_cum = std::accumulate(iteration_time_ms.begin(), iteration_time_ms.end(), 0.0, [mean](auto a, auto b) { - auto off = b - mean; - return a + off * off; - }); + double stdev_cum = std::accumulate( + iteration_time_ms.begin(), + iteration_time_ms.end(), + 0.0, + [mean](auto a, auto b) { + auto off = b - mean; + return a + off * off; + }); double stdev = std::sqrt(stdev_cum / loop_times); std::sort(iteration_time_ms.begin(), iteration_time_ms.end()); @@ -50,8 +53,8 @@ void do_benchmark(const std::string& content, const std::string& tag) median = iteration_time_ms[loop_times / 2]; } - std::cout << tag << ", " << std::boolalpha << parsed << ", " << loop_times << ", " << mean << ", " << median << ", " - << stdev << std::endl; + std::cout << tag << ", " << std::boolalpha << parsed << ", " << loop_times << ", " << mean + << ", " << median << ", " << stdev << std::endl; } int main(int argc, char** argv) @@ -80,19 +83,24 @@ int main(int argc, char** argv) using namespace json::_packed_bytes; do_benchmark>( - content, path.filename().string() + ", none"); + content, + path.filename().string() + ", none"); do_benchmark>( - content, path.filename().string() + ", bits32"); + content, + path.filename().string() + ", bits32"); do_benchmark>( - content, path.filename().string() + ", bits64"); + content, + path.filename().string() + ", bits64"); if constexpr (packed_bytes_trait<16>::available) { do_benchmark>>( - content, path.filename().string() + ", simd128"); + content, + path.filename().string() + ", simd128"); } if constexpr (packed_bytes_trait<32>::available) { do_benchmark>>( - content, path.filename().string() + ", simd256"); + content, + path.filename().string() + ", simd256"); } do_benchmark>(content, path.filename().string() + ", json5"); diff --git a/include/common/array.hpp b/include/common/array.hpp index 7665e04..d7a5479 100644 --- a/include/common/array.hpp +++ b/include/common/array.hpp @@ -47,6 +47,7 @@ class basic_array : _array_data(std::make_move_iterator(arr.begin()), std::make_move_iterator(arr.end())) { } + template < typename jsonization_t, std::enable_if_t<_utils::has_to_json_in_member::value, bool> = true> @@ -54,6 +55,7 @@ class basic_array : basic_array(value.to_json()) { } + template < typename jsonization_t, std::enable_if_t<_utils::has_to_json_in_templ_spec::value, bool> = true> @@ -65,17 +67,24 @@ class basic_array ~basic_array() noexcept = default; bool empty() const noexcept { return _array_data.empty(); } + size_t size() const noexcept { return _array_data.size(); } + bool contains(size_t pos) const { return pos < _array_data.size(); } + bool exists(size_t pos) const { return contains(pos); } + const basic_value& at(size_t pos) const; string_t dumps(std::optional indent = std::nullopt) const { return indent ? format(*indent) : to_string(); } + string_t to_string() const; + string_t format(size_t indent = 4) const { return format(indent, 0); } + template bool all() const; template typename collection_t = std::vector> @@ -124,6 +133,7 @@ class basic_array basic_array& operator=(const basic_array&) = default; basic_array& operator=(basic_array&&) noexcept = default; + template < typename value_t, std::enable_if_t>, bool> = true> @@ -133,6 +143,7 @@ class basic_array } bool operator==(const basic_array& rhs) const; + bool operator!=(const basic_array& rhs) const { return !(*this == rhs); } template < @@ -143,6 +154,7 @@ class basic_array { return as_collection(); } + template < typename jsonization_t, std::enable_if_t<_utils::has_from_json_in_member::value, bool> = @@ -155,6 +167,7 @@ class basic_array } return dst; } + template < typename jsonization_t, std::enable_if_t< diff --git a/include/common/exception.hpp b/include/common/exception.hpp index 016fb64..9c0412d 100644 --- a/include/common/exception.hpp +++ b/include/common/exception.hpp @@ -9,6 +9,7 @@ class exception : public std::exception { public: exception() = default; + exception(const std::string& msg) : _what(msg) { diff --git a/include/common/object.hpp b/include/common/object.hpp index 4f418cd..87d8c15 100644 --- a/include/common/object.hpp +++ b/include/common/object.hpp @@ -46,6 +46,7 @@ class basic_object : _object_data(std::make_move_iterator(map.begin()), std::make_move_iterator(map.end())) { } + template < typename jsonization_t, std::enable_if_t<_utils::has_to_json_in_member::value, bool> = true> @@ -53,6 +54,7 @@ class basic_object : basic_object(value.to_json()) { } + template < typename jsonization_t, std::enable_if_t<_utils::has_to_json_in_templ_spec::value, bool> = true> @@ -64,17 +66,24 @@ class basic_object ~basic_object() = default; bool empty() const noexcept { return _object_data.empty(); } + size_t size() const noexcept { return _object_data.size(); } + bool contains(const string_t& key) const; + bool exists(const string_t& key) const { return contains(key); } + const basic_value& at(const string_t& key) const; string_t dumps(std::optional indent = std::nullopt) const { return indent ? format(*indent) : to_string(); } + string_t to_string() const; + string_t format(size_t indent = 4) const { return format(indent, 0); } + template bool all() const; template typename map_t = std::map> @@ -116,6 +125,7 @@ class basic_object basic_object& operator=(const basic_object&) = default; basic_object& operator=(basic_object&&) = default; + template < typename value_t, std::enable_if_t>, bool> = true> @@ -125,6 +135,7 @@ class basic_object } bool operator==(const basic_object& rhs) const; + bool operator!=(const basic_object& rhs) const { return !(*this == rhs); } template < @@ -135,6 +146,7 @@ class basic_object { return as_map(); } + template < typename jsonization_t, std::enable_if_t<_utils::has_from_json_in_member::value, bool> = @@ -147,6 +159,7 @@ class basic_object } return dst; } + template < typename jsonization_t, std::enable_if_t< diff --git a/include/common/value.hpp b/include/common/value.hpp index 9a56c5f..9d7665a 100644 --- a/include/common/value.hpp +++ b/include/common/value.hpp @@ -76,6 +76,7 @@ class basic_value : basic_value(basic_array(std::forward(collection))) { } + template < typename map_t, std::enable_if_t< @@ -96,6 +97,7 @@ class basic_value : basic_value(value.to_json()) { } + template < typename jsonization_t, std::enable_if_t<_utils::has_to_json_in_templ_spec::value, bool> = true> @@ -118,13 +120,21 @@ class basic_value ~basic_value(); bool valid() const noexcept { return _type != value_type::invalid; } + bool empty() const noexcept { return is_null(); } + bool is_null() const noexcept { return _type == value_type::null; } + bool is_number() const noexcept { return _type == value_type::number; } + bool is_boolean() const noexcept { return _type == value_type::boolean; } + bool is_string() const noexcept { return _type == value_type::string; } + bool is_array() const noexcept { return _type == value_type::array; } + bool is_object() const noexcept { return _type == value_type::object; } + template bool is() const noexcept; @@ -133,9 +143,13 @@ class basic_value bool contains(const string_t& key) const; bool contains(size_t pos) const; + bool exists(const string_t& key) const { return contains(key); } + bool exists(size_t pos) const { return contains(pos); } + value_type type() const noexcept { return _type; } + const basic_value& at(size_t pos) const; const basic_value& at(const string_t& key) const; @@ -185,12 +199,15 @@ class basic_value { return indent ? format(*indent) : to_string(); } + // return raw string string_t to_string() const; + string_t format(size_t indent = 4) const { return format(indent, 0); } basic_value& operator=(const basic_value& rhs); basic_value& operator=(basic_value&&) noexcept; + template < typename value_t, std::enable_if_t>, bool> = true> @@ -200,6 +217,7 @@ class basic_value } bool operator==(const basic_value& rhs) const; + bool operator!=(const basic_value& rhs) const { return !(*this == rhs); } const basic_value& operator[](size_t pos) const; @@ -224,18 +242,29 @@ class basic_value basic_value& operator+=(basic_array&& rhs); explicit operator bool() const { return as_boolean(); } + explicit operator int() const { return as_integer(); } + explicit operator unsigned() const { return as_unsigned(); } + explicit operator long() const { return as_long(); } + explicit operator unsigned long() const { return as_unsigned_long(); } + explicit operator long long() const { return as_long_long(); } + explicit operator unsigned long long() const { return as_unsigned_long_long(); } + explicit operator float() const { return as_float(); } + explicit operator double() const { return as_double(); } + explicit operator long double() const { return as_long_double(); } + explicit operator string_t() const { return as_string(); } explicit operator basic_array() const { return as_array(); } + explicit operator basic_object() const { return as_object(); } template < @@ -246,6 +275,7 @@ class basic_value { return as_collection(); } + template < typename value_t, template typename map_t = std::map, @@ -254,6 +284,7 @@ class basic_value { return as_map(); } + template < typename jsonization_t, std::enable_if_t<_utils::has_from_json_in_member::value, bool> = @@ -266,6 +297,7 @@ class basic_value } return dst; } + template < typename jsonization_t, std::enable_if_t< diff --git a/include/parser/bitops.hpp b/include/parser/bitops.hpp index f30eea3..c74dbbe 100644 --- a/include/parser/bitops.hpp +++ b/include/parser/bitops.hpp @@ -2,12 +2,14 @@ #if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) #include + namespace json::_bitops { using std::countl_one; using std::countl_zero; using std::countr_one; using std::countr_zero; + inline constexpr bool is_little_endian() { return std::endian::native == std::endian::little; @@ -15,6 +17,7 @@ inline constexpr bool is_little_endian() } #else #include + namespace json::_bitops { #if defined(__GNUC__) || defined(__clang__) @@ -28,6 +31,7 @@ inline constexpr int countl_zero(uint32_t x) } return x == 0 ? 32 : __builtin_clzll(x); } + inline constexpr int countr_zero(uint32_t x) { if constexpr (sizeof(uint32_t) == sizeof(unsigned int)) { @@ -38,10 +42,12 @@ inline constexpr int countr_zero(uint32_t x) } return x == 0 ? 32 : __builtin_ctzll(x); } + inline constexpr int countl_zero(uint64_t x) { return x == 0 ? 64 : __builtin_clzll(x); } + inline constexpr int countr_zero(uint64_t x) { return x == 0 ? 64 : __builtin_ctzll(x); @@ -53,14 +59,17 @@ inline int countl_zero(uint32_t x) { return __lzcnt(x); } + inline int countr_zero(uint32_t x) { return _tzcnt_u32(x); } + inline int countl_zero(uint64_t x) { return (int)__lzcnt64(x); } + inline int countr_zero(uint64_t x) { return (int)_tzcnt_u64(x); @@ -71,16 +80,19 @@ inline constexpr int countl_zero(uint32_t x) unsigned long index = 0; return _BitScanReverse(&index, x) ? 31 - index : 32; } + inline constexpr int countr_zero(uint32_t x) { unsigned long index = 0; return _BitScanForward(&index, x) ? index : 32; } + inline constexpr int countl_zero(uint64_t x) { unsigned long index = 0; return _BitScanReverse64(&index, x) ? 63 - index : 64; } + inline constexpr int countr_zero(uint64_t x) { unsigned long index = 0; @@ -94,14 +106,17 @@ inline int countl_one(uint32_t x) { return countl_zero(~x); } + inline int countr_one(uint32_t x) { return countr_zero(~x); } + inline int countl_one(uint64_t x) { return countl_zero(~x); } + inline int countr_one(uint64_t x) { return countr_zero(~x); @@ -115,6 +130,7 @@ inline bool is_little_endian() uint32_t u32; uint8_t u8; } u = { 0x01020304 }; + return u.u8 == 4; } } // namespace json::_bitops diff --git a/include/parser/packed_bytes.hpp b/include/parser/packed_bytes.hpp index 96794b5..ebd5e79 100644 --- a/include/parser/packed_bytes.hpp +++ b/include/parser/packed_bytes.hpp @@ -66,14 +66,19 @@ struct packed_bytes_trait_uint64 return is_zero_memberwise((x) ^ (UINT64_C(0x0101010101010101) * (n))); } - __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) { return a | b; } + __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) + { + return a | b; + } __packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x) { - if (_bitops::is_little_endian()) + if (_bitops::is_little_endian()) { return _bitops::countr_zero(x) / 8; - else + } + else { return _bitops::countl_zero(x) / 8; + } } }; @@ -108,16 +113,22 @@ struct packed_bytes_trait_uint32 return is_zero_memberwise((x) ^ (~UINT32_C(0) / 255 * (n))); } - __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) { return a | b; } + __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) + { + return a | b; + } __packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x) { - if (_bitops::is_little_endian()) + if (_bitops::is_little_endian()) { return _bitops::countr_zero(x) / 8; - else + } + else { return _bitops::countl_zero(x) / 8; + } } }; + template <> struct packed_bytes<8> { @@ -133,9 +144,14 @@ struct packed_bytes<4> template using packed_bytes_trait = typename packed_bytes::traits; -using packed_bytes_trait_max = - std::conditional_t::available, packed_bytes_trait<32>, - std::conditional_t::available, packed_bytes_trait<16>, - std::conditional_t::available, packed_bytes_trait<8>, - packed_bytes_trait<4>>>>; +using packed_bytes_trait_max = std::conditional_t< + packed_bytes_trait<32>::available, + packed_bytes_trait<32>, + std::conditional_t< + packed_bytes_trait<16>::available, + packed_bytes_trait<16>, + std::conditional_t< + packed_bytes_trait<8>::available, + packed_bytes_trait<8>, + packed_bytes_trait<4>>>>; } // namespace json::_packed_bytes diff --git a/include/parser/parser.hpp b/include/parser/parser.hpp index 316029d..5a87f46 100644 --- a/include/parser/parser.hpp +++ b/include/parser/parser.hpp @@ -596,6 +596,7 @@ inline value operator""_json(const char* str, size_t len) { return operator""_jvalue(str, len); } + inline wvalue operator""_json(const wchar_t* str, size_t len) { return operator""_jvalue(str, len); @@ -605,6 +606,7 @@ inline value operator""_jvalue(const char* str, size_t len) { return parse(std::string_view(str, len)).value_or(value()); } + inline wvalue operator""_jvalue(const wchar_t* str, size_t len) { return parse(std::wstring_view(str, len)).value_or(wvalue()); @@ -615,6 +617,7 @@ inline array operator""_jarray(const char* str, size_t len) auto val = parse(std::string_view(str, len)).value_or(value()); return val.is_array() ? val.as_array() : array(); } + inline warray operator""_jarray(const wchar_t* str, size_t len) { auto val = parse(std::wstring_view(str, len)).value_or(wvalue()); @@ -626,6 +629,7 @@ inline object operator""_jobject(const char* str, size_t len) auto val = parse(std::string_view(str, len)).value_or(value()); return val.is_object() ? val.as_object() : object(); } + inline wobject operator""_jobject(const wchar_t* str, size_t len) { auto val = parse(std::wstring_view(str, len)).value_or(wvalue()); diff --git a/include/parser5/parser5.hpp b/include/parser5/parser5.hpp index fca6d8c..173665d 100644 --- a/include/parser5/parser5.hpp +++ b/include/parser5/parser5.hpp @@ -31,6 +31,7 @@ class parser5 { public: exception() = default; + exception(const std::string& type, const std::string& msg, const std::string& detail) { std::stringstream ss; @@ -38,6 +39,7 @@ class parser5 ss << detail << std::endl; _what = ss.str(); } + exception(const exception&) = default; exception& operator=(const exception&) = default; exception(exception&&) = default; @@ -188,6 +190,7 @@ class parser5 , _line_begin_cur(cbegin) { } + std::optional parse(); private: @@ -564,10 +567,12 @@ inline typename parser5::u8char parser5::peek(const std::str { return peek(str.cbegin(), str.cend()); } + inline constexpr size_t operator"" _sz(unsigned long long size) { return size; } + template inline typename parser5::u8char parser5::read() { @@ -1441,6 +1446,7 @@ inline void parser5::parseStates(ParseState state) break; } } + /* stack operation */ template inline void parser5::push() diff --git a/include/reflection/jsonization.hpp b/include/reflection/jsonization.hpp index d048ead..d859356 100644 --- a/include/reflection/jsonization.hpp +++ b/include/reflection/jsonization.hpp @@ -10,6 +10,7 @@ namespace json::_jsonization_helper struct next_is_optional_t { }; + struct va_arg_end { }; @@ -23,11 +24,13 @@ struct dumper result.emplace(key, var); return result; } + template json::value _to_json(const char*, next_is_optional_t, rest_t&&... rest) const { return _to_json(std::forward(rest)...); } + json::value _to_json(va_arg_end) const { return {}; } }; @@ -48,6 +51,7 @@ struct checker } return _check_json(in, error_key, std::forward(rest)...); } + template bool _check_json( const json::value& in, @@ -68,6 +72,7 @@ struct checker return _check_json(in, error_key, std::forward(rest)...); } + bool _check_json(const json::value&, std::string&, va_arg_end) const { return true; } }; @@ -90,6 +95,7 @@ struct loader return _from_json(in, error_key, std::forward(rest)...); } + template bool _from_json( const json::value& in, @@ -111,6 +117,7 @@ struct loader return _from_json(in, error_key, std::forward(rest)...); } + bool _from_json(const json::value&, std::string&, va_arg_end) const { return true; } }; } // namespace json::_jsonization_helper diff --git a/sample/sample.cpp b/sample/sample.cpp index 90b6d1b..74bcbb5 100644 --- a/sample/sample.cpp +++ b/sample/sample.cpp @@ -179,7 +179,9 @@ class jsonization { public: json::value to_json(const ThirdPartyStruct& t) const { return t.a; } + bool check_json(const json::value& j) const { return j.is_number(); } + bool from_json(const json::value& j, ThirdPartyStruct& out) const { out.a = j.as_integer(); @@ -206,6 +208,7 @@ void third_party_jsonization_1() MEO_JSONIZATION(outter2_a, third); }; + Outter2 o_2; } @@ -217,6 +220,7 @@ void third_party_jsonization_2() { json::value operator()(const ThirdPartyStruct& t) const { return t.a; } }; + struct Deserializer { bool operator()(const json::value& j, ThirdPartyStruct& t) const @@ -310,6 +314,7 @@ void parsing() MEO_JSONIZATION(i); }; + MyType get_custom_value = value.get("my_type", MyType {}); auto find_custom_opt = value.find("my_type"); diff --git a/test/serializing_test.cpp b/test/serializing_test.cpp index be0dffc..0c92c40 100644 --- a/test/serializing_test.cpp +++ b/test/serializing_test.cpp @@ -215,19 +215,24 @@ class jsonization { public: json::wvalue to_json(const ThirdPartyStruct& t) const { return t.a; } + bool check_json(const json::wvalue& j) const { return j.is_number(); } + bool from_json(const json::wvalue& j, ThirdPartyStruct& out) const { out.a = j.as_integer(); return true; } }; + template <> class jsonization { public: json::value to_json(const std::filesystem::path& path) const { return path.string(); } + bool check_json(const json::value& json) const { return json.is_string(); } + bool from_json(const json::value& json, std::filesystem::path& path) const { path = json.as_string();