@@ -44,6 +44,29 @@ std::size_t GetAlignOfVector()
4444 return alignof (std::vector<char >);
4545}
4646
47+ void ConstructVector (void *where, std::size_t alignOfValue)
48+ {
49+ if (alignOfValue <= sizeof (std::max_align_t )) {
50+ new (where) std::vector<char >();
51+ } else {
52+ static_assert (sizeof (std::max_align_t ) >= 8 && ROOT ::RFieldBase::kMaxAlignment == 4096 );
53+ // clang-format off
54+ switch (alignOfValue) {
55+ case 16 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 16 >>(); break ;
56+ case 32 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 32 >>(); break ;
57+ case 64 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 64 >>(); break ;
58+ case 128 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 128 >>(); break ;
59+ case 256 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 256 >>(); break ;
60+ case 512 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 512 >>(); break ;
61+ case 1024 : new (where) std::vector<ROOT ::Internal::RAlignedStorage<1024 >>(); break ;
62+ case 2048 : new (where) std::vector<ROOT ::Internal::RAlignedStorage<2048 >>(); break ;
63+ case 4096 : new (where) std::vector<ROOT ::Internal::RAlignedStorage<4096 >>(); break ;
64+ default : R__ASSERT (false );
65+ }
66+ // clang-format on
67+ }
68+ }
69+
4770} // anonymous namespace
4871
4972ROOT ::RArrayField::RArrayField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField,
@@ -673,33 +696,62 @@ void ROOT::RVectorField::ReconcileOnDiskField(const RNTupleDescriptor &desc)
673696 EnsureMatchingOnDiskCollection (desc).ThrowOnError ();
674697}
675698
676- ROOT ::RVectorField::RVectorDeleter::RVectorDeleter() : RDeleter(GetAlignOfVector()) {}
699+ void ROOT::RVectorField::ConstructValue (void *where) const
700+ {
701+ ConstructVector (where, fSubfields [0 ]->GetAlignment ());
702+ }
703+
704+ ROOT ::RVectorField::RVectorDeleter::RVectorDeleter(std::size_t itemAlignment)
705+ : RDeleter(GetAlignOfVector()), fItemAlignment (itemAlignment)
706+ {}
677707
678- ROOT ::RVectorField::RVectorDeleter::RVectorDeleter(std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
679- : RDeleter(GetAlignOfVector()), fItemSize (itemSize), fItemDeleter (std::move(itemDeleter))
708+ ROOT ::RVectorField::RVectorDeleter::RVectorDeleter(std::size_t itemSize, std::size_t itemAlignment,
709+ std::unique_ptr<RDeleter> itemDeleter)
710+ : RDeleter(GetAlignOfVector()), fItemSize (itemSize), fItemAlignment (itemAlignment),
711+ fItemDeleter (std::move(itemDeleter))
680712{
681713}
682714
683715void ROOT::RVectorField::RVectorDeleter::operator ()(void *objPtr, bool dtorOnly)
684716{
685717 auto vecPtr = static_cast <std::vector<char > *>(objPtr);
686718 if (fItemDeleter ) {
687- R__ASSERT (fItemSize > 0 );
688- R__ASSERT ((vecPtr->size () % fItemSize ) == 0 );
719+ assert (fItemSize > 0 );
689720 auto nItems = vecPtr->size () / fItemSize ;
721+ assert ((vecPtr->size () % fItemSize ) == 0 );
690722 for (std::size_t i = 0 ; i < nItems; ++i) {
691723 fItemDeleter ->operator ()(vecPtr->data () + (i * fItemSize ), true /* dtorOnly */ );
692724 }
693725 }
694- std::destroy_at (vecPtr);
726+
727+ if (fItemAlignment <= sizeof (std::max_align_t )) {
728+ std::destroy_at (vecPtr);
729+ } else {
730+ static_assert (sizeof (std::max_align_t ) >= 8 && ROOT ::RFieldBase::kMaxAlignment == 4096 );
731+ // clang-format off
732+ switch (fItemAlignment ) {
733+ case 16 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 16 >> *>(objPtr)); break ;
734+ case 32 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 32 >> *>(objPtr)); break ;
735+ case 64 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 64 >> *>(objPtr)); break ;
736+ case 128 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 128 >> *>(objPtr)); break ;
737+ case 256 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 256 >> *>(objPtr)); break ;
738+ case 512 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 512 >> *>(objPtr)); break ;
739+ case 1024 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage<1024 >> *>(objPtr)); break ;
740+ case 2048 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage<2048 >> *>(objPtr)); break ;
741+ case 4096 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage<4096 >> *>(objPtr)); break ;
742+ default : R__ASSERT (false );
743+ }
744+ // clang-format on
745+ }
746+
695747 RDeleter::operator ()(objPtr, dtorOnly);
696748}
697749
698750std::unique_ptr<ROOT ::RFieldBase::RDeleter> ROOT::RVectorField::GetDeleter () const
699751{
700752 if (fItemDeleter )
701- return std::make_unique<RVectorDeleter>(fItemSize , GetDeleterOf (*fSubfields [0 ]));
702- return std::make_unique<RVectorDeleter>();
753+ return std::make_unique<RVectorDeleter>(fItemSize , fSubfields [ 0 ]-> GetAlignment (), GetDeleterOf (*fSubfields [0 ]));
754+ return std::make_unique<RVectorDeleter>(fSubfields [ 0 ]-> GetAlignment () );
703755}
704756
705757std::vector<ROOT ::RFieldBase::RValue> ROOT::RVectorField::SplitValue (const RValue &value) const
@@ -986,11 +1038,18 @@ void ROOT::RArrayAsVectorField::GenerateColumns()
9861038 throw RException (R__FAIL (" RArrayAsVectorField fields must only be used for reading" ));
9871039}
9881040
1041+ void ROOT::RArrayAsVectorField::ConstructValue (void *where) const
1042+ {
1043+ ConstructVector (where, fSubfields [0 ]->GetAlignment ());
1044+ }
1045+
9891046std::unique_ptr<ROOT ::RFieldBase::RDeleter> ROOT::RArrayAsVectorField::GetDeleter () const
9901047{
991- if (fItemDeleter )
992- return std::make_unique<RVectorField::RVectorDeleter>(fItemSize , GetDeleterOf (*fSubfields [0 ]));
993- return std::make_unique<RVectorField::RVectorDeleter>();
1048+ if (fItemDeleter ) {
1049+ return std::make_unique<RVectorField::RVectorDeleter>(fItemSize , fSubfields [0 ]->GetAlignment (),
1050+ GetDeleterOf (*fSubfields [0 ]));
1051+ }
1052+ return std::make_unique<RVectorField::RVectorDeleter>(fSubfields [0 ]->GetAlignment ());
9941053}
9951054
9961055void ROOT::RArrayAsVectorField::ReadGlobalImpl (ROOT ::NTupleSize_t globalIndex, void *to)
0 commit comments