Skip to content

Commit

Permalink
perf
Browse files Browse the repository at this point in the history
  • Loading branch information
MistEO committed Feb 3, 2024
1 parent 7bc1729 commit da329c8
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 104 deletions.
29 changes: 5 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ struct ThirdPartyStruct
namespace json
{
template <>
class serialization<ThirdPartyStruct>
class jsonization<ThirdPartyStruct>
{
public:
json::value to_json(const ThirdPartyStruct& t) const { return t.a; }
Expand Down Expand Up @@ -244,7 +244,6 @@ std::string format = j.dumps(4);
std::ofstream ofs("meo.json");
ofs << j;
ofs.close();
```

## 解析
Expand Down Expand Up @@ -309,43 +308,25 @@ std::string nested_get = value.get("A_obj", "B_arr", 1, "C_str", "default_value"
// 如果没有 `num`,则 opt_n 将为 std::nullopt
auto opt_n = value.find<double>("num");
if (opt_n) {
// 输出: 3.141600
// Output: 3.141600
std::cout << *opt_n << std::endl;
}

```

还有一些你在序列化中已经见过的技巧

```c++
bool is_vec = value["list"].is<std::vector<int>>();

std::vector<int> to_vec = value["list"].as_collection<int>();
to_vec = (std::vector<int>)value["list"]; // 与上面相同
to_vec = value["list"].as<std::vector<int>>(); // 与上面相同

// 输出: 1, 2, 3
// Output: 1, 2, 3
for (auto&& i : to_vec) {
std::cout << i << std::endl;
}

std::list<int> to_list = value["list"].as_collection<int, std::list>();
to_list = (std::list<int>)value["list"]; // 与上面相同
to_list = value["list"].as<std::list<int>>(); // 与上面相同

std::set<int> to_set = value["list"].as_collection<int, std::set>();
to_set = (std::set<int>)value["list"]; // 与上面相同
to_set = value["list"].as<std::set<int>>(); // 与上面相同

bool is_map = value["author"].is<std::map<std::string, std::string>>();

std::map<std::string, std::string> to_map = value["author"].as_map<std::string>();
to_map = (std::map<std::string, std::string>)value["author"]; // 与上面相同
to_map = value["author"].as<std::map<std::string, std::string>>(); // 与上面相同

to_list = (std::list<int>)value["list"]; // 和上面相同
auto to_map = value["author"].as<std::map<std::string, std::string>>();
auto to_hashmap = value["author"].as_map<std::string, std::unordered_map>();
to_hashmap = (std::unordered_map<std::string, std::string>)value["author"]; // 与上面相同
to_hashmap = value["author"].as<std::unordered_map<std::string, std::string>>();// 与上面相同
```

以及不知道有啥用的字面语法
Expand Down
23 changes: 3 additions & 20 deletions README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ struct ThirdPartyStruct
namespace json
{
template <>
class serialization<ThirdPartyStruct>
class jsonization<ThirdPartyStruct>
{
public:
json::value to_json(const ThirdPartyStruct& t) const { return t.a; }
Expand Down Expand Up @@ -317,33 +317,16 @@ There are also a few tricks you've already seen with Serializing

```c++
bool is_vec = value["list"].is<std::vector<int>>();

std::vector<int> to_vec = value["list"].as_collection<int>();
to_vec = (std::vector<int>)value["list"]; // same as above
to_vec = value["list"].as<std::vector<int>>(); // same as above

// Output: 1, 2, 3
for (auto&& i : to_vec) {
std::cout << i << std::endl;
}

std::list<int> to_list = value["list"].as_collection<int, std::list>();
to_list = (std::list<int>)value["list"]; // same as above
to_list = value["list"].as<std::list<int>>(); // same as above

std::set<int> to_set = value["list"].as_collection<int, std::set>();
to_set = (std::set<int>)value["list"]; // same as above
to_set = value["list"].as<std::set<int>>(); // same as above

bool is_map = value["author"].is<std::map<std::string, std::string>>();

std::map<std::string, std::string> to_map = value["author"].as_map<std::string>();
to_map = (std::map<std::string, std::string>)value["author"]; // same as above
to_map = value["author"].as<std::map<std::string, std::string>>(); // same as above

to_list = (std::list<int>)value["list"]; // same as above
auto to_map = value["author"].as<std::map<std::string, std::string>>();
auto to_hashmap = value["author"].as_map<std::string, std::unordered_map>();
to_hashmap = (std::unordered_map<std::string, std::string>)value["author"]; // same as above
to_hashmap = value["author"].as<std::unordered_map<std::string, std::string>>();// same as above
```

And... some useless literal syntax
Expand Down
10 changes: 6 additions & 4 deletions include/common/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ class basic_array
basic_array(collection_t arr)
: _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<jsonization_t>::value, bool> = true>
basic_array(const jsonization_t& jsonization) : basic_array(jsonization.to_json())
template <typename jsonization_t,
std::enable_if_t<_utils::has_to_json_in_member<jsonization_t>::value, bool> = true>
basic_array(const jsonization_t& value) : basic_array(value.to_json())
{}
template <typename jsonization_t, std::enable_if_t<_utils::has_to_json_in_templ_spec<jsonization_t>::value, bool> = true>
basic_array(const jsonization_t& jsonization) : basic_array(to_json(jsonization))
template <typename jsonization_t,
std::enable_if_t<_utils::has_to_json_in_templ_spec<jsonization_t>::value, bool> = true>
basic_array(const jsonization_t& value) : basic_array(ext::jsonization<jsonization_t>().to_json(value))
{}

~basic_array() noexcept = default;
Expand Down
10 changes: 6 additions & 4 deletions include/common/object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ class basic_object
typename = std::enable_if_t<std::is_constructible_v<value_type, _utils::range_value_t<map_t>>>>
basic_object(map_t map) : _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<jsonization_t>::value, bool> = true>
basic_object(const jsonization_t& jsonization) : basic_object(jsonization.to_json())
template <typename jsonization_t,
std::enable_if_t<_utils::has_to_json_in_member<jsonization_t>::value, bool> = true>
basic_object(const jsonization_t& value) : basic_object(value.to_json())
{}
template <typename jsonization_t, std::enable_if_t<_utils::has_to_json_in_templ_spec<jsonization_t>::value, bool> = true>
basic_object(const jsonization_t& jsonization) : basic_object(to_json(jsonization))
template <typename jsonization_t,
std::enable_if_t<_utils::has_to_json_in_templ_spec<jsonization_t>::value, bool> = true>
basic_object(const jsonization_t& value) : basic_object(ext::jsonization<jsonization_t>().to_json(value))
{}

~basic_object() = default;
Expand Down
14 changes: 7 additions & 7 deletions include/common/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ using warray = basic_array<std::wstring>;
using wobject = basic_object<std::wstring>;
}

namespace json
namespace json::ext
{
template <typename T, typename string_t = default_string_t>
class serialization
template <typename T>
class jsonization
{
public:
// json::value to_json(const T&) const;
Expand Down Expand Up @@ -79,7 +79,7 @@ template <typename T>
class has_to_json_in_templ_spec
{
template <typename U>
static auto test(int) -> decltype(std::declval<serialization<U>>().to_json(std::declval<U>()), std::true_type());
static auto test(int) -> decltype(std::declval<ext::jsonization<U>>().to_json(std::declval<U>()), std::true_type());

template <typename U>
static std::false_type test(...);
Expand Down Expand Up @@ -107,7 +107,7 @@ class has_check_json_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<serialization<U>>().check_json(std::declval<json::basic_value<string_t>>()),
-> decltype(std::declval<ext::jsonization<U>>().check_json(std::declval<json::basic_value<string_t>>()),
std::true_type());

template <typename U>
Expand Down Expand Up @@ -136,8 +136,8 @@ class has_from_json_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<serialization<U>>().from_json(std::declval<json::basic_value<string_t>>(),
std::declval<U&>()),
-> decltype(std::declval<ext::jsonization<U>>().from_json(std::declval<json::basic_value<string_t>>(),
std::declval<U&>()),
std::true_type());

template <typename U>
Expand Down
8 changes: 4 additions & 4 deletions include/common/value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ class basic_value

template <typename jsonization_t,
std::enable_if_t<_utils::has_to_json_in_member<jsonization_t>::value, bool> = true>
basic_value(const jsonization_t& jsonization) : basic_value(jsonization.to_json())
basic_value(const jsonization_t& value) : basic_value(value.to_json())
{}
template <typename jsonization_t,
std::enable_if_t<_utils::has_to_json_in_templ_spec<jsonization_t>::value, bool> = true>
basic_value(const jsonization_t& jsonization) : basic_value(serialization<jsonization_t>().to_json(jsonization))
basic_value(const jsonization_t& value) : basic_value(ext::jsonization<jsonization_t>().to_json(value))
{}

template <typename value_t, std::enable_if_t<!std::is_convertible_v<value_t, basic_value<string_t>>, bool> = true>
Expand Down Expand Up @@ -234,7 +234,7 @@ class basic_value
explicit operator jsonization_t() const
{
jsonization_t dst;
if (!serialization<jsonization_t>().from_json(*this, dst)) {
if (!ext::jsonization<jsonization_t>().from_json(*this, dst)) {
throw exception("Wrong JSON");
}
return dst;
Expand Down Expand Up @@ -390,7 +390,7 @@ inline bool basic_value<string_t>::is() const noexcept
return value_t().check_json(*this);
}
else if constexpr (_utils::has_check_json_in_templ_spec<value_t, string_t>::value) {
return serialization<value_t>().check_json(*this);
return ext::jsonization<value_t>().check_json(*this);
}
else {
static_assert(!sizeof(value_t), "Unsupported type");
Expand Down
27 changes: 5 additions & 22 deletions sample/sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,10 @@ struct ThirdPartyStruct
int a = 100;
};

namespace json
namespace json::ext
{
template <>
class serialization<ThirdPartyStruct>
class jsonization<ThirdPartyStruct>
{
public:
json::value to_json(const ThirdPartyStruct& t) const { return t.a; }
Expand All @@ -181,7 +181,7 @@ class serialization<ThirdPartyStruct>
return true;
}
};
} // namespace json
} // namespace json::ext

void third_party_jsonization_1()
{
Expand Down Expand Up @@ -297,33 +297,16 @@ void parsing()
/* There are also a few tricks you've already seen with Serializing */

bool is_vec = value["list"].is<std::vector<int>>();

std::vector<int> to_vec = value["list"].as_collection<int>();
to_vec = (std::vector<int>)value["list"]; // same as above
to_vec = value["list"].as<std::vector<int>>(); // same as above

// Output: 1, 2, 3
for (auto&& i : to_vec) {
std::cout << i << std::endl;
}

std::list<int> to_list = value["list"].as_collection<int, std::list>();
to_list = (std::list<int>)value["list"]; // same as above
to_list = value["list"].as<std::list<int>>(); // same as above

std::set<int> to_set = value["list"].as_collection<int, std::set>();
to_set = (std::set<int>)value["list"]; // same as above
to_set = value["list"].as<std::set<int>>(); // same as above

bool is_map = value["author"].is<std::map<std::string, std::string>>();

std::map<std::string, std::string> to_map = value["author"].as_map<std::string>();
to_map = (std::map<std::string, std::string>)value["author"]; // same as above
to_map = value["author"].as<std::map<std::string, std::string>>(); // same as above

to_list = (std::list<int>)value["list"]; // same as above
auto to_map = value["author"].as<std::map<std::string, std::string>>();
auto to_hashmap = value["author"].as_map<std::string, std::unordered_map>();
to_hashmap = (std::unordered_map<std::string, std::string>)value["author"]; // same as above
to_hashmap = value["author"].as<std::unordered_map<std::string, std::string>>(); // same as above

/* And... some useless literal syntax */

Expand Down
54 changes: 35 additions & 19 deletions test/serializing_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,33 +175,49 @@ struct ThirdPartyStruct
{
int a = 0;
};
json::wvalue to_json(const ThirdPartyStruct& t)
{
return t.a;
}
bool check_json(const json::wvalue& j, const ThirdPartyStruct&)

namespace json::ext
{
return j.is_number();
}
bool from_json(const json::wvalue& j, ThirdPartyStruct& out)
template <>
class jsonization<ThirdPartyStruct>
{
out.a = j.as_integer();
return true;
}
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;
}
};
} // namespace json::ext

bool jsonizing()
{
// then you can use it as json
ThirdPartyStruct third { 100 };
json::wvalue jthird = third;
ThirdPartyStruct new_third = (ThirdPartyStruct)jthird;

//// or add to your sturcture
// struct Outter2
//{
// int outter2_a = 10;
// ThirdPartyStruct third;
json::warray arr = { third, new_third };
json::wobject obj = { { L"third", third }, { L"new_third", new_third } };

struct MyStruct
{
std::string str;
std::vector<double> vec;
std::unordered_map<std::string, std::list<std::map<std::string, std::deque<int>>>> map;

MEO_JSONIZATION(str, vec, map);
};

MyStruct mine;
mine.str = "Hello";
mine.vec.emplace_back(0.5);
mine.map = { { "key_1", { { { "inner_key_1", { 7, 8, 9 } } }, { { "inner_key_2", { 10 } } } } } };

json::value j_mine = mine;
MyStruct new_mine = (MyStruct)j_mine;

// MEO_JSONIZATION(outter2_a, third);
//};
return new_third.a == 100;
return new_third.a == 100 && new_mine.str == "Hello";
}

0 comments on commit da329c8

Please sign in to comment.