From 6c3e1aee4328e423da77efc527921cbba40b3a39 Mon Sep 17 00:00:00 2001 From: Mindaugas Date: Tue, 8 Jan 2019 16:00:02 +0200 Subject: [PATCH] removed anonymous namespace from PolymorphicBaseClass as it only works on clang, and is not standard compliant --- CHANGELOG.md | 34 ++++++++++++++++--- .../bitsery/ext/utils/polymorphism_utils.h | 18 ++++------ 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a3788c..3a51756 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,38 @@ E.g. `int64_t money = 8000;` will only use 2 bytes, instead of 8. **CompactValueAsObject** allows to use `ext()` overload, without specifying size of underlying type and sets BUFFER_OVERFLOW error if value doesn't fit in underlying type during deserialization. ### Improvements -* improved **PolymorphicContext** for registering base class hierarchies from different translation units. -Previously there was only one symbol for `PolymorphicBaseClass`, but now a primary template for this type lives in anonymous namespace, so each translation unit could get their own symbol. -`registerBasesList` was modified, so that where invocation happens, it will bind to correct symbol for `PolymorphicBaseClass`. +* improved **PolymorphicContext**, allows to extend already registered hierarchy in one translation unit, using different type other than `PolymorphicBaseClass` to avoid symbol collision between translation units or libraries. +`registerBasesList` was modified, so that it could accept user defined type (instead of `PolymorphicBaseClass`) that is used to declare hierarchy, by default it is `PolymorphicBaseClass`. This introduced breaking change, for those who used this syntax (`registerBasesList({})`) during registration. It is encouraged to define helper type, that could be used for registering hierarchy for serialization and deserialization [example](examples/smart_pointers_with_polymorphism.cpp). -* **PolymorphicContext** also get optional method `registerSingleBaseBranch`, that allows manually register hierarchies, but it is not recommended as it is error-prone. +`This is only relevant then you want to use **PolymorphicContext** between different translation units or libraries`. +```cpp +//libA +namespace bitsery { + namespace ext { + template<> + struct PolymorphicBaseClass : PolymorphicDerivedClasses {}; + } +} +using MyPolymorphicClassesForRegistering = bitsery::ext::PolymorphicClassesList; +... + ctx.registerBasesList(MyPolymorphicClassesForRegistering{}). + +//otherLib +struct MySquare: Shape {...} +//now it must define different type (exactly the same as PolymorphicBaseClass) to declare hierarchy +template +struct MyHierarchy { + using Childs = PolymorphicClassesList<>; +}; + +template <> +struct MyHierarchy: bitsery::ext::bitsery::ext::PolymorphicClassesList {}; +... +//notice that we pass MyHierarchy as second argument + ctx.registerBasesList(MyPolymorphicClassesForRegistering{}). +``` +* **PolymorphicContext** also get optional method `registerSingleBaseBranch`, that allows manually register hierarchies, this might be more convenient when using you need to register in different translation units (or libraries), but it is error-prone. # [4.3.0](https://github.com/fraillt/bitsery/compare/v4.2.1...v4.3.0) (2018-08-23) diff --git a/include/bitsery/ext/utils/polymorphism_utils.h b/include/bitsery/ext/utils/polymorphism_utils.h index 8ed8c96..79132dc 100644 --- a/include/bitsery/ext/utils/polymorphism_utils.h +++ b/include/bitsery/ext/utils/polymorphism_utils.h @@ -44,14 +44,10 @@ namespace bitsery { // although you can add all derivates to same base like this: // template <> PolymorphicBaseClass:PolymorphicDerivedClasses{}; // it will not work when you try to serialize Dog*, because it will not find Bulldog and GoldenRetriever - namespace { - // this class must be in anonymous namespace, so that it would generate different symbols when defining different hierarchies in different translation units - // https://github.com/fraillt/bitsery/issues/9 - template - struct PolymorphicBaseClass { - using Childs = PolymorphicClassesList<>; - }; - } + template + struct PolymorphicBaseClass { + using Childs = PolymorphicClassesList<>; + }; //derive from this class when specifying childs for your base class, atleast one child must exists, hence T1 //e.g. @@ -74,11 +70,11 @@ namespace bitsery { void *create() const final { return toBase(new TDerived{}); - }; + } void process(void *ser, void *obj) const final { static_cast(ser)->object(*static_cast(fromBase(obj))); - }; + } private: @@ -188,7 +184,7 @@ namespace bitsery { static_assert(std::is_base_of::value, "TDerived must be derived from TBase"); static_assert(!std::is_abstract::value, "TDerived cannot be abstract"); addToMap(std::false_type{}); - }; + } template