2 Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
5 #include "GaudiKernel/MsgStream.h"
11 //--------------------------------------------------------------------
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
20 template< class TRANS_BASE, class TRANS, class PERS >
21 PERS* TPAbstractPolyCnvBase<TRANS_BASE, TRANS, PERS>::
22 createPersistent(const TRANS* transObj, MsgStream &log) {
23 std::unique_ptr<PERS> pers(new PERS());
24 transToPers(transObj, pers.get(), log);
25 return(pers.release());
29 template< class TRANS_BASE, class TRANS, class PERS >
30 PERS* TPAbstractPolyCnvBase<TRANS_BASE, TRANS, PERS>::
31 createPersistentWithKey(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());
38 template< class TRANS_BASE, class TRANS, class PERS >
40 TPAbstractPolyCnvBase<TRANS_BASE, TRANS, PERS>::
41 toPersistentWithKey_impl( const TRANS *trans,
42 const std::string& key,
45 // make sure there is a storage object
46 if( !this->topConverter()->hasTLPersObject() ) {
47 this->topConverter()->createTLPersObject();
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 );
55 // for recursive calls use temporary persistent object
56 // as the vector storage may be reallocated in a recursive invocation
58 transToPersWithKey( trans, &tmp_pers, key, log);
59 // do NOT use back() here (the vector has already grown)
60 m_pStorage->operator[]( size ) = tmp_pers;
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" );
68 transToPersWithKey( trans, &m_pStorage->back(), key, log);
71 return TPObjRef( this->m_pStorageTID, size );
73 namespace EventContainers{
74 class IdentifiableContainerBase;
76 class IdentifiableValueContainerBase;
77 template< class TRANS_BASE, class TRANS, class PERS >
78 TRANS* TPPolyCnvBase<TRANS_BASE, TRANS, PERS>::
79 createTransient ([[maybe_unused]] const PERS* persObj, MsgStream &log)
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;
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;
89 // this is by default equivalent to 'new TRANS()'
90 std::unique_ptr<TRANS> trans = std::make_unique<TRANS>();
92 this->persToTrans(persObj, trans.get(), log);
93 return( trans.release() );
97 template< class TRANS_BASE, class TRANS, class PERS >
98 TRANS* TPPolyCnvBase<TRANS_BASE, TRANS, PERS>::
99 createTransientWithKey ([[maybe_unused]] const PERS* persObj,
100 const std::string& key,
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;
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;
111 // this is by default equivalent to 'new TRANS()'
112 std::unique_ptr<TRANS> trans = std::make_unique<TRANS>();
114 this->persToTransWithKey(persObj, trans.get(), key, log);
115 return( trans.release() );
120 template< class TRANS, class PERS >
121 TRANS* TPConverterConstBase<TRANS, PERS>::createTransientConst
122 (const PERS* persObj, MsgStream& log) const
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;
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;
132 // this is by default equivalent to 'new TRANS()'
133 std::unique_ptr<TRANS> trans = std::make_unique<TRANS>();
135 this->persToTrans(persObj, trans.get(), log);
136 return( trans.release() );
141 template< class TRANS, class PERS >
142 PERS* TPConverterConstBase<TRANS, PERS>::createPersistentConst
143 (const TRANS* transObj, MsgStream& log) const
145 std::unique_ptr<PERS> pers(new PERS());
146 transToPers(transObj, pers.get(), log);
147 return(pers.release());
151 //--------------------------------------------------------------------
153 persToTrans() and transToPers() implementation for a converter between
154 transient vector of T* (like DataVector<T>) and persistent vector<T>
156 template<class TRANS, class PERS, class CONV>
157 void TPCnvVector<TRANS, PERS, CONV>::persToTrans(const PERS* persVect,
161 typename PERS::const_iterator it;
163 transVect->reserve(persVect->size());
164 for (it = persVect->begin(); it != persVect->end(); ++it) {
165 transVect->push_back( m_elementCnv.createTransient(&(*it), log) );
169 template<class TRANS, class PERS, class CONV>
170 void TPCnvVector<TRANS, PERS, CONV>::transToPers(const TRANS* transVect,
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();
179 m_elementCnv.transToPers( *it, &(*pit), log );
185 template<class TRANS, class PERS, class CONV>
186 void TPCnvVectorConst<TRANS, PERS, CONV>::persToTrans(const PERS* persVect,
188 MsgStream &log) const {
190 typename PERS::const_iterator it;
192 transVect->reserve(persVect->size());
193 for (it = persVect->begin(); it != persVect->end(); ++it) {
194 transVect->push_back(element_cnv.createTransient(&(*it), log));
198 template<class TRANS, class PERS, class CONV>
199 void TPCnvVectorConst<TRANS, PERS, CONV>::transToPers(const TRANS* transVect,
201 MsgStream &log) const {
202 size_t size = transVect->size();
203 persVect->resize(size);
204 // convert vector entries one by one
206 typename TRANS::const_iterator it = transVect->begin();
207 typename PERS::iterator pit = persVect->begin();
209 element_cnv.transToPers( *it, &(*pit), log );
217 persToTrans() and transToPers() implementation for a converter between
218 transient vector of T and persistent vector<T>
220 template<class TRANS, class PERS, class CONV>
221 void TPCnvStdVector<TRANS, PERS, CONV>::persToTrans(const PERS* persVect,
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();
231 element_cnv.persToTrans( &(*pit), &(*it), log );
236 template<class TRANS, class PERS, class CONV>
237 void TPCnvStdVector<TRANS, PERS, CONV>::transToPers(const TRANS* transVect,
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();
247 element_cnv.transToPers( &(*it), &(*pit), log );
253 template<class TRANS, class PERS, class CONV>
254 void TPCnvStdVectorConst<TRANS, PERS, CONV>::persToTrans(const PERS* persVect,
256 MsgStream &log) const
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();
264 element_cnv.persToTrans( &(*pit), &(*it), log );
269 template<class TRANS, class PERS, class CONV>
270 void TPCnvStdVectorConst<TRANS, PERS, CONV>::transToPers(const TRANS* transVect,
272 MsgStream &log) const
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();
280 element_cnv.transToPers( &(*it), &(*pit), log );
285 //--------------------------------------------------------------------
287 persToTrans() and transToPers() implementation for a converter between
288 transient AtlasHitsVector of T* and persistent vector<T>
290 template<class TRANS, class PERS, class CONV>
291 void T_AtlasHitsVectorCnv<TRANS, PERS, CONV>::persToTrans(const PERS* persCont,
295 typename TRANS::iterator it;
296 typename PERS::const_iterator ip;
297 const typename PERS::HitVector& pvec = persCont->getVector();
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 );
303 transCont->setName(persCont->name() );
306 template<class TRANS, class PERS, class CONV>
307 void T_AtlasHitsVectorCnv<TRANS, PERS, CONV>::transToPers(const TRANS* transCont,
310 size_t size = transCont->size();
311 typename PERS::HitVector& pvec = persCont->m_cont;
313 // convert vector entries one by one
315 typename TRANS::const_iterator it = transCont->begin();
316 typename PERS::iterator pit = pvec.begin();
318 element_cnv.transToPers( &(*it), &(*pit), log );
321 persCont->m_name = transCont->Name();
325 //--------------------------------------------------------------------
327 persToTrans() and transToPers() implementation for a converter between
328 transient AthenaHitsVector of T* and persistent vector<T>
330 template<class TRANS, class PERS, class CONV>
331 void T_AthenaHitsVectorCnv<TRANS, PERS, CONV>::persToTrans(const PERS* persCont,
335 typename PERS::const_iterator it;
336 const typename PERS::HitVector& pvec = persCont->getVector();
338 transCont->reserve(pvec.size());
339 for (it = pvec.begin(); it != pvec.end(); ++it) {
340 transCont->push_back(element_cnv.createTransient(&(*it), log));
342 transCont->setName(persCont->name() );
345 template<class TRANS, class PERS, class CONV>
346 void T_AthenaHitsVectorCnv<TRANS, PERS, CONV>::transToPers(const TRANS* transCont,
349 size_t size = transCont->size();
350 typename PERS::HitVector& pvec = persCont->m_cont;
352 // convert vector entries one by one
354 typename TRANS::const_iterator it = transCont->begin();
355 typename PERS::iterator pit = pvec.begin();
357 element_cnv.transToPers( *it, &(*pit), log );
360 persCont->m_name = transCont->Name();
364 //--------------------------------------------------------------------
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.
370 template<class TRANS, class PERS, class CONV>
371 void TPCnvIDCont<TRANS, PERS, CONV>::persToTrans(const PERS* persCont,
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()) {
385 throw std::runtime_error("Failed to add collection to ID Container");
387 log << MSG::DEBUG << "TPCnvIDCont::persToTrans, collection, hash id=" << id_hash << ", added to Identifiable container." << endmsg;
391 template<class TRANS, class PERS, class CONV>
392 void TPCnvIDCont<TRANS, PERS, CONV>::transToPers(const TRANS* transCont,
396 typename TRANS::const_iterator it_Coll = transCont->begin();
397 typename TRANS::const_iterator it_CollEnd = transCont->end();
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);
403 log << MSG::DEBUG << "TPCnvIDCont::transToPers, container size was " << entries << endmsg;
406 //--------------------------------------------------------------------
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
412 template<class TRANS, class PERS, class CONV>
413 void TPCnvIDContFromIdentifier<TRANS, PERS, CONV>::persToTrans(const PERS* persCont,
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()) {
427 throw std::runtime_error("Failed to add collection to ID Container");
429 log << MSG::DEBUG << "TPCnvIDContFromIdentifier::persToTrans, collection, hash id=" << id_hash << ", added to Identifiable container." << endmsg;
433 template<class TRANS, class PERS, class CONV>
434 void TPCnvIDContFromIdentifier<TRANS, PERS, CONV>::transToPers(const TRANS* transCont,
438 typename TRANS::const_iterator it_Coll = transCont->begin();
439 typename TRANS::const_iterator it_CollEnd = transCont->end();
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);
445 log << MSG::DEBUG << "TPCnvIDContFromIdentifier::transToPers, container size was " << entries << endmsg;