@@ -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
@@ -879,10 +881,31 @@ void ROOT::Experimental::RSoAField::RSoADeleter::operator()(void *objPtr, bool d
879881 RDeleter::operator ()(objPtr, dtorOnly);
880882}
881883
882- std::vector<ROOT ::RFieldBase::RValue> ROOT::Experimental::RSoAField::SplitValue (const RValue & /* value */ ) const
884+ std::vector<ROOT ::RFieldBase::RValue> ROOT::Experimental::RSoAField::SplitValue (const RValue &value) const
883885{
884- throw RException (R__FAIL (" not yet implemented" ));
885- return std::vector<RValue>();
886+ const auto nSoAMembers = fSoAMemberOffsets .size ();
887+
888+ {
889+ std::lock_guard<std::mutex> lockGuard (*fLockSplitFields );
890+ if (!fSplitFields ) {
891+ fSplitFields = std::make_unique<std::vector<std::unique_ptr<ROOT ::RRVecField>>>();
892+ fSplitFields ->reserve (nSoAMembers);
893+ for (std::size_t i = 0 ; i < nSoAMembers; ++i) {
894+ const auto itemField = fRecordMemberFields [i];
895+ fSplitFields ->emplace_back (std::make_unique<RRVecField>(itemField->GetFieldName (), itemField->Clone (" _0" )));
896+ }
897+ }
898+ }
899+
900+ auto valuePtr = value.GetPtr <void >();
901+ auto soaPtr = static_cast <unsigned char *>(valuePtr.get ());
902+ std::vector<RValue> values;
903+ values.reserve (nSoAMembers);
904+ for (std::size_t i = 0 ; i < nSoAMembers; ++i) {
905+ values.emplace_back (
906+ (*fSplitFields )[i]->BindValue (std::shared_ptr<void >(valuePtr, soaPtr + fSoAMemberOffsets [i])));
907+ }
908+ return values;
886909}
887910
888911size_t ROOT::Experimental::RSoAField::GetValueSize () const
0 commit comments