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.
20 T_AthenaPoolViewVectorCnv<DV>::T_AthenaPoolViewVectorCnv (ISvcLocator* svcloc)
27 std::vector<pool::Guid>
28 T_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 pool::TypeH typ = pool::DbReflex::forTypeInfo (ti);
36 AthenaPoolCnvSvc::throwExcNoDictForClass (ti);
37 guids.push_back (pool::DbReflex::guid (typ));
39 // Now look for entries for previous versions.
40 // Look for a version tag in the type name and try replacing it with
41 // previous versions. Eg, if the name for pers_t contains `_v3',
42 // then we also look for guids for the same name with `_v3' replaced
43 // by `_v2' and `_v1'.
45 std::string name = typ.Name();
46 std::string::size_type vpos = 0;
47 while ((vpos = name.find ("_v", vpos)) != std::string::npos) {
49 std::string::size_type vpos2 = vpos;
50 if (isdigit (name[vpos2])) {
52 while (vpos2 < name.size() && isdigit (name[vpos2]))
54 if (vpos2 < name.size() && name[vpos2] == '>') {
55 int vers = atoi (name.substr (vpos, vpos2-vpos).c_str());
57 std::string name2 = name.substr(0,vpos) + CxxUtils::strformat("%d", vers) + name.substr(vpos2,std::string::npos);
58 pool::TypeH typ2 = pool::DbReflex::forTypeName (name2);
60 guids.push_back (pool::DbReflex::guid (typ2));
71 * @brief Standard Gaudi initialize method.
75 T_AthenaPoolViewVectorCnv<DV>::initialize()
77 CHECK( Base::initialize() );
79 m_guids = initGuids (typeid(pers_t));
80 m_guids2 = initGuids (typeid(pers2_t));
82 return StatusCode::SUCCESS;
87 * @brief Convert a transient object to persistent form.
88 * @param trans The transient object to convert.
90 * Returns a newly-allocated persistent object.
93 typename T_AthenaPoolViewVectorCnv<DV>::pers_t*
94 T_AthenaPoolViewVectorCnv<DV>::createPersistent( trans_t* trans )
96 AthenaPoolCnvSvc::debugCreatePersistent (ClassID_traits<DV>::ID());
97 pers_t* pers = new pers_t (*trans);
98 pers->setClearOnPersistent();
104 * @brief Read the persistent object and convert it to transient.
106 * Returns a newly-allocated transient object.
107 * Errors are reported by raising exceptions.
110 typename T_AthenaPoolViewVectorCnv<DV>::trans_t*
111 T_AthenaPoolViewVectorCnv<DV>::createTransient NO_SANITIZE_UNDEFINED ()
113 AthenaPoolCnvSvc::debugCreateTransient (ClassID_traits<DV>::ID());
114 // See if we're looking at one of the guids we can handle.
115 // FIXME: For old persistent versions, this works by essentially doing
116 // a reinterpret_cast from the version on the file to the current version.
117 // That works for current ElementLink classes, but it's not very nice.
118 // This also gets a ubsan warning with gcc6.2, so we suppress it
119 // for this function.
120 for (const pool::Guid& guid : m_guids) {
121 if( this->compareClassGuid( guid ) ) {
122 std::unique_ptr<pers_t> v (this->template poolReadObject< pers_t >());
123 if (guid != m_guids.front()) {
124 auto v2 = std::make_unique<pers_t> (*v);
125 // Strictly superfluous, but allows suppressing the ubsan warning
126 // about implicit reinterpret_cast by moving the locus into this
127 // function (which we've tagged with NO_SANITIZE_UNDEFINED)
128 // rather than in a libtsdc++ function.
131 // root read rule doesn't do anything in this case.
134 v->clearPersistent();
140 for (const pool::Guid& guid : m_guids2) {
141 if( this->compareClassGuid( guid ) ) {
142 std::unique_ptr<pers2_t> v (this->template poolReadObject< pers2_t >());
143 auto c = std::make_unique<ConstDataVector<trans_t> > (*v);
144 // FIXME: To get rid of this @c const_cast, the converter interfaces
145 // need to be changed to allow returning a const pointer
146 // all the way back to StoreGate.
147 trans_t* vv ATLAS_THREAD_SAFE = const_cast<trans_t*>(c.release()->asDataVector());
148 vv->clearPersistent();
153 // Didn't recognize the ID.
154 AthenaPoolCnvSvc::throwExcUnsupportedVersion (typeid(pers_t),
155 this->m_i_poolToken->classID());