ATLAS Offline Software
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 
13 namespace SG {
14 
15 
16 /**
17  * @brief Return true if index tracking is enabled for this container.
18  */
19 inline
20 bool 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  */
30 inline
31 void 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  */
41 inline
42 void 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  */
53 template <class T>
54 inline
55 bool 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  */
68 template <class T>
69 inline
70 bool
71 AuxVectorBase::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  */
84 template <class T>
85 inline
86 bool
87 AuxVectorBase::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  */
106 template <class T>
107 AuxVectorBase::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  */
127 template <class T>
128 AuxVectorBase::const_span<T>
129 AuxVectorBase::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  */
155 template <class T>
156 AuxVectorBase::span<T>
157 AuxVectorBase::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  */
177 template <class T>
178 AuxVectorBase::const_span<T>
179 AuxVectorBase::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  */
201 template <class DVL>
202 inline
203 void
204 AuxVectorBase::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  */
219 inline
220 void 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  */
239 template <class ForwardIterator>
240 inline
241 void 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  */
262 template <class ForwardIterator>
263 inline
264 void 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  */
283 template <class ForwardIterator>
284 void 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  */
307 template <class ForwardIterator>
308 inline
309 void 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  */
325 template <class ForwardIterator>
326 inline
327 void 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  */
340 template <class ForwardIterator>
341 void 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  */
360 template <class ForwardIterator>
361 void 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  */
379 template <class ForwardIterator>
380 inline
381 void 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  */
396 template <class ForwardIterator>
397 void 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  */
416 template <class DVL>
417 inline
418 void 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  */
432 inline
433 void
434 AuxVectorBase::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  */
446 template <class DVL>
447 inline
448 void 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  */
462 inline
463 void 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  */
494 template <class DVL>
495 inline
496 void 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  */
515 template <class DVL>
516 inline
517 void 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  */
552 template <class DVL>
553 void 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  */
585 inline
586 void
587 AuxVectorBase::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  */
617 template <class ForwardIterator>
618 void
619 AuxVectorBase::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  */
646 template <class ForwardIterator>
647 inline
648 void 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  */
679 template <class ForwardIterator>
680 void 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  */
710 inline
711 void 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  */
735 template <class ForwardIterator>
736 inline
737 void 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  */
763 template <class ForwardIterator>
764 inline
765 void 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  */
787 template <class ForwardIterator>
788 void 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.
809 inline
810 void* AuxVectorBase::getDataArrayForResort (SG::auxid_t auxid)
811 {
812  return this->getDataArray (auxid);
813 }
814 
815 
816 /// Helper to call @c setIndex from @c ResortAuxHelper.
817 inline
818 void AuxVectorBase::setIndexForResort (SG::AuxElement* elt, size_t i)
819 {
820  elt->setIndex (i, this);
821 }
822 
823 
824 } // namespace SG