File indexing completed on 2024-04-06 12:02:33
0001 #ifndef CondFormats_SerializationHelper_SerializationHelper_h
0002 #define CondFormats_SerializationHelper_SerializationHelper_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <string_view>
0023
0024
0025 #include "CondFormats/SerializationHelper/interface/SerializationHelperBase.h"
0026 #include "CondFormats/Serialization/interface/Archive.h"
0027 #include "FWCore/Utilities/interface/mplVector.h"
0028
0029
0030
0031 namespace cond::serialization {
0032 struct NoInitializer {};
0033
0034 template <typename T>
0035 struct ClassName;
0036
0037 template <typename T>
0038 std::unique_ptr<T> makeClass() {
0039 return std::make_unique<T>();
0040 }
0041
0042 template <typename T>
0043 struct BaseClassInfo {
0044 constexpr static bool kAbstract = false;
0045 using inheriting_classes_t = edm::mpl::Vector<>;
0046 };
0047
0048 template <typename T, bool IsAbstract, typename... INHERITING>
0049 struct BaseClassInfoImpl {
0050 constexpr static bool kAbstract = IsAbstract;
0051 using inheriting_classes_t = edm::mpl::Vector<INHERITING...>;
0052 };
0053
0054 template <typename T, typename INIT = NoInitializer>
0055 class SerializationHelper : public SerializationHelperBase {
0056 public:
0057 SerializationHelper() = default;
0058
0059 SerializationHelper(const SerializationHelper&) = delete;
0060 const SerializationHelper& operator=(const SerializationHelper&) = delete;
0061
0062
0063
0064 unique_void_ptr deserialize(std::streambuf& iBuff, const std::string_view iClassName) const final {
0065 if constexpr (not BaseClassInfo<T>::kAbstract) {
0066 using BaseClassAndInheriting =
0067 typename edm::mpl::Push<T, typename BaseClassInfo<T>::inheriting_classes_t>::Result;
0068 return deserialize_impl<BaseClassAndInheriting>(iBuff, iClassName);
0069 } else {
0070 return deserialize_impl<typename BaseClassInfo<T>::inheriting_classes_t>(iBuff, iClassName);
0071 }
0072 }
0073
0074 std::string_view serialize(std::streambuf& oBuff, void const* iObj) const final {
0075 auto iTypedObjectPtr = static_cast<T const*>(iObj);
0076 if constexpr (BaseClassInfo<T>::kAbstract) {
0077 return serialize_impl<typename BaseClassInfo<T>::inheriting_classes_t>(oBuff, iTypedObjectPtr);
0078 } else {
0079 using BaseClassAndInheriting =
0080 typename edm::mpl::Push<T, typename BaseClassInfo<T>::inheriting_classes_t>::Result;
0081 return serialize_impl<BaseClassAndInheriting>(oBuff, iTypedObjectPtr);
0082 }
0083 }
0084
0085 const std::type_info& type() const final { return typeid(T); }
0086
0087 private:
0088 template <typename TYPELIST>
0089 static unique_void_ptr deserialize_impl(std::streambuf& iBuff, const std::string_view iClassName) {
0090 if constexpr (edm::mpl::Pop<TYPELIST>::empty) {
0091 return {};
0092 } else {
0093 using CheckType = typename edm::mpl::Pop<TYPELIST>::Item;
0094 if (iClassName == ClassName<CheckType>::kName) {
0095 std::unique_ptr<CheckType> tmp = makeClass<CheckType>();
0096
0097 InputArchive ia(iBuff);
0098 ia >> (*tmp);
0099 if constexpr (not std::is_same_v<INIT, NoInitializer>) {
0100 INIT init;
0101 init(*tmp);
0102 }
0103 return unique_void_ptr(tmp.release(), [](const void* iPtr) { delete static_cast<const T*>(iPtr); });
0104
0105 } else {
0106 return deserialize_impl<typename edm::mpl::Pop<TYPELIST>::Remaining>(iBuff, iClassName);
0107 }
0108 }
0109 }
0110 template <typename TYPELIST>
0111 static std::string_view serialize_impl(std::streambuf& oBuff, T const* iObj) {
0112 if constexpr (edm::mpl::Pop<TYPELIST>::empty) {
0113 return {};
0114 } else {
0115 if (typeid(*iObj) == typeid(typename edm::mpl::Pop<TYPELIST>::Item)) {
0116 auto iTypedObjectPtr = dynamic_cast<typename edm::mpl::Pop<TYPELIST>::Item const*>(iObj);
0117 OutputArchive oa(oBuff);
0118 oa << *iTypedObjectPtr;
0119
0120 return ClassName<typename edm::mpl::Pop<TYPELIST>::Item>::kName;
0121
0122 } else {
0123 return serialize_impl<typename edm::mpl::Pop<TYPELIST>::Remaining>(oBuff, iObj);
0124 }
0125 }
0126 }
0127 };
0128 }
0129 #endif