ATLAS Offline Software
JaggedVecConversions.icc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
3  */
4 /**
5  * @file AthContainers/tools/JaggedVecConversions.icc
6  * @author scott snyder <snyder@bnl.gov>
7  * @date Jul, 2024
8  * @brief Conversions for accessing jagged vector variables.
9  */
10 
11 
12 namespace SG { namespace detail {
13 
14 
15 /**
16  * @brief Constructor.
17  * @param elts Start of the element vector.
18  * @param payload Span over the payload vector.
19  */
20 template <class PAYLOAD_T>
21 inline
22 JaggedVecConstConverter<PAYLOAD_T>::JaggedVecConstConverter (const JaggedVecEltBase* elts,
23  const_Payload_span payload)
24  : m_elts (elts),
25  m_payload (payload)
26 {
27 }
28 
29 
30 /**
31  * @brief Convert to a span.
32  * @param elt The jagged vector element to transform.
33  */
34 template <class PAYLOAD_T>
35 inline
36 auto JaggedVecConstConverter<PAYLOAD_T>::operator() (const JaggedVecEltBase& elt) const
37  -> const element_type
38 {
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");
43  }
44  const Payload_t* payload = m_payload.data();
45  return element_type (payload + beg, payload + end);
46 }
47 
48 
49 //****************************************************************************
50 
51 
52 /**
53  * @brief Constructor.
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.
57  */
58 inline
59 JaggedVecProxyBase::JaggedVecProxyBase (const AuxDataSpanBase& elts,
60  AuxVectorData& container,
61  SG::auxid_t auxid)
62  : m_elts (reinterpret_cast<Elt_t*> (elts.beg), elts.size),
63  m_container (container),
64  m_linkedVec (auxid)
65 {
66 }
67 
68 
69 /**
70  * @brief Return one jagged vector element (non-const).
71  * @param elt_index The index of the element.
72  */
73 inline
74 auto JaggedVecProxyBase::elt (size_t elt_index) noexcept -> Elt_t&
75 {
76  return m_elts[elt_index];
77 }
78 
79 
80 /**
81  * @brief Return one jagged vector element (const).
82  * @param elt_index The index of the element.
83  */
84 inline
85 auto JaggedVecProxyBase::elt (size_t elt_index) const noexcept -> const Elt_t&
86 {
87  return m_elts[elt_index];
88 }
89 
90 
91 //****************************************************************************
92 
93 
94 /**
95  * @brief Constructor.
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.
99  */
100 inline
101 JaggedVecProxyValBase::JaggedVecProxyValBase (const AuxDataSpanBase& elts,
102  AuxVectorData& container,
103  SG::auxid_t auxid)
104  : m_base (elts, container, auxid)
105 {
106 }
107 
108 
109 /**
110  * @brief Constructor.
111  * @param base The base information.
112  */
113 inline
114 JaggedVecProxyRefBase::JaggedVecProxyRefBase (JaggedVecProxyBase& base)
115  : m_base (base)
116 {
117 }
118 
119 
120 //****************************************************************************
121 
122 
123 /**
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.
130  */
131 template <class PAYLOAD_T, class BASE>
132 inline
133 JaggedVecProxyT<PAYLOAD_T, BASE>::JaggedVecProxyT (size_t elt_index,
134  Payload_span payload,
135  const AuxDataSpanBase& elts,
136  AuxVectorData& container,
137  SG::auxid_t auxid)
138  : BASE (elts, container, auxid),
139  m_index (elt_index),
140  m_payload (payload)
141 {
142 }
143 
144 
145 /**
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.
150  */
151 template <class PAYLOAD_T, class BASE>
152 inline
153 JaggedVecProxyT<PAYLOAD_T, BASE>::JaggedVecProxyT (size_t elt_index,
154  Payload_span payload,
155  JaggedVecProxyBase& base)
156  : BASE (base),
157  m_index (elt_index),
158  m_payload (payload)
159 {
160 }
161 
162 
163 /**
164  * @brief Return the size of this jagged vector element.
165  */
166 template <class PAYLOAD_T, class BASE>
167 inline
168 size_t JaggedVecProxyT<PAYLOAD_T, BASE>::size() const noexcept
169 {
170  return elt_end() - elt_begin();
171 }
172 
173 
174 /**
175  * @brief Test if this jagged vector element is empty.
176  */
177 template <class PAYLOAD_T, class BASE>
178 inline
179 bool JaggedVecProxyT<PAYLOAD_T, BASE>::empty() const noexcept
180 {
181  return size() == 0;
182 }
183 
184 
185 /**
186  * @brief Element access (non-const).
187  * @param i Index within this element's payload.
188  */
189 template <class PAYLOAD_T, class BASE>
190 inline
191 auto JaggedVecProxyT<PAYLOAD_T, BASE>::operator[] (size_t i) noexcept
192  -> reference
193 {
194  return m_payload[elt_begin()+i];
195 }
196 
197 
198 /**
199  * @brief Element access (const).
200  * @param i Index within this element's payload.
201  */
202 template <class PAYLOAD_T, class BASE>
203 inline
204 auto JaggedVecProxyT<PAYLOAD_T, BASE>::operator[] (size_t i) const noexcept
205  -> const_reference
206 {
207  return m_payload[elt_begin()+i];
208 }
209 
210 
211 /**
212  * @brief Element access (non-const, bounds-checked).
213  * @param i Index within this element's payload.
214  */
215 template <class PAYLOAD_T, class BASE>
216 inline
217 auto JaggedVecProxyT<PAYLOAD_T, BASE>::at (size_t i) -> reference
218 {
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];
223 }
224 
225 
226 /**
227  * @brief Element access (const, bounds-checked).
228  * @param i Index within this element's payload.
229  */
230 template <class PAYLOAD_T, class BASE>
231 inline
232 auto JaggedVecProxyT<PAYLOAD_T, BASE>::at (size_t i) const -> const_reference
233 {
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];
238 }
239 
240 
241 /**
242  * @brief Return a reference to the first item in this element's payload.
243  */
244 template <class PAYLOAD_T, class BASE>
245 inline
246 auto JaggedVecProxyT<PAYLOAD_T, BASE>::front() noexcept -> reference
247 {
248  return m_payload[this->elt_begin()];
249 }
250 
251 
252 /**
253  * @brief Return the first item in this element's payload.
254  */
255 template <class PAYLOAD_T, class BASE>
256 inline
257 auto JaggedVecProxyT<PAYLOAD_T, BASE>::front() const noexcept -> const_reference
258 {
259  return m_payload[this->elt_begin()];
260 }
261 
262 
263 /**
264  * @brief Return a reference to the last item in this element's payload.
265  */
266 template <class PAYLOAD_T, class BASE>
267 inline
268 auto JaggedVecProxyT<PAYLOAD_T, BASE>::back() noexcept -> reference
269 {
270  return m_payload[this->elt_end()-1];
271 }
272 
273 
274 /**
275  * @brief Return the last item in this element's payload.
276  */
277 template <class PAYLOAD_T, class BASE>
278 inline
279 auto JaggedVecProxyT<PAYLOAD_T, BASE>::back() const noexcept -> const_reference
280 {
281  return m_payload[this->elt_end()-1];
282 }
283 
284 
285 /**
286  * @brief Return a (non-const) begin iterator.
287  */
288 template <class PAYLOAD_T, class BASE>
289 inline
290 auto JaggedVecProxyT<PAYLOAD_T, BASE>::begin() noexcept -> iterator
291 {
292  return m_payload.data() + this->elt_begin();
293 }
294 
295 
296 /**
297  * @brief Return a (non-const) end iterator.
298  */
299 template <class PAYLOAD_T, class BASE>
300 inline
301 auto JaggedVecProxyT<PAYLOAD_T, BASE>::end() noexcept -> iterator
302 {
303  return m_payload.data() + this->elt_end();
304 }
305 
306 
307 /**
308  * @brief Return a (const) begin iterator.
309  */
310 template <class PAYLOAD_T, class BASE>
311 inline
312 auto JaggedVecProxyT<PAYLOAD_T, BASE>::begin() const noexcept -> const_iterator
313 {
314  return m_payload.data() + this->elt_begin();
315 }
316 
317 
318 /**
319  * @brief Return a (const) end iterator.
320  */
321 template <class PAYLOAD_T, class BASE>
322 inline
323 auto JaggedVecProxyT<PAYLOAD_T, BASE>::end() const noexcept -> const_iterator
324 {
325  return m_payload.data() + this->elt_end();
326 }
327 
328 
329 /**
330  * @brief Return a (const) begin iterator.
331  */
332 template <class PAYLOAD_T, class BASE>
333 inline
334 auto JaggedVecProxyT<PAYLOAD_T, BASE>::cbegin() const noexcept -> const_iterator
335 {
336  return m_payload.data() + this->elt_begin();
337 }
338 
339 
340 /**
341  * @brief Return a (const) end iterator.
342  */
343 template <class PAYLOAD_T, class BASE>
344 inline
345 auto JaggedVecProxyT<PAYLOAD_T, BASE>::cend() const noexcept -> const_iterator
346 {
347  return m_payload.data() + this->elt_end();
348 }
349 
350 
351 /**
352  * @brief Return a (non-const) begin reverse iterator.
353  */
354 template <class PAYLOAD_T, class BASE>
355 inline
356 auto JaggedVecProxyT<PAYLOAD_T, BASE>::rbegin() noexcept -> reverse_iterator
357 {
358  return reverse_iterator (end());
359 }
360 
361 
362 /**
363  * @brief Return a (non-const) end reverse iterator.
364  */
365 template <class PAYLOAD_T, class BASE>
366 inline
367 auto JaggedVecProxyT<PAYLOAD_T, BASE>::rend() noexcept -> reverse_iterator
368 {
369  return reverse_iterator (begin());
370 }
371 
372 
373 /**
374  * @brief Return a (const) begin reverse iterator.
375  */
376 template <class PAYLOAD_T, class BASE>
377 inline
378 auto JaggedVecProxyT<PAYLOAD_T, BASE>::rbegin() const noexcept
379  -> const_reverse_iterator
380 {
381  return const_reverse_iterator (end());
382 }
383 
384 
385 /**
386  * @brief Return a (const) end reverse iterator.
387  */
388 template <class PAYLOAD_T, class BASE>
389 inline
390 auto JaggedVecProxyT<PAYLOAD_T, BASE>::rend() const noexcept
391  -> const_reverse_iterator
392 {
393  return const_reverse_iterator (begin());
394 }
395 
396 
397 /**
398  * @brief Return a (const) begin reverse iterator.
399  */
400 template <class PAYLOAD_T, class BASE>
401 inline
402 auto JaggedVecProxyT<PAYLOAD_T, BASE>::crbegin() const noexcept
403  -> const_reverse_iterator
404 {
405  return const_reverse_iterator (end());
406 }
407 
408 
409 /**
410  * @brief Return a (const) end reverse iterator.
411  */
412 template <class PAYLOAD_T, class BASE>
413 inline
414 auto JaggedVecProxyT<PAYLOAD_T, BASE>::crend() const noexcept
415  -> const_reverse_iterator
416 {
417  return const_reverse_iterator (begin());
418 }
419 
420 
421 /**
422  * @brief Assign this jagged vector element from a range.
423  * @param range The range from which to assign.
424  */
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)
429 {
430  this->m_base.resize1 (m_index, std::size(range));
431  std::copy (range.begin(), range.end(), begin());
432  return *this;
433 }
434 
435 
436 /**
437  * @brief Convert this jagged vector element to a vector.
438  */
439 template <class PAYLOAD_T, class BASE>
440 auto JaggedVecProxyT<PAYLOAD_T, BASE>::asVector() const
441  -> std::vector<Payload_t>
442 {
443  return std::vector<Payload_t> (this->begin(), this->end());
444 }
445 
446 
447 /**
448  * @brief Convert this jagged vector element to a vector.
449  */
450 template <class PAYLOAD_T, class BASE>
451 template <class VALLOC>
452 JaggedVecProxyT<PAYLOAD_T, BASE>::operator std::vector<Payload_t, VALLOC>() const
453 {
454  return std::vector<Payload_t, VALLOC> (this->begin(), this->end());
455 }
456 
457 
458 /**
459  * @brief Add an item to the end of this jagged vector element.
460  * @param x The item to add.
461  */
462 template <class PAYLOAD_T, class BASE>
463 void JaggedVecProxyT<PAYLOAD_T, BASE>::push_back (const Payload_t& x)
464 {
465  this->m_base.adjust1 (m_index, size(), 1);
466  back() = x;
467 }
468 
469 
470 /**
471  * @brief Clear this jagged vector element.
472  */
473 template <class PAYLOAD_T, class BASE>
474 void JaggedVecProxyT<PAYLOAD_T, BASE>::clear()
475 {
476  this->m_base.resize1 (m_index, 0);
477 }
478 
479 
480 /**
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.
485  */
486 template <class PAYLOAD_T, class BASE>
487 void JaggedVecProxyT<PAYLOAD_T, BASE>::resize (size_t n,
488  const Payload_t& x /*= Payload_t()*/)
489 {
490  size_t sz = size();
491  this->m_base.adjust1 (m_index, sz, n - sz);
492  if (n > sz) {
493  std::fill_n (begin()+sz, n-sz, x);
494  }
495 }
496 
497 
498 /**
499  * @brief Erase one item from this jagged vector element.
500  * @param pos Position within the element of the item to erase.
501  */
502 template <class PAYLOAD_T, class BASE>
503 void JaggedVecProxyT<PAYLOAD_T, BASE>::erase (nonnull_iterator pos)
504 {
505  this->m_base.adjust1 (m_index, pos-begin()+1, -1);
506 }
507 
508 
509 /**
510  * @brief Erase one item from this jagged vector element.
511  * @param pos Index within the element of the item to erase.
512  */
513 template <class PAYLOAD_T, class BASE>
514 void JaggedVecProxyT<PAYLOAD_T, BASE>::erase (index_type pos)
515 {
516  this->m_base.adjust1 (m_index, pos+1, -1);
517 }
518 
519 
520 /**
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.
524  */
525 template <class PAYLOAD_T, class BASE>
526 void JaggedVecProxyT<PAYLOAD_T, BASE>::erase (nonnull_iterator first,
527  nonnull_iterator last)
528 {
529  this->m_base.adjust1 (m_index, last - begin(), -(last - first));
530 }
531 
532 
533 /**
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.
537  */
538 template <class PAYLOAD_T, class BASE>
539 void JaggedVecProxyT<PAYLOAD_T, BASE>::erase (index_type first, index_type last)
540 {
541  this->m_base.adjust1 (m_index, last, -(last - first));
542 }
543 
544 
545 /**
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.
549  */
550 template <class PAYLOAD_T, class BASE>
551 void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (nonnull_iterator pos,
552  const Payload_t& x)
553 {
554  insert (pos, 1, x);
555 }
556 
557 /**
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.
561  */
562 template <class PAYLOAD_T, class BASE>
563 void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (index_type pos,
564  const Payload_t& x)
565 {
566  insert (pos, 1, x);
567 }
568 
569 
570 /**
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.
575  */
576 template <class PAYLOAD_T, class BASE>
577 void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (nonnull_iterator pos,
578  size_t n,
579  const Payload_t& x)
580 {
581  size_t i = pos - begin();
582  this->m_base.adjust1 (m_index, i, n);
583  std::fill_n (begin()+i, n, x);
584 }
585 
586 
587 /**
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.
592  */
593 template <class PAYLOAD_T, class BASE>
594 void JaggedVecProxyT<PAYLOAD_T, BASE>::insert (index_type pos,
595  size_t n,
596  const Payload_t& x)
597 {
598  this->m_base.adjust1 (m_index, pos, n);
599  std::fill_n (begin()+pos, n, x);
600 }
601 
602 /**
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.
607  */
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,
611  ITERATOR first,
612  ITERATOR last)
613 {
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);
618 }
619 
620 
621 /**
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.
626  */
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,
630  ITERATOR first,
631  ITERATOR last)
632 {
633  size_t n_new = last - first;
634  this->m_base.adjust1 (m_index, pos, n_new);
635  std::copy (first, last, begin()+pos);
636 }
637 
638 
639 /**
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.
643  */
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,
647  const RANGE& range)
648 {
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);
653 }
654 
655 
656 /**
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.
660  */
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,
664  const RANGE& range)
665 {
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);
669 }
670 
671 
672 /**
673  * @brief Append a range of items to the end of this jagged vector element.
674  * @param range The range to append.
675  */
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)
679 {
680  size_t sz = size();
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);
684 }
685 
686 
687 /**
688  * @brief Remove the last item from this jagged vector element.
689  */
690 template <class PAYLOAD_T, class BASE>
691 void JaggedVecProxyT<PAYLOAD_T, BASE>::pop_back()
692 {
693  this->m_base.adjust1 (m_index, size(), -1);
694 }
695 
696 
697 /**
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.
701  */
702 template <class PAYLOAD_T, class BASE>
703 void JaggedVecProxyT<PAYLOAD_T, BASE>::assign (size_t n, const Payload_t& x)
704 {
705  this->m_base.resize1 (m_index, n);
706  std::fill_n (begin(), n, x);
707 }
708 
709 
710 /**
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.
714  */
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)
718 {
719  this->m_base.resize1 (m_index, last-first);
720  std::copy (first, last, begin());
721 }
722 
723 
724 /**
725  * @brief Assign this jagged vector element from a range.
726  * @param range The range from which to assign.
727  */
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)
731 {
732  this->m_base.resize1 (m_index, std::size (range));
733  std::copy (range.begin(), range.end(), begin());
734 }
735 
736 
737 /**
738  * @brief Return a reference to this proxy's element.
739  */
740 template <class PAYLOAD_T, class BASE>
741 inline
742 auto JaggedVecProxyT<PAYLOAD_T, BASE>::elt() noexcept -> Elt_t&
743 {
744  return this->m_base.elt (m_index);
745 }
746 
747 
748 /**
749  * @brief Return a (const) reference to this proxy's element.
750  */
751 template <class PAYLOAD_T, class BASE>
752 inline
753 auto JaggedVecProxyT<PAYLOAD_T, BASE>::elt() const noexcept -> const Elt_t&
754 {
755  const JaggedVecProxyBase& base = this->m_base;
756  return base.elt (m_index);
757 }
758 
759 
760 /**
761  * @brief Return the begin payload index of this proxy's element.
762  */
763 template <class PAYLOAD_T, class BASE>
764 inline
765 size_t JaggedVecProxyT<PAYLOAD_T, BASE>::elt_begin() const noexcept
766 {
767  if (m_index == 0) return 0;
768  const JaggedVecProxyBase& base = this->m_base;
769  return base.elt (m_index-1).end();
770 }
771 
772 
773 /**
774  * @brief Return the end payload index of this proxy's element.
775  */
776 template <class PAYLOAD_T, class BASE>
777 inline
778 size_t JaggedVecProxyT<PAYLOAD_T, BASE>::elt_end() const noexcept
779 {
780  const JaggedVecProxyBase& base = this->m_base;
781  return base.elt (m_index).end();
782 }
783 
784 
785 //****************************************************************************
786 
787 
788 /**
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.
793  */
794 template <class PAYLOAD_T>
795 inline
796 JaggedVecConverter<PAYLOAD_T>::JaggedVecConverter (AuxVectorData& container,
797  auxid_t auxid,
798  auxid_t linked_auxid)
799  : m_base (*container.getDataSpan (auxid), container, auxid),
800  m_payload (*container.getDataSpan (linked_auxid))
801 {
802 }
803 
804 
805 /**
806  * @brief Convert to a (read-only) span.
807  * @param elt The jagged vector element to transform.
808  */
809 template <class PAYLOAD_T>
810 inline
811 auto JaggedVecConverter<PAYLOAD_T>::operator() (const SG::JaggedVecEltBase& elt) const
812  -> const element_type
813 {
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");
819  }
820  const Payload_t* payload = m_payload.data();
821  return element_type (payload + beg, payload + end);
822 }
823 
824 
825 /**
826  * @brief Convert to a (writable) span.
827  * @param elt The jagged vector element to transform.
828  */
829 template <class PAYLOAD_T>
830 inline
831 auto JaggedVecConverter<PAYLOAD_T>::operator() (SG::JaggedVecEltBase& elt)
832  -> value_type
833 {
834  return value_type (&elt - &m_base.elt(0),
835  m_payload,
836  m_base);
837 }
838 
839 
840 } } // namespace SG::detail