ATLAS Offline Software
Loading...
Searching...
No Matches
T_AthenaPoolViewVectorCnv.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3*/
4/**
5 * @file AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.icc
6 * @author scott snyder <snyder@bnl.gov>
7 * @date Jan, 2016
8 * @brief Athena pool converter for a ViewVector class.
9 */
10
11
12#include "CxxUtils/no_sanitize_undefined.h"
13
14
15/**
16 * @brief Constructor.
17 * @param svcloc The Gaudi service locator.
18 */
19template <class DV>
20T_AthenaPoolViewVectorCnv<DV>::T_AthenaPoolViewVectorCnv (ISvcLocator* svcloc)
21 : Base (svcloc)
22{
23}
24
25
26template <class DV>
27std::vector<pool::Guid>
28T_AthenaPoolViewVectorCnv<DV>::initGuids (const std::type_info& ti) const
29{
30 std::vector<Guid> guids;
31
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);
35 if (!typ)
36 AthenaPoolCnvSvc::throwExcNoDictForClass (ti);
37 guids.push_back (pool::DbReflex::guid (typ));
38
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'.
44
45 std::string name = typ.Name();
46 std::string::size_type vpos = 0;
47 while ((vpos = name.find ("_v", vpos)) != std::string::npos) {
48 vpos += 2;
49 std::string::size_type vpos2 = vpos;
50 if (isdigit (name[vpos2])) {
51 ++vpos2;
52 while (vpos2 < name.size() && isdigit (name[vpos2]))
53 ++vpos2;
54 if (vpos2 < name.size() && name[vpos2] == '>') {
55 int vers = atoi (name.substr (vpos, vpos2-vpos).c_str());
56 while (--vers > 0) {
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);
59 if (typ2)
60 guids.push_back (pool::DbReflex::guid (typ2));
61 }
62 }
63 }
64 }
65
66 return guids;
67}
68
69
70/**
71 * @brief Standard Gaudi initialize method.
72 */
73template <class DV>
74StatusCode
75T_AthenaPoolViewVectorCnv<DV>::initialize()
76{
77 CHECK( Base::initialize() );
78
79 m_guids = initGuids (typeid(pers_t));
80 m_guids2 = initGuids (typeid(pers2_t));
81
82 return StatusCode::SUCCESS;
83}
84
85
86/**
87 * @brief Convert a transient object to persistent form.
88 * @param trans The transient object to convert.
89 *
90 * Returns a newly-allocated persistent object.
91 */
92template <class DV>
93typename T_AthenaPoolViewVectorCnv<DV>::pers_t*
94T_AthenaPoolViewVectorCnv<DV>::createPersistent( trans_t* trans )
95{
96 AthenaPoolCnvSvc::debugCreatePersistent (ClassID_traits<DV>::ID());
97 pers_t* pers = new pers_t (*trans);
98 pers->setClearOnPersistent();
99 return pers;
100}
101
102
103/**
104 * @brief Read the persistent object and convert it to transient.
105 *
106 * Returns a newly-allocated transient object.
107 * Errors are reported by raising exceptions.
108 */
109template <class DV>
110typename T_AthenaPoolViewVectorCnv<DV>::trans_t*
111T_AthenaPoolViewVectorCnv<DV>::createTransient NO_SANITIZE_UNDEFINED ()
112{
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.
129 delete v.release();
130 v = std::move (v2);
131 // root read rule doesn't do anything in this case.
132 v->toTransient();
133 }
134 v->clearPersistent();
135 return v.release();
136 }
137 }
138
139
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();
149 return vv;
150 }
151 }
152
153 // Didn't recognize the ID.
154 AthenaPoolCnvSvc::throwExcUnsupportedVersion (typeid(pers_t),
155 this->m_i_poolToken->classID());
156 return 0;
157}