[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>
|
||||
using derived_class_set_t = decltype(struct_pack_derived_decl((Base *)nullptr));
|
||||
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue