@@ -567,7 +567,41 @@ void ROOT::RVectorField::ResizeVector(void *vec, std::size_t nItems, std::size_t
567567 itemDeleter->operator ()(typedValue->data () + (i * itemSize), true /* dtorOnly */ );
568568 }
569569 }
570- typedValue->resize (nItems * itemSize);
570+
571+ // Resize the vector with correct alignment
572+ const auto itemAlignment = itemField.GetAlignment ();
573+ const auto nbytes = nItems * itemSize;
574+
575+ auto fnAlignedResize = [](auto &vecOfAlignedStorage, std::size_t targetSize) {
576+ constexpr auto valueTypeSize = sizeof (typename std::decay_t <decltype (vecOfAlignedStorage)>::value_type);
577+ constexpr auto valueTypeAlignment = alignof (typename std::decay_t <decltype (vecOfAlignedStorage)>::value_type);
578+ // Ensure that this function is used with RAlignedStorage as a template argument.
579+ // In general, the actual (user-defined) item type may have larger size than alignment.
580+ static_assert (valueTypeSize == valueTypeAlignment);
581+ assert (targetSize % valueTypeAlignment == 0 );
582+ vecOfAlignedStorage.resize (targetSize / valueTypeSize);
583+ };
584+
585+ static_assert (kMaxItemAlignment == 4096 );
586+ // clang-format off
587+ switch (itemAlignment) {
588+ case 1 : fnAlignedResize (*static_cast <std::vector<Internal::RAlignedStorage< 1 >> *>(vec), nbytes); break ;
589+ case 2 : fnAlignedResize (*static_cast <std::vector<Internal::RAlignedStorage< 2 >> *>(vec), nbytes); break ;
590+ case 4 : fnAlignedResize (*static_cast <std::vector<Internal::RAlignedStorage< 4 >> *>(vec), nbytes); break ;
591+ case 8 : fnAlignedResize (*static_cast <std::vector<Internal::RAlignedStorage< 8 >> *>(vec), nbytes); break ;
592+ case 16 : fnAlignedResize (*static_cast <std::vector<Internal::RAlignedStorage< 16 >> *>(vec), nbytes); break ;
593+ case 32 : fnAlignedResize (*static_cast <std::vector<Internal::RAlignedStorage< 32 >> *>(vec), nbytes); break ;
594+ case 64 : fnAlignedResize (*static_cast <std::vector<Internal::RAlignedStorage< 64 >> *>(vec), nbytes); break ;
595+ case 128 : fnAlignedResize (*static_cast <std::vector<Internal::RAlignedStorage< 128 >> *>(vec), nbytes); break ;
596+ case 256 : fnAlignedResize (*static_cast <std::vector<Internal::RAlignedStorage< 256 >> *>(vec), nbytes); break ;
597+ case 512 : fnAlignedResize (*static_cast <std::vector<Internal::RAlignedStorage< 512 >> *>(vec), nbytes); break ;
598+ case 1024 : fnAlignedResize (*static_cast <std::vector<Internal::RAlignedStorage<1024 >> *>(vec), nbytes); break ;
599+ case 2048 : fnAlignedResize (*static_cast <std::vector<Internal::RAlignedStorage<2048 >> *>(vec), nbytes); break ;
600+ case 4096 : fnAlignedResize (*static_cast <std::vector<Internal::RAlignedStorage<4096 >> *>(vec), nbytes); break ;
601+ default : throw RException (R__FAIL (std::string (" Unsupported alignment: " ) + std::to_string (itemAlignment)));
602+ }
603+ // clang-format on
604+
571605 if (!(itemField.GetTraits () & kTraitTriviallyConstructible )) {
572606 for (std::size_t i = allDeallocated ? 0 : oldNItems; i < nItems; ++i) {
573607 CallConstructValueOn (itemField, typedValue->data () + (i * itemSize));
0 commit comments