@@ -665,6 +665,7 @@ ROOT::Experimental::RSoAField::RSoAField(std::string_view fieldName, const RSoAF
665665 fRecordMemberFields = fSubfields [0 ]->GetMutableSubfields ();
666666 for (const auto f : fRecordMemberFields )
667667 fRecordMemberDeleters .emplace_back (GetDeleterOf (*f));
668+ fLockSplitFields = std::make_unique<std::mutex>();
668669}
669670
670671ROOT ::Experimental::RSoAField::RSoAField(std::string_view fieldName, std::string_view className)
@@ -775,6 +776,7 @@ ROOT::Experimental::RSoAField::RSoAField(std::string_view fieldName, TClass *clS
775776 fTypeAlias = renormalizedAlias;
776777
777778 fTraits |= kTraitSoACollection | kTraitTypeChecksum ;
779+ fLockSplitFields = std::make_unique<std::mutex>();
778780}
779781
780782std::unique_ptr<ROOT ::RFieldBase> ROOT::Experimental::RSoAField::CloneImpl (std::string_view newName) const
@@ -880,10 +882,31 @@ void ROOT::Experimental::RSoAField::RSoADeleter::operator()(void *objPtr, bool d
880882 RDeleter::operator ()(objPtr, dtorOnly);
881883}
882884
883- std::vector<ROOT ::RFieldBase::RValue> ROOT::Experimental::RSoAField::SplitValue (const RValue & /* value */ ) const
885+ std::vector<ROOT ::RFieldBase::RValue> ROOT::Experimental::RSoAField::SplitValue (const RValue &value) const
884886{
885- throw RException (R__FAIL (" not yet implemented" ));
886- return std::vector<RValue>();
887+ const auto nSoAMembers = fSoAMemberOffsets .size ();
888+
889+ {
890+ std::lock_guard<std::mutex> lockGuard (*fLockSplitFields );
891+ if (!fSplitFields ) {
892+ fSplitFields = std::make_unique<std::vector<std::unique_ptr<ROOT ::RRVecField>>>();
893+ fSplitFields ->reserve (nSoAMembers);
894+ for (std::size_t i = 0 ; i < nSoAMembers; ++i) {
895+ const auto itemField = fRecordMemberFields [i];
896+ fSplitFields ->emplace_back (std::make_unique<RRVecField>(itemField->GetFieldName (), itemField->Clone (" _0" )));
897+ }
898+ }
899+ }
900+
901+ auto valuePtr = value.GetPtr <void >();
902+ auto soaPtr = static_cast <unsigned char *>(valuePtr.get ());
903+ std::vector<RValue> values;
904+ values.reserve (nSoAMembers);
905+ for (std::size_t i = 0 ; i < nSoAMembers; ++i) {
906+ values.emplace_back (
907+ (*fSplitFields )[i]->BindValue (std::shared_ptr<void >(valuePtr, soaPtr + fSoAMemberOffsets [i])));
908+ }
909+ return values;
887910}
888911
889912size_t ROOT::Experimental::RSoAField::GetValueSize () const
0 commit comments