ATLAS Offline Software
Loading...
Searching...
No Matches
AuxVectorBase.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/**
6 * @file AthContainers/AuxVectorBase.icc
7 * @author scott snyder <snyder@bnl.gov>
8 * @date Oct, 2013
9 * @brief Manage index tracking and synchronization of auxiliary data.
10 */
11
12
13namespace SG {
14
15
16/**
17 * @brief Return true if index tracking is enabled for this container.
18 */
19inline
20bool AuxVectorBase::trackIndices() const
21{
22 return m_trackIndices;
23}
24
25
26/**
27 * @brief Synonym for @c setStore with @c IConstAuxStore.
28 * @param store The new store.
29 */
30inline
31void AuxVectorBase::setConstStore (const SG::IConstAuxStore* store)
32{
33 setStore (store);
34}
35
36
37/**
38 * @brief Synonym for @c setStore with @c IAuxStore.
39 * @param store The new store.
40 */
41inline
42void AuxVectorBase::setNonConstStore (SG::IAuxStore* store)
43{
44 setStore (store);
45}
46
47
48/**
49 * @brief Test to see if a variable exists in the store.
50 * @param name Name of the aux variable.
51 * @param clsname The name of the associated class. May be blank.
52 */
53template <class T>
54inline
55bool AuxVectorBase::isAvailable (const std::string& name,
56 const std::string& clsname /*= ""*/) const
57{
58 auxid_t id = SG::AuxTypeRegistry::instance().getAuxID<T> (name, clsname);
59 return AuxVectorData::isAvailable (id);
60}
61
62
63/**
64 * @brief Test to see if a variable is available for writing.
65 * @param name Name of the aux variable.
66 * @param clsname The name of the associated class. May be blank.
67 */
68template <class T>
69inline
70bool
71AuxVectorBase::isAvailableWritable (const std::string& name,
72 const std::string& clsname /*= ""*/)
73{
74 auxid_t id = SG::AuxTypeRegistry::instance().getAuxID<T> (name, clsname);
75 return AuxVectorData::isAvailableWritable (id);
76}
77
78
79/**
80 * @brief Test to see if a variable is available for writing as a decoration.
81 * @param name Name of the aux variable.
82 * @param clsname The name of the associated class. May be blank.
83 */
84template <class T>
85inline
86bool
87AuxVectorBase::isAvailableWritableAsDecoration (const std::string& name,
88 const std::string& clsname /*= ""*/) const
89{
90 auxid_t id = SG::AuxTypeRegistry::instance().getAuxID<T> (name, clsname);
91 return AuxVectorData::isAvailableWritableAsDecoration (id);
92}
93
94
95/**
96 * @brief Return a span over an aux data item.
97 * @param auxid The desired aux data item.
98 *
99 * This will return a span containing the value of the requested
100 * auxiliary variable for all elements in the container.
101 * If the item doesn't exist, it will be created.
102 * Errors are signaled by raising an exception.
103 * Note that the @c value_type of the span is not necessarily @c T;
104 * an example is @c bool for which we return a span of @c char.
105 */
106template <class T>
107AuxVectorBase::span<T> AuxVectorBase::getDataSpan (const std::string& name)
108{
109 using container_pointer_type = typename AuxDataTraits<T>::container_pointer_type;
110 auxid_t id = SG::AuxTypeRegistry::instance().getAuxID<T> (name);
111 auto beg = reinterpret_cast<container_pointer_type> (AuxVectorData::getDataArray (id));
112 return span<T> (beg, size_v());
113}
114
115
116/**
117 * @brief Return a span over an aux data item.
118 * @param auxid The desired aux data item.
119 *
120 * This will return a span containing the value of the requested
121 * auxiliary variable for all elements in the container.
122 * If the item doesn't exist, it will be created.
123 * Errors are signaled by raising an exception.
124 * Note that the @c value_type of the span is not necessarily @c T;
125 * an example is @c bool for which we return a span of @c char.
126 */
127template <class T>
128AuxVectorBase::const_span<T>
129AuxVectorBase::getDataSpan (const std::string& name) const
130{
131 using const_container_pointer_type = typename AuxDataTraits<T>::const_container_pointer_type;
132 auxid_t id = SG::AuxTypeRegistry::instance().getAuxID<T> (name);
133 auto beg = reinterpret_cast<const_container_pointer_type> (AuxVectorData::getDataArray (id));
134 return const_span<T> (beg, size_v());
135}
136
137
138/**
139 * @brief Return a span over an aux data item for a decoration.
140 * @param auxid The desired aux data item.
141 *
142 * This will return a span containing the value of the requested
143 * auxiliary variable for all elements in the container.
144 * If the item doesn't exist, it will be created.
145 * Errors are signaled by raising an exception.
146 * Note that the @c value_type of the span is not necessarily @c T;
147 * an example is @c bool for which we return a span of @c char.
148 *
149 * The difference between @c getDecorationSpan and @c getDataSpan is that
150 * @c getDecorationSpan takes a const container as input, but returns
151 * a span over non-const objects. This will only succeed if either the
152 * container is not locked or the item was first accessed
153 * as a decoration.
154 */
155template <class T>
156AuxVectorBase::span<T>
157AuxVectorBase::getDecorationSpan (const std::string& name) const
158{
159 using container_pointer_type = typename AuxDataTraits<T>::container_pointer_type;
160 auxid_t id = SG::AuxTypeRegistry::instance().getAuxID<T> (name);
161 auto beg = reinterpret_cast<container_pointer_type> (AuxVectorData::getDecorationArray (id));
162 return span<T> (beg, size_v());
163}
164
165
166/**
167 * @brief Return a span over an aux data item.
168 * @param auxid The desired aux data item.
169 *
170 * This will return a span containing the value of the requested
171 * auxiliary variable for all elements in the container.
172 * If the item doesn't exist, it will be created.
173 * Errors are signaled by raising an exception.
174 * Note that the @c value_type of the span is not necessarily @c T;
175 * an example is @c bool for which we return a span of @c char.
176 */
177template <class T>
178AuxVectorBase::const_span<T>
179AuxVectorBase::getConstDataSpan (const std::string& name) const
180{
181 using const_container_pointer_type = typename AuxDataTraits<T>::const_container_pointer_type;
182 auxid_t id = SG::AuxTypeRegistry::instance().getAuxID<T> (name);
183 auto beg = reinterpret_cast<const_container_pointer_type> (AuxVectorData::getDataArray (id));
184 return const_span<T> (beg, size_v());
185}
186
187
188/**
189 * @brief Initialize index tracking mode.
190 * @param ownPolicy The container ownership policy.
191 * @param indexTrackingPolicy The requested index tracking policy.
192 *
193 * DVL should be the most-derived class for this container.
194 *
195 * This handles the logic for setting the state of index tracking.
196 * If this container does not handle aux data, then index tracking
197 * is always off. Otherwise, it depends on the requested policies.
198 * In any case, it is an error to turn off index tracking
199 * for a container that has an associated aux store.
200 */
201template <class DVL>
202inline
203void
204AuxVectorBase::initAuxVectorBase (SG::OwnershipPolicy ownPolicy,
205 SG::IndexTrackingPolicy indexTrackingPolicy)
206{
207 // Forward to the appropriate specialization, depending on whether
208 // or not aux data is supported.
209 this->initAuxVectorBase1 (typename AuxStore_traits<DVL>::flag(),
210 ownPolicy,
211 indexTrackingPolicy);
212}
213
214
215/**
216 * @brief Swap with another container.
217 * @param other The container with which to swap.
218 */
219inline
220void AuxVectorBase::swap (AuxVectorBase& other)
221{
222 std::swap (m_trackIndices, other.m_trackIndices);
223 SG::AuxVectorData::swap (other);
224}
225
226
227/**
228 * @brief Set container/index for all elements within a range.
229 * @param beg Beginning of the range.
230 * @param end End of the range.
231 * @param first Index to set for the first element in the range.
232 *
233 * For all elements in the range, the container will be set to this container,
234 * and indices will be set sequentially, starting with @c first.
235 *
236 * @c ForwardIterator should be an iterator over the @c DataVector
237 * (not a base iterator).
238 */
239template <class ForwardIterator>
240inline
241void AuxVectorBase::setIndices (ForwardIterator beg,
242 ForwardIterator end,
243 size_t first /*= 0*/)
244{
245 // Forward to the appropriate specialization, depending on whether
246 // or not aux data is supported.
247 typedef typename std::iterator_traits<ForwardIterator>::value_type valtype;
248 setIndices1 (typename AuxStore_traits<valtype>::flag(),
249 beg, end, first);
250}
251
252
253/**
254 * @brief Set container/index for all elements within a range.
255 * @param beg Beginning of the range.
256 * @param end End of the range.
257 * @param first Index to set for the first element in the range.
258 *
259 * This is the no-auxdata case; doesn't do anything other than checking
260 * @c m_trackIndices.
261 */
262template <class ForwardIterator>
263inline
264void AuxVectorBase::setIndices1 (const std::false_type&,
265 ForwardIterator,
266 ForwardIterator,
267 size_t)
268{
269 ATHCONTAINERS_ASSERT (!m_trackIndices);
270}
271
272
273/**
274 * @brief Set container/index for all elements within a range.
275 * @param beg Beginning of the range.
276 * @param end End of the range.
277 * @param first Index to set for the first element in the range.
278 *
279 * This is the auxdata case.
280 * For all elements in the range, the container will be set to this container,
281 * and indices will be set sequentially, starting with @c first.
282 */
283template <class ForwardIterator>
284void AuxVectorBase::setIndices1 (const std::true_type&,
285 ForwardIterator beg,
286 ForwardIterator end,
287 size_t first)
288{
289 if (!m_trackIndices)
290 return;
291
292 for (; beg != end; ++beg) {
293 if (*beg)
294 (*beg)->setIndex (first, this);
295 ++first;
296 }
297}
298
299
300/**
301 * @brief Clear the container / index for element @c elt.
302 * @param elt Iterator to the element to clear.
303 *
304 * @c ForwardIterator should be an iterator over the @c DataVector
305 * (not a base iterator).
306 */
307template <class ForwardIterator>
308inline
309void AuxVectorBase::clearIndex (ForwardIterator elt)
310{
311 // Forward to the appropriate specialization, depending on whether
312 // or not aux data is supported.
313 typedef typename std::iterator_traits<ForwardIterator>::value_type valtype;
314 clearIndex1 (typename AuxStore_traits<valtype>::flag(), elt);
315}
316
317
318/**
319 * @brief Clear the container / index for element @c elt.
320 * @param elt Iterator to the element to clear.
321 *
322 * This is the no-auxdata case; doesn't do anything other than checking
323 * @c m_trackIndices.
324 */
325template <class ForwardIterator>
326inline
327void AuxVectorBase::clearIndex1 (const std::false_type&,
328 ForwardIterator /*elt*/)
329{
330 ATHCONTAINERS_ASSERT (!m_trackIndices);
331}
332
333
334/**
335 * @brief Clear the container / index for element @c elt.
336 * @param elt Iterator to the element to clear.
337 *
338 * This is the auxdata case.
339 */
340template <class ForwardIterator>
341void AuxVectorBase::clearIndex1 (const std::true_type&,
342 ForwardIterator elt)
343{
344 if (!m_trackIndices)
345 return;
346
347 if (*elt)
348 (*elt)->setIndex (0, 0);
349}
350
351
352/**
353 * @brief Clear the container / index for a range of elements.
354 * @param beg Beginning of the range.
355 * @param end End of the range.
356 *
357 * @c ForwardIterator should be an iterator over the @c DataVector
358 * (not a base iterator).
359 */
360template <class ForwardIterator>
361void AuxVectorBase::clearIndices (ForwardIterator beg,
362 ForwardIterator end)
363{
364 // Forward to the appropriate specialization, depending on whether
365 // or not aux data is supported.
366 typedef typename std::iterator_traits<ForwardIterator>::value_type valtype;
367 clearIndices1 (typename AuxStore_traits<valtype>::flag(),
368 beg, end);
369}
370
371
372/**
373 * @brief Clear the container / index for a range of elements.
374 * @param beg Beginning of the range.
375 * @param end End of the range.
376 *
377 * No-auxdata case; a no-op except for checking @c m_trackIndices.
378 */
379template <class ForwardIterator>
380inline
381void AuxVectorBase::clearIndices1 (const std::false_type&,
382 ForwardIterator,
383 ForwardIterator)
384{
385 ATHCONTAINERS_ASSERT (!m_trackIndices);
386}
387
388
389/**
390 * @brief Clear the container / index for a range of elements.
391 * @param beg Beginning of the range.
392 * @param end End of the range.
393 *
394 * Auxdata case.
395 */
396template <class ForwardIterator>
397void AuxVectorBase::clearIndices1 (const std::true_type&,
398 ForwardIterator beg,
399 ForwardIterator end)
400{
401 if (!m_trackIndices)
402 return;
403
404 for (; beg != end; ++beg)
405 if (*beg)
406 (*beg)->setIndex (0, 0);
407}
408
409
410/**
411 * @brief Resize the aux data associated with this container.
412 * @param size The new container size.
413 *
414 * DVL should be the most-derived class for this container.
415 */
416template <class DVL>
417inline
418void AuxVectorBase::resize (size_t size)
419{
420 // Forward to the appropriate specialization, depending on whether
421 // or not aux data is supported.
422 resize1 (typename AuxStore_traits<DVL>::flag(), size);
423}
424
425
426/**
427 * @brief Resize the aux data associated with this container.
428 * @param size The new container size.
429 *
430 * The no-auxdata case; a no-op except for checking @c m_trackIndices.
431 */
432inline
433void
434AuxVectorBase::resize1 (const std::false_type&, size_t /*size*/)
435{
436 ATHCONTAINERS_ASSERT (!m_trackIndices);
437}
438
439
440/**
441 * @brief Change the capacity of the aux data associated with this container.
442 * @param size The new container size.
443 *
444 * DVL should be the most-derived class for this container.
445 */
446template <class DVL>
447inline
448void AuxVectorBase::reserve (size_t size)
449{
450 // Forward to the appropriate specialization, depending on whether
451 // or not aux data is supported.
452 reserve1 (typename AuxStore_traits<DVL>::flag(), size);
453}
454
455
456/**
457 * @brief Change the capacity of the aux data associated with this container.
458 * @param size The new container size.
459 *
460 * The no-auxdata case; a no-op except for checking @c m_trackIndices.
461 */
462inline
463void AuxVectorBase::reserve1 (const std::false_type&, size_t)
464{
465 ATHCONTAINERS_ASSERT (!m_trackIndices);
466}
467
468
469/**
470 * @brief Shift the elements of the container.
471 * @param cont The container that's being shifted.
472 * @param pos The starting index for the shift.
473 * @param offs The (signed) amount of the shift.
474 *
475 * The container should be the derived container.
476 * The elements in the container should have already been shifted;
477 * this operation will then adjust the element indices and also shift
478 * the elements in the vectors for all aux data items.
479 * @c offs may be either positive or negative.
480 *
481 * If @c offs is positive, then the container is growing.
482 * The container size should be increased by @c offs,
483 * the element at @c pos moved to @c pos + @c offs,
484 * and similarly for following elements.
485 * The elements between @c pos and @c pos + @c offs should
486 * be default-initialized.
487 *
488 * If @c offs is negative, then the container is shrinking.
489 * The element at @c pos should be moved to @c pos + @c offs,
490 * and similarly for following elements.
491 * The container should then be shrunk by @c -offs elements
492 * (running destructors as appropriate).
493 */
494template <class DVL>
495inline
496void AuxVectorBase::shift (DVL& cont,
497 size_t pos,
498 ptrdiff_t offs)
499{
500 // Forward to the appropriate specialization, depending on whether
501 // or not aux data is supported.
502 shift1 (typename AuxStore_traits<DVL>::flag(),
503 cont, pos, offs);
504}
505
506
507/**
508 * @brief Shift the elements of the container.
509 * @param cont The container that's being shifted.
510 * @param pos The starting index for the shift.
511 * @param offs The (signed) amount of the shift.
512 *
513 * No-auxdata version; a no-op except for checking @c m_trackIndices.
514 */
515template <class DVL>
516inline
517void AuxVectorBase::shift1 (const std::false_type&,
518 DVL& /*cont*/,
519 size_t /*pos*/, ptrdiff_t /*offs*/)
520{
521 ATHCONTAINERS_ASSERT (!m_trackIndices);
522}
523
524
525/**
526 * @brief Shift the elements of the container.
527 * @param cont The container that's being shifted.
528 * @param pos The starting index for the shift.
529 * @param offs The (signed) amount of the shift.
530 *
531 * Auxdata version.
532 *
533 * The container should be the derived container.
534 * The elements in the container should have already been shifted;
535 * this operation will then adjust the element indices and also shift
536 * the elements in the vectors for all aux data items.
537 * @c offs may be either positive or negative.
538 *
539 * If @c offs is positive, then the container is growing.
540 * The container size should be increased by @c offs,
541 * the element at @c pos moved to @c pos + @c offs,
542 * and similarly for following elements.
543 * The elements between @c pos and @c pos + @c offs should
544 * be default-initialized.
545 *
546 * If @c offs is negative, then the container is shrinking.
547 * The element at @c pos should be moved to @c pos + @c offs,
548 * and similarly for following elements.
549 * The container should then be shrunk by @c -offs elements
550 * (running destructors as appropriate).
551 */
552template <class DVL>
553void AuxVectorBase::shift1 (const std::true_type&,
554 DVL& cont,
555 size_t pos, ptrdiff_t offs)
556{
557 if (!m_trackIndices) return;
558
559 typename DVL::iterator end = cont.end();
560 typename DVL::iterator pos_it = cont.begin() + pos + offs;
561 for (; pos_it != end; ++pos_it)
562 {
563 SG::AuxElement* elt = *pos_it;
564 elt->setIndex (elt->index() + offs, this);
565 }
566
567 if (this->hasNonConstStore()) {
568 this->getStore()->shift (pos, offs);
569 clearCache();
570 }
571 else if (this->hasStore())
572 throw SG::ExcConstAuxData ("shift");
573}
574
575
576/**
577 * @brief Set index on an element and copy auxiliary data.
578 * @param index Container index at which the new element is being added.
579 * @param p The new element being added.
580 * @param clear If true, then any auxiliary data initially associated
581 * with @c p are cleared after being copied.
582 *
583 * Overload for the no-auxdata case.
584 */
585inline
586void
587AuxVectorBase::moveAux (size_t /*index*/,
588 const void /*p*/*,
589 bool /*clear = false*/,
590 bool /*skipDestClear = false*/)
591{
592 ATHCONTAINERS_ASSERT (!m_trackIndices);
593}
594
595
596/**
597 * @brief Set index on a range of elements and copy auxiliary data.
598 * @param index Container index at which the first new element is being added.
599 * @param beg The start of the range of new elements.
600 * @param end The end of the range of new elements.
601 * @param clear If true, then any auxiliary data initially associated
602 * with the elements are cleared after being copied.
603 * @param skipDestClear Normally, if the elements do not have auxiliary data,
604 * then the variables of the destination are cleared.
605 * If this flag is true, then this clear is skipped.
606 * This can be appropriate as part of a push_back,
607 * where the destination is already known to be clear.
608 *
609 * The elements in the range are being a added to the container at @c index.
610 * If the new elements have associated auxiliary data,
611 * copy it to the container starting at @c index.
612 * Then set the container / index on the elements in the range.
613 *
614 * @c ForwardIterator should be an iterator over the @c DataVector
615 * (not a base iterator).
616 */
617template <class ForwardIterator>
618void
619AuxVectorBase::moveAux (size_t index, ForwardIterator beg, ForwardIterator end,
620 bool clear /*= false*/,
621 bool skipDestClear /*= false*/)
622{
623 // Forward to the appropriate specialization, depending on whether
624 // or not aux data is supported.
625 typedef typename std::iterator_traits<ForwardIterator>::value_type valtype;
626 moveAux1 (typename AuxStore_traits<valtype>::flag(),
627 index, beg, end, clear, skipDestClear);
628}
629
630
631/**
632 * @brief Set index on a range of elements and copy auxiliary data.
633 * @param index Container index at which the first new element is being added.
634 * @param beg The start of the range of new elements.
635 * @param end The end of the range of new elements.
636 * @param clear If true, then any auxiliary data initially associated
637 * with the elements are cleared after being copied.
638 * @param skipDestClear Normally, if the elements do not have auxiliary data,
639 * then the variables of the destination are cleared.
640 * If this flag is true, then this clear is skipped.
641 * This can be appropriate as part of a push_back,
642 * where the destination is already known to be clear.
643 *
644 * No-auxdata version; a no-op except for checking @c m_trackIndices.
645 */
646template <class ForwardIterator>
647inline
648void AuxVectorBase::moveAux1 (const std::false_type&,
649 size_t /*index*/,
650 ForwardIterator /*beg*/,
651 ForwardIterator /*end*/,
652 bool /*clear = false*/,
653 bool /*skipDestClear = false*/)
654{
655 ATHCONTAINERS_ASSERT (!m_trackIndices);
656}
657
658
659/**
660 * @brief Set index on a range of elements and copy auxiliary data.
661 * @param index Container index at which the first new element is being added.
662 * @param beg The start of the range of new elements.
663 * @param end The end of the range of new elements.
664 * @param clear If true, then any auxiliary data initially associated
665 * with the elements are cleared after being copied.
666 * @param skipDestClear Normally, if the elements do not have auxiliary data,
667 * then the variables of the destination are cleared.
668 * If this flag is true, then this clear is skipped.
669 * This can be appropriate as part of a push_back,
670 * where the destination is already known to be clear.
671 *
672 * The elements in the range are being a added to the container at @c index.
673 * If the new elements have associated auxiliary data,
674 * copy it to the container starting at @c index.
675 * Then set the container / index on the elements in the range.
676 *
677 * The auxdata case.
678 */
679template <class ForwardIterator>
680void AuxVectorBase::moveAux1 (const std::true_type&,
681 size_t index,
682 ForwardIterator beg,
683 ForwardIterator end,
684 bool clear /*= false*/,
685 bool skipDestClear /*= false*/)
686{
687 if (!m_trackIndices)
688 return;
689
690 while (beg != end) {
691 this->moveAux (index, *beg, clear, skipDestClear);
692 ++beg;
693 ++index;
694 }
695}
696
697
698/**
699 * @brief Swap indices and auxiliary data between two elements.
700 * @param aindex Index of the first element, in this container.
701 * @param bindex Index of the second element, in @c bcont.
702 * @param a Pointer to the first element.
703 * @param b Pointer to the second element.
704 * @param bcont Container holding the second element.
705 * (May be the same as this, but doesn't have to be.)
706 *
707 * This is the no-auxdata case; it is a no-op except for checking
708 * @c m_trackIndices.
709 */
710inline
711void AuxVectorBase::swapElementsAux (size_t /*aindex*/,
712 size_t /*bindex*/,
713 const void* /*a*/,
714 const void* /*b*/,
715 AuxVectorBase* /*bcont*/)
716{
717 ATHCONTAINERS_ASSERT (!m_trackIndices);
718}
719
720
721/**
722 * @brief Reset indices / reorder aux data after elements have been permuted.
723 * @param index Index in the container of the start of the range.
724 * @param beg Start of the range of elements to process.
725 * @param end End of the range of elements to process.
726 *
727 * Call this after some operation that has permuted the elements in the
728 * container (such as sort). The index information in the elements
729 * will be used to permute all auxiliary data in the same way.
730 * Finally, all the indices will be reset in the correct order.
731 *
732 * @c ForwardIterator should be an iterator over the @c DataVector
733 * (not a base iterator).
734 */
735template <class ForwardIterator>
736inline
737void AuxVectorBase::resortAux (size_t index,
738 ForwardIterator beg,
739 ForwardIterator end)
740{
741 // If the xAOD base classes are used, then they always report that
742 // static auxids are present. However, if the container is empty,
743 // these variables are not actually retrievable, which can cause
744 // an exception in the ResortAuxHelper ctor. Work around here.
745 if (beg==end) return;
746
747 // Forward to the appropriate specialization, depending on whether
748 // or not aux data is supported.
749 typedef typename std::iterator_traits<ForwardIterator>::value_type valtype;
750 resortAux1 (typename AuxStore_traits<valtype>::flag(),
751 index, beg, end);
752}
753
754
755/**
756 * @brief Reset indices / reorder aux data after elements have been permuted.
757 * @param index Index in the container of the start of the range.
758 * @param beg Start of the range of elements to process.
759 * @param end End of the range of elements to process.
760 *
761 * No-auxdata version; a no-op except for checking @c m_trackIndices.
762 */
763template <class ForwardIterator>
764inline
765void AuxVectorBase::resortAux1 (const std::false_type&,
766 size_t /*index*/,
767 ForwardIterator /*beg*/,
768 ForwardIterator /*end*/)
769{
770 ATHCONTAINERS_ASSERT (!m_trackIndices);
771}
772
773
774/**
775 * @brief Reset indices / reorder aux data after elements have been permuted.
776 * @param index Index in the container of the start of the range.
777 * @param beg Start of the range of elements to process.
778 * @param end End of the range of elements to process.
779 *
780 * Call this after some operation that has permuted the elements in the
781 * container (such as sort). The index information in the elements
782 * will be used to permute all auxiliary data in the same way.
783 * Finally, all the indices will be reset in the correct order.
784 *
785 * The auxdata case.
786 */
787template <class ForwardIterator>
788void AuxVectorBase::resortAux1 (const std::true_type&,
789 size_t index,
790 ForwardIterator beg,
791 ForwardIterator end)
792{
793 if (!m_trackIndices) return;
794 if (!this->hasStore()) {
795 this->setIndices (beg, end, index);
796 return;
797 }
798 if (!this->hasNonConstStore()) {
799 throw SG::ExcConstAuxData ("resortAux");
800 }
801
802 ResortAuxHelper h (end-beg, index, *this);
803 for (size_t i = 0; beg < end; ++beg, ++i)
804 h.resortElement (i, *beg);
805}
806
807
808/// Helper to call @c getDataArray from @c ResortAuxHelper.
809inline
810void* AuxVectorBase::getDataArrayForResort (SG::auxid_t auxid)
811{
812 return this->getDataArray (auxid);
813}
814
815
816/// Helper to call @c setIndex from @c ResortAuxHelper.
817inline
818void AuxVectorBase::setIndexForResort (SG::AuxElement* elt, size_t i)
819{
820 elt->setIndex (i, this);
821}
822
823
824} // namespace SG