@@ -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,65 @@ 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+ {
707+ }
677708
678- ROOT ::RVectorField::RVectorDeleter::RVectorDeleter(std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
679- : RDeleter(GetAlignOfVector()), fItemSize (itemSize), fItemDeleter (std::move(itemDeleter))
709+ ROOT ::RVectorField::RVectorDeleter::RVectorDeleter(std::size_t itemSize, std::size_t itemAlignment,
710+ std::unique_ptr<RDeleter> itemDeleter)
711+ : RDeleter(GetAlignOfVector()),
712+ fItemSize (itemSize),
713+ fItemAlignment(itemAlignment),
714+ fItemDeleter(std::move(itemDeleter))
680715{
681716}
682717
683718void ROOT::RVectorField::RVectorDeleter::operator ()(void *objPtr, bool dtorOnly)
684719{
685720 auto vecPtr = static_cast <std::vector<char > *>(objPtr);
686721 if (fItemDeleter ) {
687- R__ASSERT (fItemSize > 0 );
688- R__ASSERT ((vecPtr->size () % fItemSize ) == 0 );
722+ assert (fItemSize > 0 );
689723 auto nItems = vecPtr->size () / fItemSize ;
724+ assert ((vecPtr->size () % fItemSize ) == 0 );
690725 for (std::size_t i = 0 ; i < nItems; ++i) {
691726 fItemDeleter ->operator ()(vecPtr->data () + (i * fItemSize ), true /* dtorOnly */ );
692727 }
693728 }
694- std::destroy_at (vecPtr);
729+
730+ if (fItemAlignment <= sizeof (std::max_align_t )) {
731+ std::destroy_at (vecPtr);
732+ } else {
733+ static_assert (sizeof (std::max_align_t ) >= 8 && ROOT ::RFieldBase::kMaxAlignment == 4096 );
734+ // clang-format off
735+ switch (fItemAlignment ) {
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 : R__ASSERT (false );
746+ }
747+ // clang-format on
748+ }
749+
695750 RDeleter::operator ()(objPtr, dtorOnly);
696751}
697752
698753std::unique_ptr<ROOT ::RFieldBase::RDeleter> ROOT::RVectorField::GetDeleter () const
699754{
700755 if (fItemDeleter )
701- return std::make_unique<RVectorDeleter>(fItemSize , GetDeleterOf (*fSubfields [0 ]));
702- return std::make_unique<RVectorDeleter>();
756+ return std::make_unique<RVectorDeleter>(fItemSize , fSubfields [ 0 ]-> GetAlignment (), GetDeleterOf (*fSubfields [0 ]));
757+ return std::make_unique<RVectorDeleter>(fSubfields [ 0 ]-> GetAlignment () );
703758}
704759
705760std::vector<ROOT ::RFieldBase::RValue> ROOT::RVectorField::SplitValue (const RValue &value) const
@@ -986,11 +1041,18 @@ void ROOT::RArrayAsVectorField::GenerateColumns()
9861041 throw RException (R__FAIL (" RArrayAsVectorField fields must only be used for reading" ));
9871042}
9881043
1044+ void ROOT::RArrayAsVectorField::ConstructValue (void *where) const
1045+ {
1046+ ConstructVector (where, fSubfields [0 ]->GetAlignment ());
1047+ }
1048+
9891049std::unique_ptr<ROOT ::RFieldBase::RDeleter> ROOT::RArrayAsVectorField::GetDeleter () const
9901050{
991- if (fItemDeleter )
992- return std::make_unique<RVectorField::RVectorDeleter>(fItemSize , GetDeleterOf (*fSubfields [0 ]));
993- return std::make_unique<RVectorField::RVectorDeleter>();
1051+ if (fItemDeleter ) {
1052+ return std::make_unique<RVectorField::RVectorDeleter>(fItemSize , fSubfields [0 ]->GetAlignment (),
1053+ GetDeleterOf (*fSubfields [0 ]));
1054+ }
1055+ return std::make_unique<RVectorField::RVectorDeleter>(fSubfields [0 ]->GetAlignment ());
9941056}
9951057
9961058void ROOT::RArrayAsVectorField::ReadGlobalImpl (ROOT ::NTupleSize_t globalIndex, void *to)
0 commit comments