Skip to content

Commit

Permalink
[struct_pack][feat] support user-define global config
Browse files Browse the repository at this point in the history
  • Loading branch information
poor-circle committed Aug 9, 2024
1 parent a2709a0 commit 32323c9
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 42 deletions.
27 changes: 27 additions & 0 deletions include/ylt/struct_pack/reflection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,33 @@ template <typename T, typename = void>
constexpr bool user_defined_config_by_ADL = user_defined_config_by_ADL_impl<T>::value;
#endif

template<typename T>
constexpr decltype(auto) delay_sp_config_eval() {
if constexpr (sizeof(T)==0) {
return (T*){};
}
else {
return (sp_config*){};
}
}

#if __cpp_concepts >= 201907L
template<typename T>
concept has_default_config = std::is_same_v<decltype(set_default(decltype(delay_sp_config_eval<T>()){})),struct_pack::sp_config>;
#else
template <typename T, typename = void>
struct has_default_config_impl : std::false_type {};

template <typename T>
struct has_default_config_impl<T, std::void_t<
std::enable_if_t<std::is_same_v<decltype(set_default(decltype(delay_sp_config_eval<T>()){})),struct_pack::sp_config>>>>
: std::true_type {};

template <typename T>
constexpr bool has_default_config = has_default_config_impl<T>::value;
#endif


#if __cpp_concepts >= 201907L
template <typename Type>
concept user_defined_config = requires {
Expand Down
64 changes: 24 additions & 40 deletions include/ylt/struct_pack/type_calculate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,18 +153,25 @@ constexpr decltype(auto) get_type_end_flag() {
}
}

