Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:02:33

0001 #ifndef CondFormats_SerializationHelper_SerializationHelper_h
0002 #define CondFormats_SerializationHelper_SerializationHelper_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     CondFormats/SerializationHelper
0006 // Class  :     SerializationHelper
0007 //
0008 /**\class SerializationHelper SerializationHelper.h "CondFormats/SerializationHelper/interface/SerializationHelper.h"
0009 
0010  Description: concrete implementation of the SerializationHelperBase interface
0011 
0012  Usage:
0013     <usage>
0014 
0015 */
0016 //
0017 // Original Author:  Christopher Jones
0018 //         Created:  Wed, 31 May 2023 14:55:13 GMT
0019 //
0020 
0021 // system include files
0022 #include <string_view>
0023 
0024 // user include files
0025 #include "CondFormats/SerializationHelper/interface/SerializationHelperBase.h"
0026 #include "CondFormats/Serialization/interface/Archive.h"
0027 #include "FWCore/Utilities/interface/mplVector.h"
0028 
0029 // forward declarations
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;                   // stop default
0060     const SerializationHelper& operator=(const SerializationHelper&) = delete;  // stop default
0061 
0062     // ---------- const member functions ---------------------
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 }  // namespace cond::serialization
0129 #endif