2 * Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
5 * @file AthContainers/tools/JaggedVecConversions.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief Conversions for accessing jagged vector variables.
12 namespace SG { namespace detail {
17 * @param elts Start of the element vector.
18 * @param payload Span over the payload vector.
20 template <class PAYLOAD_T>
22 JaggedVecConstConverter<PAYLOAD_T>::JaggedVecConstConverter (const JaggedVecEltBase* elts,
23 const_Payload_span payload)
31 * @brief Convert to a span.
32 * @param elt The jagged vector element to transform.
34 template <class PAYLOAD_T>
36 auto JaggedVecConstConverter<PAYLOAD_T>::operator() (const JaggedVecEltBase& elt) const
39 size_t beg = elt.begin(&elt - m_elts);
40 size_t end = elt.end();
41 if (beg > end || end > m_payload.size()) {
42 throw std::out_of_range ("JaggedVecConstConverter");
44 const Payload_t* payload = m_payload.data();
45 return element_type (payload + beg, payload + end);
49 //****************************************************************************
54 * @param elts The elements of the jagged vector.
55 * @param container The container holding this variable.
56 * @param auxid The aux ID of this variable.
59 JaggedVecProxyBase::JaggedVecProxyBase (const AuxDataSpanBase& elts,
60 AuxVectorData& container,
62 : m_elts (reinterpret_cast<Elt_t*> (elts.beg), elts.size),
63 m_container (container),
70 * @brief Return one jagged vector element (non-const).
71 * @param elt_index The index of the element.
74 auto JaggedVecProxyBase::elt (size_t elt_index) noexcept -> Elt_t&
76 return m_elts[elt_index];
81 * @brief Return one jagged vector element (const).
82 * @param elt_index The index of the element.
85 auto JaggedVecProxyBase::elt (size_t elt_index) const noexcept -> const Elt_t&
87 return m_elts[elt_index];
91 //****************************************************************************
96 * @param elts The elements of the jagged vector.
97 * @param container The container holding this variable.
98 * @param auxid The aux ID of this variable.
101 JaggedVecProxyValBase::JaggedVecProxyValBase (const AuxDataSpanBase& elts,
102 AuxVectorData& container,
104 : m_base (elts, container, auxid)
110 * @brief Constructor.
111 * @param base The base information.
114 JaggedVecProxyRefBase::JaggedVecProxyRefBase (JaggedVecProxyBase& base)
120 //****************************************************************************
124 * @brief Constructor.
125 * @param elt_index Index of the jagged vector element.
126 * @param payload Reference to a range over the payload vector.
127 * @param elts The elements of the jagged vector.
128 * @param container The container holding this variable.
129 * @param auxid The aux ID of this variable.
131 template <class PAYLOAD_T, class BASE>
133 JaggedVecProxyT<PAYLOAD_T, BASE>::JaggedVecProxyT (size_t elt_index,
134 Payload_span payload,
135 const AuxDataSpanBase& elts,
136 AuxVectorData& container,
138 : BASE (elts, container, auxid),
146 * @brief Constructor.
147 * @param elt_index Index of the jagged vector element.
148 * @param payload Reference to a range over the payload vector.
149 * @param base The base information.
151 template <class PAYLOAD_T, class BASE>
153 JaggedVecProxyT<PAYLOAD_T, BASE>::JaggedVecProxyT (size_t elt_index,
154 Payload_span payload,
155 JaggedVecProxyBase& base)
164 * @brief Return the size of this jagged vector element.
166 template <class PAYLOAD_T, class BASE>
168 size_t JaggedVecProxyT<PAYLOAD_T, BASE>::size() const noexcept
170 return elt_end() - elt_begin();
175 * @brief Test if this jagged vector element is empty.
177 template <class PAYLOAD_T, class BASE>
179 bool JaggedVecProxyT<PAYLOAD_T, BASE>::empty() const noexcept
186 * @brief Element access (non-const).
187 * @param i Index within this element's payload.
189 template <class PAYLOAD_T, class BASE>
191 auto JaggedVecProxyT<PAYLOAD_T, BASE>::operator[] (size_t i) noexcept
194 return m_payload[elt_begin()+i];
199 * @brief Element access (const).
200 * @param i Index within this element's payload.
202 template <class PAYLOAD_T, class BASE>
204 auto JaggedVecProxyT<PAYLOAD_T, BASE>::operator[] (size_t i) const noexcept
207 return m_payload[elt_begin()+i];
212 * @brief Element access (non-const, bounds-checked).
213 * @param i Index within this element's payload.
215 template <class PAYLOAD_T, class BASE>
217 auto JaggedVecProxyT<PAYLOAD_T, BASE>::at (size_t i) -> reference
219 size_t beg = this->elt_begin();
220 size_t end = this->elt_end();
221 if (i >= (end-beg)) throw std::out_of_range ("JaggedVecProxyT");
222 return m_payload[i+beg];
227 * @brief Element access (const, bounds-checked).
228 * @param i Index within this element's payload.
230 template <class PAYLOAD_T, class BASE>
232 auto JaggedVecProxyT<PAYLOAD_T, BASE>::at (size_t i) const -> const_reference
234 size_t beg = this->elt_begin();
235 size_t end = this->elt_end();
236 if (i >= (end-beg)) throw std::out_of_range ("JaggedVecProxyT");
237 return m_payload[i+beg];
242 * @brief Return a reference to the first item in this element's payload.
244 template <class PAYLOAD_T, class BASE>
246 auto JaggedVecProxyT<PAYLOAD_T, BASE>::front() noexcept -> reference
248 return m_payload[this->elt_begin()];
253 * @brief Return the first item in this element's payload.
255 template <class PAYLOAD_T, class BASE>
257 auto JaggedVecProxyT<PAYLOAD_T, BASE>::front() const noexcept -> const_reference
259 return m_payload[this->elt_begin()];
264 * @brief Return a reference to the last item in this element's payload.
266 template <class PAYLOAD_T, class BASE>
268 auto JaggedVecProxyT<PAYLOAD_T, BASE>::back() noexcept -> reference
270 return m_payload[this->elt_end()-1];
275 * @brief Return the last item in this element's payload.
277 template <class PAYLOAD_T, class BASE>
279 auto JaggedVecProxyT<PAYLOAD_T, BASE>::back() const noexcept -> const_reference
281 return m_payload[this->elt_end()-1];
286 * @brief Return a (non-const) begin iterator.
288 template <class PAYLOAD_T, class BASE>
290 auto JaggedVecProxyT<PAYLOAD_T, BASE>::begin() noexcept -> iterator
292 return m_payload.data() + this->elt_begin();
297 * @brief Return a (non-const) end iterator.
299 template <class PAYLOAD_T, class BASE>
301 auto JaggedVecProxyT<PAYLOAD_T, BASE>::end() noexcept -> iterator
303 return m_payload.data() + this->elt_end();
308 * @brief Return a (const) begin iterator.
310 template <class PAYLOAD_T, class BASE>
312 auto JaggedVecProxyT<PAYLOAD_T, BASE>::begin() const noexcept -> const_iterator
314 return m_payload.data() + this->elt_begin();
319 * @brief Return a (const) end iterator.
321 template <class PAYLOAD_T, class BASE>
323 auto JaggedVecProxyT<PAYLOAD_T, BASE>::end() const noexcept -> const_iterator
325 return m_payload.data() + this->elt_end();
330 * @brief Return a (const) begin iterator.
332 template <class PAYLOAD_T, class BASE>
334 auto JaggedVecProxyT<PAYLOAD_T, BASE>::cbegin() const noexcept -> const_iterator
336 return m_payload.data() + this->elt_begin();
341 * @brief Return a (const) end iterator.
343 template <class PAYLOAD_T, class BASE>
345 auto JaggedVecProxyT<PAYLOAD_T, BASE>::cend() const noexcept -> const_iterator
347 return m_payload.data() + this->elt_end();
352 * @brief Return a (non-const) begin reverse iterator.
354 template <class PAYLOAD_T, class BASE>
356 auto JaggedVecProxyT<PAYLOAD_T, BASE>::rbegin() noexcept -> reverse_iterator
358 return reverse_iterator (end());
363 * @brief Return a (non-const) end reverse iterator.
365 template <class PAYLOAD_T, class BASE>
367 auto JaggedVecProxyT<PAYLOAD_T, BASE>::rend() noexcept -> reverse_iterator
369 return reverse_iterator (begin());
374 * @brief Return a (const) begin reverse iterator.
376 template <class PAYLOAD_T, class BASE>
378 auto JaggedVecProxyT<PAYLOAD_T, BASE>::rbegin() const noexcept
379 -> const_reverse_iterator
381 return const_reverse_iterator (end());
386 * @brief Return a (const) end reverse iterator.
388 template <class PAYLOAD_T, class BASE>
390 auto JaggedVecProxyT<PAYLOAD_T, BASE>::rend() const noexcept
391 -> const_reverse_iterator
393 return const_reverse_iterator (begin());
398 * @brief Return a (const) begin reverse iterator.
400 template <class PAYLOAD_T, class BASE>
402 auto JaggedVecProxyT<PAYLOAD_T, BASE>::crbegin() const noexcept
403 -> const_reverse_iterator
405 return const_reverse_iterator (end());
410 * @brief Return a (const) end reverse iterator.
412 template <class PAYLOAD_T, class BASE>
414 auto JaggedVecProxyT<PAYLOAD_T, BASE>::crend() const noexcept
415 -> const_reverse_iterator
417 return const_reverse_iterator (begin());
422 * @brief Assign this jagged vector element from a range.
423 * @param range The range from which to assign.
425 template <class PAYLOAD_T, class BASE>
426 template <CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
427 JaggedVecProxyT<PAYLOAD_T, BASE>&
428 JaggedVecProxyT<PAYLOAD_T, BASE>::operator= (const RANGE& range)
430 this->m_base.resize1 (m_index, std::size(range));
431 std::copy (range.begin(), range.end(), begin());
437 * @brief Convert this jagged vector element to a vector.
439 template <class PAYLOAD_T, class BASE>
440 auto JaggedVecProxyT<PAYLOAD_T, BASE>::asVector() const
441 -> std::vector<Payload_t>
443 return std::vector<Payload_t> (this->begin(), this->end());
448 * @brief Convert this jagged vector element to a vector.
450 template <class PAYLOAD_T, class BASE>
451 template <class VALLOC>
452 JaggedVecProxyT<PAYLOAD_T, BASE>::operator std::vector<Payload_t, VALLOC>() const
454 return std::vector<Payload_t, VALLOC> (this->begin(), this->end());
459 * @brief Add an item to the end of this jagged vector element.
460 * @param x The item to add.
462 template <class PAYLOAD_T, class BASE>
463 void JaggedVecProxyT<PAYLOAD_T, BASE>::push_back (const Payload_t& x)
465 this->m_base.adjust1 (m_index, size(), 1);
471 * @brief Clear this jagged vector element.
473 template <class PAYLOAD_T, class BASE>
474 void JaggedVecProxyT<PAYLOAD_T, BASE>::clear()
476 this->m_base.resize1 (m_index, 0);
481 * @brief Resize this jagged vector element.
482 * @param n New size for the element.
483 * @param x If the element is being enlarged, initialize the new
484 * elements with this value.
486 template <class PAYLOAD_T, class BASE>
487 void JaggedVecProxyT<PAYLOAD_T, BASE>::resize (size_t n,
488 const Payload_t& x /*= Payload_t()*/)
491 this->m_base.adjust1 (m_index, sz, n - sz);
493 std::fill_n (begin()+sz, n-sz, x);
499 * @brief Erase one item from this jagged vector element.
500 * @param pos Position within the element of the item to erase.
502 template <class PAYLOAD_T, class BASE>
503 void JaggedVecProxyT<PAYLOAD_T, BASE>::erase (nonnull_iterator pos)
505 this->m_base.adjust1 (m_index, pos-begin()+1, -1);
510 * @brief Erase one item from this jagged vector element.
511 * @param pos Index within the element of the item to erase.
513 template <class PAYLOAD_T, class BASE>
514 void JaggedVecProxyT<PAYLOAD_T, BASE>::erase (index_type pos)
516 this->m_base.adjust1 (m_index, pos+1, -1);
521 * @brief Erase a range of items from this jagged vector element.
522 * @param first Position within the element of the first item to erase.
523 * @param last One past the position within the element of the last item to erase.
525 template <class PAYLOAD_T, class BASE>
526 void JaggedVecProxyT<PAYLOAD_T, BASE>::erase (nonnull_iterator first,
527 nonnull_iterator last)
529 this->m_base.adjust1 (m_index, last - begin(), -(last - first));
534 * @brief Erase a range of items from this jagged vector element.
535 * @param first Index within the element of the first item to erase.
536 * @param last One past the index within the element of the last item to erase.
538 template <class PAYLOAD_T, class BASE>
539 void JaggedVecProxyT<PAYLOAD_T, BASE>::erase (index_type first, index_type last)
541 this->m_base.adjust1 (m_index, last, -(last - first));
546 * @brief Insert an item into this jagged vector element.
547 * @param pos Position within the element at which to insert.
548 * @param x The item to insert.
550 template <class PAYLOAD_T, class BASE>
551 void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (nonnull_iterator pos,
558 * @brief Insert an item into this jagged vector element.
559 * @param pos Index within the element at which to insert.
560 * @param x The item to insert.
562 template <class PAYLOAD_T, class BASE>
563 void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (index_type pos,
571 * @brief Insert a number of items into this jagged vector element.
572 * @param pos Position within the element at which to insert.
573 * @param n The number of items to insert.
574 * @param x The value to insert.
576 template <class PAYLOAD_T, class BASE>
577 void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (nonnull_iterator pos,
581 size_t i = pos - begin();
582 this->m_base.adjust1 (m_index, i, n);
583 std::fill_n (begin()+i, n, x);
588 * @brief Insert a number of items into this jagged vector element.
589 * @param pos Index within the element at which to insert.
590 * @param n The number of items to insert.
591 * @param x The value to insert.
593 template <class PAYLOAD_T, class BASE>
594 void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (index_type pos,
598 this->m_base.adjust1 (m_index, pos, n);
599 std::fill_n (begin()+pos, n, x);
603 * @brief Insert a range of items into this jagged vector element.
604 * @param pos Position within the element at which to insert.
605 * @param first Start of the range to insert.
606 * @param last End of the range to insert.
608 template <class PAYLOAD_T, class BASE>
609 template <CxxUtils::detail::InputValIterator<PAYLOAD_T> ITERATOR>
610 void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (nonnull_iterator pos,
614 size_t i = pos - begin();
615 size_t n_new = last - first;
616 this->m_base.adjust1 (m_index, i, n_new);
617 std::copy (first, last, begin()+i);
622 * @brief Insert a range of items into this jagged vector element.
623 * @param pos Index within the element at which to insert.
624 * @param first Start of the range to insert.
625 * @param last End of the range to insert.
627 template <class PAYLOAD_T, class BASE>
628 template <CxxUtils::detail::InputValIterator<PAYLOAD_T> ITERATOR>
629 void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (index_type pos,
633 size_t n_new = last - first;
634 this->m_base.adjust1 (m_index, pos, n_new);
635 std::copy (first, last, begin()+pos);
640 * @brief Insert a range of items into this jagged vector element.
641 * @param pos Position within the element at which to insert.
642 * @param range The range to insert.
644 template <class PAYLOAD_T, class BASE>
645 template <CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
646 void JaggedVecProxyT<PAYLOAD_T, BASE>::insert_range (nonnull_iterator pos,
649 size_t i = pos - begin();
650 size_t n_new = std::size (range);
651 this->m_base.adjust1 (m_index, i, n_new);
652 std::copy (range.begin(), range.end(), begin()+i);
657 * @brief Insert a range of items into this jagged vector element.
658 * @param pos Index within the element at which to insert.
659 * @param range The range to insert.
661 template <class PAYLOAD_T, class BASE>
662 template <CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
663 void JaggedVecProxyT<PAYLOAD_T, BASE>::insert_range (index_type pos,
666 size_t n_new = std::size (range);
667 this->m_base.adjust1 (m_index, pos, n_new);
668 std::copy (range.begin(), range.end(), begin()+pos);
673 * @brief Append a range of items to the end of this jagged vector element.
674 * @param range The range to append.
676 template <class PAYLOAD_T, class BASE>
677 template <CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
678 void JaggedVecProxyT<PAYLOAD_T, BASE>::append_range (const RANGE& range)
681 size_t n_new = std::size (range);
682 this->m_base.adjust1 (m_index, sz, n_new);
683 std::copy (range.begin(), range.end(), begin()+sz);
688 * @brief Remove the last item from this jagged vector element.
690 template <class PAYLOAD_T, class BASE>
691 void JaggedVecProxyT<PAYLOAD_T, BASE>::pop_back()
693 this->m_base.adjust1 (m_index, size(), -1);
698 * @brief Set this jagged vector element to a number of items.
699 * @param n The number of items to assign.
700 * @param x The value to assign.
702 template <class PAYLOAD_T, class BASE>
703 void JaggedVecProxyT<PAYLOAD_T, BASE>::assign (size_t n, const Payload_t& x)
705 this->m_base.resize1 (m_index, n);
706 std::fill_n (begin(), n, x);
711 * @brief Assign this jagged vector element from a range.
712 * @param first Start of the range to assign.
713 * @param last End of the range to assign.
715 template <class PAYLOAD_T, class BASE>
716 template <CxxUtils::detail::InputValIterator<PAYLOAD_T> ITERATOR>
717 void JaggedVecProxyT<PAYLOAD_T, BASE>::assign (ITERATOR first, ITERATOR last)
719 this->m_base.resize1 (m_index, last-first);
720 std::copy (first, last, begin());
725 * @brief Assign this jagged vector element from a range.
726 * @param range The range from which to assign.
728 template <class PAYLOAD_T, class BASE>
729 template <CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
730 void JaggedVecProxyT<PAYLOAD_T, BASE>::assign_range (const RANGE& range)
732 this->m_base.resize1 (m_index, std::size (range));
733 std::copy (range.begin(), range.end(), begin());
738 * @brief Return a reference to this proxy's element.
740 template <class PAYLOAD_T, class BASE>
742 auto JaggedVecProxyT<PAYLOAD_T, BASE>::elt() noexcept -> Elt_t&
744 return this->m_base.elt (m_index);
749 * @brief Return a (const) reference to this proxy's element.
751 template <class PAYLOAD_T, class BASE>
753 auto JaggedVecProxyT<PAYLOAD_T, BASE>::elt() const noexcept -> const Elt_t&
755 const JaggedVecProxyBase& base = this->m_base;
756 return base.elt (m_index);
761 * @brief Return the begin payload index of this proxy's element.
763 template <class PAYLOAD_T, class BASE>
765 size_t JaggedVecProxyT<PAYLOAD_T, BASE>::elt_begin() const noexcept
767 if (m_index == 0) return 0;
768 const JaggedVecProxyBase& base = this->m_base;
769 return base.elt (m_index-1).end();
774 * @brief Return the end payload index of this proxy's element.
776 template <class PAYLOAD_T, class BASE>
778 size_t JaggedVecProxyT<PAYLOAD_T, BASE>::elt_end() const noexcept
780 const JaggedVecProxyBase& base = this->m_base;
781 return base.elt (m_index).end();
785 //****************************************************************************
789 * @brief Constructor.
790 * @param container The container holding this variable.
791 * @param auxid The aux ID of this variable.
792 * @param linked_auxid The aux ID for the linked payload variable.
794 template <class PAYLOAD_T>
796 JaggedVecConverter<PAYLOAD_T>::JaggedVecConverter (AuxVectorData& container,
798 auxid_t linked_auxid)
799 : m_base (*container.getDataSpan (auxid), container, auxid),
800 m_payload (*container.getDataSpan (linked_auxid))
806 * @brief Convert to a (read-only) span.
807 * @param elt The jagged vector element to transform.
809 template <class PAYLOAD_T>
811 auto JaggedVecConverter<PAYLOAD_T>::operator() (const SG::JaggedVecEltBase& elt) const
812 -> const element_type
814 size_t idx = &elt - &m_base.elt(0);
815 size_t beg = elt.begin(idx);
816 size_t end = elt.end();
817 if (beg > end || end > m_payload.size()) {
818 throw std::out_of_range ("JaggedVecConverter");
820 const Payload_t* payload = m_payload.data();
821 return element_type (payload + beg, payload + end);
826 * @brief Convert to a (writable) span.
827 * @param elt The jagged vector element to transform.
829 template <class PAYLOAD_T>
831 auto JaggedVecConverter<PAYLOAD_T>::operator() (SG::JaggedVecEltBase& elt)
834 return value_type (&elt - &m_base.elt(0),
840 } } // namespace SG::detail