2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
5 * @file AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief Athena pool converter for a ViewVector class.
12#include "CxxUtils/no_sanitize_undefined.h"
17 * @param svcloc The Gaudi service locator.
20T_AthenaPoolViewVectorCnv<DV>::T_AthenaPoolViewVectorCnv (ISvcLocator* svcloc)
28T_AthenaPoolViewVectorCnv<DV>::initGuids (const std::type_info& ti) const
30 std::vector<Guid> guids;
32 // Make a list of all the guids that this converter can read.
33 // First, add the entry for pers_t.
34 RootType temp = RootType(ti);
35 RootType typ = (temp) ? temp : RootType(pool::DbTypeInfo::typeName(ti));
37 AthenaPoolCnvSvc::throwExcNoDictForClass (ti);
38 guids.push_back (pool::DbReflex::guid (typ));
40 // Now look for entries for previous versions.
41 // Look for a version tag in the type name and try replacing it with
42 // previous versions. Eg, if the name for pers_t contains `_v3',
43 // then we also look for guids for the same name with `_v3' replaced
44 // by `_v2' and `_v1'.
46 std::string name = typ.Name();
47 std::string::size_type vpos = 0;
48 while ((vpos = name.find ("_v", vpos)) != std::string::npos) {
50 std::string::size_type vpos2 = vpos;
51 if (isdigit (name[vpos2])) {
53 while (vpos2 < name.size() && isdigit (name[vpos2]))
55 if (vpos2 < name.size() && name[vpos2] == '>') {
56 int vers = atoi (name.substr (vpos, vpos2-vpos).c_str());
58 std::string name2 = name.substr(0,vpos) + CxxUtils::strformat("%d", vers) + name.substr(vpos2,std::string::npos);
59 RootType typ2 = RootType(name2);
61 guids.push_back (pool::DbReflex::guid (typ2));
72 * @brief Standard Gaudi initialize method.
76T_AthenaPoolViewVectorCnv<DV>::initialize()
78 CHECK( Base::initialize() );
80 m_guids = initGuids (typeid(pers_t));
81 m_guids2 = initGuids (typeid(pers2_t));
83 return StatusCode::SUCCESS;
88 * @brief Convert a transient object to persistent form.
89 * @param trans The transient object to convert.
91 * Returns a newly-allocated persistent object.
94typename T_AthenaPoolViewVectorCnv<DV>::pers_t*
95T_AthenaPoolViewVectorCnv<DV>::createPersistent( trans_t* trans )
97 AthenaPoolCnvSvc::debugCreatePersistent (ClassID_traits<DV>::ID());
98 pers_t* pers = new pers_t (*trans);
99 pers->setClearOnPersistent();
105 * @brief Read the persistent object and convert it to transient.
107 * Returns a newly-allocated transient object.
108 * Errors are reported by raising exceptions.
111typename T_AthenaPoolViewVectorCnv<DV>::trans_t*
112T_AthenaPoolViewVectorCnv<DV>::createTransient NO_SANITIZE_UNDEFINED (const Token* token)
114 AthenaPoolCnvSvc::debugCreateTransient (ClassID_traits<DV>::ID());
115 // See if we're looking at one of the guids we can handle.
116 // FIXME: For old persistent versions, this works by essentially doing
117 // a reinterpret_cast from the version on the file to the current version.
118 // That works for current ElementLink classes, but it's not very nice.
119 // This also gets a ubsan warning with gcc6.2, so we suppress it
120 // for this function.
121 for (const Guid& guid : m_guids) {
122 if( this->compareClassGuid(token, guid ) ) {
123 std::unique_ptr<pers_t> v (this->template poolReadObject< pers_t >(token));
124 if (guid != m_guids.front()) {
125 auto v2 = std::make_unique<pers_t> (*v);
126 // Strictly superfluous, but allows suppressing the ubsan warning
127 // about implicit reinterpret_cast by moving the locus into this
128 // function (which we've tagged with NO_SANITIZE_UNDEFINED)
129 // rather than in a libtsdc++ function.
132 // root read rule doesn't do anything in this case.
135 v->clearPersistent();
141 for (const Guid& guid : m_guids2) {
142 if( this->compareClassGuid(token, guid ) ) {
143 std::unique_ptr<pers2_t> v (this->template poolReadObject< pers2_t >(token));
144 auto c = std::make_unique<ConstDataVector<trans_t> > (*v);
145 // FIXME: To get rid of this @c const_cast, the converter interfaces
146 // need to be changed to allow returning a const pointer
147 // all the way back to StoreGate.
148 trans_t* vv ATLAS_THREAD_SAFE = const_cast<trans_t*>(c.release()->asDataVector());
149 vv->clearPersistent();
154 // Didn't recognize the ID.
155 AthenaPoolCnvSvc::throwExcUnsupportedVersion (typeid(pers_t),