@@ -40,6 +40,29 @@ std::size_t GetAlignOfVector()
4040 return alignof (std::vector<char >);
4141}
4242
43+ void ConstructVector (void *where, std::size_t alignOfValue)
44+ {
45+ static_assert (ROOT ::RVectorField::kMaxItemAlignment == 4096 );
46+ // clang-format off
47+ switch (alignOfValue) {
48+ case 1 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 1 >>(); break ;
49+ case 2 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 2 >>(); break ;
50+ case 4 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 4 >>(); break ;
51+ case 8 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 8 >>(); break ;
52+ case 16 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 16 >>(); break ;
53+ case 32 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 32 >>(); break ;
54+ case 64 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 64 >>(); break ;
55+ case 128 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 128 >>(); break ;
56+ case 256 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 256 >>(); break ;
57+ case 512 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 512 >>(); break ;
58+ case 1024 : new (where) std::vector<ROOT ::Internal::RAlignedStorage<1024 >>(); break ;
59+ case 2048 : new (where) std::vector<ROOT ::Internal::RAlignedStorage<2048 >>(); break ;
60+ case 4096 : new (where) std::vector<ROOT ::Internal::RAlignedStorage<4096 >>(); break ;
61+ default : throw ROOT::RException (R__FAIL (std::string (" Unsupported alignment: " ) + std::to_string (alignOfValue)));
62+ }
63+ // clang-format on
64+ }
65+
4366} // anonymous namespace
4467
4568ROOT ::RArrayField::RArrayField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField,
@@ -672,33 +695,65 @@ void ROOT::RVectorField::ReconcileOnDiskField(const RNTupleDescriptor &desc)
672695 EnsureMatchingOnDiskCollection (desc).ThrowOnError ();
673696}
674697
675- ROOT ::RVectorField::RVectorDeleter::RVectorDeleter() : RDeleter(GetAlignOfVector()) {}
698+ void ROOT::RVectorField::ConstructValue (void *where) const
699+ {
700+ ConstructVector (where, fSubfields [0 ]->GetAlignment ());
701+ }
702+
703+ ROOT ::RVectorField::RVectorDeleter::RVectorDeleter(std::size_t itemAlignment)
704+ : RDeleter(GetAlignOfVector()), fItemAlignment (itemAlignment)
705+ {
706+ }
676707
677- ROOT ::RVectorField::RVectorDeleter::RVectorDeleter(std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
678- : 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()),
711+ fItemSize (itemSize),
712+ fItemAlignment(itemAlignment),
713+ fItemDeleter(std::move(itemDeleter))
679714{
680715}
681716
682717void ROOT::RVectorField::RVectorDeleter::operator ()(void *objPtr, bool dtorOnly)
683718{
684719 auto vecPtr = static_cast <std::vector<char > *>(objPtr);
685720 if (fItemDeleter ) {
686- R__ASSERT (fItemSize > 0 );
687- R__ASSERT ((vecPtr->size () % fItemSize ) == 0 );
721+ assert (fItemSize > 0 );
688722 auto nItems = vecPtr->size () / fItemSize ;
723+ assert ((vecPtr->size () % fItemSize ) == 0 );
689724 for (std::size_t i = 0 ; i < nItems; ++i) {
690725 fItemDeleter ->operator ()(vecPtr->data () + (i * fItemSize ), true /* dtorOnly */ );
691726 }
692727 }
693- std::destroy_at (vecPtr);
728+
729+ static_assert (kMaxItemAlignment == 4096 );
730+ // clang-format off
731+ switch (fItemAlignment ) {
732+ case 1 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 1 >> *>(objPtr)); break ;
733+ case 2 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 2 >> *>(objPtr)); break ;
734+ case 4 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 4 >> *>(objPtr)); break ;
735+ case 8 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 8 >> *>(objPtr)); break ;
736+ case 16 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 16 >> *>(objPtr)); break ;
737+ case 32 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 32 >> *>(objPtr)); break ;
738+ case 64 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 64 >> *>(objPtr)); break ;
739+ case 128 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 128 >> *>(objPtr)); break ;
740+ case 256 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 256 >> *>(objPtr)); break ;
741+ case 512 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 512 >> *>(objPtr)); break ;
742+ case 1024 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage<1024 >> *>(objPtr)); break ;
743+ case 2048 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage<2048 >> *>(objPtr)); break ;
744+ case 4096 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage<4096 >> *>(objPtr)); break ;
745+ default : throw ROOT::RException (R__FAIL (std::string (" Unsupported alignment: " ) + std::to_string (fItemAlignment )));
746+ }
747+ // clang-format on
748+
694749 RDeleter::operator ()(objPtr, dtorOnly);
695750}
696751
697752std::unique_ptr<ROOT ::RFieldBase::RDeleter> ROOT::RVectorField::GetDeleter () const
698753{
699754 if (fItemDeleter )
700- return std::make_unique<RVectorDeleter>(fItemSize , GetDeleterOf (*fSubfields [0 ]));
701- return std::make_unique<RVectorDeleter>();
755+ return std::make_unique<RVectorDeleter>(fItemSize , fSubfields [ 0 ]-> GetAlignment (), GetDeleterOf (*fSubfields [0 ]));
756+ return std::make_unique<RVectorDeleter>(fSubfields [ 0 ]-> GetAlignment () );
702757}
703758
704759std::vector<ROOT ::RFieldBase::RValue> ROOT::RVectorField::SplitValue (const RValue &value) const
@@ -985,11 +1040,18 @@ void ROOT::RArrayAsVectorField::GenerateColumns()
9851040 throw RException (R__FAIL (" RArrayAsVectorField fields must only be used for reading" ));
9861041}
9871042
1043+ void ROOT::RArrayAsVectorField::ConstructValue (void *where) const
1044+ {
1045+ ConstructVector (where, fSubfields [0 ]->GetAlignment ());
1046+ }
1047+
9881048std::unique_ptr<ROOT ::RFieldBase::RDeleter> ROOT::RArrayAsVectorField::GetDeleter () const
9891049{
990- if (fItemDeleter )
991- return std::make_unique<RVectorField::RVectorDeleter>(fItemSize , GetDeleterOf (*fSubfields [0 ]));
992- return std::make_unique<RVectorField::RVectorDeleter>();
1050+ if (fItemDeleter ) {
1051+ return std::make_unique<RVectorField::RVectorDeleter>(fItemSize , fSubfields [0 ]->GetAlignment (),
1052+ GetDeleterOf (*fSubfields [0 ]));
1053+ }
1054+ return std::make_unique<RVectorField::RVectorDeleter>(fSubfields [0 ]->GetAlignment ());
9931055}
9941056
9951057void ROOT::RArrayAsVectorField::ReadGlobalImpl (ROOT ::NTupleSize_t globalIndex, void *to)
0 commit comments