Skip to content

Commit

Permalink
improve
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos committed May 28, 2024
1 parent 5154d54 commit 0086607
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 6 deletions.
8 changes: 5 additions & 3 deletions iguana/reflection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,14 +576,16 @@ struct base {
return *((T *)ptr);
}

template <typename T>
template <typename T, typename FiledType = T>
void set_field_value(std::string_view name, T val) {
auto info = get_field_info(name);
check_field<T>(name, info);
check_field<FiledType>(name, info);

auto ptr = (((char *)this) + info.offset);

*((T *)ptr) = std::move(val);
static_assert(std::is_constructible_v<FiledType, T>, "can not assign");

*((FiledType *)ptr) = std::move(val);
}
virtual ~base() {}

Expand Down
6 changes: 6 additions & 0 deletions lang/struct_pb_intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ std::shared_ptr<base> t = iguana::create_instance("nest1");
```
“根据对象实例和字段名获取或设置字段的值” 如果字段名不存在则会抛异常;如果设置的值类型和结构体字段类型不相同则会抛异常;需要类型完全一样,不允许隐式转换。比如字段类型是double,但是设置字段的值类型是int也会抛异常,必须显式传double;如果字段类型是std::string, 设置值类型是const char * 同样会报错;如果字段类型是int32_t, 设置值类型是uint_8也会抛异常,因为类型不相同。
设置字段值时也可以显式指定字段类型:
```cpp
t->set_field_value<std::string>("name", "test");
```
这种方式则不要求设置值的类型和字段类型完全一样,只要能赋值成功即可。如果显式指定的字段类型不是实际的字段类型时也会抛异常。

## benchmark
在benchmark monster场景下,struct_pb 性能比protobuf 更好,序列化速度是protobuf的2.4倍,反序列化是protobuf的3.4倍。详情可以自行运行struct_pack 中的benchmark复现结果。

Expand Down
12 changes: 9 additions & 3 deletions test/test_pb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,12 @@ TEST_CASE("test reflection") {
CHECK(r == 41);
auto &r1 = t->get_field_value<my_struct>("value");
CHECK(r1.x == 2);

t->set_field_value<std::string>("name", "hello");
auto &s = t->get_field_value<std::string>("name");
CHECK(s == "hello");

CHECK_THROWS_AS(t->set_field_value<int>("name", 42), std::invalid_argument);
}
{
auto t = iguana::create_instance("pair_t");
Expand All @@ -275,9 +281,9 @@ TEST_CASE("test reflection") {
CHECK(st->y == t1.y);
}
auto t = iguana::create_instance("numer_st");
t->set_field_value("a", true);
t->set_field_value("b", double(25));
t->set_field_value("c", float(42));
t->set_field_value<bool>("a", true);
t->set_field_value<double>("b", 25);
t->set_field_value<float>("c", 42);
auto &r0 = t->get_field_value<bool>("a");
CHECK(r0);
auto &r = t->get_field_value<double>("b");
Expand Down

0 comments on commit 0086607

Please sign in to comment.