[struct_pack] fixed serialize std::unique_ptr<T> with T is derived class. (#634)

This commit is contained in:
saipubw 2024-03-18 15:58:44 +08:00 committed by GitHub
parent ba4685d98e
commit 6f59fa254a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 57 additions and 4 deletions

View File

@ -168,6 +168,9 @@ struct deserialize_one_derived_class_helper {
}
};
template <typename T>
void struct_pack_derived_decl(const T *) = delete;
template <typename Base>
using derived_class_set_t = decltype(struct_pack_derived_decl((Base *)nullptr));

View File

@ -14,9 +14,8 @@
* limitations under the License.
*/
#include "foreach_macro.h"
#pragma once
#include "foreach_macro.h"
#define GET_STRUCT_PACK_ID_IMPL_FOR_LOOP(idx, type) \
inline uint32_t type::get_struct_pack_id() const { \
@ -26,7 +25,7 @@
#define STRUCT_PACK_DERIVED_DECL(base, ...) \
\
inline decltype(struct_pack::detail::derived_decl_impl<base, __VA_ARGS__>()) \
struct_pack_derived_decl(base*);
struct_pack_derived_decl(const base*);
#define STRUCT_PACK_DERIVED_IMPL(base, ...) \
STRUCT_PACK_EXPAND_EACH(, GET_STRUCT_PACK_ID_IMPL_FOR_LOOP, base, \

View File

@ -167,4 +167,55 @@ TEST_CASE("test unique_ptr<Base> with virtual base") {
auto res2 = struct_pack::deserialize<std::unique_ptr<base>>(buffer2);
CHECK(res2);
CHECK(res2.value()->get_name() == std::make_unique<derived4>()->get_name());
}
}
namespace derived_class_contain_another_derived_class {
struct base {
virtual uint32_t get_struct_pack_id() const = 0;
virtual std::string get_name() const = 0;
static std::unique_ptr<base> deserialize(std::string& serialized);
virtual ~base(){};
};
struct derived1 : public base {
int b;
virtual uint32_t get_struct_pack_id() const override;
std::string get_name() const override { return "derived1"; }
};
STRUCT_PACK_REFL(derived1, b);
struct derived2 : public base {
std::string c;
std::unique_ptr<derived1> child;
virtual uint32_t get_struct_pack_id() const override;
std::string get_name() const override { return "derived2"; }
};
STRUCT_PACK_REFL(derived2, c, child);
STRUCT_PACK_DERIVED_IMPL(base, derived1, derived2);
std::unique_ptr<base> base::deserialize(std::string& serialized) {
return struct_pack::deserialize_derived_class<base, derived1, derived2>(
serialized)
.value();
}
} // namespace derived_class_contain_another_derived_class
TEST_CASE("test derived class contain by other derived class") {
using namespace derived_class_contain_another_derived_class;
{
auto serialized = struct_pack::serialize<std::string>(derived1{});
auto x = base::deserialize(serialized);
REQUIRE(x);
CHECK(x->get_name() == "derived1");
}
{
auto serialized = struct_pack::serialize<std::string>(derived2{});
auto x = base::deserialize(serialized);
REQUIRE(x);
CHECK(x->get_name() == "derived2");
}
}