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