@@ -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+ if (alignOfValue <= sizeof (std::max_align_t )) {
46+ new (where) std::vector<char >();
47+ } else {
48+ static_assert (sizeof (std::max_align_t ) >= 8 && ROOT ::RVectorField::kMaxItemAlignment == 4096 );
49+ // clang-format off
50+ switch (alignOfValue) {
51+ case 16 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 16 >>(); break ;
52+ case 32 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 32 >>(); break ;
53+ case 64 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 64 >>(); break ;
54+ case 128 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 128 >>(); break ;
55+ case 256 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 256 >>(); break ;
56+ case 512 : new (where) std::vector<ROOT ::Internal::RAlignedStorage< 512 >>(); break ;
57+ case 1024 : new (where) std::vector<ROOT ::Internal::RAlignedStorage<1024 >>(); break ;
58+ case 2048 : new (where) std::vector<ROOT ::Internal::RAlignedStorage<2048 >>(); break ;
59+ case 4096 : new (where) std::vector<ROOT ::Internal::RAlignedStorage<4096 >>(); break ;
60+ default : throw ROOT::RException (R__FAIL (std::string (" Unsupported alignment: " ) + std::to_string (alignOfValue)));
61+ }
62+ // clang-format on
63+ }
64+ }
65+
4366} // anonymous namespace
4467
4568ROOT ::RArrayField::RArrayField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField,
@@ -669,33 +692,65 @@ void ROOT::RVectorField::ReconcileOnDiskField(const RNTupleDescriptor &desc)
669692 EnsureMatchingOnDiskCollection (desc).ThrowOnError ();
670693}
671694
672- ROOT ::RVectorField::RVectorDeleter::RVectorDeleter() : RDeleter(GetAlignOfVector()) {}
695+ void ROOT::RVectorField::ConstructValue (void *where) const
696+ {
697+ ConstructVector (where, fSubfields [0 ]->GetAlignment ());
698+ }
673699
674- ROOT ::RVectorField::RVectorDeleter::RVectorDeleter(std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
675- : RDeleter(GetAlignOfVector()), fItemSize (itemSize), fItemDeleter (std::move(itemDeleter))
700+ ROOT ::RVectorField::RVectorDeleter::RVectorDeleter(std::size_t itemAlignment)
701+ : RDeleter(GetAlignOfVector()), fItemAlignment (itemAlignment)
702+ {
703+ }
704+
705+ ROOT ::RVectorField::RVectorDeleter::RVectorDeleter(std::size_t itemSize, std::size_t itemAlignment,
706+ std::unique_ptr<RDeleter> itemDeleter)
707+ : RDeleter(GetAlignOfVector()),
708+ fItemSize (itemSize),
709+ fItemAlignment(itemAlignment),
710+ fItemDeleter(std::move(itemDeleter))
676711{
677712}
678713
679714void ROOT::RVectorField::RVectorDeleter::operator ()(void *objPtr, bool dtorOnly)
680715{
681716 auto vecPtr = static_cast <std::vector<char > *>(objPtr);
682717 if (fItemDeleter ) {
683- R__ASSERT (fItemSize > 0 );
684- R__ASSERT ((vecPtr->size () % fItemSize ) == 0 );
718+ assert (fItemSize > 0 );
685719 auto nItems = vecPtr->size () / fItemSize ;
720+ assert ((vecPtr->size () % fItemSize ) == 0 );
686721 for (std::size_t i = 0 ; i < nItems; ++i) {
687722 fItemDeleter ->operator ()(vecPtr->data () + (i * fItemSize ), true /* dtorOnly */ );
688723 }
689724 }
690- std::destroy_at (vecPtr);
725+
726+ if (fItemAlignment <= sizeof (std::max_align_t )) {
727+ std::destroy_at (vecPtr);
728+ } else {
729+ static_assert (sizeof (std::max_align_t ) >= 8 && kMaxItemAlignment == 4096 );
730+ // clang-format off
731+ switch (fItemAlignment ) {
732+ case 16 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 16 >> *>(objPtr)); break ;
733+ case 32 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 32 >> *>(objPtr)); break ;
734+ case 64 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 64 >> *>(objPtr)); break ;
735+ case 128 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 128 >> *>(objPtr)); break ;
736+ case 256 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 256 >> *>(objPtr)); break ;
737+ case 512 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage< 512 >> *>(objPtr)); break ;
738+ case 1024 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage<1024 >> *>(objPtr)); break ;
739+ case 2048 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage<2048 >> *>(objPtr)); break ;
740+ case 4096 : std::destroy_at (static_cast <std::vector<Internal::RAlignedStorage<4096 >> *>(objPtr)); break ;
741+ default : R__ASSERT (false );
742+ }
743+ // clang-format on
744+ }
745+
691746 RDeleter::operator ()(objPtr, dtorOnly);
692747}
693748
694749std::unique_ptr<ROOT ::RFieldBase::RDeleter> ROOT::RVectorField::GetDeleter () const
695750{
696751 if (fItemDeleter )
697- return std::make_unique<RVectorDeleter>(fItemSize , GetDeleterOf (*fSubfields [0 ]));
698- return std::make_unique<RVectorDeleter>();
752+ return std::make_unique<RVectorDeleter>(fItemSize , fSubfields [ 0 ]-> GetAlignment (), GetDeleterOf (*fSubfields [0 ]));
753+ return std::make_unique<RVectorDeleter>(fSubfields [ 0 ]-> GetAlignment () );
699754}
700755
701756std::vector<ROOT ::RFieldBase::RValue> ROOT::RVectorField::SplitValue (const RValue &value) const
@@ -982,11 +1037,18 @@ void ROOT::RArrayAsVectorField::GenerateColumns()
9821037 throw RException (R__FAIL (" RArrayAsVectorField fields must only be used for reading" ));
9831038}
9841039
1040+ void ROOT::RArrayAsVectorField::ConstructValue (void *where) const
1041+ {
1042+ ConstructVector (where, fSubfields [0 ]->GetAlignment ());
1043+ }
1044+
9851045std::unique_ptr<ROOT ::RFieldBase::RDeleter> ROOT::RArrayAsVectorField::GetDeleter () const
9861046{
987- if (fItemDeleter )
988- return std::make_unique<RVectorField::RVectorDeleter>(fItemSize , GetDeleterOf (*fSubfields [0 ]));
989- return std::make_unique<RVectorField::RVectorDeleter>();
1047+ if (fItemDeleter ) {
1048+ return std::make_unique<RVectorField::RVectorDeleter>(fItemSize , fSubfields [0 ]->GetAlignment (),
1049+ GetDeleterOf (*fSubfields [0 ]));
1050+ }
1051+ return std::make_unique<RVectorField::RVectorDeleter>(fSubfields [0 ]->GetAlignment ());
9901052}
9911053
9921054void ROOT::RArrayAsVectorField::ReadGlobalImpl (ROOT ::NTupleSize_t globalIndex, void *to)
0 commit comments