ATLAS Offline Software
Loading...
Searching...
No Matches
AthLinks/ElementLink.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4/**
5 * @file AthLinks/ElementLink.h
6 * @author scott snyder <snyder@bnl.gov>
7 * @date Apr, 2014
8 * @brief a persistable pointer to an element of a STORABLE (data object)
9 */
10
11
12#include "AthLinks/exceptions.h"
13#include "AthenaKernel/proxyDictFromEventContext.h"
14
15
16/**
17 * @brief Return the CLID for the class that we reference.
18 */
19template <class STORABLE>
20inline
21CLID ElementLink<STORABLE>::classID()
22{
23 return ClassID_traits<value_type>::ID();
24}
25
26
27/**
28 * @brief Default constructor. Makes a null link.
29 */
30template <class STORABLE>
31inline
32ElementLink<STORABLE>::ElementLink()
33{
34}
35
36
37/**
38 * @brief Construct a link from a string storable key and an index. O(1)
39 * @param dataID Key of the object.
40 * @param elemID The index of the element within the container.
41 * @param sg Associated store.
42 *
43 * If @c sg is 0, we take the global default.
44 */
45template <class STORABLE>
46inline
47ElementLink<STORABLE>::ElementLink(const ID_type& dataID, index_type elemID,
48 IProxyDict* sg /*= 0*/)
49 : Base (dataID, classID(), elemID, sg)
50{
51}
52
53
54/**
55 * @brief Construct a link from a string storable key and an index. O(1)
56 * @param dataID Key of the object.
57 * @param elemID The index of the element within the container.
58 * @param ctx Event context for this link.
59 */
60template <class STORABLE>
61inline
62ElementLink<STORABLE>::ElementLink(const ID_type& dataID, index_type elemID,
63 const EventContext& ctx)
64 : Base (dataID, classID(), elemID, Atlas::proxyDictFromEventContext(ctx))
65{
66}
67
68
69/**
70 * @brief Construct a link from a hashed storable key and an index. O(1)
71 * @param key Hashed key of the object.
72 * @param elemID The index of the element within the container.
73 * @param sg Associated store.
74 *
75 * If @c sg is 0, we take the global default.
76 */
77template <class STORABLE>
78inline
79ElementLink<STORABLE>::ElementLink(sgkey_t key, index_type elemID,
80 IProxyDict* sg /*= 0*/)
81 : Base (key, classID(), elemID, sg)
82{
83}
84
85
86/**
87 * @brief Construct a link from a hashed storable key and an index. O(1)
88 * @param key Hashed key of the object.
89 * @param elemID The index of the element within the container.
90 * @param ctx Event context for this link.
91 */
92template <class STORABLE>
93inline
94ElementLink<STORABLE>::ElementLink(sgkey_t key, index_type elemID,
95 const EventContext& ctx)
96 : Base (key, classID(), elemID, Atlas::proxyDictFromEventContext(ctx))
97{
98}
99
100
101/**
102 * @brief Construct from a string storable key, index, AND pointer to element. O(1)
103 * @param dataID Key of the object.
104 * @param elemID The index of the element within the container.
105 * @param pEl Pointer to the element.
106 * @param sg Associated store.
107 *
108 * USE CAREFULLY: no coherency checks, we just trust you!
109 *
110 * If @c sg is 0, we take the global default.
111 */
112template <class STORABLE>
113inline
114ElementLink<STORABLE>::ElementLink(const ID_type& dataID,
115 index_type elemID,
116 ElementType pEl,
117 IProxyDict* sg /*= 0*/)
118 : Base (dataID, classID(), elemID, pEl, sg)
119{
120}
121
122
123/**
124 * @brief Construct from a string storable key, index, AND pointer to element. O(1)
125 * @param dataID Key of the object.
126 * @param elemID The index of the element within the container.
127 * @param pEl Pointer to the element.
128 * @param ctx Event context for this link.
129 *
130 * USE CAREFULLY: no coherency checks, we just trust you!
131 */
132template <class STORABLE>
133inline
134ElementLink<STORABLE>::ElementLink(const ID_type& dataID,
135 index_type elemID,
136 ElementType pEl,
137 const EventContext& ctx)
138 : Base (dataID, classID(), elemID, pEl, Atlas::proxyDictFromEventContext(ctx))
139{
140}
141
142
143/**
144 * @brief Construct from a hashed storable key, index, AND pointer to element. O(1)
145 * @param key Hashed key of the object.
146 * @param elemID The index of the element within the container.
147 * @param pEl Pointer to the element.
148 * @param sg Associated store.
149 *
150 * USE CAREFULLY: no coherency checks, we just trust you!
151 *
152 * If @c sg is 0, we take the global default.
153 */
154template <class STORABLE>
155inline
156ElementLink<STORABLE>::ElementLink (sgkey_t key,
157 index_type elemID,
158 ElementType pEl,
159 IProxyDict* sg /*= 0*/)
160 : Base (key, classID(), elemID, pEl, sg)
161{
162}
163
164
165/**
166 * @brief Construct from a hashed storable key, index, AND pointer to element. O(1)
167 * @param key Hashed key of the object.
168 * @param elemID The index of the element within the container.
169 * @param pEl Pointer to the element.
170 * @param ctx Event context for this link.
171 *
172 * USE CAREFULLY: no coherency checks, we just trust you!
173 */
174template <class STORABLE>
175inline
176ElementLink<STORABLE>::ElementLink (sgkey_t key,
177 index_type elemID,
178 ElementType pEl,
179 const EventContext& ctx)
180 : Base (key, classID(), elemID, pEl, Atlas::proxyDictFromEventContext(ctx))
181{
182}
183
184
185/**
186 * @brief Construct a link from an index and reference to the container. O(1)
187 * @param data Reference to the container (storable).
188 * @param elemID The index of the element within the container.
189 * @param sg Associated store.
190 *
191 * If @c sg is 0, we take the global default.
192 */
193template <class STORABLE>
194inline
195ElementLink<STORABLE>::ElementLink (BaseConstReference data,
196 index_type elemID,
197 IProxyDict* sg /* = 0*/)
198 : Base (&data, classID(), elemID, sg)
199{
200}
201
202
203/**
204 * @brief Construct a link from an index and reference to the container. O(1)
205 * @param data Reference to the container (storable).
206 * @param elemID The index of the element within the container.
207 * @param ctx Event context for this link.
208 */
209template <class STORABLE>
210inline
211ElementLink<STORABLE>::ElementLink (BaseConstReference data,
212 index_type elemID,
213 const EventContext& ctx)
214 : Base (&data, classID(), elemID, Atlas::proxyDictFromEventContext(ctx))
215{
216}
217
218
219/**
220 * @brief Construct from an element and reference to the container. O(N)
221 * @param element The element to reference.
222 * @param data Reference to the container (storable).
223 * @param sg Associated store.
224 *
225 * Does the same thing as the default ctor followed by @c toContainedElement.
226 * Note the reversed parameter order compared to the previous
227 * constructor. This is to prevent ambiguities in the case that
228 * the contained type is convertable to an int.
229 *
230 * Will throw @c SG::ExcElementNotFound if the element is not
231 * in the container.
232 *
233 * If @c sg is 0, we take the global default.
234 */
235template <class STORABLE>
236inline
237ElementLink<STORABLE>::ElementLink (const ElementType& element,
238 BaseConstReference data,
239 IProxyDict* sg /*= 0*/)
240{
241 toContainedElement (data, element, sg);
242}
243
244
245/**
246 * @brief Construct from an element and reference to the container. O(N)
247 * @param element The element to reference.
248 * @param data Reference to the container (storable).
249 * @param ctx Event context for this link.
250 *
251 * Does the same thing as the default ctor followed by @c toContainedElement.
252 * Note the reversed parameter order compared to the previous
253 * constructor. This is to prevent ambiguities in the case that
254 * the contained type is convertable to an int.
255 *
256 * Will throw @c SG::ExcElementNotFound if the element is not
257 * in the container.
258 */
259template <class STORABLE>
260inline
261ElementLink<STORABLE>::ElementLink (const ElementType& element,
262 BaseConstReference data,
263 const EventContext& ctx)
264{
265 toContainedElement (data, element, ctx);
266}
267
268
269/**
270 * @brief Construct a link from another link, changing the index.
271 * @param other The source link.
272 * @param elemID The index for the new link.
273 *
274 * The index being constructed will reference the same container
275 * as @c other, but it will refer to element @c elemID.
276 */
277template <class STORABLE>
278inline
279ElementLink<STORABLE>::ElementLink (const ElementLink& other,
280 index_type elemID)
281 : Base (other, elemID)
282{
283}
284
285
286/**
287 * @brief Construct a link from a DataLink and an index.
288 * @param dlink Link to the container.
289 * @param index The index of the element within the container.
290 */
291template <class STORABLE>
292inline
293ElementLink<STORABLE>::ElementLink (const DataLink<STORABLE>& dlink,
294 index_type index)
295 : Base (dlink, index)
296{
297}
298
299
300/**
301 * @brief Constructor allowing a derived -> base conversion.
302 */
303template <class STORABLE>
304template <class U>
305inline
306ElementLink<STORABLE>::ElementLink (const ElementLink<U>& other)
307 : Base (other,
308 (SG::ElementLinkTraits<U>*)0,
309 (Traits*)0)
310{
311}
312
313
314/**
315 * @brief Return a pointer to the currently-referenced container object.
316 * @return A pointer to an object of the type given by @a clid,
317 * or null on a failure (or if the reference is null).
318 */
319template <class STORABLE>
320inline
321typename ElementLink<STORABLE>::const_pointer
322ElementLink<STORABLE>::getDataPtr() const
323{
324 return reinterpret_cast<const_pointer> (this->storable());
325}
326
327
328/**
329 * @brief Return a pointer to the currently-referenced container object.
330 * @return A pointer to an object of the type given by @a clid,
331 * or null on a failure (or if the reference is null).
332 */
333template <class STORABLE>
334inline
335typename ElementLink<STORABLE>::pointer
336ElementLink<STORABLE>::getDataNonConstPtr()
337{
338 return reinterpret_cast<pointer> (this->storableNonConst());
339}
340
341
342/**
343 * @brief Return a link to the currently-referenced container object.
344 */
345template <class STORABLE>
346inline
347DataLink<STORABLE> ElementLink<STORABLE>::getDataLink()
348{
349 return DataLink<STORABLE> (this->key(), this->proxyHolder());
350}
351
352
353/**
354 * @brief Return a link to the currently-referenced container object.
355 */
356template <class STORABLE>
357inline
358const DataLink<STORABLE> ElementLink<STORABLE>::getDataLink() const
359{
360 return DataLink<STORABLE> (this->key(), this->proxyHolder());
361}
362
363
364/**
365 * @brief Return a pointer to the currently-referenced container object.
366 */
367template <class STORABLE>
368inline
369typename ElementLink<STORABLE>::BaseConstPointer
370ElementLink<STORABLE>::getStorableObjectPointer() const
371{
372 return getDataPtr();
373}
374
375
376/**
377 * @brief Return a reference to the currently-referenced container object.
378 */
379template <class STORABLE>
380inline
381typename ElementLink<STORABLE>::BaseConstReference
382ElementLink<STORABLE>::getStorableObjectRef() const
383{
384 return *getDataPtr();
385}
386
387
388/**
389 * @brief Return a pointer to the referenced element.
390 *
391 * Be aware: if the element is a pointer, then this will yield
392 * a pointer to a pointer.
393 */
394template <class STORABLE>
395inline
396typename ElementLink<STORABLE>::ElementConstPointer
397ElementLink<STORABLE>::cptr() const
398{
399 ElementConstPointer ret = 0;
400 if (this->getCachedElement (ret))
401 return ret;
402
403 const STORABLE* ptr = this->getDataPtr();
404 if (ptr && IndexingPolicy::isValid(this->storedIndex())) {
405 this->setCachedElement (IndexingPolicy::lookup(this->storedIndex(), *ptr));
406 (void)this->getCachedElement (ret);
407 }
408 return ret;
409}
410
411
412/**
413 * @brief Return a reference to the referenced element.
414 *
415 * Will throw an exception if the link is not valid.
416 */
417template <class STORABLE>
418inline
419typename ElementLink<STORABLE>::ElementConstReference
420ElementLink<STORABLE>::operator* () const
421{
422 ElementConstPointer ptr = cptr();
423 if (!ptr)
424 SG::throwExcInvalidLink (classID(), this->dataID(), this->key());
425 return *ptr;
426}
427
428
429/**
430 * @brief Return a pointer to the referenced element.
431 */
432template <class STORABLE>
433inline
434typename ElementLink<STORABLE>::ElementConstPointer
435ElementLink<STORABLE>::operator->() const
436{
437 return cptr();
438}
439
440
441/**
442 * @brief Convert to a pointer to the referenced element.
443 */
444template <class STORABLE>
445inline
446ElementLink<STORABLE>::operator ElementConstPointer () const
447{
448 return cptr();
449}
450
451
452/**
453 * @brief Test to see if the link can be dereferenced.
454 *
455 * Will throw an exception if the container is not empty and the
456 * referenced element cannot be retrieved.
457 */
458template <class STORABLE>
459inline
460bool ElementLink<STORABLE>::isValid() const
461{
462 // This used to just call cptr(), but that was leading to dangling-pointer
463 // warnings with gcc12 when we were returning ElementLink's by value,
464 // as in ElementLinkVector. Doing it like this allows us to save
465 // a little work, anyway.
466 if (this->hasCachedElement()) return true;
467
468 const STORABLE* ptr = this->getDataPtr();
469 if (ptr && !ptr->empty() && IndexingPolicy::isValid(this->storedIndex())) {
470 this->setCachedElement (IndexingPolicy::lookup(this->storedIndex(), *ptr));
471 return true;
472 }
473 return false;
474}
475
476
477/**
478 * @brief Test to see if the link can not be dereferenced.
479 */
480template <class STORABLE>
481inline
482bool ElementLink<STORABLE>::operator!() const
483{
484 return !isValid();
485}
486
487
488/**
489 * @brief Return the cached element, if any.
490 */
491template <class STORABLE>
492inline
493typename ElementLink<STORABLE>::ElementType
494ElementLink<STORABLE>::cachedElement() const
495{
496 ElementConstPointer ret = 0;
497 if (this->getCachedElement (ret))
498 return *ret;
499 return ElementType();
500}
501
502
503/**
504 * @brief Set the link to an element given by index and pointer to container.
505 * @param data Reference to the container (storable).
506 * @param elemID The index of the element within the container.
507 * @param sg Associated store.
508 * @returns True if the link was changed.
509 *
510 * If the link is already set, this will return false and leave the
511 * link unchanged.
512 *
513 * If @c sg is 0, then we take the store from whatever the link's currently
514 * set to. If the link has no current store, then we take the global
515 * default.
516 */
517template <class STORABLE>
518inline
519bool
520ElementLink<STORABLE>::toIndexedElement(BaseConstReference data,
521 index_type elemID,
522 IProxyDict* sg /*= 0*/)
523{
524 return Base::toIndexedElement (&data, classID(), elemID, sg);
525}
526
527
528/**
529 * @brief Set the link to an element given by index and pointer to container.
530 * @param data Reference to the container (storable).
531 * @param elemID The index of the element within the container.
532 * @param ctx The event context.
533 * @returns True if the link was changed.
534 *
535 * If the link is already set, this will return false and leave the
536 * link unchanged.
537 */
538template <class STORABLE>
539inline
540bool
541ElementLink<STORABLE>::toIndexedElement(BaseConstReference data,
542 index_type elemID,
543 const EventContext& ctx)
544{
545 return Base::toIndexedElement (&data, classID(), elemID, Atlas::proxyDictFromEventContext(ctx));
546}
547
548
549/**
550 * @brief Set from element pointer and a reference to the container (storable)
551 * @param data Reference to the container (storable).
552 * @param element The element.
553 * @param sg Associated store.
554 * @returns True if the link was changed.
555 *
556 * O(N) for sequences!
557 *
558 * If the link is already set, this will return false and leave the
559 * link unchanged.
560 *
561 * If @c sg is 0, then we take the store from whatever the link's currently
562 * set to. If the link has no current store, then we take the global
563 * default.
564 */
565template <class STORABLE>
566inline
567bool ElementLink<STORABLE>::toContainedElement(BaseConstReference data,
568 ElementType element,
569 IProxyDict* sg /*= 0*/)
570{
571 index_type index = this->index();
572 IndexingPolicy::reverseLookup (data, element, index);
573 bool ret = Base::toIndexedElement (&data, classID(), index, sg);
574 if (ret)
575 this->storeCachedElement (element);
576 return ret;
577}
578
579
580/**
581 * @brief Set from element pointer and a reference to the container (storable)
582 * @param data Reference to the container (storable).
583 * @param element The element.
584 * @param ctx The event context.
585 * @returns True if the link was changed.
586 *
587 * O(N) for sequences!
588 *
589 * If the link is already set, this will return false and leave the
590 * link unchanged.
591 */
592template <class STORABLE>
593inline
594bool ElementLink<STORABLE>::toContainedElement(BaseConstReference data,
595 ElementType element,
596 const EventContext& ctx)
597{
598 index_type index = this->index();
599 IndexingPolicy::reverseLookup (data, element, index);
600 bool ret = Base::toIndexedElement (&data, classID(), index, Atlas::proxyDictFromEventContext(ctx));
601 if (ret)
602 this->storeCachedElement (element);
603 return ret;
604}
605
606
607/**
608 * @brief Set to point to an element.
609 * @param element The element.
610 * @returns True if the link was changed.
611 *
612 * The collection and the element can be specified independently
613 * using @c setElement and @c setStorableObject.
614 *
615 * If the link is already set, this will return false and leave the
616 * link unchanged.
617 */
618template <class STORABLE>
619inline
620bool ElementLink<STORABLE>::setElement(ElementType element)
621{
622 if (!this->isDefaultIndex() || this->hasCachedElement())
623 return false;
624 this->storeCachedElement (element);
625 const STORABLE* ptr = this->getDataPtr();
626 if (ptr) {
627 index_type index = this->index();
628 IndexingPolicy::reverseLookup (*ptr, element, index);
629 this->setIndex (index);
630 }
631 return true;
632}
633
634
635/**
636 * @brief Set link to point to a new container (storable).
637 * @param data Reference to the container (storable).
638 * @param replace True if we can change an existing link.
639 * @param sg Associated store.
640 * @returns True if the link was changed.
641 *
642 * If the link is already set, this will return false and leave the
643 * link unchanged unless @c replace is set. The @c replace argument
644 * should be set if the element is now in a new storable container;
645 * e.g. element ptr has been put in a new view container.
646 *
647 * If @c sg is 0, then we take the store from whatever the link's currently
648 * set to. If the link has no current store, then we take the global
649 * default.
650 */
651template <class STORABLE>
652inline
653bool ElementLink<STORABLE>::setStorableObject(BaseConstReference data,
654 bool replace /*= false*/,
655 IProxyDict* sg /*= 0*/)
656{
657 bool ret = Base::setStorableObject (&data, classID(), replace, sg);
658 if (ret) {
659 ElementConstPointer elt = 0;
660 if (this->isDefaultIndex() && this->getCachedElement (elt)) {
661 index_type index = this->index();
662 IndexingPolicy::reverseLookup (data, *elt, index);
663 this->setIndex (index);
664 return true;
665 }
666 }
667 return ret;
668}
669
670
671/**
672 * @brief Set link to point to a new container (storable).
673 * @param data Reference to the container (storable).
674 * @param ctx The event context.
675 * @returns True if the link was changed.
676 *
677 * If the link is already set, this will return false and leave the
678 * link unchanged.
679 */
680template <class STORABLE>
681inline
682bool ElementLink<STORABLE>::setStorableObject(BaseConstReference data,
683 const EventContext& ctx)
684{
685 return this->setStorableObject (data, false, ctx);
686}
687
688
689/**
690 * @brief Set link to point to a new container (storable).
691 * @param data Reference to the container (storable).
692 * @param replace True if we can change an existing link.
693 * @param ctx The event context.
694 * @returns True if the link was changed.
695 *
696 * If the link is already set, this will return false and leave the
697 * link unchanged unless @c replace is set. The @c replace argument
698 * should be set if the element is now in a new storable container;
699 * e.g. element ptr has been put in a new view container.
700 */
701template <class STORABLE>
702inline
703bool ElementLink<STORABLE>::setStorableObject(BaseConstReference data,
704 bool replace,
705 const EventContext& ctx)
706{
707 bool ret = Base::setStorableObject (&data, classID(), replace, Atlas::proxyDictFromEventContext(ctx));
708 if (ret) {
709 ElementConstPointer elt = 0;
710 if (this->isDefaultIndex() && this->getCachedElement (elt)) {
711 index_type index = this->index();
712 IndexingPolicy::reverseLookup (data, *elt, index);
713 this->setIndex (index);
714 return true;
715 }
716 }
717 return ret;
718}
719
720
721/**
722 * @brief Set the link to an element given by string key and index.
723 * @param dataID Key of the object.
724 * @param elemID The index of the element within the container.
725 * @param sg Associated store.
726 *
727 * If @c sg is 0, then we take the store from whatever the link's currently
728 * set to. If the link has no current store, then we take the global
729 * default.
730 */
731template <class STORABLE>
732inline
733void ElementLink<STORABLE>::resetWithKeyAndIndex(const ID_type& dataID,
734 index_type elemID,
735 IProxyDict* sg /*= 0*/)
736{
737 Base::resetWithKeyAndIndex (dataID, classID(), elemID, sg);
738}
739
740
741/**
742 * @brief Set the link to an element given by string key and index.
743 * @param dataID Key of the object.
744 * @param elemID The index of the element within the container.
745 * @param ctx The event context.
746 */
747template <class STORABLE>
748inline
749void ElementLink<STORABLE>::resetWithKeyAndIndex(const ID_type& dataID,
750 index_type elemID,
751 const EventContext& ctx)
752{
753 Base::resetWithKeyAndIndex (dataID, classID(), elemID, Atlas::proxyDictFromEventContext(ctx));
754}
755
756
757/**
758 * @brief Set the link to an element given by string key and index.
759 * @param key Hashed key of the object.
760 * @param elemID The index of the element within the container.
761 * @param sg Associated store.
762 *
763 * If @c sg is 0, then we take the store from whatever the link's currently
764 * set to. If the link has no current store, then we take the global
765 * default.
766 */
767template <class STORABLE>
768inline
769void ElementLink<STORABLE>::resetWithKeyAndIndex(sgkey_t key,
770 index_type elemID,
771 IProxyDict* sg /*= 0*/)
772{
773 Base::resetWithKeyAndIndex (key, classID(), elemID, sg);
774}
775
776
777/**
778 * @brief Set the link to an element given by string key and index.
779 * @param key Hashed key of the object.
780 * @param elemID The index of the element within the container.
781 * @param ctx The event context.
782 */
783template <class STORABLE>
784inline
785void ElementLink<STORABLE>::resetWithKeyAndIndex(sgkey_t key,
786 index_type elemID,
787 const EventContext& ctx)
788{
789 Base::resetWithKeyAndIndex (key, classID(), elemID, Atlas::proxyDictFromEventContext(ctx));
790}
791
792
793/**
794 * @brief Return a (void) pointer to the currently-referenced
795 * container object.
796 * @return A pointer to an object of the type given by @a clid,
797 * or null on a failure (or if the reference is null).
798 */
799template <class STORABLE>
800inline
801const void* ElementLink<STORABLE>::storable() const
802{
803 typedef STORABLE* fn_t (SG::DataProxy*);
804 fn_t* fn = &SG::DataProxy_cast<STORABLE>;
805 return this->storableBase (reinterpret_cast<castfn_t*> (fn), classID(), true);
806}
807
808
809/**
810 * @brief Return a (void) pointer to the currently-referenced
811 * container object.
812 * @return A pointer to an object of the type given by @a clid,
813 * or null on a failure (or if the reference is null).
814 */
815template <class STORABLE>
816inline
817void* ElementLink<STORABLE>::storableNonConst()
818{
819 typedef STORABLE* fn_t (SG::DataProxy*);
820 fn_t* fn = &SG::DataProxy_cast<STORABLE>;
821 return this->storableBase (reinterpret_cast<castfn_t*> (fn), classID(), false);
822}
823
824
825/**
826 * @brief Ordering relation for @c ElementLink (less-than)
827 * @param lhs Left-hand-side EL.
828 * @param rhs Right-hand-side EL.
829 */
830template <typename STORABLE>
831bool operator < (const ElementLink<STORABLE>& lhs,
832 const ElementLink<STORABLE>& rhs)
833{
834 bool lhsDefault = lhs.isDefault();
835 bool rhsDefault = rhs.isDefault();
836 if (lhsDefault && rhsDefault) return false;
837 if (lhsDefault) return true;
838 if (rhsDefault) return false;
839 if (lhs.key() == 0 || rhs.key() == 0 || lhs.isDefaultIndex() || rhs.isDefaultIndex())
840 SG::throwExcIncomparableEL();
841 if (SG::sgkeyLess (lhs.key(), rhs.key())) return true;
842 if (SG::sgkeyLess (rhs.key(), lhs.key())) return false;
843 if (lhs.index() < rhs.index()) return true;
844 return false;
845}
846
847
848/**
849 * @brief Ordering relation for @c ElementLink (greater-than)
850 * @param lhs Left-hand-side EL.
851 * @param rhs Right-hand-side EL.
852 */
853template <typename STORABLE>
854inline
855bool operator > (const ElementLink<STORABLE>& lhs,
856 const ElementLink<STORABLE>& rhs)
857{
858 return (rhs < lhs);
859}
860
861
862/**
863 * @brief Equality relation for @c ElementLink.
864 * @param lhs Left-hand-side EL.
865 * @param rhs Right-hand-side EL.
866 */
867template <typename STORABLE>
868inline
869bool operator == (const ElementLink<STORABLE>& lhs,
870 const ElementLink<STORABLE>& rhs)
871{
872 return !((lhs < rhs) || (rhs < lhs));
873}
874
875
876/**
877 * @brief Inequality relation for @c ElementLink.
878 * @param lhs Left-hand-side EL.
879 * @param rhs Right-hand-side EL.
880 */
881template <typename STORABLE>
882inline
883bool operator != (const ElementLink<STORABLE>& lhs,
884 const ElementLink<STORABLE>& rhs)
885{
886 return !(lhs == rhs);
887}
888
889
890namespace SG_detail {
891
892
893/**
894 * @brief See if an EL is being remapped.
895 * @param sgkey_in Original hashed key of the EL.
896 * @param dum_in Ignored.
897 * @param sgkey_out[out] New hashed key for the EL.
898 * @param dum_out[out] Ignored.
899 * @return True if there is a remapping; false otherwise.
900 *
901 * This version catches the cases where the container index type
902 * isn't a @c size_t. We don't support changing the index in this case.
903 */
904template <class T>
905inline
906bool checkForRemap (IProxyDict* sg,
907 SG::sgkey_t sgkey_in,
908 const T& /*dum_in*/,
909 SG::sgkey_t& sgkey_out,
910 T& /*dum_out*/)
911{
912 size_t index_in = 0;
913 size_t index_out;
914 return checkForRemap (sg, sgkey_in, index_in, sgkey_out, index_out);
915}
916
917
918} // namespace SG_detail
919
920
921namespace SG {
922
923
924/*
925 * @brief Do post-read processing for ElementLink el.
926 * @param el The ElementLink that was just read.
927 * @param sg The current event store.
928 */
929template <class STORABLE>
930inline
931void ToTransient<ElementLink<STORABLE> >::toTransient
932 (ElementLink<STORABLE>& el, IProxyDict* sg /*= nullptr*/)
933{
934 el.toTransient (sg);
935}
936
937
938/*
939 * @brief Do post-read processing for ElementLink el.
940 * @param el The ElementLink that was just read.
941 * @param ctx The current event context.
942 */
943template <class STORABLE>
944inline
945void ToTransient<ElementLink<STORABLE> >::toTransient
946 (ElementLink<STORABLE>& el, const EventContext& ctx)
947{
948 toTransient (el, Atlas::proxyDictFromEventContext (ctx));
949}
950
951
952/*
953 * @brief Do post-read processing for vector of ElementLinks elv.
954 * @param elv The vector of ElementLinks that was just read.
955 * @param sg The current event store.
956 */
957template <class STORABLE, class ALLOC>
958void ToTransient<std::vector<ElementLink<STORABLE>, ALLOC> >::toTransient
959 (std::vector<ElementLink<STORABLE>, ALLOC>& elv, IProxyDict* sg /*= nullptr*/)
960{
961 for (auto& el : elv) {
962 el.toTransient (sg);
963 }
964}
965
966
967/*
968 * @brief Do post-read processing for vector of ElementLinks elv.
969 * @param elv The vector of ElementLinks that was just read.
970 * @param ctx The current event context.
971 */
972template <class STORABLE, class ALLOC>
973inline
974void ToTransient<std::vector<ElementLink<STORABLE>, ALLOC> >::toTransient
975 (std::vector<ElementLink<STORABLE>, ALLOC>& elv, const EventContext& ctx)
976{
977 toTransient (elv, Atlas::proxyDictFromEventContext (ctx));
978}
979
980
981/*
982 * @brief Do post-read processing for vector of vector of ElementLinks elvv.
983 * @param elvv The vector of vectors of ElementLinks that was just read.
984 * @param sg The current event store.
985 */
986template <class STORABLE, class ALLOC1, class ALLOC2>
987void ToTransient<std::vector<std::vector<ElementLink<STORABLE>, ALLOC1>, ALLOC2> >::toTransient
988 (std::vector<std::vector<ElementLink<STORABLE>, ALLOC1>, ALLOC2>& elvv,
989 IProxyDict* sg /*= nullptr*/)
990{
991 for (auto& elv : elvv) {
992 ToTransient<std::vector<ElementLink<STORABLE>, ALLOC1> >::toTransient (elv, sg);
993 }
994}
995
996
997/*
998 * @brief Do post-read processing for vector of vector of ElementLinks elvv.
999 * @param elvv The vector of vectors of ElementLinks that was just read.
1000 * @param ctx The current event context.
1001 */
1002template <class STORABLE, class ALLOC1, class ALLOC2>
1003inline
1004void ToTransient<std::vector<std::vector<ElementLink<STORABLE>, ALLOC1>, ALLOC2> >::toTransient
1005 (std::vector<std::vector<ElementLink<STORABLE>, ALLOC1>, ALLOC2>& elvv,
1006 const EventContext& ctx)
1007{
1008 toTransient (elvv, Atlas::proxyDictFromEventContext (ctx));
1009}
1010
1011
1012} // namespace SG