From a679fafc3c12bd297279fe7d9364e7bd2dedc039 Mon Sep 17 00:00:00 2001 From: saipubw Date: Fri, 9 Aug 2024 16:51:29 +0800 Subject: [PATCH] [struct_pack][feat] support user-define global config (#741) --- include/ylt/struct_pack/reflection.hpp | 27 ++++++++ include/ylt/struct_pack/type_calculate.hpp | 64 +++++++------------ src/struct_pack/examples/serialize_config.cpp | 9 +++ .../tests/test_type_info_config.cpp | 19 ++++++ .../docs/en/struct_pack/struct_pack_tips.md | 18 +++++- .../docs/zh/struct_pack/struct_pack_tips.md | 19 +++++- 6 files changed, 114 insertions(+), 42 deletions(-) create mode 100644 src/struct_pack/tests/test_type_info_config.cpp diff --git a/include/ylt/struct_pack/reflection.hpp b/include/ylt/struct_pack/reflection.hpp index 473324392..fb61b2ced 100644 --- a/include/ylt/struct_pack/reflection.hpp +++ b/include/ylt/struct_pack/reflection.hpp @@ -590,6 +590,33 @@ template constexpr bool user_defined_config_by_ADL = user_defined_config_by_ADL_impl::value; #endif +template +constexpr decltype(auto) delay_sp_config_eval() { + if constexpr (sizeof(T)==0) { + return (T*){}; + } + else { + return (sp_config*){}; + } +} + +#if __cpp_concepts >= 201907L + template + concept has_default_config = std::is_same_v()){})),struct_pack::sp_config>; +#else + template + struct has_default_config_impl : std::false_type {}; + + template + struct has_default_config_impl()){})),struct_pack::sp_config>>>> + : std::true_type {}; + + template + constexpr bool has_default_config = has_default_config_impl::value; +#endif + + #if __cpp_concepts >= 201907L template concept user_defined_config = requires { diff --git a/include/ylt/struct_pack/type_calculate.hpp b/include/ylt/struct_pack/type_calculate.hpp index b53a0d22c..1d7cbc343 100644 --- a/include/ylt/struct_pack/type_calculate.hpp +++ b/include/ylt/struct_pack/type_calculate.hpp @@ -153,18 +153,25 @@ constexpr decltype(auto) get_type_end_flag() { } } -template -constexpr uint64_t get_parent_tag_impl() { - if constexpr (user_defined_config_by_ADL) { - return static_cast(set_sp_config((Arg *)nullptr)); +template +constexpr sp_config get_type_config() { + if constexpr (struct_pack::detail::user_defined_config_by_ADL) { + return set_sp_config((T *)nullptr); } - else if constexpr (user_defined_config) { - return static_cast(Arg::struct_pack_config); + else if constexpr (struct_pack::detail::user_defined_config) { + return static_cast(T::struct_pack_config); + } + else if constexpr (struct_pack::detail::has_default_config) { + return set_default(decltype(delay_sp_config_eval()){}); } else { - return 0; + return sp_config::DEFAULT; } } +template +constexpr uint64_t get_parent_tag_impl() { + return static_cast(get_type_config()); +} template constexpr uint64_t get_parent_tag() { @@ -715,26 +722,12 @@ template 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) { - constexpr auto config = set_sp_config((T *)nullptr) & 0b11; - if constexpr (config == sp_config::DEFAULT) { - return serialize_static_config::has_type_literal; - } - else { - return config == sp_config::ENABLE_TYPE_INFO; - } - } - else if constexpr (struct_pack::detail::user_defined_config) { - constexpr auto config = T::struct_pack_config & 0b11; - if constexpr (config == sp_config::DEFAULT) { - return serialize_static_config::has_type_literal; - } - else { - return config == sp_config::ENABLE_TYPE_INFO; - } + constexpr auto config = get_type_config() & 0b11; + if constexpr (config == sp_config::DEFAULT) { + return serialize_static_config::has_type_literal; } else { - return serialize_static_config::has_type_literal; + return config == sp_config::ENABLE_TYPE_INFO; } } else { @@ -830,22 +823,13 @@ constexpr bool check_if_has_container() { template 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) { - 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) { - 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() & 0b11; + return config == sp_config::DISABLE_ALL_META_INFO; + } + else { + return config == sp_config::DISABLE_ALL_META_INFO; } - return true; } template diff --git a/src/struct_pack/examples/serialize_config.cpp b/src/struct_pack/examples/serialize_config.cpp index 97abc7e0c..001cd6e09 100644 --- a/src/struct_pack/examples/serialize_config.cpp +++ b/src/struct_pack/examples/serialize_config.cpp @@ -16,6 +16,9 @@ #include +#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 @@ -26,6 +29,12 @@ // add this macro to enable support of int128/uint128 #include +// 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; diff --git a/src/struct_pack/tests/test_type_info_config.cpp b/src/struct_pack/tests/test_type_info_config.cpp new file mode 100644 index 000000000..540bcb20f --- /dev/null +++ b/src/struct_pack/tests/test_type_info_config.cpp @@ -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); diff --git a/website/docs/en/struct_pack/struct_pack_tips.md b/website/docs/en/struct_pack/struct_pack_tips.md index be24f8cc0..0c6752417 100644 --- a/website/docs/en/struct_pack/struct_pack_tips.md +++ b/website/docs/en/struct_pack/struct_pack_tips.md @@ -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 diff --git a/website/docs/zh/struct_pack/struct_pack_tips.md b/website/docs/zh/struct_pack/struct_pack_tips.md index 3192632bd..5f6d5c1da 100644 --- a/website/docs/zh/struct_pack/struct_pack_tips.md +++ b/website/docs/zh/struct_pack/struct_pack_tips.md @@ -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 {