ATLAS Offline Software
Loading...
Searching...
No Matches
TPConverter.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "GaudiKernel/MsgStream.h"
6
7#include <stdexcept>
8#include <memory>
9
10
11//--------------------------------------------------------------------
12/*
13 Default implementation of the 2 methods that create new objects:
14 createTransient() and createPersistent()
15 The 2 remaining methods persToTrans() and transToPers() do not have
16 default implementations, they needs to be supplied by the user-defined
17 superclass
18*/
19
20template< class TRANS_BASE, class TRANS, class PERS >
21PERS* TPAbstractPolyCnvBase<TRANS_BASE, TRANS, PERS>::
22createPersistent(const TRANS* transObj, MsgStream &log) {
23 std::unique_ptr<PERS> pers(new PERS());
24 transToPers(transObj, pers.get(), log);
25 return(pers.release());
26}
27
28
29template< class TRANS_BASE, class TRANS, class PERS >
30PERS* TPAbstractPolyCnvBase<TRANS_BASE, TRANS, PERS>::
31createPersistentWithKey(const TRANS* transObj, const std::string& key, MsgStream &log) {
32 std::unique_ptr<PERS> pers(new PERS());
33 transToPersWithKey(transObj, pers.get(), key, log);
34 return(pers.release());
35}
36
37
38template< class TRANS_BASE, class TRANS, class PERS >
39TPObjRef
40TPAbstractPolyCnvBase<TRANS_BASE, TRANS, PERS>::
41toPersistentWithKey_impl( const TRANS *trans,
42 const std::string& key,
43 MsgStream &log )
44{
45 // make sure there is a storage object
46 if( !this->topConverter()->hasTLPersObject() ) {
47 this->topConverter()->createTLPersObject();
48 }
49 // make a new space in the storage vector
50 size_t size = m_pStorage->size();
51 // cppcheck-suppress uninitvar
52 m_pStorage->resize( size+1 );
53
54 if( m_recursive ) {
55 // for recursive calls use temporary persistent object
56 // as the vector storage may be reallocated in a recursive invocation
57 PERS tmp_pers;
58 transToPersWithKey( trans, &tmp_pers, key, log);
59 // do NOT use back() here (the vector has already grown)
60 m_pStorage->operator[]( size ) = std::move(tmp_pers);
61 } else {
62 if( m_curRecLevel > 0 && !m_ignoreRecursion) {
63 throw std::runtime_error(
64 std::string("T/P converter: ") + typeid(*this).name()
65 + " called recursively! -> enable the recursive flag" );
66 }
67 m_curRecLevel++;
68 transToPersWithKey( trans, &m_pStorage->back(), key, log);
69 m_curRecLevel--;
70 }
71 return TPObjRef( this->m_pStorageTID, size );
72}
73namespace EventContainers{
74class IdentifiableContainerBase;
75}
76class IdentifiableValueContainerBase;
77template< class TRANS_BASE, class TRANS, class PERS >
78TRANS* TPPolyCnvBase<TRANS_BASE, TRANS, PERS>::
79createTransient ([[maybe_unused]] const PERS* persObj, MsgStream &log)
80{
81 if constexpr(std::is_base_of< EventContainers::IdentifiableContainerBase, TRANS>::value && !std::is_default_constructible<TRANS>::value) {
82 log << "IdentifiableContainerBase is not compatable with createTransient" << std::endl;
83 return nullptr;
84 }else if constexpr(std::is_base_of< IdentifiableValueContainerBase, TRANS>::value && !std::is_default_constructible<TRANS>::value){
85 log << "IdentifiableValueContainerBase is not compatable with createTransient" << std::endl;
86 return nullptr;
87 }
88 else{
89 // this is by default equivalent to 'new TRANS()'
90 std::unique_ptr<TRANS> trans = std::make_unique<TRANS>();
91
92 this->persToTrans(persObj, trans.get(), log);
93 return( trans.release() );
94 }
95}
96
97template< class TRANS_BASE, class TRANS, class PERS >
98TRANS* TPPolyCnvBase<TRANS_BASE, TRANS, PERS>::
99createTransientWithKey ([[maybe_unused]] const PERS* persObj,
100 const std::string& key,
101 MsgStream& log)
102{
103 if constexpr(std::is_base_of< EventContainers::IdentifiableContainerBase, TRANS>::value && !std::is_default_constructible<TRANS>::value) {
104 log << "IdentifiableContainerBase is not compatable with createTransient" << std::endl;
105 return nullptr;
106 }else if constexpr(std::is_base_of< IdentifiableValueContainerBase, TRANS>::value && !std::is_default_constructible<TRANS>::value){
107 log << "IdentifiableValueContainerBase is not compatable with createTransient" << std::endl;
108 return nullptr;
109 }
110 else{
111 // this is by default equivalent to 'new TRANS()'
112 std::unique_ptr<TRANS> trans = std::make_unique<TRANS>();
113
114 this->persToTransWithKey(persObj, trans.get(), key, log);
115 return( trans.release() );
116 }
117}
118
119
120template< class TRANS, class PERS >
121TRANS* TPConverterConstBase<TRANS, PERS>::createTransientConst
122 (const PERS* persObj, MsgStream& log) const
123{
124 if constexpr(std::is_base_of< EventContainers::IdentifiableContainerBase, TRANS>::value && !std::is_default_constructible<TRANS>::value) {
125 log << "IdentifiableContainerBase is not compatable with createTransient" << std::endl;
126 return nullptr;
127 }else if constexpr(std::is_base_of< IdentifiableValueContainerBase, TRANS>::value && !std::is_default_constructible<TRANS>::value){
128 log << "IdentifiableValueContainerBase is not compatable with createTransient" << std::endl;
129 return nullptr;
130 }
131 else{
132 // this is by default equivalent to 'new TRANS()'
133 std::unique_ptr<TRANS> trans = std::make_unique<TRANS>();
134
135 this->persToTrans(persObj, trans.get(), log);
136 return( trans.release() );
137 }
138}
139
140
141template< class TRANS, class PERS >
142PERS* TPConverterConstBase<TRANS, PERS>::createPersistentConst
143 (const TRANS* transObj, MsgStream& log) const
144{
145 std::unique_ptr<PERS> pers(new PERS());
146 transToPers(transObj, pers.get(), log);
147 return(pers.release());
148}
149
150
151//--------------------------------------------------------------------
152/*
153 persToTrans() and transToPers() implementation for a converter between
154 transient vector of T* (like DataVector<T>) and persistent vector<T>
155*/
156template<class TRANS, class PERS, class CONV>
157void TPCnvVector<TRANS, PERS, CONV>::persToTrans(const PERS* persVect,
158 TRANS* transVect,
159 MsgStream &log)
160{
161 typename PERS::const_iterator it;
162 transVect->clear();
163 transVect->reserve(persVect->size());
164 for (it = persVect->begin(); it != persVect->end(); ++it) {
165 transVect->push_back( m_elementCnv.createTransient(&(*it), log) );
166 }
167}
168
169template<class TRANS, class PERS, class CONV>
170void TPCnvVector<TRANS, PERS, CONV>::transToPers(const TRANS* transVect,
171 PERS* persVect,
172 MsgStream &log) {
173 size_t size = transVect->size();
174 persVect->resize(size);
175 // convert vector entries one by one
176 typename TRANS::const_iterator it = transVect->begin();
177 typename PERS::iterator pit = persVect->begin();
178 while(size) {
179 m_elementCnv.transToPers( *it, &(*pit), log );
180 ++pit; ++it; --size;
181 }
182}
183
184
185template<class TRANS, class PERS, class CONV>
186void TPCnvVectorConst<TRANS, PERS, CONV>::persToTrans(const PERS* persVect,
187 TRANS* transVect,
188 MsgStream &log) const {
189 CONV element_cnv;
190 typename PERS::const_iterator it;
191 transVect->clear();
192 transVect->reserve(persVect->size());
193 for (it = persVect->begin(); it != persVect->end(); ++it) {
194 transVect->push_back(element_cnv.createTransient(&(*it), log));
195 }
196}
197
198template<class TRANS, class PERS, class CONV>
199void TPCnvVectorConst<TRANS, PERS, CONV>::transToPers(const TRANS* transVect,
200 PERS* persVect,
201 MsgStream &log) const {
202 size_t size = transVect->size();
203 persVect->resize(size);
204 // convert vector entries one by one
205 CONV element_cnv;
206 typename TRANS::const_iterator it = transVect->begin();
207 typename PERS::iterator pit = persVect->begin();
208 while(size) {
209 element_cnv.transToPers( *it, &(*pit), log );
210 ++pit; ++it; --size;
211 }
212}
213
214
215
216/*
217 persToTrans() and transToPers() implementation for a converter between
218 transient vector of T and persistent vector<T>
219*/
220template<class TRANS, class PERS, class CONV>
221void TPCnvStdVector<TRANS, PERS, CONV>::persToTrans(const PERS* persVect,
222 TRANS* transVect,
223 MsgStream &log)
224{
225 CONV element_cnv;
226 size_t i = persVect->size();
227 transVect->resize( i );
228 typename PERS::const_iterator pit = persVect->begin();
229 typename TRANS::iterator it = transVect->begin();
230 while(i) {
231 element_cnv.persToTrans( &(*pit), &(*it), log );
232 ++it; ++pit; --i;
233 }
234}
235
236template<class TRANS, class PERS, class CONV>
237void TPCnvStdVector<TRANS, PERS, CONV>::transToPers(const TRANS* transVect,
238 PERS* persVect,
239 MsgStream &log)
240{
241 CONV element_cnv;
242 size_t i = transVect->size();
243 persVect->resize( i );
244 typename TRANS::const_iterator it = transVect->begin();
245 typename PERS::iterator pit = persVect->begin();
246 while(i) {
247 element_cnv.transToPers( &(*it), &(*pit), log );
248 ++pit; ++it; --i;
249 }
250}
251
252
253template<class TRANS, class PERS, class CONV>
254void TPCnvStdVectorConst<TRANS, PERS, CONV>::persToTrans(const PERS* persVect,
255 TRANS* transVect,
256 MsgStream &log) const
257{
258 CONV element_cnv;
259 size_t i = persVect->size();
260 transVect->resize( i );
261 typename PERS::const_iterator pit = persVect->begin();
262 typename TRANS::iterator it = transVect->begin();
263 while(i) {
264 element_cnv.persToTrans( &(*pit), &(*it), log );
265 ++it; ++pit; --i;
266 }
267}
268
269template<class TRANS, class PERS, class CONV>
270void TPCnvStdVectorConst<TRANS, PERS, CONV>::transToPers(const TRANS* transVect,
271 PERS* persVect,
272 MsgStream &log) const
273{
274 CONV element_cnv;
275 size_t i = transVect->size();
276 persVect->resize( i );
277 typename TRANS::const_iterator it = transVect->begin();
278 typename PERS::iterator pit = persVect->begin();
279 while(i) {
280 element_cnv.transToPers( &(*it), &(*pit), log );
281 ++pit; ++it; --i;
282 }
283}
284
285//--------------------------------------------------------------------
286/*
287 persToTrans() and transToPers() implementation for a converter between
288 transient AtlasHitsVector of T* and persistent vector<T>
289*/
290template<class TRANS, class PERS, class CONV>
291void T_AtlasHitsVectorCnv<TRANS, PERS, CONV>::persToTrans(const PERS* persCont,
292 TRANS* transCont,
293 MsgStream &log) {
294 CONV element_cnv;
295 typename TRANS::iterator it;
296 typename PERS::const_iterator ip;
297 const typename PERS::HitVector& pvec = persCont->getVector();
298 transCont->clear();
299 transCont->resize( pvec.size() );
300 for (it=transCont->begin(), ip = pvec.begin(); ip != pvec.end(); ++ip, ++it) {
301 element_cnv.persToTrans( &*ip, &*it, log );
302 }
303 transCont->setName(persCont->name() );
304}
305
306template<class TRANS, class PERS, class CONV>
307void T_AtlasHitsVectorCnv<TRANS, PERS, CONV>::transToPers(const TRANS* transCont,
308 PERS* persCont,
309 MsgStream &log) {
310 size_t size = transCont->size();
311 typename PERS::HitVector& pvec = persCont->m_cont;
312 pvec.resize(size);
313 // convert vector entries one by one
314 CONV element_cnv;
315 typename TRANS::const_iterator it = transCont->begin();
316 typename PERS::iterator pit = pvec.begin();
317 while(size) {
318 element_cnv.transToPers( &(*it), &(*pit), log );
319 ++it; ++pit; --size;
320 }
321 persCont->m_name = transCont->Name();
322}
323
324
325//--------------------------------------------------------------------
326/*
327 persToTrans() and transToPers() implementation for a converter between
328 transient AthenaHitsVector of T* and persistent vector<T>
329*/
330template<class TRANS, class PERS, class CONV>
331void T_AthenaHitsVectorCnv<TRANS, PERS, CONV>::persToTrans(const PERS* persCont,
332 TRANS* transCont,
333 MsgStream &log) {
334 CONV element_cnv;
335 typename PERS::const_iterator it;
336 const typename PERS::HitVector& pvec = persCont->getVector();
337 transCont->clear();
338 transCont->reserve(pvec.size());
339 for (it = pvec.begin(); it != pvec.end(); ++it) {
340 transCont->push_back(element_cnv.createTransient(&(*it), log));
341 }
342 transCont->setName(persCont->name() );
343}
344
345template<class TRANS, class PERS, class CONV>
346void T_AthenaHitsVectorCnv<TRANS, PERS, CONV>::transToPers(const TRANS* transCont,
347 PERS* persCont,
348 MsgStream &log) {
349 size_t size = transCont->size();
350 typename PERS::HitVector& pvec = persCont->m_cont;
351 pvec.resize(size);
352 // convert vector entries one by one
353 CONV element_cnv;
354 typename TRANS::const_iterator it = transCont->begin();
355 typename PERS::iterator pit = pvec.begin();
356 while(size) {
357 element_cnv.transToPers( *it, &(*pit), log );
358 ++it; ++pit; --size;
359 }
360 persCont->m_name = transCont->Name();
361}
362
363
364//--------------------------------------------------------------------
365/*
366 persToTrans() and transToPers() implementation for a converter between
367 transient IdentifiableContainer<T> and persistent std::vector<T>
368 This version assumes RDO collection returns an identifier as a unsigned int.
369*/
370template<class TRANS, class PERS, class CONV>
371void TPCnvIDCont<TRANS, PERS, CONV>::persToTrans(const PERS* persCont,
372 TRANS* transCont,
373 MsgStream &log)
374{
375 typename PERS::const_iterator pers_elem;
376 for (pers_elem = persCont->begin(); pers_elem != persCont->end(); ++pers_elem) {
377 COLLECTION_t* coll = m_elementCnv.createTransient(&(*pers_elem), log);
378 // register the rdo collection in IDC
379 //typename COLLECTION_t::ID id_coll =
380 //IdentifierHash is_hash = hashFcn(id_coll);
381 unsigned int id_hash = transCont->idToHash((unsigned int)coll->identify());
382 StatusCode sc = transCont->addCollection(coll, id_hash);
383 if (sc.isFailure()) {
384 delete coll;
385 throw std::runtime_error("Failed to add collection to ID Container");
386 }
387 log << MSG::DEBUG << "TPCnvIDCont::persToTrans, collection, hash id=" << id_hash << ", added to Identifiable container." << endmsg;
388 }
389}
390
391template<class TRANS, class PERS, class CONV>
392void TPCnvIDCont<TRANS, PERS, CONV>::transToPers(const TRANS* transCont,
393 PERS* persCont,
394 MsgStream &log)
395{
396 typename TRANS::const_iterator it_Coll = transCont->begin();
397 typename TRANS::const_iterator it_CollEnd = transCont->end();
398 int entries;
399 for (entries = 0; it_Coll != it_CollEnd; ++entries, ++it_Coll) {
400 persCont->resize(entries + 1);
401 m_elementCnv.transToPers(&(**it_Coll), &(*persCont)[entries], log);
402 }
403 log << MSG::DEBUG << "TPCnvIDCont::transToPers, container size was " << entries << endmsg;
404}
405
406//--------------------------------------------------------------------
407/*
408 persToTrans() and transToPers() implementation for a converter between
409 transient IdentifiableContainer<T> and persistent std::vector<T>
410 This version assumes RDO collection returns an identifier as an Identifier
411*/
412template<class TRANS, class PERS, class CONV>
413void TPCnvIDContFromIdentifier<TRANS, PERS, CONV>::persToTrans(const PERS* persCont,
414 TRANS* transCont,
415 MsgStream &log)
416{
417 typename PERS::const_iterator pers_elem;
418 for (pers_elem = persCont->begin(); pers_elem != persCont->end(); ++pers_elem) {
419 COLLECTION_t* coll = m_elementCnv.createTransient(&(*pers_elem), log);
420 // register the rdo collection in IDC
421 //typename COLLECTION_t::ID id_coll =
422 //IdentifierHash is_hash = hashFcn(id_coll);
423 unsigned int id_hash = transCont->idToHash(coll->identify().get_identifier32().get_compact());
424 StatusCode sc = transCont->addCollection(coll, id_hash);
425 if (sc.isFailure()) {
426 delete coll;
427 throw std::runtime_error("Failed to add collection to ID Container");
428 }
429 log << MSG::DEBUG << "TPCnvIDContFromIdentifier::persToTrans, collection, hash id=" << id_hash << ", added to Identifiable container." << endmsg;
430 }
431}
432
433template<class TRANS, class PERS, class CONV>
434void TPCnvIDContFromIdentifier<TRANS, PERS, CONV>::transToPers(const TRANS* transCont,
435 PERS* persCont,
436 MsgStream &log)
437{
438 typename TRANS::const_iterator it_Coll = transCont->begin();
439 typename TRANS::const_iterator it_CollEnd = transCont->end();
440 int entries;
441 for (entries = 0; it_Coll != it_CollEnd; ++entries, ++it_Coll) {
442 persCont->resize(entries + 1);
443 m_elementCnv.transToPers(&(**it_Coll), &(*persCont)[entries], log);
444 }
445 log << MSG::DEBUG << "TPCnvIDContFromIdentifier::transToPers, container size was " << entries << endmsg;
446}