template <typename Arg, typename...>
constexpr uint64_t get_parent_tag_impl() {
if constexpr (user_defined_config_by_ADL<Arg>) {
return static_cast<uint64_t>(set_sp_config((Arg *)nullptr));
template <typename T>
constexpr sp_config get_type_config() {
if constexpr (struct_pack::detail::user_defined_config_by_ADL<T>) {
return set_sp_config((T *)nullptr);
}
else if constexpr (user_defined_config<Arg>) {
return static_cast<uint64_t>(Arg::struct_pack_config);
else if constexpr (struct_pack::detail::user_defined_config<T>) {
return static_cast<sp_config>(T::struct_pack_config);
}
else if constexpr (struct_pack::detail::has_default_config<T>) {
return set_default(decltype(delay_sp_config_eval<T>()){});
}
else {
return 0;
return sp_config::DEFAULT;
}
}
template <typename T, typename... Args>
constexpr uint64_t get_parent_tag_impl() {
return static_cast<uint64_t>(get_type_config<T>());
}

template <typename... Args>
constexpr uint64_t get_parent_tag() {
Expand Down Expand Up @@ -715,26 +722,12 @@ template <uint64_t conf, typename T>
constexpr bool check_if_add_type_literal() {
constexpr auto config = conf & 0b11;
if constexpr (config == sp_config::DEFAULT) {
if constexpr (struct_pack::detail::user_defined_config_by_ADL<T>) {
constexpr auto config = set_sp_config((T *)nullptr) & 0b11;
if constexpr (config == sp_config::DEFAULT) {
return serialize_static_config<T>::has_type_literal;
}
else {
return config == sp_config::ENABLE_TYPE_INFO;
}
}
else if constexpr (struct_pack::detail::user_defined_config<T>) {
constexpr auto config = T::struct_pack_config & 0b11;
if constexpr (config == sp_config::DEFAULT) {
return serialize_static_config<T>::has_type_literal;
}
else {
return config == sp_config::ENABLE_TYPE_INFO;
}
constexpr auto config = get_type_config<T>() & 0b11;
if constexpr (config == sp_config::DEFAULT) {
return serialize_static_config<T>::has_type_literal;
}
else {
return serialize_static_config<T>::has_type_literal;
return config == sp_config::ENABLE_TYPE_INFO;
}
}
else {
Expand Down Expand Up @@ -830,22 +823,13 @@ constexpr bool check_if_has_container() {
template <uint64_t conf, typename T>
constexpr bool check_if_disable_hash_head_impl() {
constexpr auto config = conf & 0b11;
if constexpr (config != sp_config::DISABLE_ALL_META_INFO) {
if constexpr (struct_pack::detail::user_defined_config_by_ADL<T>) {
constexpr auto config = set_sp_config((T *)nullptr) & 0b11;
if constexpr (config == sp_config::DISABLE_ALL_META_INFO) {
return true;
}
}
else if constexpr (struct_pack::detail::user_defined_config<T>) {
constexpr auto config = T::struct_pack_config & 0b11;
if constexpr (config == sp_config::DISABLE_ALL_META_INFO) {
return true;
}
}
return false;
if constexpr (config == sp_config::DEFAULT) {
constexpr auto config = get_type_config<T>() & 0b11;
return config == sp_config::DISABLE_ALL_META_INFO;
}
else {
return config == sp_config::DISABLE_ALL_META_INFO;
}
return true;
}

template <uint64_t conf, typename T>
Expand Down
9 changes: 9 additions & 0 deletions src/struct_pack/examples/serialize_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

#include <cassert>

#include "ylt/struct_pack/reflection.hpp"
#include "ylt/struct_pack/type_calculate.hpp"

#define STRUCT_PACK_OPTIMIZE // add this macro to speed up
// serialize/deserialize but it will cost more
// time to compile
Expand All @@ -26,6 +29,12 @@
// add this macro to enable support of int128/uint128

#include <ylt/struct_pack.hpp>
// set global default struct pack config
namespace struct_pack {
constexpr sp_config set_default(sp_config*) {
return sp_config::DISABLE_TYPE_INFO;
}
} // namespace struct_pack

struct rect {
int a, b, c, d;
Expand Down
19 changes: 19 additions & 0 deletions src/struct_pack/tests/test_type_info_config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "ylt/struct_pack.hpp"
#include "ylt/struct_pack/reflection.hpp"
// set global default struct pack config
namespace struct_pack {
constexpr sp_config set_default(sp_config*) {
return sp_config::DISABLE_ALL_META_INFO;
}
} // namespace struct_pack
struct rect {
int a, b, c, d;
};
struct rect2 {
int a, b, c, d;
};
constexpr struct_pack::sp_config set_sp_config(rect2*) {
return struct_pack::sp_config::DISABLE_TYPE_INFO;
}
static_assert(struct_pack::get_needed_size(rect{}).size() == 16);
static_assert(struct_pack::get_needed_size(rect2{}).size() == 20);
18 changes: 17 additions & 1 deletion website/docs/en/struct_pack/struct_pack_tips.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,28 @@ Also, note that if structure A nests structure B, the configuration for A will n
For example:
```cpp
struct rect {
var_int a, b, c, d;
int a, b, c, d;
};
```
## global config
`sp_config::default` is default global config, you can also use other config value by following codes:
```cpp
namespace struct_pack {
//default global config
constexpr sp_config set_default(sp_config*){ return sp_config::DISABLE_ALL_META_INFO; }
}
static_assert(struct_pack::get_needed_size(rect{}).size()==16);
```

You can have different config value in different code unit(*.cpp file).

### config by class static member

This config takes precedence over global config.

Just add a constexpr static member named `struct_pack_config` to the class

```cpp
Expand Down
19 changes: 18 additions & 1 deletion website/docs/zh/struct_pack/struct_pack_tips.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,26 @@ struct rect {
};
```
### 全局配置
`sp_config::default`是默认情况下的全局配置,你也可以自定义默认的全局配置。
```cpp
namespace struct_pack {
//设置全局默认配置
constexpr sp_config set_default(sp_config*){ return sp_config::DISABLE_ALL_META_INFO; }
}
static_assert(struct_pack::get_needed_size(rect{}).size()==16);
```

你可以在不同的代码单元(*.cpp文件)中声明不同的默认配置值。

### 通过类静态成员配置

在类中添加一个constexpr static的成员struct_pack_config即可
在类中添加一个constexpr static的成员struct_pack_config即可。

该配置的优先级高于全局配置。

```cpp
struct rect {
Expand Down

0 comments on commit 32323c9

Please sign in to comment.