2 * Copyright (C) 2002-2025 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#include "CxxUtils/throw_out_of_range.h"
15namespace SG { namespace detail {
20 * @param elts Start of the element vector.
21 * @param payload Span over the payload vector.
23template <class PAYLOAD_T>
25JaggedVecConstConverter<PAYLOAD_T>::JaggedVecConstConverter (const JaggedVecEltBase* elts,
26 const_Payload_span payload)
34 * @brief Convert to a span.
35 * @param elt The jagged vector element to transform.
37template <class PAYLOAD_T>
39auto JaggedVecConstConverter<PAYLOAD_T>::operator() (const JaggedVecEltBase& elt) const
42 size_t beg = elt.begin(&elt - m_elts);
43 size_t end = elt.end();
44 if (beg > end || end > m_payload.size()) {
45 CxxUtils::throw_out_of_range (__PRETTY_FUNCTION__, end, m_payload.size(), this);
47 const Payload_t* payload = m_payload.data();
48 return element_type (payload + beg, payload + end);
52//****************************************************************************
57 * @param elts The elements of the jagged vector.
58 * @param container The container holding this variable.
59 * @param auxid The aux ID of this variable.
62JaggedVecProxyBase::JaggedVecProxyBase (const AuxDataSpanBase& elts,
63 AuxVectorData& container,
65 : m_elts (reinterpret_cast<Elt_t*> (elts.beg), elts.size),
66 m_container (container),
73 * @brief Return one jagged vector element (non-const).
74 * @param elt_index The index of the element.
77auto JaggedVecProxyBase::elt (size_t elt_index) noexcept -> Elt_t&
79 return m_elts[elt_index];
84 * @brief Return one jagged vector element (const).
85 * @param elt_index The index of the element.
88auto JaggedVecProxyBase::elt (size_t elt_index) const noexcept -> const Elt_t&
90 return m_elts[elt_index];
94//****************************************************************************
99 * @param elts The elements of the jagged vector.
100 * @param container The container holding this variable.
101 * @param auxid The aux ID of this variable.
104JaggedVecProxyValBase::JaggedVecProxyValBase (const AuxDataSpanBase& elts,
105 AuxVectorData& container,
107 : m_base (elts, container, auxid)
113 * @brief Constructor.
114 * @param base The base information.
117JaggedVecProxyRefBase::JaggedVecProxyRefBase (JaggedVecProxyBase& base)
123//****************************************************************************
127 * @brief Constructor.
128 * @param elt_index Index of the jagged vector element.
129 * @param payload Reference to a range over the payload vector.
130 * @param elts The elements of the jagged vector.
131 * @param container The container holding this variable.
132 * @param auxid The aux ID of this variable.
134template <class PAYLOAD_T, class BASE>
136JaggedVecProxyT<PAYLOAD_T, BASE>::JaggedVecProxyT (size_t elt_index,
137 Payload_span payload,
138 const AuxDataSpanBase& elts,
139 AuxVectorData& container,
141 : BASE (elts, container, auxid),
149 * @brief Constructor.
150 * @param elt_index Index of the jagged vector element.
151 * @param payload Reference to a range over the payload vector.
152 * @param base The base information.
154template <class PAYLOAD_T, class BASE>
156JaggedVecProxyT<PAYLOAD_T, BASE>::JaggedVecProxyT (size_t elt_index,
157 Payload_span payload,
158 JaggedVecProxyBase& base)
167 * @brief Return the size of this jagged vector element.
169template <class PAYLOAD_T, class BASE>
171size_t JaggedVecProxyT<PAYLOAD_T, BASE>::size() const noexcept
173 return elt_end() - elt_begin();
178 * @brief Test if this jagged vector element is empty.
180template <class PAYLOAD_T, class BASE>
182bool JaggedVecProxyT<PAYLOAD_T, BASE>::empty() const noexcept
189 * @brief Element access (non-const).
190 * @param i Index within this element's payload.
192template <class PAYLOAD_T, class BASE>
194auto JaggedVecProxyT<PAYLOAD_T, BASE>::operator[] (size_t i) noexcept
197 return m_payload[elt_begin()+i];
202 * @brief Element access (const).
203 * @param i Index within this element's payload.
205template <class PAYLOAD_T, class BASE>
207auto JaggedVecProxyT<PAYLOAD_T, BASE>::operator[] (size_t i) const noexcept
210 return m_payload[elt_begin()+i];
215 * @brief Element access (non-const, bounds-checked).
216 * @param i Index within this element's payload.
218template <class PAYLOAD_T, class BASE>
220auto JaggedVecProxyT<PAYLOAD_T, BASE>::at (size_t i) -> reference
222 size_t beg = this->elt_begin();
223 size_t end = this->elt_end();
224 if (i >= (end-beg)) CxxUtils::throw_out_of_range (__PRETTY_FUNCTION__, i, end-beg, this);
225 return m_payload[i+beg];
230 * @brief Element access (const, bounds-checked).
231 * @param i Index within this element's payload.
233template <class PAYLOAD_T, class BASE>
235auto JaggedVecProxyT<PAYLOAD_T, BASE>::at (size_t i) const -> const_reference
237 size_t beg = this->elt_begin();
238 size_t end = this->elt_end();
239 if (i >= (end-beg)) CxxUtils::throw_out_of_range (__PRETTY_FUNCTION__, i, end-beg, this);
240 return m_payload[i+beg];
245 * @brief Return a reference to the first item in this element's payload.
247template <class PAYLOAD_T, class BASE>
249auto JaggedVecProxyT<PAYLOAD_T, BASE>::front() noexcept -> reference
251 return m_payload[this->elt_begin()];
256 * @brief Return the first item in this element's payload.
258template <class PAYLOAD_T, class BASE>
260auto JaggedVecProxyT<PAYLOAD_T, BASE>::front() const noexcept -> const_reference
262 return m_payload[this->elt_begin()];
267 * @brief Return a reference to the last item in this element's payload.
269template <class PAYLOAD_T, class BASE>
271auto JaggedVecProxyT<PAYLOAD_T, BASE>::back() noexcept -> reference
273 return m_payload[this->elt_end()-1];
278 * @brief Return the last item in this element's payload.
280template <class PAYLOAD_T, class BASE>
282auto JaggedVecProxyT<PAYLOAD_T, BASE>::back() const noexcept -> const_reference
284 return m_payload[this->elt_end()-1];
289 * @brief Return a (non-const) begin iterator.
291template <class PAYLOAD_T, class BASE>
293auto JaggedVecProxyT<PAYLOAD_T, BASE>::begin() noexcept -> iterator
295 return m_payload.data() + this->elt_begin();
300 * @brief Return a (non-const) end iterator.
302template <class PAYLOAD_T, class BASE>
304auto JaggedVecProxyT<PAYLOAD_T, BASE>::end() noexcept -> iterator
306 return m_payload.data() + this->elt_end();
311 * @brief Return a (const) begin iterator.
313template <class PAYLOAD_T, class BASE>
315auto JaggedVecProxyT<PAYLOAD_T, BASE>::begin() const noexcept -> const_iterator
317 return m_payload.data() + this->elt_begin();
322 * @brief Return a (const) end iterator.
324template <class PAYLOAD_T, class BASE>
326auto JaggedVecProxyT<PAYLOAD_T, BASE>::end() const noexcept -> const_iterator
328 return m_payload.data() + this->elt_end();
333 * @brief Return a (const) begin iterator.
335template <class PAYLOAD_T, class BASE>
337auto JaggedVecProxyT<PAYLOAD_T, BASE>::cbegin() const noexcept -> const_iterator
339 return m_payload.data() + this->elt_begin();
344 * @brief Return a (const) end iterator.
346template <class PAYLOAD_T, class BASE>
348auto JaggedVecProxyT<PAYLOAD_T, BASE>::cend() const noexcept -> const_iterator
350 return m_payload.data() + this->elt_end();
355 * @brief Return a (non-const) begin reverse iterator.
357template <class PAYLOAD_T, class BASE>
359auto JaggedVecProxyT<PAYLOAD_T, BASE>::rbegin() noexcept -> reverse_iterator
361 return reverse_iterator (end());
366 * @brief Return a (non-const) end reverse iterator.
368template <class PAYLOAD_T, class BASE>
370auto JaggedVecProxyT<PAYLOAD_T, BASE>::rend() noexcept -> reverse_iterator
372 return reverse_iterator (begin());
377 * @brief Return a (const) begin reverse iterator.
379template <class PAYLOAD_T, class BASE>
381auto JaggedVecProxyT<PAYLOAD_T, BASE>::rbegin() const noexcept
382 -> const_reverse_iterator
384 return const_reverse_iterator (end());
389 * @brief Return a (const) end reverse iterator.
391template <class PAYLOAD_T, class BASE>
393auto JaggedVecProxyT<PAYLOAD_T, BASE>::rend() const noexcept
394 -> const_reverse_iterator
396 return const_reverse_iterator (begin());
401 * @brief Return a (const) begin reverse iterator.
403template <class PAYLOAD_T, class BASE>
405auto JaggedVecProxyT<PAYLOAD_T, BASE>::crbegin() const noexcept
406 -> const_reverse_iterator
408 return const_reverse_iterator (end());
413 * @brief Return a (const) end reverse iterator.
415template <class PAYLOAD_T, class BASE>
417auto JaggedVecProxyT<PAYLOAD_T, BASE>::crend() const noexcept
418 -> const_reverse_iterator
420 return const_reverse_iterator (begin());
425 * @brief Assign this jagged vector element from a range.
426 * @param range The range from which to assign.
428template <class PAYLOAD_T, class BASE>
429template <CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
430JaggedVecProxyT<PAYLOAD_T, BASE>&
431JaggedVecProxyT<PAYLOAD_T, BASE>::operator= (const RANGE& range)
433 this->m_base.resize1 (m_index, std::size(range));
434 std::copy (range.begin(), range.end(), begin());
440 * @brief Convert this jagged vector element to a vector.
442template <class PAYLOAD_T, class BASE>
443auto JaggedVecProxyT<PAYLOAD_T, BASE>::asVector() const
444 -> std::vector<Payload_t>
446 return std::vector<Payload_t> (this->begin(), this->end());
451 * @brief Convert this jagged vector element to a vector.
453template <class PAYLOAD_T, class BASE>
454template <class VALLOC>
455JaggedVecProxyT<PAYLOAD_T, BASE>::operator std::vector<Payload_t, VALLOC>() const
457 return std::vector<Payload_t, VALLOC> (this->begin(), this->end());
462 * @brief Add an item to the end of this jagged vector element.
463 * @param x The item to add.
465template <class PAYLOAD_T, class BASE>
466void JaggedVecProxyT<PAYLOAD_T, BASE>::push_back (const Payload_t& x)
468 this->m_base.adjust1 (m_index, size(), 1);
474 * @brief Clear this jagged vector element.
476template <class PAYLOAD_T, class BASE>
477void JaggedVecProxyT<PAYLOAD_T, BASE>::clear()
479 this->m_base.resize1 (m_index, 0);
484 * @brief Resize this jagged vector element.
485 * @param n New size for the element.
486 * @param x If the element is being enlarged, initialize the new
487 * elements with this value.
489template <class PAYLOAD_T, class BASE>
490void JaggedVecProxyT<PAYLOAD_T, BASE>::resize (size_t n,
491 const Payload_t& x /*= Payload_t()*/)
494 this->m_base.adjust1 (m_index, sz, n - sz);
496 std::fill_n (begin()+sz, n-sz, x);
502 * @brief Erase one item from this jagged vector element.
503 * @param pos Position within the element of the item to erase.
505template <class PAYLOAD_T, class BASE>
506void JaggedVecProxyT<PAYLOAD_T, BASE>::erase (nonnull_iterator pos)
508 this->m_base.adjust1 (m_index, pos-begin()+1, -1);
513 * @brief Erase one item from this jagged vector element.
514 * @param pos Index within the element of the item to erase.
516template <class PAYLOAD_T, class BASE>
517void JaggedVecProxyT<PAYLOAD_T, BASE>::erase (index_type pos)
519 this->m_base.adjust1 (m_index, pos+1, -1);
524 * @brief Erase a range of items from this jagged vector element.
525 * @param first Position within the element of the first item to erase.
526 * @param last One past the position within the element of the last item to erase.
528template <class PAYLOAD_T, class BASE>
529void JaggedVecProxyT<PAYLOAD_T, BASE>::erase (nonnull_iterator first,
530 nonnull_iterator last)
532 this->m_base.adjust1 (m_index, last - begin(), -(last - first));
537 * @brief Erase a range of items from this jagged vector element.
538 * @param first Index within the element of the first item to erase.
539 * @param last One past the index within the element of the last item to erase.
541template <class PAYLOAD_T, class BASE>
542void JaggedVecProxyT<PAYLOAD_T, BASE>::erase (index_type first, index_type last)
544 this->m_base.adjust1 (m_index, last, -(last - first));
549 * @brief Insert an item into this jagged vector element.
550 * @param pos Position within the element at which to insert.
551 * @param x The item to insert.
553template <class PAYLOAD_T, class BASE>
554void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (nonnull_iterator pos,
561 * @brief Insert an item into this jagged vector element.
562 * @param pos Index within the element at which to insert.
563 * @param x The item to insert.
565template <class PAYLOAD_T, class BASE>
566void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (index_type pos,
574 * @brief Insert a number of items into this jagged vector element.
575 * @param pos Position within the element at which to insert.
576 * @param n The number of items to insert.
577 * @param x The value to insert.
579template <class PAYLOAD_T, class BASE>
580void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (nonnull_iterator pos,
584 size_t i = pos - begin();
585 this->m_base.adjust1 (m_index, i, n);
586 std::fill_n (begin()+i, n, x);
591 * @brief Insert a number of items into this jagged vector element.
592 * @param pos Index within the element at which to insert.
593 * @param n The number of items to insert.
594 * @param x The value to insert.
596template <class PAYLOAD_T, class BASE>
597void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (index_type pos,
601 this->m_base.adjust1 (m_index, pos, n);
602 std::fill_n (begin()+pos, n, x);
606 * @brief Insert a range of items into this jagged vector element.
607 * @param pos Position within the element at which to insert.
608 * @param first Start of the range to insert.
609 * @param last End of the range to insert.
611template <class PAYLOAD_T, class BASE>
612template <CxxUtils::detail::InputValIterator<PAYLOAD_T> ITERATOR>
613void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (nonnull_iterator pos,
617 size_t i = pos - begin();
618 size_t n_new = last - first;
619 this->m_base.adjust1 (m_index, i, n_new);
620 std::copy (first, last, begin()+i);
625 * @brief Insert a range of items into this jagged vector element.
626 * @param pos Index within the element at which to insert.
627 * @param first Start of the range to insert.
628 * @param last End of the range to insert.
630template <class PAYLOAD_T, class BASE>
631template <CxxUtils::detail::InputValIterator<PAYLOAD_T> ITERATOR>
632void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (index_type pos,
636 size_t n_new = last - first;
637 this->m_base.adjust1 (m_index, pos, n_new);
638 std::copy (first, last, begin()+pos);
643 * @brief Insert a range of items into this jagged vector element.
644 * @param pos Position within the element at which to insert.
645 * @param range The range to insert.
647template <class PAYLOAD_T, class BASE>
648template <CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
649void JaggedVecProxyT<PAYLOAD_T, BASE>::insert_range (nonnull_iterator pos,
652 size_t i = pos - begin();
653 size_t n_new = std::size (range);
654 this->m_base.adjust1 (m_index, i, n_new);
655 std::copy (range.begin(), range.end(), begin()+i);
660 * @brief Insert a range of items into this jagged vector element.
661 * @param pos Index within the element at which to insert.
662 * @param range The range to insert.
664template <class PAYLOAD_T, class BASE>
665template <CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
666void JaggedVecProxyT<PAYLOAD_T, BASE>::insert_range (index_type pos,
669 size_t n_new = std::size (range);
670 this->m_base.adjust1 (m_index, pos, n_new);
671 std::copy (range.begin(), range.end(), begin()+pos);
676 * @brief Append a range of items to the end of this jagged vector element.
677 * @param range The range to append.
679template <class PAYLOAD_T, class BASE>
680template <CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
681void JaggedVecProxyT<PAYLOAD_T, BASE>::append_range (const RANGE& range)
684 size_t n_new = std::size (range);
685 this->m_base.adjust1 (m_index, sz, n_new);
686 std::copy (range.begin(), range.end(), begin()+sz);
691 * @brief Remove the last item from this jagged vector element.
693template <class PAYLOAD_T, class BASE>
694void JaggedVecProxyT<PAYLOAD_T, BASE>::pop_back()
696 this->m_base.adjust1 (m_index, size(), -1);
701 * @brief Set this jagged vector element to a number of items.
702 * @param n The number of items to assign.
703 * @param x The value to assign.
705template <class PAYLOAD_T, class BASE>
706void JaggedVecProxyT<PAYLOAD_T, BASE>::assign (size_t n, const Payload_t& x)
708 this->m_base.resize1 (m_index, n);
709 std::fill_n (begin(), n, x);
714 * @brief Assign this jagged vector element from a range.
715 * @param first Start of the range to assign.
716 * @param last End of the range to assign.
718template <class PAYLOAD_T, class BASE>
719template <CxxUtils::detail::InputValIterator<PAYLOAD_T> ITERATOR>
720void JaggedVecProxyT<PAYLOAD_T, BASE>::assign (ITERATOR first, ITERATOR last)
722 this->m_base.resize1 (m_index, last-first);
723 std::copy (first, last, begin());
728 * @brief Assign this jagged vector element from a range.
729 * @param range The range from which to assign.
731template <class PAYLOAD_T, class BASE>
732template <CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
733void JaggedVecProxyT<PAYLOAD_T, BASE>::assign_range (const RANGE& range)
735 this->m_base.resize1 (m_index, std::size (range));
736 std::copy (range.begin(), range.end(), begin());
741 * @brief Return a reference to this proxy's element.
743template <class PAYLOAD_T, class BASE>
745auto JaggedVecProxyT<PAYLOAD_T, BASE>::elt() noexcept -> Elt_t&
747 return this->m_base.elt (m_index);
752 * @brief Return a (const) reference to this proxy's element.
754template <class PAYLOAD_T, class BASE>
756auto JaggedVecProxyT<PAYLOAD_T, BASE>::elt() const noexcept -> const Elt_t&
758 const JaggedVecProxyBase& base = this->m_base;
759 return base.elt (m_index);
764 * @brief Return the begin payload index of this proxy's element.
766template <class PAYLOAD_T, class BASE>
768size_t JaggedVecProxyT<PAYLOAD_T, BASE>::elt_begin() const noexcept
770 if (m_index == 0) return 0;
771 const JaggedVecProxyBase& base = this->m_base;
772 return base.elt (m_index-1).end();
777 * @brief Return the end payload index of this proxy's element.
779template <class PAYLOAD_T, class BASE>
781size_t JaggedVecProxyT<PAYLOAD_T, BASE>::elt_end() const noexcept
783 const JaggedVecProxyBase& base = this->m_base;
784 return base.elt (m_index).end();
788//****************************************************************************
792 * @brief Constructor.
793 * @param container The container holding this variable.
794 * @param auxid The aux ID of this variable.
795 * @param linked_auxid The aux ID for the linked payload variable.
797template <class PAYLOAD_T>
799JaggedVecConverter<PAYLOAD_T>::JaggedVecConverter (AuxVectorData& container,
801 auxid_t linked_auxid)
802 : m_base (*container.getDataSpan (auxid), container, auxid),
803 m_payload (*container.getDataSpan (linked_auxid))
809 * @brief Convert to a (read-only) span.
810 * @param elt The jagged vector element to transform.
812template <class PAYLOAD_T>
814auto JaggedVecConverter<PAYLOAD_T>::operator() (const SG::JaggedVecEltBase& elt) const
815 -> const element_type
817 size_t idx = &elt - &m_base.elt(0);
818 size_t beg = elt.begin(idx);
819 size_t end = elt.end();
820 if (beg > end || end > m_payload.size()) {
821 CxxUtils::throw_out_of_range (__PRETTY_FUNCTION__, end, m_payload.size(), this);
823 const Payload_t* payload = m_payload.data();
824 return element_type (payload + beg, payload + end);
829 * @brief Convert to a (writable) span.
830 * @param elt The jagged vector element to transform.
832template <class PAYLOAD_T>
834auto JaggedVecConverter<PAYLOAD_T>::operator() (SG::JaggedVecEltBase& elt)
837 return value_type (&elt - &m_base.elt(0),
843} } // namespace SG::detail