diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.h index 7b82a2483cb30ae974a8eb8d8017c15a1e4427df..de237e26d31b8e1a4be82bfd5867422ed15cf2bd 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.h +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.h @@ -1,7 +1,7 @@ // This file's extension implies that it's C, but it's really -*- C++ -*-. /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration */ // $Id$ @@ -17,6 +17,7 @@ #define ATHENAPOOLCNVSVC_TPCNVELT_H +#include "AthenaPoolCnvSvc/T_AthenaPoolCreateFuncs.h" #include "PersistentDataModel/Guid.h" #include #include @@ -73,6 +74,7 @@ public: /** * @brief Read the persistent object and convert it to transient. * @param parent The top-level pool converter object. + * @param key The SG key of the object being read. * @param msg MsgStream for error reporting. * * Returns a newly-allocated object. @@ -80,13 +82,15 @@ public: * type that this converter handles, return nullptr. * Other errors are reported by raising exceptions. */ - Trans_t* createTransient (CNV& parent, MsgStream& msg); + std::unique_ptr + createTransient (CNV& parent, const std::string& key, MsgStream& msg); /** * @brief Read the persistent object and convert it to transient. * @param parent The top-level pool converter object. * @param trans The transient object to modify. + * @param key The SG key of the object being read. * @param msg MsgStream for error reporting. * * Overwrites the provided transient object. @@ -94,7 +98,7 @@ public: * type that this converter handles, returns false. * Other errors are reported by raising exceptions. */ - bool persToTrans (CNV& parent, Trans_t* trans, MsgStream& msg); + bool persToTrans (CNV& parent, Trans_t* trans, const std::string& key, MsgStream& msg); private: @@ -128,6 +132,7 @@ public: /** * @brief Read the persistent object and convert it to transient. * @param parent The top-level pool converter object. + * @param key The SG key of the object being read. * @param msg MsgStream for error reporting. * * Returns a newly-allocated object. @@ -135,13 +140,15 @@ public: * type that this converter handles, return nullptr. * Other errors are reported by raising exceptions. */ - Trans_t* createTransient (CNV& parent, MsgStream& msg); + std::unique_ptr + createTransient (CNV& parent, const std::string& key, MsgStream& msg); /** * @brief Read the persistent object and convert it to transient. * @param parent The top-level pool converter object. * @param trans The transient object to modify. + * @param key The SG key of the object being read. * @param msg MsgStream for error reporting. * * Overwrites the provided transient object. @@ -149,7 +156,7 @@ public: * type that this converter handles, returns false. * Other errors are reported by raising exceptions. */ - bool persToTrans (CNV& parent, Trans_t* trans, MsgStream& msg); + bool persToTrans (CNV& parent, Trans_t* trans, const std::string& key, MsgStream& msg); private: diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.icc index 46ec8f189b2bb9d2d360e2abd40e68c5881b3318..be99ed012fc15a67dcbb31982c199246d818fd10 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.icc +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.icc @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration */ // $Id$ @@ -28,6 +28,7 @@ TPCnvElt::TPCnvElt() /** * @brief Read the persistent object and convert it to transient. * @param parent The top-level pool converter object. + * @param key The SG key of the object being read. * @param msg MsgStream for error reporting. * * Returns a newly-allocated object. @@ -36,14 +37,16 @@ TPCnvElt::TPCnvElt() * Other errors are reported by raising exceptions. */ template -typename TPCnvElt::Trans_t* -TPCnvElt::createTransient (CNV& parent, MsgStream& msg) +std::unique_ptr::Trans_t> +TPCnvElt::createTransient (CNV& parent, + const std::string& key, + MsgStream& msg) { if (!parent.compareClassGuid (m_guid)) - return nullptr; + return std::unique_ptr::Trans_t>(); std::unique_ptr old (parent.template poolReadObject() ); - return m_cnv.createTransient(old.get(), msg); + return AthenaPoolCnvSvc::createTransient (m_cnv, old.get(), key, msg); } @@ -51,6 +54,7 @@ TPCnvElt::createTransient (CNV& parent, MsgStream& msg) * @brief Read the persistent object and convert it to transient. * @param parent The top-level pool converter object. * @param trans The transient object to modify. + * @param key The SG key of the object being read. * @param msg MsgStream for error reporting. * * Overwrites the provided transient object. @@ -60,7 +64,9 @@ TPCnvElt::createTransient (CNV& parent, MsgStream& msg) */ template bool -TPCnvElt::persToTrans (CNV& parent, Trans_t* trans, MsgStream& msg) +TPCnvElt::persToTrans (CNV& parent, Trans_t* trans, + const std::string& /*key*/, + MsgStream& msg) { if (!parent.compareClassGuid (m_guid)) return false; @@ -90,6 +96,7 @@ TPCnvElt >::TPCnvElt() /** * @brief Read the persistent object and convert it to transient. * @param parent The top-level pool converter object. + * @param key The SG key of the object being read. * @param msg MsgStream for error reporting. * * Specialization for the case of no conversion. @@ -100,14 +107,16 @@ TPCnvElt >::TPCnvElt() * Other errors are reported by raising exceptions. */ template -typename TPCnvElt >::Trans_t* +std::unique_ptr >::Trans_t> TPCnvElt >::createTransient (CNV& parent, + const std::string& /*key*/, MsgStream& /*msg*/) { - if (!parent.compareClassGuid (m_guid)) - return nullptr; - - return parent.template poolReadObject(); + Pers_t* p = nullptr; + if (parent.compareClassGuid (m_guid)) { + p = parent.template poolReadObject(); + } + return std::unique_ptr >::Trans_t>(p); } @@ -115,6 +124,7 @@ TPCnvElt >::createTransient (CNV& parent, * @brief Read the persistent object and convert it to transient. * @param parent The top-level pool converter object. * @param trans The transient object to modify. + * @param key The SG key of the object being read. * @param msg MsgStream for error reporting. * * Specialization for the case of no conversion. @@ -128,6 +138,7 @@ template bool TPCnvElt >::persToTrans (CNV& parent, Trans_t* trans, + const std::string& /*key*/, MsgStream& /*msg*/) { if (!parent.compareClassGuid (m_guid)) diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.h index 8c737fb2b25d7b77f5ce94ecb2acff0e39e10392..82d92413dc5ed98128242881024ccea6f56beeaa 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.h +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.h @@ -1,7 +1,7 @@ // This file's extension implies that it's C, but it's really -*- C++ -*-. /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration */ // $Id$ @@ -47,12 +47,16 @@ class TPCnvList /// on each. Stop once one succeeds. struct do_create_transient { - do_create_transient (CNV& parent, MsgStream& msg); - + do_create_transient (CNV& parent, const std::string& key, MsgStream& msg); + + // FIXME: It would be better to pass a unique_ptr through here. + // But that requires the resolution of DR2055, which g++ only implements + // with c++20. template typename ELT::Trans_t* operator() (typename ELT::Trans_t* p, ELT& elt); CNV& m_parent; + const std::string& m_key; MsgStream& m_msg; }; @@ -61,13 +65,14 @@ class TPCnvList /// on each. Stop once one succeeds. struct do_pers_to_trans { - do_pers_to_trans (CNV& parent, TRANS* trans, MsgStream& msg); + do_pers_to_trans (CNV& parent, TRANS* trans, const std::string& key, MsgStream& msg); template bool operator() (bool found, ELT& elt); CNV& m_parent; TRANS* m_trans; + const std::string& m_key; MsgStream& m_msg; }; @@ -89,6 +94,7 @@ public: /** * @brief Read the persistent object and convert it to transient. * @param parent The top-level pool converter object. + * @param key The SG key of the object being read. * @param msg MsgStream for error reporting. * * Returns a newly-allocated object. @@ -96,13 +102,15 @@ public: * the type of any of our TP converters, return nullptr. * Other errors are reported by raising exceptions. */ - TRANS* createTransient (CNV& parent, MsgStream& msg); + std::unique_ptr + createTransient (CNV& parent, const std::string& key, MsgStream& msg); /** * @brief Read the persistent object and convert it to transient. * @param parent The top-level pool converter object. * @param trans The transient object to modify. + * @param key The SG key of the object being read. * @param msg MsgStream for error reporting. * * Overwrites the provided transient object. @@ -110,7 +118,7 @@ public: * the type of any of our TP converters, return false. * Other errors are reported by raising exceptions. */ - bool persToTrans (CNV& parent, TRANS* trans, MsgStream& msg); + bool persToTrans (CNV& parent, TRANS* trans, const std::string& key, MsgStream& msg); private: diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.icc index 699c959a00bf6e56de8be9a4618cf5cbe115d3e2..b73cf94dcbf14b6ef5c483a5381a11875c4d1da9 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.icc +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.icc @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration */ // $Id$ @@ -17,12 +17,16 @@ namespace AthenaPoolCnvSvc { /** * @brief Constructor. * @param parent The parent Athena pool converter. + * @param key SG key of the object being read. * @param msg MsgStream for error reporting. */ template inline -TPCnvList::do_create_transient::do_create_transient (CNV& parent, MsgStream& msg) +TPCnvList::do_create_transient::do_create_transient (CNV& parent, + const std::string& key, + MsgStream& msg) : m_parent (parent), + m_key (key), m_msg (msg) { } @@ -48,21 +52,24 @@ TPCnvList::do_create_transient::operator() (typename ELT::Trans_t* p, ELT& elt) { if (p) return p; - return elt.createTransient (m_parent, m_msg); + return elt.createTransient (m_parent, m_key, m_msg).release(); } /** * @brief Constructor. * @param parent The parent Athena pool converter. + * @param trans The transient object to modify. + * @param key The SG key of the object being read. * @param msg MsgStream for error reporting. */ template inline TPCnvList::do_pers_to_trans::do_pers_to_trans - (CNV& parent, TRANS* trans, MsgStream& msg) +(CNV& parent, TRANS* trans, const std::string& key, MsgStream& msg) : m_parent (parent), m_trans (trans), + m_key (key), m_msg (msg) { } @@ -86,7 +93,7 @@ bool TPCnvList::do_pers_to_trans::operator() (bool found, ELT& elt) { if (found) return true; - return elt.persToTrans (m_parent, m_trans, m_msg); + return elt.persToTrans (m_parent, m_trans, m_key, m_msg); } @@ -94,6 +101,7 @@ bool TPCnvList::do_pers_to_trans::operator() /** * @brief Read the persistent object and convert it to transient. * @param parent The top-level pool converter object. + * @param key The SG key of the object being read. * @param msg MsgStream for error reporting. * * Returns a newly-allocated object. @@ -102,13 +110,16 @@ bool TPCnvList::do_pers_to_trans::operator() * Other errors are reported by raising exceptions. */ template -TRANS* TPCnvList::createTransient (CNV& parent, - MsgStream& msg) +std::unique_ptr +TPCnvList::createTransient (CNV& parent, + const std::string& key, + MsgStream& msg) { // Try createTransient on each TPCnv; stop when one succeeds. TRANS* p = nullptr; - return boost::fusion::accumulate - (m_list, p, do_create_transient(parent, msg)); + p = boost::fusion::accumulate + (m_list, p, do_create_transient(parent, key, msg)); + return std::unique_ptr (p); } #endif @@ -118,6 +129,7 @@ TRANS* TPCnvList::createTransient (CNV& parent, * @brief Read the persistent object and convert it to transient. * @param parent The top-level pool converter object. * @param trans The transient object to modify. + * @param key The SG key of the object being read. * @param msg MsgStream for error reporting. * * Overwrites the provided transient object. @@ -128,11 +140,12 @@ TRANS* TPCnvList::createTransient (CNV& parent, template bool TPCnvList::persToTrans (CNV& parent, TRANS* trans, + const std::string& key, MsgStream& msg) { // Try persToTrans on each TPCnv; stop when one succeeds. return boost::fusion::accumulate - (m_list, false, do_pers_to_trans(parent, trans, msg)); + (m_list, false, do_pers_to_trans(parent, trans, key, msg)); } #endif diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc index d019be6c0e1241bf70691df10c0e18dcde579620..8f3634a8a71d080c0b0ba155a924e4c2a325f961 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc @@ -47,7 +47,7 @@ T_AthenaPoolAuxContainerCnv::createPersistentWithKey( AUXST */ template AUXSTORE* -T_AthenaPoolAuxContainerCnv::createTransientWithKey (const std::string& /*key*/) +T_AthenaPoolAuxContainerCnv::createTransientWithKey (const std::string& key) { AthenaPoolCnvSvc::debugCreateTransient (ClassID_traits::ID()); if ( this->compareClassGuid( m_guid ) ) { @@ -56,9 +56,9 @@ T_AthenaPoolAuxContainerCnv::createTransientWithKey (const } // Try a converter. - AUXSTORE* c = m_tpcnvs.createTransient (*this, this->msg()); + std::unique_ptr c = m_tpcnvs.createTransient (*this, key, this->msg()); if (c) - return c; + return c.release(); // Didn't recognize the GUID. AthenaPoolCnvSvc::throwExcUnsupportedVersion (typeid(AUXSTORE), diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCreateFuncs.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCreateFuncs.h new file mode 100644 index 0000000000000000000000000000000000000000..f9d4e0aaafd1c005c032907f58f700b22a7e7b47 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCreateFuncs.h @@ -0,0 +1,143 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. +/* + * Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration. + */ +/** + * @file AthenaPoolCnvSvc/T_AthenaPoolCreateFuncs.h + * @author scott snyder + * @date Sep, 2019 + * @brief Helpers for calling TP converters. + * + * This file providers two helpers for calling TP converters from the + * templated pool converters. + * + * Some TP converters derive from ITPConverter. In that case, we want to + * call createPersistent / createTransient(). But some TP converters do not; + * in that case, we should call transToPers() / persToTrans() directly. + * + * In the first case, we actually call the *WithKey versions. + * We don't support passing the key to converters that don't derive + * from ITPConverter. + */ + + +#ifndef ATHENAPOOLCNVSVC_T_ATHENAPOOLCREATEFUNCS_H +#define ATHENAPOOLCNVSVC_T_ATHENAPOOLCREATEFUNCS_H + + +#include "TPTools/ITPConverter.h" +#include "GaudiKernel/MsgStream.h" +#include +#include +class IdentifiableContainerBase; + + +namespace AthenaPoolCnvSvc { + + +/** + * @brief Create a persistent object from a transient object. + * @param cnv The TP converter to call. + * @param transObj The transient object to convert. + * @param The SG key of the object. + * @param log For logging messages. + * + * This version is used when CNV derives from ITPConverter. + * We call TPCNV::createPersistentWithKey(). + */ +template >* = nullptr> +std::unique_ptr +createPersistent (TPCNV& cnv, + const typename TPCNV::Trans_t* transObj, + const std::string& key, + MsgStream& log) +{ + return std::unique_ptr + (cnv.createPersistentWithKey (transObj, key, log)); +} + + +/** + * @brief Create a persistent object from a transient object. + * @param cnv The TP converter to call. + * @param transObj The transient object to convert. + * @param The SG key of the object. + * @param log For logging messages. + * + * This version is used when CNV does not derivce from ITPConverter. + * We create the persistent object directly and call TPCnv::transToPers(). + */ +template >* = nullptr> +std::unique_ptr +createPersistent (TPCNV& cnv, + const typename TPCNV::Trans_t* transObj, + const std::string& /*key*/, + MsgStream& log) +{ + auto pers = std::make_unique(); + cnv.transToPers(transObj, pers.get(), log); + return pers; +} + + +/** + * @brief Create a transient object from a persistent object. + * @param cnv The TP converter to call. + * @param persObj The persistent object to convert. + * @param The SG key of the object. + * @param log For logging messages. + * + * This version is used when CNV derives from ITPConverter. + * We call TPCNV::createTransientWithKey(). + */ +template >* = nullptr> +std::unique_ptr +createTransient (TPCNV& cnv, + const typename TPCNV::Pers_t* persObj, + const std::string& key, + MsgStream& log) +{ + return std::unique_ptr + (cnv.createTransientWithKey (persObj, key, log)); +} + + +/** + * @brief Create a transient object from a persistent object. + * @param cnv The TP converter to call. + * @param persObj The persistent object to convert. + * @param The SG key of the object. + * @param log For logging messages. + * + * This version is used when CNV does not derivce from ITPConverter. + * We create the transient object directly and call TPCnv::persToTrans(). + */ +template >* = nullptr> +std::unique_ptr +createTransient (TPCNV& cnv, + const typename TPCNV::Pers_t* persObj, + const std::string& /*key*/, + MsgStream& log) +{ + typedef typename TPCNV::Trans_t Trans_t; + if constexpr(std::is_base_of< IdentifiableContainerBase, Trans_t>::value && + !std::is_default_constructible::value) + { + log << "IdentifiableContainerBase is not compatible with createTransient" << endmsg; + return std::unique_ptr(); + } + + auto trans = std::make_unique(); + cnv.persToTrans(persObj, trans.get(), log); + return trans; +} + + +} // namespace AthenaPoolCnvSvc + + +#endif // not ATHENAPOOLCNVSVC_T_ATHENAPOOLCREATEFUNCS_H diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h index 65e85081b9892a037cd25cca6ae405979cf7cfb6..c77bb1e3813fd5bd478de337560ac7b8f2e755ea 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h @@ -19,6 +19,7 @@ #include "AthenaPoolCnvSvc/TPCnvList.h" #include "AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h" +#include "AthenaPoolCnvSvc/T_AthenaPoolCreateFuncs.h" #include "AthenaPoolCnvSvc/exceptions.h" #include "AthenaPoolCnvSvc/debug.h" #include "AthenaKernel/ClassName.h" @@ -35,7 +36,7 @@ */ template class T_AthenaPoolTPCnvCnv - : public T_AthenaPoolCustomCnv + : public T_AthenaPoolCustomCnvWithKey { friend class CnvFactory< T_AthenaPoolTPCnvCnv >; @@ -43,7 +44,7 @@ class T_AthenaPoolTPCnvCnv friend class AthenaPoolCnvSvc::TPCnvElt; public: - typedef T_AthenaPoolCustomCnv Base; + typedef T_AthenaPoolCustomCnvWithKey Base; typedef typename TPCNV_CUR::Pers_t Pers_t; @@ -57,19 +58,22 @@ public: /** * @brief Convert a transient object to persistent form. * @param trans The transient object to convert. + * @param key The SG key of the object being written. * * Returns a newly-allocated persistent object. */ - virtual Pers_t* createPersistent( TRANS* trans ) override; + virtual Pers_t* createPersistentWithKey( TRANS* trans, + const std::string& key ) override; /** * @brief Read the persistent object and convert it to transient. + * @param key The SG key of the object being read. * * Returns a newly-allocated transient object. * Errors are reported by raising exceptions. */ - virtual TRANS* createTransient() override; + virtual TRANS* createTransientWithKey (const std::string& key) override; private: diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc index a35a13ad61e669839cd25d6e63dd8ebe162847ec..6ba026c279706fe55c9b3ed8d0d547f7084a7608 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration */ // $Id$ @@ -25,40 +25,43 @@ T_AthenaPoolTPCnvCnv::T_AthenaPoolTPCnvCnv( ISvcLoc /** * @brief Convert a transient object to persistent form. + * @param key The SG key of the object being written. * @param trans The transient object to convert. * * Returns a newly-allocated persistent object. */ template typename T_AthenaPoolTPCnvCnv::Pers_t* -T_AthenaPoolTPCnvCnv::createPersistent( TRANS* trans ) +T_AthenaPoolTPCnvCnv::createPersistentWithKey( TRANS* trans, + const std::string& key) { AthenaPoolCnvSvc::debugCreatePersistent (ClassID_traits::ID()); - return m_tpcnv_cur.createPersistent (trans, this->msg()); + return AthenaPoolCnvSvc::createPersistent (m_tpcnv_cur, trans, key, this->msg()).release(); } /** * @brief Read the persistent object and convert it to transient. + * @param key The SG key of the object being read. * * Returns a newly-allocated transient object. * Errors are reported by raising exceptions. */ template TRANS* -T_AthenaPoolTPCnvCnv::createTransient() +T_AthenaPoolTPCnvCnv::createTransientWithKey (const std::string& key) { AthenaPoolCnvSvc::debugCreateTransient (ClassID_traits::ID()); if ( this->compareClassGuid( m_guid ) ) { // It's the latest version. std::unique_ptr persObj( this->template poolReadObject() ); - return m_tpcnv_cur.createTransient( persObj.get(), this->msg() ); + return AthenaPoolCnvSvc::createTransient (m_tpcnv_cur, persObj.get(), key, this->msg()).release(); } // Try a converter. - TRANS* c = m_tpcnvs.createTransient (*this, this->msg()); + std::unique_ptr c = m_tpcnvs.createTransient (*this, key, this->msg()); if (c) - return c; + return c.release(); // Didn't recognize the GUID. AthenaPoolCnvSvc::throwExcUnsupportedVersion (typeid(TRANS), diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h index b696499eef878bf7e1a7eb618a19d71aaf5a153a..943e19e1b6fab219ff59223d4684c792b769967e 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h @@ -40,6 +40,9 @@ using T_AthenaPoolTPCnvBase = TPConverterBase; template< class TRANS, class PERS > using T_AthenaPoolTPCnvConstBase = TPConverterConstBase; +template< class TRANS, class PERS > +using T_AthenaPoolTPCnvWithKeyBase = TPConverterWithKeyBase; + template using T_AthenaPoolTPPtrVectorCnv = TPPtrVectorCnv; diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc index ddb788e2aab2af66fffcbb7f6da42baf1720b172..27c5451f9b0f936266dc648d64dc48b65cbbc7a7 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc @@ -58,7 +58,7 @@ T_AthenaPoolxAODCnv::createTransientWithKey (const std::string& } else { // Try a converter. - c = m_tpcnvs.createTransient (*this, this->msg()); + c = m_tpcnvs.createTransient (*this, key, this->msg()).release(); } if (c) { diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt b/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt index 62e7f4b0a5c1d33a6624eb3cce4d4bf603601d55..fab0a4af81a6df557334d9d86e18e3ddce4a26af 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt @@ -69,6 +69,11 @@ atlas_add_test( TPCnvList_test INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} LINK_LIBRARIES ${ROOT_LIBRARIES} GaudiKernel AthenaPoolCnvSvcLib ) +atlas_add_test( T_AthenaPoolCreateFuncs_test + SOURCES test/T_AthenaPoolCreateFuncs_test.cxx + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} GaudiKernel AthenaPoolCnvSvcLib ) + atlas_add_test( T_AthenaPoolViewVectorCnv_test SOURCES test/T_AthenaPoolViewVectorCnv_test.cxx INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolCreateFuncs_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolCreateFuncs_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..11bcd7b0be025a1e22891a6c6b9ef113c3f26997 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolCreateFuncs_test.ref @@ -0,0 +1,2 @@ +AthenaPoolCnvSvc/T_AthenaPoolCreateFuncs_test +test1 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvElt_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvElt_test.cxx index 173f5a0a13cfc3b70010d630b208f8a2f9895f96..37fd692d71c30c276e615faf13a88b53d090f69f 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvElt_test.cxx +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvElt_test.cxx @@ -1,8 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration */ - -// $Id$ /** * @file AthenaPoolCnvSvc/test/TPCnvElt_test.cxx * @author scott snyder @@ -16,6 +14,7 @@ #include "AthenaPoolCnvSvcTestDict.h" #include "GaudiKernel/MsgStream.h" #include "TSystem.h" +#include "TestConverterBase.h" #include #include #include @@ -25,11 +24,16 @@ using namespace AthenaPoolCnvSvcTest; class XCnv_p1 + : public TestConverterBase { public: typedef X Trans_t; typedef X_p1 Pers_t; + X* createTransientWithKey (const X_p1* pers, const std::string&, MsgStream& log) + { + return createTransient (pers, log); + } X* createTransient (const X_p1* pers, MsgStream&) { return new X(pers->m_a*2); } @@ -77,28 +81,30 @@ void test2() AthenaPoolCnvSvc::TPCnvElt tpcnv; TestConverter cnv1 (X_p1_guid); - X* x = tpcnv.createTransient (cnv1, msg); - assert (x->m_a == 20); - delete x; + { + std::unique_ptr xptr = tpcnv.createTransient (cnv1, "key", msg); + assert (xptr->m_a == 20); + } X x2 (0); - assert (tpcnv.persToTrans (cnv1, &x2, msg)); + assert (tpcnv.persToTrans (cnv1, &x2, "key", msg)); assert (x2.m_a == 20); TestConverter cnv2 ("8ADE9DD7-ED1F-447E-A096-0F8F786291CD"); - assert (tpcnv.createTransient (cnv2, msg) == nullptr); - assert (!tpcnv.persToTrans (cnv2, &x2, msg)); + assert (tpcnv.createTransient (cnv2, "key", msg) == nullptr); + assert (!tpcnv.persToTrans (cnv2, &x2, "key", msg)); AthenaPoolCnvSvc::TPCnvElt > tpcnv_null; TestConverter cnv3 (X_guid); - x = tpcnv_null.createTransient (cnv3, msg); - assert (x->m_a == 10); - delete x; - assert (tpcnv_null.createTransient (cnv1, msg) == nullptr); + { + std::unique_ptr xptr = tpcnv_null.createTransient (cnv3, "key", msg); + assert (xptr->m_a == 10); + } + assert (tpcnv_null.createTransient (cnv1, "key", msg) == nullptr); - assert (tpcnv_null.persToTrans (cnv3, &x2, msg)); + assert (tpcnv_null.persToTrans (cnv3, &x2, "key", msg)); assert (x2.m_a == 10); - assert (!tpcnv_null.persToTrans (cnv1, &x2, msg)); + assert (!tpcnv_null.persToTrans (cnv1, &x2, "key", msg)); } diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvList_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvList_test.cxx index b1cc8a859733f99b70cf8413a003580091010751..4788bcf513dceb14326d253943bdc2395c4db137 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvList_test.cxx +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvList_test.cxx @@ -1,8 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration */ - -// $Id$ /** * @file AthenaPoolCnvSvc/test/TPCnvList_test.cxx * @author scott snyder @@ -16,6 +14,7 @@ #include "AthenaPoolCnvSvcTestDict.h" #include "GaudiKernel/MsgStream.h" #include "TSystem.h" +#include "TestConverterBase.h" #include #include #include @@ -25,11 +24,16 @@ using namespace AthenaPoolCnvSvcTest; class XCnv_p1 + : public TestConverterBase { public: typedef X Trans_t; typedef X_p1 Pers_t; + X* createTransientWithKey (const X_p1* pers, const std::string&, MsgStream& log) + { + return createTransient (pers, log); + } X* createTransient (const X_p1* pers, MsgStream&) { return new X(pers->m_a*2); } @@ -41,11 +45,16 @@ public: class XCnv_p2 + : public TestConverterBase { public: typedef X Trans_t; typedef X_p2 Pers_t; + X* createTransientWithKey (const X_p2* pers, const std::string&, MsgStream& log) + { + return createTransient (pers, log); + } X* createTransient (const X_p2* pers, MsgStream&) { return new X(pers->m_a*3); } @@ -88,36 +97,38 @@ void test1() XCnv_p1, T_TPCnvNull > tpcnv; - X* x = nullptr; X x2(0); TestConverter cnv1 (X_p1_guid); - x = tpcnv.createTransient (cnv1, msg); - assert (x->m_a == 20); - delete x; + { + std::unique_ptr xptr = tpcnv.createTransient (cnv1, "key", msg); + assert (xptr->m_a == 20); + } - assert (tpcnv.persToTrans (cnv1, &x2, msg)); + assert (tpcnv.persToTrans (cnv1, &x2, "key", msg)); assert (x2.m_a == 20); TestConverter cnv2 (X_p2_guid); - x = tpcnv.createTransient (cnv2, msg); - assert (x->m_a == 30); - delete x; + { + std::unique_ptr xptr = tpcnv.createTransient (cnv2, "key", msg); + assert (xptr->m_a == 30); + } - assert (tpcnv.persToTrans (cnv2, &x2, msg)); + assert (tpcnv.persToTrans (cnv2, &x2, "key", msg)); assert (x2.m_a == 30); TestConverter cnv0 (X_guid); - x = tpcnv.createTransient (cnv0, msg); - assert (x->m_a == 10); - delete x; + { + std::unique_ptr xptr = tpcnv.createTransient (cnv0, "key", msg); + assert (xptr->m_a == 10); + } - assert (tpcnv.persToTrans (cnv0, &x2, msg)); + assert (tpcnv.persToTrans (cnv0, &x2, "key", msg)); assert (x2.m_a == 10); TestConverter cnvx ("B3FCEE90-66FC-4AE1-A81B-5257A0306EF8"); - assert (tpcnv.createTransient (cnvx, msg) == nullptr); - assert (!tpcnv.persToTrans (cnvx, &x2, msg)); + assert (tpcnv.createTransient (cnvx, "key", msg) == nullptr); + assert (!tpcnv.persToTrans (cnvx, &x2, "key", msg)); } diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolCreateFuncs_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolCreateFuncs_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..7737866a1535b2c60f266775f58c2fc210d3c23c --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolCreateFuncs_test.cxx @@ -0,0 +1,120 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ +/** + * @file AthenaPoolCnvSvc/test/T_AthenaPoolCreateFuncs_test.cxx + * @author scott snyder + * @date Sep, 2019 + * @brief Tests for T_AthenaPoolCreateFuncs_test. + */ + + +#undef NDEBUG +#include "AthenaPoolCnvSvc/T_AthenaPoolCreateFuncs.h" +#include "GaudiKernel/MsgStream.h" +#include "TestConverterBase.h" +#include +#include + + +struct X +{ + X() {} + X (int x, const std::string& key) : m_x(x), m_key(key) {} + int m_x = 0; + std::string m_key; +}; +struct X_p1 +{ + X_p1() {} + X_p1 (int x, const std::string& key) : m_x(x), m_key(key) {} + int m_x = 0; + std::string m_key; +}; + + +class TPCnv1 + : public TestConverterBase +{ +public: + typedef X Trans_t; + typedef X_p1 Pers_t; + + X_p1* createPersistentWithKey (const X* x, const std::string& key, MsgStream&) + { + return new X_p1 (x->m_x, key); + } + + + X* createTransientWithKey (const X_p1* xp, const std::string& key, MsgStream&) + { + return new X (xp->m_x, key); + } +}; + + +class TPCnv2 +{ +public: + typedef X Trans_t; + typedef X_p1 Pers_t; + + void transToPers (const X* x, X_p1* xp, MsgStream&) + { + xp->m_x = x->m_x; + xp->m_key = x->m_key; + } + + void persToTrans (const X_p1* xp, X* x, MsgStream&) + { + x->m_x = xp->m_x; + x->m_key = xp->m_key; + } +}; + + +void test1() +{ + std::cout << "test1\n"; + MsgStream msg (nullptr, ""); + X x (1, "x"); + X_p1 xp (2, "xp"); + TPCnv1 cnv1; + { + std::unique_ptr xp_ptr = + AthenaPoolCnvSvc::createPersistent (cnv1, &x, "key", msg); + assert (xp_ptr->m_x == 1); + assert (xp_ptr->m_key == "key"); + } + + { + std::unique_ptr x_ptr = + AthenaPoolCnvSvc::createTransient (cnv1, &xp, "key", msg); + assert (x_ptr->m_x == 2); + assert (x_ptr->m_key == "key"); + } + + TPCnv2 cnv2; + { + std::unique_ptr xp_ptr = + AthenaPoolCnvSvc::createPersistent (cnv2, &x, "key", msg); + assert (xp_ptr->m_x == 1); + assert (xp_ptr->m_key == "x"); + } + + { + std::unique_ptr x_ptr = + AthenaPoolCnvSvc::createTransient (cnv2, &xp, "key", msg); + assert (x_ptr->m_x == 2); + assert (x_ptr->m_key == "xp"); + } +} + + +int main() +{ + std::cout << "AthenaPoolCnvSvc/T_AthenaPoolCreateFuncs_test\n"; + test1(); + return 0; +} + diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolTPCnvCnv_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolTPCnvCnv_test.cxx index c519b7d3cc00c85405f841ec2c86289d60f71ece..3b835aef78183e635dcd43c1d48ff97870b5df01 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolTPCnvCnv_test.cxx +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolTPCnvCnv_test.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration */ // $Id$ @@ -127,7 +127,7 @@ void test1 (ISvcLocator* svcloc, TestCnvSvc& /*testsvc*/) trans.push_back (new X(i)); { - XCont_p2* pers2 = cnv.createPersistent (&trans); + XCont_p2* pers2 = cnv.createPersistentWithKey (&trans, "key"); assert (pers2->m_v.size() == N); for (size_t i = 0; i < N; i++) assert (pers2->m_v[i].m_a == static_cast(i*10)); diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestConverterBase.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestConverterBase.h new file mode 100644 index 0000000000000000000000000000000000000000..6ebf8fb9b507e163c348321325297690b0ee0207 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestConverterBase.h @@ -0,0 +1,45 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. +/* + * Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration. + */ +/** + * @file AthenaPoolCnvSvc/TestConverterBase.h + * @author scott snyder + * @date Sep, 2019 + * @brief Dummy base class for test converters. + */ + + +#ifndef ATHENAPOOLCNVSVC_TESTCONVERTERBASE_H +#define ATHENAPOOLCNVSVC_TESTCONVERTERBASE_H + + +#include "AthenaPoolCnvSvc/ITPConverter.h" + + +class TestConverterBase + : public ITPConverter +{ +public: + virtual void persToTransUntyped(const void*, void*, MsgStream&) override + { std::abort(); } + virtual void transToPersUntyped(const void*, void*, MsgStream&) override + { std::abort(); } + virtual const std::type_info& transientTInfo() const override + { std::abort(); } + virtual const std::type_info& persistentTInfo() const override + { std::abort(); } + virtual void setTopConverter(TopLevelTPCnvBase*, const TPObjRef::typeID_t&) override + { std::abort(); } + virtual void setRuntimeTopConverter(TopLevelTPCnvBase*) override + { std::abort(); } + virtual const TPObjRef::typeID_t& typeID() const override + { std::abort(); } + virtual const std::type_info& transBaseTInfo() const override + { std::abort(); } + virtual void reservePStorage(size_t) override + { std::abort(); } +}; + + +#endif // not ATHENAPOOLCNVSVC_TESTCONVERTERBASE_H diff --git a/Database/TPTools/TPTools/TPConverter.h b/Database/TPTools/TPTools/TPConverter.h index 24a6cb9e4e2dab5306162874454cded62aaf81de..87ca6133be8a662c7c834cf00bc42e78f1a9d58e 100644 --- a/Database/TPTools/TPTools/TPConverter.h +++ b/Database/TPTools/TPTools/TPConverter.h @@ -336,6 +336,37 @@ public: */ virtual void transToPers(const TRANS* transObj, PERS* persObj, MsgStream &log) = 0; + /** Convert persistent representation to transient one. Copies data + members from persistent object to an existing transient one. + Needs to be implemented by the developer on the actual converter. + @param persObj [IN] persistent object + @param transObj [IN] transient object + @param key [IN] SG key of object being read. + @param log [IN] output message stream + */ + virtual void persToTransWithKey(const PERS* persObj, TRANS* transObj, + const std::string& /*key*/, + MsgStream &log) + { + return persToTrans (persObj, transObj, log); + } + + + /** Convert transient representation to persistent one. Copies data + members from transient object to an existing persistent one. + Needs to be implemented by the developer on the actual converter. + @param transObj [IN] transient object + @param persObj [IN] persistent object + @param key [IN] SG key of object being written. + @param log [IN] output message stream + */ + virtual void transToPersWithKey(const TRANS* transObj, PERS* persObj, + const std::string& /*key*/, + MsgStream &log) + { + return transToPers (transObj, persObj, log); + } + /// @copydoc ITPCnvBase::persToTransUntyped() virtual void persToTransUntyped(const void* pers, void* trans, @@ -367,6 +398,17 @@ public: */ virtual PERS* createPersistent(const TRANS* transObj, MsgStream &log); + /** Create persistent representation of a transient object, with SG key. + Simply creates a new persistent object and calls transToPersWithKey() + @param transObj [IN] transient object + @param key [IN] SG key of object being written + @param log [IN] output message stream + @return the created persistent representation + */ + virtual PERS* createPersistentWithKey(const TRANS* transObj, + const std::string& key, + MsgStream &log); + /** Convert transient object to persistent representation. Stores the result in the storage vector of the top-level object and returns a TP Ref to it. @@ -510,6 +552,15 @@ public: */ virtual TRANS* createTransient(const PERS* persObj, MsgStream &log); + /** Create transient representation of a persistent object, with SG key. + Simply creates a new transient object and calls persToTransWithKey() + @param persObj [IN] persistent object + @param key [IN] SG key of object being read + @param log [IN] output message stream + @return the created transient object + */ + virtual TRANS* createTransientWithKey(const PERS* persObj, const std::string& key, MsgStream &log); + /** Internal interface method that is used to invoke the real conversion method (createTransient) @param index [IN] index of the persistent object in the storage vector @@ -607,6 +658,87 @@ public: }; +/** @class TPConverterWithKeyBase + TP Converter template for a "regular" type. + This provides interfaces allowing the SG key to be passed to the converters. +*/ +template< class TRANS, class PERS > +class TPConverterWithKeyBase + : public TPConverterConstBase< TRANS, PERS > +{ +public: + using TPConverterConstBase< TRANS, PERS >::transToPers; + using TPConverterConstBase< TRANS, PERS >::persToTrans; + + // To shorten using declarations in derived classes. + using base_class = TPConverterWithKeyBase; + + + /** Convert persistent representation to transient one. Copies data + members from persistent object to an existing transient one. + Needs to be implemented by the developer on the actual converter. + @param persObj [IN] persistent object + @param transObj [IN] transient object + @param key [IN] SG key of the object being read. + @param log [IN] output message stream + */ + virtual void persToTransWithKey (const PERS* persObj, + TRANS* transObj, + const std::string& key, + MsgStream &log) const = 0; + + + /** Convert transient representation to persistent one. Copies data + members from transient object to an existing persistent one. + Needs to be implemented by the developer on the actual converter. + @param transObj [IN] transient object + @param persObj [IN] persistent object + @param key [IN] SG key of the object being written. + @param log [IN] output message stream + */ + virtual void transToPersWithKey (const TRANS* transObj, + PERS* persObj, + const std::string& key, + MsgStream &log) const = 0; + + + // These call through to the const implementations. + virtual void persToTransWithKey (const PERS* persObj, + TRANS* transObj, + const std::string& key, + MsgStream &log) override final + { + return const_cast(this)->persToTransWithKey (persObj, transObj, key, log); + } + + + virtual void transToPersWithKey (const TRANS* transObj, + PERS* persObj, + const std::string& key, + MsgStream &log) override final + { + return const_cast(this)->transToPersWithKey (transObj, persObj, key, log); + } + + + // It's an error if the non-key versions get called. + virtual void persToTrans(const PERS* /*persObj*/, + TRANS* /*transObj*/, + MsgStream& /*log*/) const override final + { + throw std::runtime_error ("persToTrans called where persToTransWithKey required."); + } + + + virtual void transToPers(const TRANS* /*transObj*/, + PERS* /*persObj*/, + MsgStream& /*log*/) const override final + { + throw std::runtime_error ("transToPers called where transToPersWithKey required."); + } +}; + + // -------------------------------------------------------------- /** @class TPPtrVectorCnv diff --git a/Database/TPTools/TPTools/TPConverter.icc b/Database/TPTools/TPTools/TPConverter.icc index 36e8b801bf350768ac417a367ccd1dedf3de994e..ac4090551527ef9b83a4fa9c3f8e3dd6764747b3 100644 --- a/Database/TPTools/TPTools/TPConverter.icc +++ b/Database/TPTools/TPTools/TPConverter.icc @@ -26,6 +26,15 @@ createPersistent(const TRANS* transObj, MsgStream &log) { } +template< class TRANS_BASE, class TRANS, class PERS > +PERS* TPAbstractPolyCnvBase:: +createPersistentWithKey(const TRANS* transObj, const std::string& key, MsgStream &log) { + std::unique_ptr pers(new PERS()); + transToPersWithKey(transObj, pers.get(), key, log); + return(pers.release()); +} + + template< class TRANS_BASE, class TRANS, class PERS > TPObjRef TPAbstractPolyCnvBase:: @@ -62,7 +71,7 @@ toPersistent_impl( const TRANS *trans, MsgStream &log ) class IdentifiableContainerBase; template< class TRANS_BASE, class TRANS, class PERS > TRANS* TPPolyCnvBase:: -createTransient(const PERS* persObj [[maybe_unused]], MsgStream &log) +createTransient ([[maybe_unused]] const PERS* persObj, MsgStream &log) { if constexpr(std::is_base_of< IdentifiableContainerBase, TRANS>::value && !std::is_default_constructible::value) { log << "IdentifiableContainerBase is not compatable with createTransient" << std::endl; @@ -77,6 +86,26 @@ createTransient(const PERS* persObj [[maybe_unused]], MsgStream &log) } } +class IdentifiableContainerBase; +template< class TRANS_BASE, class TRANS, class PERS > +TRANS* TPPolyCnvBase:: +createTransientWithKey ([[maybe_unused]] const PERS* persObj, + const std::string& key, + MsgStream& log) +{ + if constexpr(std::is_base_of< IdentifiableContainerBase, TRANS>::value && !std::is_default_constructible::value) { + log << "IdentifiableContainerBase is not compatable with createTransient" << std::endl; + return nullptr; + } + else{ + // this is by default equivalent to 'new TRANS()' + std::unique_ptr trans = std::make_unique(); + + this->persToTransWithKey(persObj, trans.get(), key, log); + return( trans.release() ); + } +} + //--------------------------------------------------------------------