[struct_pack] fixed serialize std::unique_ptr<T> with T is derived class. (#634)
This commit is contained in:
parent
ba4685d98e
commit
6f59fa254a
|
@ -168,6 +168,9 @@ struct deserialize_one_derived_class_helper {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void struct_pack_derived_decl(const T *) = delete;
|
||||||
|
|
||||||
template <typename Base>
|
template <typename Base>
|
||||||
using derived_class_set_t = decltype(struct_pack_derived_decl((Base *)nullptr));
|
using derived_class_set_t = decltype(struct_pack_derived_decl((Base *)nullptr));
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "foreach_macro.h"
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "foreach_macro.h"
|
||||||
|
|
||||||
#define GET_STRUCT_PACK_ID_IMPL_FOR_LOOP(idx, type) \
|
#define GET_STRUCT_PACK_ID_IMPL_FOR_LOOP(idx, type) \
|
||||||
inline uint32_t type::get_struct_pack_id() const { \
|
inline uint32_t type::get_struct_pack_id() const { \
|
||||||
|
@ -26,7 +25,7 @@
|
||||||
#define STRUCT_PACK_DERIVED_DECL(base, ...) \
|
#define STRUCT_PACK_DERIVED_DECL(base, ...) \
|
||||||
\
|
\
|
||||||
inline decltype(struct_pack::detail::derived_decl_impl<base, __VA_ARGS__>()) \
|
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, ...) \
|
#define STRUCT_PACK_DERIVED_IMPL(base, ...) \
|
||||||
STRUCT_PACK_EXPAND_EACH(, GET_STRUCT_PACK_ID_IMPL_FOR_LOOP, base, \
|
STRUCT_PACK_EXPAND_EACH(, GET_STRUCT_PACK_ID_IMPL_FOR_LOOP, base, \
|
||||||
|
|
|
@ -167,4 +167,55 @@ TEST_CASE("test unique_ptr<Base> with virtual base") {
|
||||||
auto res2 = struct_pack::deserialize<std::unique_ptr<base>>(buffer2);
|
auto res2 = struct_pack::deserialize<std::unique_ptr<base>>(buffer2);
|
||||||
CHECK(res2);
|
CHECK(res2);
|
||||||
CHECK(res2.value()->get_name() == std::make_unique<derived4>()->get_name());
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue